rx dummychain works
This commit is contained in:
parent
36a7c75eea
commit
2248525442
10 changed files with 101 additions and 18 deletions
13
config.json
13
config.json
|
@ -15,7 +15,10 @@
|
||||||
"duplexTimeout": 30
|
"duplexTimeout": 30
|
||||||
},
|
},
|
||||||
"lorawan": {
|
"lorawan": {
|
||||||
"enabled": false
|
"enabled": true,
|
||||||
|
"mqttserver": "mqtt://eu1.cloud.thethings.network:1883",
|
||||||
|
"username": "<Username>",
|
||||||
|
"password": "<Password>"
|
||||||
},
|
},
|
||||||
"dapnet": {
|
"dapnet": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
@ -24,11 +27,9 @@
|
||||||
"pagers": {
|
"pagers": {
|
||||||
"birdyslim": {
|
"birdyslim": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"formatRecvAck": "|5||S||V||G||D||C|>A",
|
"rxchain": {
|
||||||
"formatReadAck": "|5||S||V||G||D||C|>B",
|
"lorawan": true
|
||||||
"formatOperAck": "|5||S||V||G||D||C|$OP",
|
}
|
||||||
"formatStatus": "|S||V||G||D||C|",
|
|
||||||
"formatSOS": "|S||V||G||D||C|"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
2
index.js
2
index.js
|
@ -15,7 +15,7 @@ if (!!config.connectors.lorawan && config.connectors.lorawan.enabled === true) {
|
||||||
types.ConnectorRegistry.register(new types.Connectors.LoRaWANConnector(connection))
|
types.ConnectorRegistry.register(new types.Connectors.LoRaWANConnector(connection))
|
||||||
}
|
}
|
||||||
if (!!config.connectors.dapnet && config.connectors.dapnet.enabled === true) {
|
if (!!config.connectors.dapnet && config.connectors.dapnet.enabled === true) {
|
||||||
types.ConnectorRegistry.register(new types.Connectors.DAPNETConnector())
|
types.ConnectorRegistry.register(new types.Connectors.DAPNETConnector(connection))
|
||||||
}
|
}
|
||||||
types.ConnectorRegistry.register(new types.Connectors.DummyConnector())
|
types.ConnectorRegistry.register(new types.Connectors.DummyConnector())
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,10 @@
|
||||||
"@supercharge/strings": "^1.18.0",
|
"@supercharge/strings": "^1.18.0",
|
||||||
"amqp-connection-manager": "^3.2.2",
|
"amqp-connection-manager": "^3.2.2",
|
||||||
"amqplib": "^0.7.0",
|
"amqplib": "^0.7.0",
|
||||||
|
"async-mqtt": "^2.6.1",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"md5": "^2.3.0"
|
"md5": "^2.3.0",
|
||||||
|
"mqtt": "^4.2.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
const events = require('events')
|
const events = require('events')
|
||||||
const md5 = require('md5')
|
const md5 = require('md5')
|
||||||
|
const DeviceRegistry = require("./DeviceRegistry")
|
||||||
|
|
||||||
class ConnectorRegistry {
|
class ConnectorRegistry {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.Connectors = {}
|
this.Connectors = {}
|
||||||
this.events = new events.EventEmitter()
|
this.events = new events.EventEmitter()
|
||||||
this.events.on('ping', (x) => console.log('connector event "ping" from', x))
|
this.events.on('ping', (x) => console.log('connector event "ping" from', x))
|
||||||
|
this.events.on('response', this.receive.bind(this))
|
||||||
}
|
}
|
||||||
register(connector) {
|
register(connector) {
|
||||||
this.Connectors[ connector.name ] = connector
|
this.Connectors[ connector.name ] = connector
|
||||||
|
@ -35,7 +37,10 @@ class ConnectorRegistry {
|
||||||
|
|
||||||
|
|
||||||
//W.I.P
|
//W.I.P
|
||||||
receive(id, data) {
|
async receive(data, connector) {
|
||||||
|
for (let device of DeviceRegistry.getDevices()) {
|
||||||
|
if (await device.tryReceive(data, connector) === true) { break; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const registry = new ConnectorRegistry()
|
const registry = new ConnectorRegistry()
|
||||||
|
|
|
@ -5,6 +5,12 @@ class DeviceRegistry {
|
||||||
register(device) {
|
register(device) {
|
||||||
this.Devices[ device.name ] = device
|
this.Devices[ device.name ] = device
|
||||||
}
|
}
|
||||||
|
getDevices() {
|
||||||
|
return Object.values(this.Devices)
|
||||||
|
}
|
||||||
|
/*tryReceive(deviceName, data) {
|
||||||
|
return this.Devices[ deviceName ].tryReceive(data)
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
const registry = new DeviceRegistry()
|
const registry = new DeviceRegistry()
|
||||||
module.exports = registry
|
module.exports = registry
|
|
@ -50,6 +50,12 @@ class MessageManager {
|
||||||
else
|
else
|
||||||
this.DeliverOneWay(msgId)
|
this.DeliverOneWay(msgId)
|
||||||
}
|
}
|
||||||
|
attachMetadata(msgId, metadata) {
|
||||||
|
if (!this.messages[ msgId ]._routerData.metadata) {
|
||||||
|
this.messages[ msgId ]._routerData.metadata = []
|
||||||
|
}
|
||||||
|
this.messages[ msgId ]._routerData.metadata.push(metadata)
|
||||||
|
}
|
||||||
_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`)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const Connector = require("./Connector")
|
const Connector = require("./Connector")
|
||||||
const md5 = require('md5')
|
const md5 = require('md5')
|
||||||
|
|
||||||
|
const config = require('../../config.json')
|
||||||
class DummyConnector extends Connector {
|
class DummyConnector extends Connector {
|
||||||
constructor (amqpConnMngr) {
|
constructor (amqpConnMngr) {
|
||||||
super(amqpConnMngr)
|
super(amqpConnMngr)
|
||||||
|
@ -13,16 +14,18 @@ class DummyConnector extends Connector {
|
||||||
// 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,6e3))
|
||||||
// Pager Configuration Response Format "|5||S||V||G||D||C"
|
this.connectorRegistry.events.emit('response', { //reconstruct the response coming from a lorawan connector
|
||||||
let virtGPS = "+001.38207+43.7717105"
|
type: 'ack',
|
||||||
let virtSerial = "1337"
|
ack: 'recv',
|
||||||
let virtRSSI = "22"
|
rssi: 22,
|
||||||
let virtDate = "01/01/2024"
|
msgid: msgId,
|
||||||
let virtBattery = 0x28.toString(16)
|
f_port: 1,
|
||||||
this.connectorRegistry.events.emit('response', `${ msgId }|${ virtSerial }|${ virtBattery }|${ virtGPS }|${ virtDate }|${ virtRSSI }`)
|
date: new Date(),
|
||||||
|
device_id: 'dummy'
|
||||||
|
})
|
||||||
// this will happen somewhere else, down the response processing chain
|
// this will happen somewhere else, down the response processing chain
|
||||||
this.connectorRegistry.events.emit(`msg:status:${ msgId }:delivered`)
|
//this.connectorRegistry.events.emit(`msg:status:${ msgId }:delivered`)
|
||||||
this.connectorRegistry.reportDelivered(msg, UUID) // cheating lol
|
//this.connectorRegistry.reportDelivered(msg, UUID) // cheating lol
|
||||||
}
|
}
|
||||||
async transmitMessage(msg, params) { // lets pretend to be a Birdy Slim
|
async transmitMessage(msg, params) { // lets pretend to be a Birdy Slim
|
||||||
const UUID = this.name+':'+md5(JSON.stringify([ this.name, ...params ])) // uuid=name+hash of name+args
|
const UUID = this.name+':'+md5(JSON.stringify([ this.name, ...params ])) // uuid=name+hash of name+args
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const Connector = require("./Connector")
|
const Connector = require("./Connector")
|
||||||
|
const config = require('../../config.json')
|
||||||
|
|
||||||
class LoRaWANConnector extends Connector {
|
class LoRaWANConnector extends Connector {
|
||||||
// this is optimized for only receiving LoRa uplink Messages (from Birdy Pagers)
|
// this is optimized for only receiving LoRa uplink Messages (from Birdy Pagers)
|
||||||
|
@ -7,6 +8,32 @@ class LoRaWANConnector extends Connector {
|
||||||
super(amqpConnMngr)
|
super(amqpConnMngr)
|
||||||
this.name = "lorawan"
|
this.name = "lorawan"
|
||||||
this.duplexCapable = true
|
this.duplexCapable = true
|
||||||
|
const MQTT = require('async-mqtt')
|
||||||
|
this.client = MQTT.connect(config.connectors.lorawan.mqttserver, {
|
||||||
|
username: config.connectors.lorawan.username,
|
||||||
|
password: config.connectors.lorawan.password,
|
||||||
|
})
|
||||||
|
this.client.on('error', (x) => console.error)
|
||||||
|
this.client.on('connect', this.onMQTTConnect.bind(this))
|
||||||
|
this.client.on('message', this.onMQTTMessage.bind(this))
|
||||||
|
}
|
||||||
|
async onMQTTConnect() {
|
||||||
|
await this.client.subscribe(`v3/${ config.connectors.lorawan.username }/devices/#`)
|
||||||
|
console.log('[lorawan] subscribed')
|
||||||
|
}
|
||||||
|
async onMQTTMessage(topic, message) {
|
||||||
|
//if (topic.indexOf('/up') > -1) return
|
||||||
|
const json = JSON.parse(Buffer.from(message).toString('utf-8'))
|
||||||
|
console.log(topic, json)
|
||||||
|
if (!!json.uplink_message) {
|
||||||
|
this.connectorRegistry.events.emit('response', {
|
||||||
|
...json.uplink_message.decoded_payload,
|
||||||
|
port: json.uplink_message.f_port,
|
||||||
|
date: new Date(json.received_at),
|
||||||
|
device_id: json.end_device_ids.device_id,
|
||||||
|
metadata: json,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = LoRaWANConnector
|
module.exports = LoRaWANConnector
|
|
@ -1,6 +1,7 @@
|
||||||
const MessageManager = require("../MessageManager")
|
const MessageManager = require("../MessageManager")
|
||||||
const PagerDevice = require("./Device")
|
const PagerDevice = require("./Device")
|
||||||
const Str = require('@supercharge/strings')
|
const Str = require('@supercharge/strings')
|
||||||
|
const config = require('../../config.json')
|
||||||
|
|
||||||
// Birdy Slim (IoT) Device
|
// Birdy Slim (IoT) Device
|
||||||
class BirdySlim extends PagerDevice {
|
class BirdySlim extends PagerDevice {
|
||||||
|
@ -8,6 +9,21 @@ 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) }`
|
||||||
|
@ -17,5 +33,21 @@ class BirdySlim extends PagerDevice {
|
||||||
await MessageManager.BindMsg(msg)
|
await MessageManager.BindMsg(msg)
|
||||||
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) {
|
||||||
|
console.log(data)
|
||||||
|
if (typeof(data) === 'object' && !!data.type) {
|
||||||
|
switch (data.type) {
|
||||||
|
case 'ack':
|
||||||
|
if (data.ack === 'recv') {
|
||||||
|
require('../ConnectorRegistry').reportDelivered({ id: data.msgid }, `lorawan:${ data.device_id }`) // cheating lol
|
||||||
|
require('../MessageManager').attachMetadata(data.msgid, data)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
// config.pagers.birdyslim.formatRecvAck
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports = BirdySlim
|
module.exports = BirdySlim
|
|
@ -4,6 +4,7 @@ class PagerDevice {
|
||||||
this.name = "_base"
|
this.name = "_base"
|
||||||
}
|
}
|
||||||
async formatTX(msg) { }
|
async formatTX(msg) { }
|
||||||
|
async tryReceive(data, connector) { }
|
||||||
RandID() { }
|
RandID() { }
|
||||||
}
|
}
|
||||||
module.exports = PagerDevice
|
module.exports = PagerDevice
|
Loading…
Add table
Reference in a new issue