Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMX TCR Updates #806

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions vendor/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,16 @@ vendors:
name: Parametric Engineering GmbH
vendorID: 315

- id: pmx
name: PMX Systems AG
vendorID: 1141
website: https://www.pmx.systems
logo: pmx-logo.svg
description: PMX Systems AG is a Swiss company specialising in smart outdoor sensors.
social:
linkedin: https://www.linkedin.com/company/pmx-systems
github: pmx-systems

- id: proesys
name: ProEsys SRL
vendorID: 323
Expand Down
2 changes: 2 additions & 0 deletions vendor/pmx/index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
endDevices:
- pmx-tcr
26 changes: 26 additions & 0 deletions vendor/pmx/pmx-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions vendor/pmx/pmx-tcr-codec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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: pmx-tcr.js
examples:
- description: device id uplink
input:
fPort: 190
bytes: [210, 10, 2, 2, 17, 0, 66, 0]
output:
data:
typestr: TCR-DLI
fu_level: PRO
speedclass: HS
fw_version: 1.1.0
sbx_version: 4.2.0

- description: Unfiltered detections counter (UDC) uplink (port 13)
input:
fPort: 13
bytes: [162, 20, 10, 3, 232, 50, 4, 76, 52, 51]
output:
data:
time: 2010
udc_ltr_cnt: 1000
udc_ltr_spd: 50
udc_rtl_cnt: 1100
udc_rtl_spd: 52
volts: 5.1

- description: cat 1 counter uplink (port 14)
input:
fPort: 14
bytes: [162, 20, 10, 3, 232, 50, 4, 76, 52, 51]
output:
data:
time: 2010
cat1_ltr_cnt: 1000
cat1_ltr_spd: 50
cat1_rtl_cnt: 1100
cat1_rtl_spd: 52
volts: 5.1

- description: cat 2 counter uplink (port 15)
input:
fPort: 15
bytes: [162, 20, 10, 3, 232, 50, 4, 76, 52, 51]
output:
data:
time: 2010
cat2_ltr_cnt: 1000
cat2_ltr_spd: 50
cat2_rtl_cnt: 1100
cat2_rtl_spd: 52
volts: 5.1

- description: cat 3 counter uplink (port 16)
input:
fPort: 16
bytes: [162, 20, 10, 3, 232, 50, 4, 76, 52, 51]
output:
data:
time: 2010
cat3_ltr_cnt: 1000
cat3_ltr_spd: 50
cat3_rtl_cnt: 1100
cat3_rtl_spd: 52
volts: 5.1

- description: cat 4 counter uplink (port 17)
input:
fPort: 17
bytes: [162, 20, 10, 3, 232, 50, 4, 76, 52, 51]
output:
data:
time: 2010
cat4_ltr_cnt: 1000
cat4_ltr_spd: 50
cat4_rtl_cnt: 1100
cat4_rtl_spd: 52
volts: 5.1
Binary file added vendor/pmx/pmx-tcr-kit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
223 changes: 223 additions & 0 deletions vendor/pmx/pmx-tcr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/**
* PMX TCR Payload
*
* THIS SOFTWARE IS PROVIDED BY PMX SYSTEMS AG AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
const DeviceTypes = [
"TCR-LS", /* 0 Low Speed (2 Speed Groups) */
"TCR-LSS", /* 1 Low Speed Solar (2 Speed Groups) */
"TCR-HS", /* 2 High Speed (4 Speed Groups) */
"TCR-HSS", /* 3 High Speed Solar (4 Speed Groups) */
"TCR-LSA", /* 4 Low Speed AC Powered (2 Speed Groups) */
"TCR-LSB", /* 5 Low Speed AC External Battery Powered (4 Speed Groups) */
"TCR-HSA", /* 6 High Speed AC Powered (4 Speed Groups) */
"TCR-HSB", /* 7 High Speed External Battery Powered (4 Speed Groups) */
"TCR-LSBS", /* 8 Low Speed External Battery (External) + Solar (2 Speed Groups) */
"TCR-HSBS", /* 9 High Speed External Battery (External) + Solar (4 Speed Groups) */
"TCR-DLI", /* 10 DC powered, LoRaWAN, Internal Antenna */
"TCR-DLE", /* 11 DC powered, LoRaWAN, External Antenna */
"TCR-SLI", /* 12 Solar powered, LoRaWAN, Internal Antenna */
"TCR-SLE", /* 13 Solar powered, LoRaWAN, External Antenna */
"PCR2-OD", /* 14 Outdoor Models w/o battery*/
"PCR2-ODS", /* 15 Outdoor Models, Solar Powered */
];

// Function levels
const FeatureLevel = [
"BASIC", /* 0 BASIC Features enabled (no licence installed) */
"ADVANCED", /* 1 ADVANCED Features enabled */
"PRO" /* 2 PRO Features enabled */
];

// Speed classes
const SpeedClassTypes = [
"P", /* 0 Speed class for people counting (very low speed) */
"LS", /* 1 Low speed traffic counting */
"HS" /* 2 High speed traffic counting */
];

// Array of all available config keys (since JavaScript has no enum)
// Use this array to have a key instead of just an index number
const ConfigKeys = {

// 0 Totals
LR_CF_CMD_CAT0_ENABLED: 0x01, /** Enable category */
LR_CF_CMD_CAT0_MIN_SIZE: 0x02, /** Change min object size of category */
LR_CF_CMD_CAT0_MAX_SIZE: 0x03, /** Overwrite max object size of category */
LR_CF_CMD_CAT0_MIN_SPEED: 0x04, /** Overwrite min object speed of category */
LR_CF_CMD_CAT0_MAX_SPEED: 0x05, /** Overwrite max object speed of category */

// 1
LR_CF_CMD_CAT1_ENABLED: 0x11, /** Enable category */
LR_CF_CMD_CAT1_MIN_SIZE: 0x12, /** Overwrite min object size of category */
LR_CF_CMD_CAT1_MAX_SIZE: 0x13, /** Overwrite max object size of category */
LR_CF_CMD_CAT1_MIN_SPEED: 0x14, /** Overwrite min object speed of category */
LR_CF_CMD_CAT1_MAX_SPEED: 0x15, /** Overwrite max object speed of category */

// 2
LR_CF_CMD_CAT2_ENABLED: 0x21, /** Enable category */
LR_CF_CMD_CAT2_MIN_SIZE: 0x22, /** Overwrite min object size of category */
LR_CF_CMD_CAT2_MAX_SIZE: 0x23, /** Overwrite max object size of category */
LR_CF_CMD_CAT2_MIN_SPEED: 0x24, /** Overwrite min object speed of category */
LR_CF_CMD_CAT2_MAX_SPEED: 0x25, /** Overwrite max object speed of category */

// 3
LR_CF_CMD_CAT3_ENABLED: 0x31, /** Enable category */
LR_CF_CMD_CAT3_MIN_SIZE: 0x32, /** Overwrite min object size of category */
LR_CF_CMD_CAT3_MAX_SIZE: 0x33, /** Overwrite max object size of category */
LR_CF_CMD_CAT3_MIN_SPEED: 0x34, /** Overwrite min object speed of category */
LR_CF_CMD_CAT3_MAX_SPEED: 0x35, /** Overwrite max object speed of category */

// 4
LR_CF_CMD_CAT4_ENABLED: 0x41, /** Enable category */
LR_CF_CMD_CAT4_MIN_SIZE: 0x42, /** Overwrite min object size of category */
LR_CF_CMD_CAT4_MAX_SIZE: 0x43, /** Overwrite max object size of category */
LR_CF_CMD_CAT4_MIN_SPEED: 0x44, /** Overwrite min object speed of category */
LR_CF_CMD_CAT4_MAX_SPEED: 0x45, /** Overwrite max object speed of category */

/* Device Settings */
LR_CF_CMD_LIC_KEY: 0x51, /** Licence Key RW */
LR_CF_CMD_FU_LEVEL: 0x52, /** Feauture Level RO*/
LR_CF_CMD_SPEED_CLASS: 0x53, /** Feauture Level RO*/
LR_CF_CMD_MEAS_INTERVAL: 0x54, /** Meas Interval RW */

/* Radar Settings */
LR_CF_CMD_RADAR_ENABLED: 0x61, /** Switch radar module on / off */
LR_CF_CMD_RADAR_CHANNEL: 0x62, /** Choose Radar Channel: 1, 2 */
LR_CF_CMD_RADAR_SENS: 0x63, /** Radar Sensitivity Level [%]*/
LR_CF_CMD_RADAR_AUTOSENS: 0x64, /** Enable Autosens, 0 = off , 1 = on */

/* LoRaWAN Settings */
LR_CF_CMD_LORA_UL_CONFIRMED: 0x71, /** Set confirmed uplinks mode*/


LR_CF_CMD_CLEAR: 0xcc, /** cf starts the configuration uplink sequence */
LR_CF_CMD_CONFIG_SEQ: 0xcf, /** cf starts the configuration uplink sequence */
LR_CF_CMD_DEFAULTS: 0xdf, /** df set factory defaults (use ee for saving to ROM) */
LR_CF_CMD_RESTART: 0xee /** ee Restart device with new settings */
};

function d2_decoder(bytes, port) {
var obj = {};
obj.typestr = DeviceTypes[bytes[1]]; // 00: TCR-LS, 01: TCR-LSS , ...
obj.fu_level = FeatureLevel[bytes[2]]; // 00: BASIC, 01: ADVANCED , ...
obj.speedclass = SpeedClassTypes[bytes[3]]; // 00: Speedclass, 01: LS , 02: HS
obj.fw_version = (bytes[4] & 0xf0) / 0x10 + "." + (bytes[4] & 0x0f) + "." + bytes[5]; // Firmware Major Version
obj.sbx_version = (bytes[6] & 0xf0) / 0x10 + "." + (bytes[6] & 0x0f) + "." + bytes[7]; // SBX Solar Charger Firmware Version
return obj;
}

function a2_decoder(bytes, port) {
var obj = {};

if (port == 13) // Unfiltered Detections
{
obj.time = bytes[1] * 100 + bytes[2]; // Measure Interval End Timestamp (Military Time format)
obj.udc_ltr_cnt = (bytes[3] << 8) | (bytes[4]); // Left-to-Right (LTR) Counter Value (0-65535)
obj.udc_ltr_spd = bytes[5]; // Left-to-Right (LTR) average speed of all objects counted in this interval [km/h]
obj.udc_rtl_cnt = (bytes[6] << 8) | (bytes[7]); // Right-to-Left (RTL) Counter Value (0-65535)
obj.udc_rtl_spd = bytes[8]; // Right-to-Left (RTL) average speed of all objects counted in this interval [km/h]
}

if (port == 14) // Filter Category 1
{
obj.time = bytes[1] * 100 + bytes[2]; // Measure Interval End Timestamp (Military Time format)
obj.cat1_ltr_cnt = (bytes[3] << 8) | (bytes[4]); // Left-to-Right (LTR) Counter Value (0-65535)
obj.cat1_ltr_spd = bytes[5]; // Left-to-Right (LTR) average speed of all objects counted in this interval [km/h]
obj.cat1_rtl_cnt = (bytes[6] << 8) | (bytes[7]); // Right-to-Left (RTL) Counter Value (0-65535)
obj.cat1_rtl_spd = bytes[8]; // Right-to-Left (RTL) average speed of all objects counted in this interval [km/h]
}

if (port == 15) // Filter Category 2
{
obj.time = bytes[1] * 100 + bytes[2]; // Measure Interval End Timestamp (Military Time format)
obj.cat2_ltr_cnt = (bytes[3] << 8) | (bytes[4]); // Left-to-Right (LTR) Counter Value (0-65535)
obj.cat2_ltr_spd = bytes[5]; // Left-to-Right (LTR) average speed of all objects counted in this interval [km/h]
obj.cat2_rtl_cnt = (bytes[6] << 8) | (bytes[7]); // Right-to-Left (RTL) Counter Value (0-65535)
obj.cat2_rtl_spd = bytes[8]; // Right-to-Left (RTL) average speed of all objects counted in this interval [km/h]
}

if (port == 16) // Filter Category 3
{
obj.time = bytes[1] * 100 + bytes[2]; // Measure Interval End Timestamp (Military Time format)
obj.cat3_ltr_cnt = (bytes[3] << 8) | (bytes[4]); // Left-to-Right (LTR) Counter Value (0-65535)
obj.cat3_ltr_spd = bytes[5]; // Left-to-Right (LTR) average speed of all objects counted in this interval [km/h]
obj.cat3_rtl_cnt = (bytes[6] << 8) | (bytes[7]); // Right-to-Left (RTL) Counter Value (0-65535)
obj.cat3_rtl_spd = bytes[8]; // Right-to-Left (RTL) average speed of all objects counted in this interval [km/h]
}

if (port == 17) // Filter Category 4
{
obj.time = bytes[1] * 100 + bytes[2]; // Measure Interval End Timestamp (Military Time format)
obj.cat4_ltr_cnt = (bytes[3] << 8) | (bytes[4]); // Left-to-Right (LTR) Counter Value (0-65535)
obj.cat4_ltr_spd = bytes[5]; // Left-to-Right (LTR) average speed of all objects counted in this interval [km/h]
obj.cat4_rtl_cnt = (bytes[6] << 8) | (bytes[7]); // Right-to-Left (RTL) Counter Value (0-65535)
obj.cat4_rtl_spd = bytes[8]; // Right-to-Left (RTL) average speed of all objects counted in this interval [km/h]
}

obj.volts = bytes[9] / 10; // Power supply voltage. Divide by 10 to get volts.
return obj;
}

function c2_decoder(bytes, port) {
var obj = {};

// 8 Bit values
if (bytes.length == 3) {
obj[ConfigKeys[bytes[1]]] = bytes[2];
}

// 16 Bit values
if (bytes.length >= 4) {
obj[ConfigKeys[bytes[1]]] = (bytes[2] << 8) | (bytes[3]);
}
return obj;
}

function bin16dec(bin) {
var num = bin & 0xFFFF;
if (0x8000 & num) num = -(0x010000 - num);
return num;
}

function hexToBytes(hex) {
hex = hex.replace(/\s/g, "");
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
}


function decodeUplink(input) {
var data = {};
var bytes = input.bytes;
var port = input.fPort;

// it's a Device ID Payload V2 (PMX Firmware for TCR)
if (port == 190 && bytes[0] == 0xd2) {

data = d2_decoder(bytes, port);
}

// it's a Counter Payload V2 (PMX Firmware for TCR)
if (port >= 13 && port <= 17 && bytes[0] == 0xa2) {

data = a2_decoder(bytes, port);
}

// it's a Config Payload Response (PMX Firmware for TCR)
if (port == 1 && bytes[0] == 0xc2) {

data = c2_decoder(bytes, port);
}
return {
data: data,
};
}
Binary file added vendor/pmx/pmx-tcr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading