mirror of
https://github.com/zyphlar/doorlock.git
synced 2024-04-03 21:36:03 +00:00
Fetch cards from Cobot, log access
This commit is contained in:
parent
9c11a0506a
commit
710f7953b6
147
doorlock.js
147
doorlock.js
|
@ -5,6 +5,7 @@ const https = require('https')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const SerialPort = require('serialport')
|
const SerialPort = require('serialport')
|
||||||
const tessel = require('tessel')
|
const tessel = require('tessel')
|
||||||
|
const relaylib = require('relay-mono')
|
||||||
const {
|
const {
|
||||||
CARD_UPDATE_INTERVAL,
|
CARD_UPDATE_INTERVAL,
|
||||||
CARDS_PATH,
|
CARDS_PATH,
|
||||||
|
@ -21,6 +22,22 @@ const {
|
||||||
|
|
||||||
const TEST = ENV === 'test'
|
const TEST = ENV === 'test'
|
||||||
|
|
||||||
|
const relay = relaylib.use(tessel.port['A'])
|
||||||
|
|
||||||
|
relay.on('ready', function relayReady() {
|
||||||
|
console.log('Ready!')
|
||||||
|
relay.turnOff(1, function toggleOneResult(err) {
|
||||||
|
if (err) console.log('Err toggling 1', err)
|
||||||
|
})
|
||||||
|
relay.turnOff(2, function toggleOneResult(err) {
|
||||||
|
if (err) console.log('Err toggling 1', err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
relay.on('latch', function(channel, value) {
|
||||||
|
console.log('latch on relay channel ' + channel + ' switched to', value)
|
||||||
|
})
|
||||||
|
|
||||||
class Cobot {
|
class Cobot {
|
||||||
constructor(token) {
|
constructor(token) {
|
||||||
this.token = token
|
this.token = token
|
||||||
|
@ -206,53 +223,57 @@ class DoorLock {
|
||||||
return device.pipe(parser)
|
return device.pipe(parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
validateCard(number) {
|
// validateCard(number) {
|
||||||
console.log('raw:', JSON.stringify(number.toString().trim()))
|
// console.log('raw:', JSON.stringify(number.toString().trim()))
|
||||||
const scanned = parseInt(
|
// const scanned = parseInt(
|
||||||
number
|
// number
|
||||||
.toString('hex')
|
// .toString('hex')
|
||||||
.trim() // Remove any whiespace or newlines
|
// .trim() // Remove any whiespace or newlines
|
||||||
.replace('\u0003', '') // Remove "end of text" character
|
// .replace('\u0003', '') // Remove "end of text" character
|
||||||
.replace('\u0002', '') // Remove "start of text" character
|
// .replace('\u0002', '') // Remove "start of text" character
|
||||||
.substring(3) // Strip off con
|
// .substring(3) // Strip off con
|
||||||
.slice(0, -2), // Strip off checksum
|
// .slice(0, -2), // Strip off checksum
|
||||||
16
|
// 16
|
||||||
)
|
// )
|
||||||
|
|
||||||
this.log('Scanned card:', scanned)
|
// this.log('Scanned card:', scanned)
|
||||||
|
|
||||||
return this.readCardsFromSDCard().then(cards => {
|
// return this.readCardsFromSDCard().then(cards => {
|
||||||
const card = cards.find(c => parseInt(c.number) === scanned)
|
// const card = cards.find(c => parseInt(c.number) === scanned)
|
||||||
|
|
||||||
if (card) {
|
// if (card) {
|
||||||
const name = card.name.split(' ')[0]
|
// const name = card.name.split(' ')[0]
|
||||||
this.log(`Welcome in ${name}!`, scanned)
|
// this.log(`Welcome in ${name}!`, scanned)
|
||||||
this.openDoor()
|
// this.openDoor()
|
||||||
} else {
|
// } else {
|
||||||
this.log('Card is invalid:', scanned)
|
// this.log('Card is invalid:', scanned)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
openDoor() {
|
// openDoor() {
|
||||||
return new Promise(resolve => {
|
// return new Promise(resolve => {
|
||||||
this.log('Opening door!')
|
// this.log('Opening door!')
|
||||||
|
|
||||||
// TODO: trigger door opening...
|
// // TODO: trigger door opening...
|
||||||
if (tessel.led) tessel.led[3].on()
|
// if (tessel.led) tessel.led[3].on()
|
||||||
|
// relay.turnOn(1, console.log)
|
||||||
|
// relay.turnOn(2, console.log)
|
||||||
|
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// TODO: trigger door closing
|
// // TODO: trigger door closing
|
||||||
this.closeDoor()
|
// this.closeDoor()
|
||||||
resolve()
|
// resolve()
|
||||||
}, DOOR_OPEN_DELAY)
|
// }, DOOR_OPEN_DELAY)
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
closeDoor() {
|
// closeDoor() {
|
||||||
this.log('Closing door!')
|
// this.log('Closing door!')
|
||||||
if (tessel.led) tessel.led[3].off()
|
// if (tessel.led) tessel.led[3].off()
|
||||||
}
|
// relay.turnOff(1, console.log)
|
||||||
|
// relay.turnOff(2, console.log)
|
||||||
|
// }
|
||||||
|
|
||||||
fetchCardListFromCobot() {
|
fetchCardListFromCobot() {
|
||||||
this.log('Updating cards...')
|
this.log('Updating cards...')
|
||||||
|
@ -274,31 +295,31 @@ class DoorLock {
|
||||||
.catch(this.logErrorMessage)
|
.catch(this.logErrorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
sortCardsByName(cards) {
|
// sortCardsByName(cards) {
|
||||||
const sorted = cards.sort(
|
// const sorted = cards.sort(
|
||||||
(a, b) => (a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1)
|
// (a, b) => (a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1)
|
||||||
)
|
// )
|
||||||
return sorted
|
// return sorted
|
||||||
}
|
// }
|
||||||
|
|
||||||
writeCardsToSDCard(cards) {
|
// writeCardsToSDCard(cards) {
|
||||||
const json = JSON.stringify(this.sortCardsByName(cards))
|
// const json = JSON.stringify(this.sortCardsByName(cards))
|
||||||
return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
fs.writeFile(CARDS_PATH, json, err => {
|
// fs.writeFile(CARDS_PATH, json, err => {
|
||||||
if (err) return reject(err)
|
// if (err) return reject(err)
|
||||||
resolve()
|
// resolve()
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
readCardsFromSDCard() {
|
// readCardsFromSDCard() {
|
||||||
return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
fs.readFile(CARDS_PATH, (err, data) => {
|
// fs.readFile(CARDS_PATH, (err, data) => {
|
||||||
if (err) return reject(err)
|
// if (err) return reject(err)
|
||||||
resolve(JSON.parse(data))
|
// resolve(JSON.parse(data))
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
logErrorMessage(error) {
|
logErrorMessage(error) {
|
||||||
if (TEST) return
|
if (TEST) return
|
||||||
|
|
|
@ -47,6 +47,7 @@ p {
|
||||||
.button:hover {
|
.button:hover {
|
||||||
background: var(--color-primary-dark);
|
background: var(--color-primary-dark);
|
||||||
border-color: var(--color-primary-dark);
|
border-color: var(--color-primary-dark);
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
.button-danger {
|
.button-danger {
|
||||||
background: var(--color-danger);
|
background: var(--color-danger);
|
||||||
|
|
|
@ -15,6 +15,7 @@ module.exports = class Cards {
|
||||||
|
|
||||||
static write(cards) {
|
static write(cards) {
|
||||||
const json = JSON.stringify(this.sortByName(cards))
|
const json = JSON.stringify(this.sortByName(cards))
|
||||||
|
console.log('WRITING CARDS:', json)
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.writeFile(CARDS_PATH, json, err => {
|
fs.writeFile(CARDS_PATH, json, err => {
|
||||||
if (err) return reject(err)
|
if (err) return reject(err)
|
||||||
|
@ -24,7 +25,9 @@ module.exports = class Cards {
|
||||||
}
|
}
|
||||||
|
|
||||||
static validate(number) {
|
static validate(number) {
|
||||||
return this.all().then(cards => cards.find(c => c.number === number))
|
return this.all().then(cards =>
|
||||||
|
cards.find(c => parseInt(c.number, 10) === parseInt(number, 10))
|
||||||
|
)
|
||||||
// console.log(':', JSON.stringify(number.toString().trim()))
|
// console.log(':', JSON.stringify(number.toString().trim()))
|
||||||
// const scanned = parseInt(
|
// const scanned = parseInt(
|
||||||
// number
|
// number
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
const Cards = require('./cards')
|
||||||
const https = require('https')
|
const https = require('https')
|
||||||
const {
|
const {
|
||||||
CARD_UPDATE_INTERVAL,
|
CARD_UPDATE_INTERVAL,
|
||||||
|
@ -7,7 +8,7 @@ const {
|
||||||
COBOT_SCOPE,
|
COBOT_SCOPE,
|
||||||
COBOT_USER_EMAIL,
|
COBOT_USER_EMAIL,
|
||||||
COBOT_USER_PASSWORD,
|
COBOT_USER_PASSWORD,
|
||||||
} = require('./constants')
|
} = require('../../constants')
|
||||||
|
|
||||||
module.exports = class Cobot {
|
module.exports = class Cobot {
|
||||||
constructor(token) {
|
constructor(token) {
|
||||||
|
@ -144,22 +145,17 @@ module.exports = class Cobot {
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCards() {
|
static getCards() {
|
||||||
this.log('Updating cards...')
|
console.log('Updating cards...')
|
||||||
this.authorize()
|
return this.authorize()
|
||||||
.then(cobot => cobot.cards())
|
.then(cobot => cobot.cards())
|
||||||
.then(cards => {
|
.then(cards => Cards.write(cards))
|
||||||
this.log('UPDATED CARDS:', cards.length, 'cards')
|
// .then(() => {
|
||||||
this.writeCardsToSDCard(cards)
|
// console.log(
|
||||||
this.cards = cards
|
// 'Updating card list in',
|
||||||
})
|
// CARD_UPDATE_INTERVAL / 1000,
|
||||||
.then(() => {
|
// 'seconds...'
|
||||||
this.log(
|
// )
|
||||||
'Updating card list in',
|
// setTimeout(this.getCards.bind(this), CARD_UPDATE_INTERVAL)
|
||||||
CARD_UPDATE_INTERVAL / 1000,
|
// })
|
||||||
'seconds...'
|
|
||||||
)
|
|
||||||
setTimeout(this.fetchCardListFromCobot.bind(this), CARD_UPDATE_INTERVAL)
|
|
||||||
})
|
|
||||||
.catch(this.logErrorMessage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,32 @@
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const LOGS_PATH = path.join(process.cwd(), 'logs.json')
|
||||||
|
|
||||||
module.exports = class Logs {
|
module.exports = class Logs {
|
||||||
static all() {
|
static all() {
|
||||||
return Promise.all([
|
return new Promise((resolve, reject) => {
|
||||||
{
|
fs.readFile(LOGS_PATH, (err, data) => {
|
||||||
timestamp: 1531256719431,
|
if (err) return reject(err)
|
||||||
card: { name: 'John Smith', number: '1234023423423' },
|
resolve(JSON.parse(data))
|
||||||
},
|
})
|
||||||
{
|
})
|
||||||
timestamp: 1531256756227,
|
}
|
||||||
card: { name: 'Jane Doe', number: '2394723984752983' },
|
|
||||||
},
|
static write(logs) {
|
||||||
])
|
const json = JSON.stringify(logs)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.writeFile(LOGS_PATH, json, err => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static log(access) {
|
||||||
|
return this.all().then(all => {
|
||||||
|
all.push(access)
|
||||||
|
return this.write(all)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const Cards = require('../models/cards')
|
const Cards = require('../models/cards')
|
||||||
|
const Logs = require('../models/logs')
|
||||||
|
|
||||||
module.exports = (req, res) => {
|
module.exports = (req, res) => {
|
||||||
const rfid = req.body.rfid.trim().toLowerCase()
|
const rfid = req.body.rfid.trim().toLowerCase()
|
||||||
|
@ -9,6 +10,9 @@ module.exports = (req, res) => {
|
||||||
// TODO: add to log if success
|
// TODO: add to log if success
|
||||||
if (card) {
|
if (card) {
|
||||||
res.redirect('/success?name=' + card.name)
|
res.redirect('/success?name=' + card.name)
|
||||||
|
Logs.log({ timestamp: new Date().getTime(), card }).then(() =>
|
||||||
|
console.log('Logged!')
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
res.redirect('/failure')
|
res.redirect('/failure')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
const Logs = require('../models/logs')
|
const Logs = require('../models/logs')
|
||||||
|
|
||||||
module.exports = (req, res) => {
|
module.exports = (req, res) => {
|
||||||
Logs.all().then(logs => res.render('logs', { logs }))
|
Logs.all().then(logs => {
|
||||||
|
logs = logs.sort((a, b) => a.timestamp < b.timestamp)
|
||||||
|
res.render('logs', { logs })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
10
src/routes/update.js
Normal file
10
src/routes/update.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const Cobot = require('../models/cobot')
|
||||||
|
|
||||||
|
module.exports = (req, res) => {
|
||||||
|
Cobot.getCards()
|
||||||
|
.then(cards => {
|
||||||
|
console.log('GOT CARDS:', cards)
|
||||||
|
res.redirect('/')
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ app.get('/success', require('./routes/success'))
|
||||||
app.get('/failure', require('./routes/failure'))
|
app.get('/failure', require('./routes/failure'))
|
||||||
app.get('/cards', require('./routes/cards'))
|
app.get('/cards', require('./routes/cards'))
|
||||||
app.get('/logs', require('./routes/logs'))
|
app.get('/logs', require('./routes/logs'))
|
||||||
|
app.get('/update', require('./routes/update'))
|
||||||
app.get('/', (req, res) => res.render('home', {}))
|
app.get('/', (req, res) => res.render('home', {}))
|
||||||
|
|
||||||
app.listen(PORT, () => console.log('Example app listening on port 3000!'))
|
app.listen(PORT, () => console.log('Example app listening on port 3000!'))
|
||||||
|
|
|
@ -5,7 +5,11 @@ block title
|
||||||
| Cards
|
| Cards
|
||||||
|
|
||||||
block content
|
block content
|
||||||
h1.page-heading Cards
|
a.button.button-sm.fr(href='/update')
|
||||||
|
i.fas.fa-sync.mr-sm
|
||||||
|
| Update
|
||||||
|
h1.page-heading
|
||||||
|
| Cards
|
||||||
table.collapse.w-100
|
table.collapse.w-100
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
|
|
|
@ -14,5 +14,5 @@ block content
|
||||||
a(href='/') ← Back
|
a(href='/') ← Back
|
||||||
|
|
||||||
script.
|
script.
|
||||||
//- setTimeout(function () { window.location.href = '/' }, 6000)
|
setTimeout(function () { window.location.href = '/' }, 4000)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user