-
-
Save Safrone/274db80f5a8c3e8f97fb3692a776d225 to your computer and use it in GitHub Desktop.
Chirpstack JS decoder for Radiobridge devices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Decode decodes an array of bytes into an object. | |
// - fPort contains the LoRaWAN fPort number | |
// - bytes is an array of bytes, e.g. [225, 230, 255, 0] | |
// The function must return an object, e.g. {"temperature": 22.5} | |
/* | |
@reference https://radiobridge.com/documents/Common%20Sensor%20Messages.pdf | |
Sensors Name Designation | |
------------------------------------------------------------ | |
Water Sensor RBS301-WAT-US | |
Water Rope Sensor RBS301-WR1M-US | |
External Probe Temperature Sensor RBS301-TEMP-EXT-US | |
Ultrasonic Level Sensor RBS306-US10M-US | |
Air Temperature and Humidity Sensor RBS306-ATH-EXT-US | |
Tilt Sensor RBS301-TILT-US | |
Acceleration-based Movement Sensor RBS301-ABM-US | |
*/ | |
function Decode(fPort, bytes, variables) { | |
switch (bytes[1]) { | |
case 0: // Reset Message | |
return { | |
"messageCount": {0: bytes[0] & 15}, | |
// See Common Message Protocols (linked in Wiki Article above) for sensor type definitions | |
"sensorType": {0: bytes[2]}, | |
"hardwareVersion": {0: bytes[3]}, | |
"firmwareVersion": {0: (bytes[4] << 8) + bytes[5]} | |
}; | |
case 1: // Supervisory Message | |
var output = { | |
"messageCount": {1: bytes[0] & 15}, | |
"supervisoryCodes" : {1: { | |
// 0 for if no error, 1 if error | |
"tamperDetected": {1: (bytes[2] & 16) === 16 ? 1 : 0}, | |
"currentTamper": {1: (bytes[2] & 8) === 8 ? 1 : 0}, | |
"downlinkError": {1: (bytes[2] & 4) === 4 ? 1 : 0}, | |
"batteryLow": {1: (bytes[2] & 2) === 2 ? 1 : 0}, | |
"radioError": {1: (bytes[2] & 1) === 1 ? 1 : 0} | |
}, | |
"sensorState": {1: bytes[3]}, | |
// Battery level is the voltage value of the battery | |
"batteryLevel": {1: ((bytes[4] & 240) / 16) + ((bytes[4] & 15) / 10)}, | |
// Total number of events since the last supervisory message | |
"eventTotal": {1: bytes[8] * 256 + bytes[9]}} | |
}; | |
if (typeof variables !== 'undefined' && 'radiobridgeModel' in variables) { | |
switch (variables['radiobridgeModel']) { | |
case 'RBS301-WAT-US': | |
case 'RBS301-WR1M-US': | |
output['waterNotLeaking'] = {8: bytes[5]}; | |
output['relativeResistance'] = {8: bytes[3]}; | |
break; | |
case 'RBS306-ATH-EXT': | |
var temperature = (bytes[5] & (1 << 7)) !== 0 ? (bytes[5] - 256) : bytes[5]; | |
output['temperature'] = {13: temperature + ((bytes[6] >> 4) / 10)}; | |
output['relativeHumidity'] = {13: bytes[7] + ((bytes[8] >> 4) / 10)}; | |
break; | |
case 'RBS301-TEMP-EXT-US': | |
output['temperature'] = {9: (bytes[3] & (1 << 7)) !== 0 ? (bytes[3] - 256) : bytes[3]}; | |
break; | |
} | |
} | |
return output; | |
case 8: | |
// Water Sensor/Water Rope Sensor | |
// 3rd byte is the event payload; 0 means water is leaking, 1 for water is not leaking | |
// 4th byte is the relative resistance of the liquid | |
return { | |
"messageCount": {8: bytes[0] & 15}, | |
"waterNotLeaking": {8: bytes[2]}, | |
"relativeResistance": {8: bytes[3]} | |
}; | |
case 9: | |
// External Probe Temperature Sensor | |
// 3rd byte is the event payload; consult user guide for definitions | |
// 4th byte is the temperature reading in celsius | |
// 5th byte is the relative temperature measurement (raw analog to digital measurement) | |
var temperature = (bytes[3] & (1 << 7)) !== 0 ? (bytes[3] - 256) : bytes[3]; | |
return { | |
"messageCount": {9: bytes[0] & 15}, | |
// Event Payload: | |
// 0: Periodic Report | |
// 1: Temperature has risen above upper threshold | |
// 2: Temperature has fallen below lower threshold | |
// 3: Report on change increase | |
// 4: Report on change decrease | |
"eventPayload": {9: bytes[2]}, | |
"temperature": {9: temperature}, | |
"relativeTemperature": {9: bytes[4]} | |
}; | |
case 10: // Tilt Sensor | |
// 3rd byte is the event payload; consult user guide for definitions | |
// 4th byte is the tilt angle from the vertical axis. Small angles are closer to vertical, | |
// large angles are closer to horizontal | |
return { | |
"messageCount": {10: bytes[0] & 15}, | |
// Event Payload: | |
// 0: Sensor transitioned to vertical | |
// 1: Sensor transitioned to horizontal | |
// 2: Report on change toward vertical | |
// 3: Report on change toward horizontal | |
"eventPayload": {10: bytes[2]}, | |
"tiltAngleFromVertical": {10: bytes[3]} | |
}; | |
case 13: // Air Temperature and Humidity Sensor | |
var temperature = (bytes[3] & (1 << 7)) !== 0 ? (bytes[3] - 256) : bytes[3]; | |
return { | |
"messageCount": {13: bytes[0] & 15}, | |
// Event Payload: | |
// 0: Periodic Report | |
// 1: Temperature has risen above upper threshold | |
// 2: Temperature has fallen below lower threshold | |
// 3: Temperature report on change increase | |
// 4: Temperature report on change decrease | |
// 5: Humidity has risen above upper threshold | |
// 6: Humidity has fallen below lower threshold | |
// 7: Humidity report on change increase | |
// 8: Humidity report on change decrease | |
"eventPayload": {13: bytes[2]}, | |
"temperature": {13: temperature + ((bytes[4] >> 4) / 10)}, | |
"relativeHumidity": {13: bytes[5] + ((bytes[6] >> 4) / 10)} | |
}; | |
case 14: // Acceleration-based Movement Sensor | |
// 3rd byte is the event payload; 00 for Movement Start, 01 for Movement Stop | |
return { | |
"messageCount": {14: bytes[0] & 15}, | |
"movementStop": {14: bytes[2]} | |
}; | |
case 16: // Ultrasonic Level Sensor | |
// 3rd byte is the event payload; consult user guide for definitions | |
// 4th byte is the upper byte, 5th is the lower byte (in mm) | |
return { | |
"messageCount": {16: bytes[0] & 15}, | |
"distance": {16: bytes[3] * 256 + bytes[4]}, | |
// Event Payload: | |
// 0: Periodic Report | |
// 1: Distance has risen above upper threshold | |
// 2: Distance has fallen below lower threshold | |
// 3: Report on change increase | |
// 4: Report on change decrease | |
"eventPayload": {16: bytes[2]} | |
}; | |
default: | |
return {} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment