added Device Data Collection and Ack Handling
This commit is contained in:
parent
f13ec66878
commit
a5c4a44987
6 changed files with 67 additions and 26 deletions
8
index.js
8
index.js
|
@ -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;
|
break;
|
||||||
|
case 'sos':
|
||||||
|
stateSet.sos = {
|
||||||
|
sos: data.sos,
|
||||||
|
date: data.date,
|
||||||
|
}
|
||||||
|
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…
Add table
Reference in a new issue