added Device Data Collection and Ack Handling

master
cheetah 4 years ago
parent f13ec66878
commit a5c4a44987

@ -47,4 +47,12 @@ app.get('/api/message/ack/recv/:id', async (req, res) => { //TODO: make this fan
return res.json(true) return res.json(true)
}) })
app.get('/api/device/:id', async (req, res) => {
return res.json(
req.params.id.length == 1
? Object.keys(types.DeviceRegistry.DeviceStates)
: types.DeviceRegistry.DeviceStates[ req.params.id ]
)
})
app.listen(3000) app.listen(3000)

@ -1,6 +1,7 @@
class DeviceRegistry { class DeviceRegistry {
constructor() { constructor() {
this.Devices = {} this.Devices = {}
this.DeviceStates = {} // for keeping device states
} }
register(device) { register(device) {
this.Devices[ device.name ] = device this.Devices[ device.name ] = device
@ -8,6 +9,12 @@ class DeviceRegistry {
getDevices() { getDevices() {
return Object.values(this.Devices) return Object.values(this.Devices)
} }
stateSet(deviceType, deviceId, stateData) {
const key = `${ deviceType }:${ deviceId }`
if (!this.DeviceStates[ key ])
this.DeviceStates[ key ] = {}
Object.assign(this.DeviceStates[ key], stateData)
}
/*tryReceive(deviceName, data) { /*tryReceive(deviceName, data) {
return this.Devices[ deviceName ].tryReceive(data) return this.Devices[ deviceName ].tryReceive(data)
}*/ }*/

@ -32,7 +32,7 @@ class MessageManager {
deliveryLog: {}, deliveryLog: {},
}) })
console.log(`Type:\t\t${ type }\nDevice:\t\t${ routingParams.device }`) console.log(`Type:\t\t${ type }\nDevice:\t\t${ routingParams.device }`)
console.log(`Message UUID:\t${ msgObj.id }`) console.log(`Message UUID:\t${ msgObj.id } HEX: ${ Buffer.from(msgObj.id, 'utf-8').toString('hex') }`)
console.log(`Connectors:\t${ JSON.parse(JSON.stringify(routingParams.connectors)).map(x=>`${x[0]}=${x.splice(1).join(',')}`).join('&') }`) console.log(`Connectors:\t${ JSON.parse(JSON.stringify(routingParams.connectors)).map(x=>`${x[0]}=${x.splice(1).join(',')}`).join('&') }`)
console.log(`Message Original Payload:\t"${ payload }"`) console.log(`Message Original Payload:\t"${ payload }"`)
console.log(`Processed Device Payload:\t"${ msgObj.payload }"`) console.log(`Processed Device Payload:\t"${ msgObj.payload }"`)
@ -56,6 +56,12 @@ class MessageManager {
} }
this.messages[ msgId ]._routerData.metadata.push(metadata) this.messages[ msgId ]._routerData.metadata.push(metadata)
} }
markMessageRead(msgId) {
this.messages[ msgId ]._routerData.readAck = true
}
respondToMessage(msgId, response) {
this.messages[ msgId ]._routerData.response = response
}
_clearEventHandlers4MsgID(msgId) { _clearEventHandlers4MsgID(msgId) {
ConnectorRegistry.events.removeAllListeners(`msg:status:${ msgId }:delivered`) ConnectorRegistry.events.removeAllListeners(`msg:status:${ msgId }:delivered`)
ConnectorRegistry.events.removeAllListeners(`msg:status:${ msgId }:failed`) ConnectorRegistry.events.removeAllListeners(`msg:status:${ msgId }:failed`)
@ -109,7 +115,7 @@ class MessageManager {
}) })
.catch(($) => { .catch(($) => {
this._clearEventHandlers4MsgID(msgId) this._clearEventHandlers4MsgID(msgId)
console.log('DELIVERY WAS A TOTAL FAILURE , FUCK THIS PLANET', $) console.log('DELIVERY WAS A TOTAL FAILURE', $)
}) })
return true return true
} }
@ -152,7 +158,7 @@ class MessageManager {
}) })
.catch(($) => { .catch(($) => {
this._clearEventHandlers4MsgID(msgId) this._clearEventHandlers4MsgID(msgId)
console.log('ROUTING WAS A TOTAL FAILURE , FUCK THIS PLANET', $) console.log('ROUTING WAS A TOTAL FAILURE', $)
}) })
} }
async BindMsg(msg) { async BindMsg(msg) {

@ -13,7 +13,7 @@ class DummyConnector extends Connector {
await new Promise((res)=>setTimeout(res,3e3)) await new Promise((res)=>setTimeout(res,3e3))
// set Routed // set Routed
this.connectorRegistry.reportState(msg, UUID, 'routed') this.connectorRegistry.reportState(msg, UUID, 'routed')
await new Promise((res)=>setTimeout(res,6e3)) await new Promise((res)=>setTimeout(res,16e3))
this.connectorRegistry.events.emit('response', { //reconstruct the response coming from a lorawan connector this.connectorRegistry.events.emit('response', { //reconstruct the response coming from a lorawan connector
type: 'ack', type: 'ack',
ack: 'recv', ack: 'recv',

@ -6,7 +6,7 @@ class POCSAGConnector extends Connector {
constructor (amqpConnMngr) { constructor (amqpConnMngr) {
super(amqpConnMngr) super(amqpConnMngr)
this.name = "pocsag" this.name = "pocsag"
this.duplexCapable = true this.duplexCapable = false
this.channelWrapper = this.amqpConnMngr.createChannel({ this.channelWrapper = this.amqpConnMngr.createChannel({
json: false, json: false,
setup: function(channel) { setup: function(channel) {

@ -9,21 +9,6 @@ class BirdySlim extends PagerDevice {
super() super()
this.duplex = true this.duplex = true
this.name = "birdyslim" this.name = "birdyslim"
/*this.birdyParamMapper = {
//'A': ['beaconIDinstant'], // It is the ID of current localisation beacon.
//'B': ['beaconIDstored'], // It is the ID of the last localisation beacon seen by the BIRDY
'C': ['rssi', 2], // It is the POCSAG carrier received level (in dBm) transmitted by the POCSAG emitter and received by the pager.
//'D': ['date'], // Timestamp in seconds from 01/01/2014.
//'E': ['beaconRoundIDstored'], // It is the ID of the last round beacon seen by the pager
'G': ['gps', (1+3+1+5)+(1+2+1+5)+2], // Longitude and latitude in decimal degrees and last acquisition time in minutes.
'I': ['identityRIC'], // BIRDY first RIC code
'N': ['messageNumber', 5], // To display message number message must begin with ***Mxxx*** where xxx is the message number.
'S': ['serial', 13], // BIRDY serial number
//'T': ['receivedRIC'], // Message receipt RIC code
'V': ['batteryVoltage', 2], // BIRDY battery voltage in HEX
//'X': ['lowBattBeacon'], // It is the ID of a beacon with a low battery voltage
'5': ['msgId', 5], // It is to recall first 5 characters of received message in an acknowledgement.
}*/
} }
RandID() { RandID() {
return `B${ Str.random(4) }` return `B${ Str.random(4) }`
@ -34,20 +19,55 @@ class BirdySlim extends PagerDevice {
msg.payload = msg.type === 'duplex' ? `${ msg.id }${ msg.payload }` : msg.payload // only if duplex wanted we add the id msg.payload = msg.type === 'duplex' ? `${ msg.id }${ msg.payload }` : msg.payload // only if duplex wanted we add the id
} }
async tryReceive(data, connector) { async tryReceive(data, connector) {
console.log(data)
if (typeof(data) === 'object' && !!data.type) { if (typeof(data) === 'object' && !!data.type) {
const stateSet = {
lastSeen: data.date
}
// If we have a Battery Measurement, we should store it
if (!!data.battery) stateSet.battery = data.battery/1e1
// the same if we have an rssi measurement
if (!!data.rssi) stateSet.rssi = data.rssi
// and if we have the 3 components of a GPS Block
if (!!data.latitude && !!data.longitude && !!data.lastGPSAcquisition) stateSet.gps = {
gps: {
lastGPSAcquisition: data.lastGPSAcquisition,
latitude: data.latitude,
longitude: data.longitude,
},
}
switch (data.type) { switch (data.type) {
case 'ack': case 'ack': {
if (data.ack === 'recv') { switch (data.ack) {
require('../ConnectorRegistry').reportDelivered({ id: data.msgid }, `lorawan:${ data.device_id }`) // cheating lol case 'recv':
require('../MessageManager').attachMetadata(data.msgid, data) require('../ConnectorRegistry').reportDelivered({ id: data.msgid }, `lorawan:${ data.device_id }`)
break;
case 'read':
require('../MessageManager').markMessageRead(data.msgid)
break;
case 'operational':
require('../MessageManager').respondToMessage(data.msgid, data.operationalData)
break;
}
// If we have had a Ack. Event, we should store some Metadate about it too
require('../MessageManager').attachMetadata(data.msgid, {
ack: data.ack,
rssi: data.rssi,
date: data.date
})
}
break;
case 'sos':
stateSet.sos = {
sos: data.sos,
date: data.date,
} }
break; break;
} }
require('../DeviceRegistry').stateSet(this.name, data.device_id, stateSet)
return true return true
} }
return false return false
// config.pagers.birdyslim.formatRecvAck
} }
} }
module.exports = BirdySlim module.exports = BirdySlim
Loading…
Cancel
Save