Fetch cards from Cobot, log access

This commit is contained in:
Dana Woodman 2018-07-10 16:25:05 -07:00
parent 9c11a0506a
commit 710f7953b6
11 changed files with 155 additions and 94 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)
} }
} }

View File

@ -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)
})
} }
} }

View File

@ -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')
} }

View File

@ -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
View 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)
}

View File

@ -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!'))

View File

@ -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

View File

@ -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)