diff --git a/vendor/elv/elv-bm-trx1.js b/vendor/elv/elv-bm-trx1.js index 2ad2af1bf2..3b7d464533 100644 --- a/vendor/elv/elv-bm-trx1.js +++ b/vendor/elv/elv-bm-trx1.js @@ -1,7 +1,7 @@ /* * ELV modular system Payload-Parser * - * Version: V1.6.0 + * Version: V1.7.0 * * */ @@ -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]; }); @@ -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)); } @@ -588,3 +780,4 @@ function Decoder(bytes, port) { return decoded; } + diff --git a/vendor/elv/elv-lw-mob.yaml b/vendor/elv/elv-lw-mob.yaml index e555e996a8..5c251b43bb 100644 --- a/vendor/elv/elv-lw-mob.yaml +++ b/vendor/elv/elv-lw-mob.yaml @@ -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: diff --git a/vendor/elv/elv-lw-omo-backview.png b/vendor/elv/elv-lw-omo-backview.png new file mode 100644 index 0000000000..1e33e86679 Binary files /dev/null and b/vendor/elv/elv-lw-omo-backview.png differ diff --git a/vendor/elv/elv-lw-omo-codec.yaml b/vendor/elv/elv-lw-omo-codec.yaml new file mode 100644 index 0000000000..59b44ab8cb --- /dev/null +++ b/vendor/elv/elv-lw-omo-codec.yaml @@ -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 diff --git a/vendor/elv/elv-lw-omo-components.png b/vendor/elv/elv-lw-omo-components.png new file mode 100644 index 0000000000..04c6e785ab Binary files /dev/null and b/vendor/elv/elv-lw-omo-components.png differ diff --git a/vendor/elv/elv-lw-omo-frontview.png b/vendor/elv/elv-lw-omo-frontview.png new file mode 100644 index 0000000000..c504175ff6 Binary files /dev/null and b/vendor/elv/elv-lw-omo-frontview.png differ diff --git a/vendor/elv/elv-lw-omo-housing.png b/vendor/elv/elv-lw-omo-housing.png new file mode 100644 index 0000000000..adf41922d1 Binary files /dev/null and b/vendor/elv/elv-lw-omo-housing.png differ diff --git a/vendor/elv/elv-lw-omo.js b/vendor/elv/elv-lw-omo.js new file mode 100644 index 0000000000..41b9c6980a --- /dev/null +++ b/vendor/elv/elv-lw-omo.js @@ -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; +} \ No newline at end of file diff --git a/vendor/elv/elv-lw-omo.yaml b/vendor/elv/elv-lw-omo.yaml new file mode 100644 index 0000000000..3a40c70a0d --- /dev/null +++ b/vendor/elv/elv-lw-omo.yaml @@ -0,0 +1,118 @@ +name: ELV Outdoor Motion Sensor for LoRaWAN® +description: The ELV-LW-OMO is a device to track acceleration, vibration or realtive position changes of an outdoor asset. Fields of application are e.g. the monitoring of garbage cans or the detection of activity at a bird house + +# Hardware versions (optional, use when you have revisions) +hardwareVersions: + - version: '1.0' + numeric: 1 + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '1.0.3' + numeric: 1 + # Corresponding hardware versions (optional) + hardwareVersions: + - '1.0' + + # Firmware features (optional) + # Valid values are: remote rejoin (trigger a join from the application layer), transmission interval (configure how + # often he device sends a message). + features: + - remote rejoin + - transmission interval + + # LoRaWAN Device Profiles per region + # Supported regions are EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, + # RU864-870 + profiles: + EU863-870: + # Optional identifier of the vendor of the profile. When you specify the vendorID, the profile is loaded from + # the vendorID's folder. This allows you to reuse profiles from module or LoRaWAN end device stack vendors. + # If vendorID is empty, the current vendor ID is used. In this example, the vendorID is the current vendor ID, + # which is verbose. + #vendorID: elv + # Identifier of the profile (lowercase, alphanumeric with dashes, max 36 characters) + id: trx1-profile + lorawanCertified: true + codec: elv-lw-omo-codec + +# Sensors that this device features (optional) +# Valid values are: +# 4-20 ma, accelerometer, altitude, analog input, auxiliary, barometer, battery, button, bvoc, co, co2, conductivity, +# current, digital input, dissolved oxygen, distance, dust, energy, gps, gyroscope, h2s, humidity, iaq, level, light, +# lightning, link, magnetometer, moisture, motion, no, no2, o3, particulate matter, ph, pir, pm2.5, pm10, potentiometer, +# power, precipitation, pressure, proximity, pulse count, pulse frequency, radar, rainfall, rssi, smart valve, snr, so2, +# solar radiation, sound, strain, surface temperature, temperature, tilt, time, tvoc, uv, vapor pressure, velocity, +# vibration, voltage, water potential, water, weight, wifi ssid, wind direction, wind speed. +sensors: + - accelerometer + - button + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 18 + length: 17 + height: 81 + +# Weight in grams (optional) +weight: 43 + +# Battery information (optional) +battery: + replaceable: true + type: LR03 + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -10 + max: 55 + # Relative humidity (fraction of 1) + relativeHumidity: + min: 0 + max: 0.97 + +# Key provisioning (optional) +# Valid values are: custom (user can configure keys), join server and manifest. +keyProvisioning: + - custom + - join server + +# Key programming (optional) +# Valid values are: bluetooth, nfc, wifi, serial (when the user has a serial interface to set the keys) +# and firmware (when the user should change the firmware to set the keys). +keyProgramming: + - firmware + +# Key security (optional) +# Valid values are: none, read protected and secure element. +keySecurity: none + +# Firmware programming (optional) +# Valid values are: serial (when the user has a serial interface to update the firmware), fuota lorawan (when the device +# supports LoRaWAN FUOTA via standard interfaces) and fuota other (other wireless update mechanism). +firmwareProgramming: + - serial + +# Product and data sheet URLs (optional) +productURL: https://de.elv.com/ + +# Commercial information +resellerURLs: + - name: 'ELVshop' + region: + - European Union + url: https://de.elv.com/elv-lorawan-erschuetterungssensor-outdoor-elv-lw-omo-158753 +msrp: + EUR: 39.95 + +# Photos +photos: + main: elv-lw-omo-housing.png + other: + - elv-lw-omo-frontview.png + - elv-lw-omo-backview.png + - elv-lw-omo-components.png diff --git a/vendor/elv/index.yaml b/vendor/elv/index.yaml index 9782e8fb99..120553dfb9 100644 --- a/vendor/elv/index.yaml +++ b/vendor/elv/index.yaml @@ -6,3 +6,4 @@ endDevices: - elv-lw-esi - elv-lw-gps1 - elv-lw-mob + - elv-lw-omo