Skip to content

Commit

Permalink
Add new Device: ELV-LW-OMO and new payload decoder to support upcomin…
Browse files Browse the repository at this point in the history
…g devices (#646)

* add elv-bm-trx1

* Mail address added

* Mail address added

* add elv-bm-trx1

* Mail address added

* Mail address added

* added elv-lw-gps1 and elv-lw-esi, changed image of elv-bm-trx1

* added elv-lw-esi and elv-lw-gps1 to index.yaml, changed image elv-bm-trx-1, flipped shop urls

* changed image size elv-bm-trx-1.jpg

* validate fmt

* added Mail Address to commit

* added elv-lw-gps1 and elv-lw-esi, changed image of elv-bm-trx1

* added elv-lw-esi and elv-lw-gps1 to index.yaml, changed image elv-bm-trx-1, flipped shop urls

* changed image size elv-bm-trx-1.jpg

* validate fmt

* added Mail Address to commit

* added hardware versions to all devices, updated payload decoder elv-bm-trx1.js to latest version

* set mail address for commit

* added new device elv-lw-mob

* updated payload decoder for elv-bm-trx1 to version 1.6.0, adjusted codec to match ourput

* added new device ELV-LW-OMO

* Upadate payload decoder to V1.7.0

* checked files concerning merge conflict

---------

Co-authored-by: Jaime Trinidad <[email protected]>
  • Loading branch information
ELV-Elektronik-AG and Jaime-Trinidad authored Jul 18, 2023
1 parent b921bfc commit 9e73236
Show file tree
Hide file tree
Showing 10 changed files with 477 additions and 5 deletions.
199 changes: 196 additions & 3 deletions vendor/elv/elv-bm-trx1.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* ELV modular system Payload-Parser
*
* Version: V1.6.0
* Version: V1.7.0
*
* */

Expand Down Expand Up @@ -559,11 +559,202 @@ function Decoder(bytes, port) {
}
break;
}
//case 0x??: // Further Data Type
case 0x10: // Absolute angle
{
// Get the 8 bit value
index++; // Set index to data value
Temp_Value = bytes[index];
switch ( bytes[index] )
{
case 0xff:
{
decoded.Absolut_Angle = "Unknown";
}
break;
default:
{
Temp_Value *= 2.5; // Multiply the value with the angle resolution of 2.5 °
decoded.Absolut_Angle = String(Temp_Value.toFixed(1));
}
break;
}
break;
}
case 0x11: // Speed
{
// Get the 16 bit value
index++; // Set index to high byte data value
Temp_Value = (bytes[index] * 256);
index++; // Set index to low byte data value
Temp_Value += bytes[index];

// Check the wind detection bit
if( Temp_Value & 0x0800 )
{
decoded.Wind_Detection = "1";
}
else
{
decoded.Wind_Detection = "0";
}

// Get the unsigned 11 bit speed value
Temp_Value &= 0x07ff;
switch ( Temp_Value )
{
case 0x7ff:
{
decoded.Wind_Speed = "Unknown";
}
break;
case 0x7fe:
{
decoded.Wind_Speed = "Overflow";
}
break;
default:
{
Temp_Value *= 0.1; // Multiply the value with the speed resolution of 0.1 km/h
decoded.Wind_Speed = String(Temp_Value.toFixed(1));
}
break;
}
break;
}
case 0x12: // Wind
{
// Get the 16 bit value
index++; // Set index to high byte data value
Temp_Value = (bytes[index] * 256);
index++; // Set index to low byte data value
Temp_Value += bytes[index];

// Check the variation range
switch ( ((Temp_Value & 0xf000) / 4096) )
{
case 0xf:
{
decoded.Variation_Angle = "Unknown";
}
break;
case 0xe:
{
decoded.Variation_Angle = "Overflow";
}
break;
default:
{
decoded.Variation_Angle = String(((11.25 * (Temp_Value & 0xf000) / 4096)).toFixed(2));
}
break;

}
// Check the wind detection bit
if( Temp_Value & 0x0800 )
{
decoded.Wind_Detection = "1";
}
else
{
decoded.Wind_Detection = "0";
}

// break;
// Get the unsigned 11 bit speed value
Temp_Value &= 0x07ff;
switch ( Temp_Value )
{
case 0x7ff:
{
decoded.Wind_Speed = "Unknown";
}
break;
case 0x7fe:
{
decoded.Wind_Speed = "Overflow";
}
break;
default:
{
Temp_Value *= 0.1; // Multiply the value with the speed resolution of 0.1 km/h
decoded.Wind_Speed = String(Temp_Value.toFixed(1));
}
break;
}

// Get the 8 bit value
index++; // Set index to data value
Temp_Value = bytes[index];
switch ( bytes[index] )
{
case 0xff:
{
decoded.Absolut_Angle = "Unknown";
}
break;
default:
{
Temp_Value *= 2.5; // Multiply the value with the angle resolution of 2.5 °
decoded.Absolut_Angle = String(Temp_Value.toFixed(1));
}
break;
}
break;
}
case 0x13: // Rainfall
{
// Get the 16 bit value
index++; // Set index to high byte data value
Temp_Value = (bytes[index] * 256);
index++; // Set index to low byte data value
Temp_Value += bytes[index];

// Check the rain detection bit
if( Temp_Value & 0x8000 )
{
decoded.Rain_Detection = "1";
}
else
{
decoded.Rain_Detection = "0";
}

// Check the rain counter overflow bit
if( Temp_Value & 0x4000 )
{
decoded.Rain_Counter_Overflow = "1";
}
else
{
decoded.Rain_Counter_Overflow = "0";
}

// Get the unsigned 14 bit rain amount value
Temp_Value &= 0x3fff;
switch ( Temp_Value )
{
case 0x3fff:
{
decoded.Rain_Amount = "Unknown";
}
break;
default:
{
Temp_Value *= 0.1; // Multiply the value with the rainfall resolution of 0.1 l/m²
decoded.Rain_Amount = String(Temp_Value.toFixed(1));
}
break;
}
break;
}
// case 0x??: // Further Data Type
// {
// .
// .
// .
// break;
// }
default: // There is something wrong with the data type value
{
// Removing all added properties from the "decoded" object with a deep clean
// https://stackoverflow.com/questions/19316857/removing-all-properties-from-a-object/19316873#19316873
// Object.keys(decoded).forEach(function(key){ delete decoded[key]; });
Expand All @@ -574,6 +765,7 @@ function Decoder(bytes, port) {
// Add error code propertiy to the "decoded" object
decoded.parser_error = "Data Type Failure --> Please update your payload parser";
break;
}
}
} while ((++index < bytes.length) && ('parser_error' in decoded === false));
}
Expand All @@ -588,3 +780,4 @@ function Decoder(bytes, port) {

return decoded;
}

4 changes: 2 additions & 2 deletions vendor/elv/elv-lw-mob.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: ELV LoRaWAN® Bewegungssensor/1-Tastenfernbedienung ELV-LW-MOB
description: Compact LoRaWAN® battery radio remote control with acceleration and tilt detection from ELV
name: ELV Motion Button for LoRaWAN®
description: Compact LoRaWAN® battery powered radio remote control with acceleration and tilt detection from ELV

# Hardware versions (optional, use when you have revisions)
hardwareVersions:
Expand Down
Binary file added vendor/elv/elv-lw-omo-backview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions vendor/elv/elv-lw-omo-codec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Uplink decoder decodes binary data uplink into a JSON object (optional)
# For documentation on writing encoders and decoders, see: https://www.thethingsindustries.com/docs/integrations/payload-formatters/javascript/
uplinkDecoder:
fileName: elv-lw-omo.js
# Examples (optional)
examples:
- description: device status information
input:
fPort: 10
bytes: [0x96, 0x01, 0x01, 0x00, 0x00, 0x00, 0x10]
output:
data:
Supply_Voltage: 1500
frame_type: 'Device_State'
TX_Reason: 'Button Pressed'
Accelerated: false
Tilt_Area_0: false
Tilt_Area_1: false
Tilt_Area_2: false
Angle: 0
Activation_count: 16
- description: device acceleration
input:
fPort: 10
bytes: [0x96, 0x02, 0x05, 0x01, 0x2D]
output:
data:
Supply_Voltage: 1500
frame_type: 'Acceleration_Data'
TX_Reason: 'Acceleration'
Accelerated: true
Tilt_Area_0: false
Tilt_Area_1: false
Tilt_Area_2: false
Angle: 45
Binary file added vendor/elv/elv-lw-omo-components.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added vendor/elv/elv-lw-omo-frontview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added vendor/elv/elv-lw-omo-housing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 125 additions & 0 deletions vendor/elv/elv-lw-omo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* ELV-LW-OMO Payload Parser
*
* Version: V1.0.1
*
* */

function decodeUplink(input) {
var data = input.bytes;
var valid = true;

if (typeof Decoder === "function") {
data = Decoder(data, input.fPort);
}

if (typeof Converter === "function") {
data = Converter(data, input.fPort);
}

if (typeof Validator === "function") {
valid = Validator(data, input.fPort);
}

if (valid) {
return {
data: data
};
} else {
return {
data: {},
errors: ["Invalid data received"]
};
}
}

var tx_reason = ["Undefined","Button Pressed", "Heartbeat", "Settings", "Joined", "Acceleration", "Tilt", "Ongoing Acceleration", "Inactivity", "Error"];
var frame_type = ["Device_Info", "Device_State", "Acceleration_Data", "Button_Pressed", "Config_Data"];
var device_modes = ["Acceleration", "Tilt"];
/*
* @brief Receives the bytes transmitted from a device of the ELV-LW-OMO
* @param bytes: Array with the data stream
* @param port: Used TTN/TTS data port
* @return Decoded data from a device of the ELV-LW-OMO
* */
function Decoder(bytes, port) {
var decoded = {}; // Container with the decoded output
var Temp_Value = 0; // Variable for temporarily calculated values

if (port === 10) { // The default port for app data
// Minimum 5 Bytes for Header

// Collecting header data

decoded.Supply_Voltage = bytes[0] * 10;
decoded.frame_type = frame_type[(bytes[1])]; //Frametype encodes what Kind of Payload is being sent
decoded.TX_Reason = tx_reason[(bytes[2])];
//Write every reason for sending correspondig to bit n
switch (decoded.frame_type)
{
case "Device_Info":
var bl_version_major = bytes[3];
var bl_version_minor = bytes[4];
var bl_version_patch = bytes[5];

decoded.Bootloader_Version = `${bl_version_major}.${bl_version_minor}.${bl_version_patch}`; //Build version-String from 3 previous values

var fw_version_major = bytes[6];
var fw_version_minor = bytes[7];
var fw_version_patch = bytes[8];

decoded.Firmware_Version = `${fw_version_major}.${fw_version_minor}.${fw_version_patch}`;//Build version-String from 3 previous values

decoded.hw_revision = bytes[9] << 8 | bytes[10]; // //HW version is encoded as 16-Bit int
break;
case "Device_State":
decoded.Accelerated = !!(bytes[3] & 0x1);
decoded.Tilt_Area_0 = !!(bytes[3] & 0x10);
decoded.Tilt_Area_1 = !!(bytes[3] & 0x20);
decoded.Tilt_Area_2 = !!(bytes[3] & 0x40);

decoded.Angle = bytes[4];

decoded.Activation_count = (bytes[5] << 8 | bytes[6]);
break;
case "Acceleration_Data":
decoded.Accelerated = !!(bytes[3] & 0x1);
decoded.Tilt_Area_0 = !!(bytes[3] & 0x10);
decoded.Tilt_Area_1 = !!(bytes[3] & 0x20);
decoded.Tilt_Area_2 = !!(bytes[3] & 0x40);

decoded.Angle = bytes[4];
break;
case "Button_Pressed":
decoded.Button_Count = bytes[3];
break;
case "Config_Data":
decoded.device_mode = "";
for(let i = 0; i < 8; i++)
{
if((bytes[3] >> i) & 1)
{
decoded.device_mode += device_modes[i];
}
}

decoded.sensor_threshold = bytes[4];

decoded.range = bytes[5];
decoded.alpha = bytes[6];

decoded.beta = bytes[7];

decoded.hysteresis = bytes[8];

decoded.senc_cycle_minutes = bytes[9] * 6;
break;
}

}
else {
decoded.parser_error = "Wrong Port Number";
}

return decoded;
}
Loading

0 comments on commit 9e73236

Please sign in to comment.