rx dummychain works

master
cheetah 4 years ago
parent 36a7c75eea
commit 2248525442

@ -15,7 +15,10 @@
"duplexTimeout": 30
},
"lorawan": {
"enabled": false
"enabled": true,
"mqttserver": "mqtt://eu1.cloud.thethings.network:1883",
"username": "<Username>",
"password": "<Password>"
},
"dapnet": {
"enabled": false
@ -24,11 +27,9 @@
"pagers": {
"birdyslim": {
"enabled": true,
"formatRecvAck": "|5||S||V||G||D||C|>A",
"formatReadAck": "|5||S||V||G||D||C|>B",
"formatOperAck": "|5||S||V||G||D||C|$OP",
"formatStatus": "|S||V||G||D||C|",
"formatSOS": "|S||V||G||D||C|"
"rxchain": {
"lorawan": true
}
}
}
}

@ -15,7 +15,7 @@ if (!!config.connectors.lorawan && config.connectors.lorawan.enabled === true) {
types.ConnectorRegistry.register(new types.Connectors.LoRaWANConnector(connection))
}
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())

@ -20,8 +20,10 @@
"@supercharge/strings": "^1.18.0",
"amqp-connection-manager": "^3.2.2",
"amqplib": "^0.7.0",
"async-mqtt": "^2.6.1",
"body-parser": "^1.19.0",
"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 md5 = require('md5')
const DeviceRegistry = require("./DeviceRegistry")
class ConnectorRegistry {
constructor() {
this.Connectors = {}
this.events = new events.EventEmitter()
this.events.on('ping', (x) => console.log('connector event "ping" from', x))
this.events.on('response', this.receive.bind(this))
}
register(connector) {
this.Connectors[ connector.name ] = connector
@ -35,7 +37,10 @@ class ConnectorRegistry {
//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()

@ -5,6 +5,12 @@ class DeviceRegistry {
register(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()
module.exports = registry

@ -50,6 +50,12 @@ class MessageManager {
else
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) {
ConnectorRegistry.events.removeAllListeners(`msg:status:${ msgId }:delivered`)
ConnectorRegistry.events.removeAllListeners(`msg:status:${ msgId }:failed`)

@ -1,6 +1,7 @@
const Connector = require("./Connector")
const md5 = require('md5')
const config = require('../../config.json')
class DummyConnector extends Connector {
constructor (amqpConnMngr) {
super(amqpConnMngr)
@ -13,16 +14,18 @@ class DummyConnector extends Connector {
// set Routed
this.connectorRegistry.reportState(msg, UUID, 'routed')
await new Promise((res)=>setTimeout(res,6e3))
// Pager Configuration Response Format "|5||S||V||G||D||C"
let virtGPS = "+001.38207+43.7717105"
let virtSerial = "1337"
let virtRSSI = "22"
let virtDate = "01/01/2024"
let virtBattery = 0x28.toString(16)
this.connectorRegistry.events.emit('response', `${ msgId }|${ virtSerial }|${ virtBattery }|${ virtGPS }|${ virtDate }|${ virtRSSI }`)
this.connectorRegistry.events.emit('response', { //reconstruct the response coming from a lorawan connector
type: 'ack',
ack: 'recv',
rssi: 22,
msgid: msgId,
f_port: 1,
date: new Date(),
device_id: 'dummy'
})
// this will happen somewhere else, down the response processing chain
this.connectorRegistry.events.emit(`msg:status:${ msgId }:delivered`)
this.connectorRegistry.reportDelivered(msg, UUID) // cheating lol
//this.connectorRegistry.events.emit(`msg:status:${ msgId }:delivered`)
//this.connectorRegistry.reportDelivered(msg, UUID) // cheating lol
}
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

@ -1,4 +1,5 @@
const Connector = require("./Connector")
const config = require('../../config.json')
class LoRaWANConnector extends Connector {
// this is optimized for only receiving LoRa uplink Messages (from Birdy Pagers)
@ -7,6 +8,32 @@ class LoRaWANConnector extends Connector {
super(amqpConnMngr)
this.name = "lorawan"
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

@ -1,6 +1,7 @@
const MessageManager = require("../MessageManager")
const PagerDevice = require("./Device")
const Str = require('@supercharge/strings')
const config = require('../../config.json')
// Birdy Slim (IoT) Device
class BirdySlim extends PagerDevice {
@ -8,6 +9,21 @@ class BirdySlim extends PagerDevice {
super()
this.duplex = true
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() {
return `B${ Str.random(4) }`
@ -17,5 +33,21 @@ class BirdySlim extends PagerDevice {
await MessageManager.BindMsg(msg)
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

@ -4,6 +4,7 @@ class PagerDevice {
this.name = "_base"
}
async formatTX(msg) { }
async tryReceive(data, connector) { }
RandID() { }
}
module.exports = PagerDevice
Loading…
Cancel
Save