index.js 3,3 ko
Newer Older
Quentin Vauthier's avatar
Quentin Vauthier a validé
import connection from './db.js'
import { parse } from 'path'
Quentin Vauthier's avatar
Quentin Vauthier a validé
import wss from './websocket.js'
import {port, parser} from './port.js'
Quentin Vauthier's avatar
Quentin Vauthier a validé

Quentin Vauthier's avatar
Quentin Vauthier a validé
let status = null
let history = null
Quentin Vauthier's avatar
Quentin Vauthier a validé

Quentin Vauthier's avatar
Quentin Vauthier a validé
// If port is already open, fetch status from arduino, otherwise wait for port to open
// the delay is to make sure the arduino is ready to receive data
if(port.isOpen) {
    setTimeout(getStatusFromArduino, 3000)
}else {
    port.on('open', () => {setTimeout(getStatusFromArduino, 3000)})
Quentin Vauthier's avatar
Quentin Vauthier a validé
}
Quentin Vauthier's avatar
Quentin Vauthier a validé

Quentin Vauthier's avatar
Quentin Vauthier a validé
// Fetch history from database on startup
await upadteHistory()

// Listen for data from arduino
parser.on('data', function returnStatus(data) {
Quentin Vauthier's avatar
Quentin Vauthier a validé
    const status = JSON.parse(data.toString())
    updateStatus(status)
    wss.clients.forEach(client => {
Quentin Vauthier's avatar
Quentin Vauthier a validé
        client.send(JSON.stringify({status: status}))
Quentin Vauthier's avatar
Quentin Vauthier a validé
})

Quentin Vauthier's avatar
Quentin Vauthier a validé
// Listen for websocket connections
Quentin Vauthier's avatar
Quentin Vauthier a validé
const allowedMessages = ['lock', 'unlock', 'catEntered', 'catLeft', 'status']
wss.on('connection', async function connection(ws) {
Quentin Vauthier's avatar
Quentin Vauthier a validé
    if(!status) await getStatusFromArduino()
    await upadteHistory()
    ws.send(JSON.stringify({status, history}))
    ws.on('message', async function incoming(buffer) {
        const message = buffer.toString('utf8').trim()
Quentin Vauthier's avatar
Quentin Vauthier a validé
        console.log(`received: ${message}`)
        if(allowedMessages.includes(message)) {
            port.write(`${message}\n`)
            port.flush()
Quentin Vauthier's avatar
Quentin Vauthier a validé
        }else if(message === 'history') {
            if(!history) await upadteHistory()
            ws.write(JSON.stringify(history))
Quentin Vauthier's avatar
Quentin Vauthier a validé
})

Quentin Vauthier's avatar
Quentin Vauthier a validé
function getStatusFromArduino() {
Quentin Vauthier's avatar
Quentin Vauthier a validé
    port.write('status\n')
    port.flush()
Quentin Vauthier's avatar
Quentin Vauthier a validé
}
Quentin Vauthier's avatar
Quentin Vauthier a validé

Quentin Vauthier's avatar
Quentin Vauthier a validé
async function upadteHistory() {
    const [lockLog, catLog] = await Promise.all([
        connection.query(`SELECT * FROM lock_log ORDER BY date DESC LIMIT 10`),
        connection.query(`SELECT * FROM cat_log ORDER BY date DESC LIMIT 10`)
    ])
    const lockHistoryForWebsocket = lockLog.map(log => {
        return {
            date: new Date(log.date),
            event: log.action
        }
    })
    const catHistoryForWebsocket = catLog.map(log => {
        return {
            date: new Date(log.date),
            event: log.action,
            catsInside: log.cats_inside
        }
    })
    history = {
        lockLog: lockHistoryForWebsocket,
        catLog: catHistoryForWebsocket
    }
}

async function updateStatus(newStatus) {
    if(!status) return status = newStatus
    if(newStatus.locked === status.locked && newStatus.catsInside === status.catsInside) return
    if(newStatus.locked !== status.locked) {
        await connection.query(`INSERT INTO lock_log (date, action) VALUES ('${(new Date()).toISOString()}', '${newStatus.locked ? 'locked' : 'unlocked'}')`)
        history.lockLog.unshift({event: newStatus.locked ? 'locked' : 'unlocked', date: new Date()})
    }else if(newStatus.catsInside < status.catsInside) {
        await connection.query(`INSERT INTO cat_log (date, action, cats_inside) VALUES ('${(new Date()).toISOString()}', 'left', ${newStatus.catsInside})`)
        history.catLog.unshift({event: 'left', date: new Date(), catsInside: newStatus.catsInside})
    }else {
        await connection.query(`INSERT INTO cat_log (date, action, cats_inside) VALUES ('${(new Date()).toISOString()}', 'entered', ${newStatus.catsInside})`)
        history.catLog.unshift({event: 'entered', date: new Date(), catsInside: newStatus.catsInside})
    }
    status = newStatus
Quentin Vauthier's avatar
Quentin Vauthier a validé
}