workable L8 with decoder updated and function test report revised

This commit is contained in:
Yunhorn 2024-11-19 21:00:19 +08:00
parent c04476ee08
commit 2199ea2151
5 changed files with 1112 additions and 526 deletions

View File

@ -252,6 +252,12 @@ typedef struct sts_fhmos_sensor_config
} sts_fhmos_sensor_config_t;
typedef struct sts_fhmos_sensor_ambient_height
{
uint32_t h2cm[64]; //height in 2cm scan data, ensure it less than 250*2=500cm, 5meter
} sts_fhmos_sensor_ambient_height_t;
/**
* @brief Store/Write/Flash Configuration in RW RAM
*/
@ -313,6 +319,7 @@ void STS_PRESENCE_SENSOR_Function_Test_Process(uint8_t *self_test_result, uint8_
void STS_PRESENCE_SENSOR_Distance_Measure_Process(void);
void STS_TOF_L8_Process(void);
void STS_LMZ_Ambient_Height_Scan_Process(void);
void STS_FHMOS_sensor_read(sts_fhmos_sensor_data_t *sts_fhmos_data);
void STS_FHMOS_sensor_config_init(void);
void STS_FHMOS_sensor_config_update(void);

View File

@ -640,7 +640,7 @@ void USER_APP_Parse_CMD_P(uint8_t *parse_buffer, uint8_t parse_buffer_size)
{
uint8_t sts_fhmos_cfg_index = (uint8_t)(parse_buffer[CFG_CMD5]-0x30);
uint8_t sts_fhmos_cfg_value = (parse_buffer[CFG_CMD6]-0x30)*100+(parse_buffer[CFG_CMD7]-0x30)*10+(parse_buffer[CFG_CMD8]-0x30);
APP_LOG(TS_OFF, VLEVEL_M, "\r\nCFG_CMD VALUE =0X%02X =%d \r\n", sts_fhmos_cfg_value,sts_fhmos_cfg_value);
//APP_LOG(TS_OFF, VLEVEL_M, "\r\nCFG_CMD VALUE =0X%02X =%d \r\n", sts_fhmos_cfg_value,sts_fhmos_cfg_value);
switch (sts_fhmos_cfg_index) {
case 1: // head level height threshold
sts_fhmos_cfg.sts_head_level_height_threshold_cm = sts_fhmos_cfg_value;
@ -1821,9 +1821,11 @@ void STS_SENSOR_Distance_Test_Process(void)
#if defined(VL53LX)||defined(L8)
//MX_TOF_Init();
//MX_TOF_Process();
MX_TOF_Process();
sts_sensor_install_height = (uint16_t)MX_TOF_Ranging_Process();
APP_LOG(TS_OFF, VLEVEL_M, "\n STS SENSOR INSTALLATION HEIGHT =%d mm\n\r", (uint16_t)sts_sensor_install_height);
STS_LMZ_Ambient_Height_Scan_Process();
#endif
#if defined(VL53L0)
STS_TOF_VL53L0X_Range_Process();
@ -1851,24 +1853,34 @@ void STS_SENSOR_Function_Test_Process(void)
tstbuf[i++] = (uint8_t) sts_hardware_ver;
tstbuf[i++] = (uint8_t) (99*GetBatteryLevel()/254)&0xff;
#if (defined(STS_P2)||defined(STS_T6))
#if (defined(STS_P2)||defined(STS_T6))||defined(L8)
STS_SENSOR_MEMS_Get_ID(&sensor_id);
printf("\r\n Sensor id =%04x \r\n", sensor_id);
#if defined(L8)
if (((sensor_id & 0xff)!= 0x0C) && (((sensor_id >>8) & 0xFF)!=0xF0)) // no VL53L8X found
{
tstbuf[i++] = (uint8_t) 'X'; // Slave MEMS Not Avaliable
}
#else
if (((sensor_id & 0xff)!= 0xCC) && (((sensor_id >>8) & 0xFF)!=0xEA)) // no VL53L1X found
{
tstbuf[i++] = (uint8_t) 'X'; // Slave MEMS Not Avaliable
} else
}
#endif
else
{
STS_SENSOR_Distance_Test_Process();
APP_LOG(TS_OFF, VLEVEL_M, "\nSensor Install Height =%4d mm\n", sts_sensor_install_height);
tstbuf[i++] = (uint8_t) (2)&0xff; //length of following data
tstbuf[i++] = (uint8_t) (4)&0xff; //length of following data
tstbuf[i++] = (uint8_t) (sensor_id >>8)&0xFF;
tstbuf[i++] = (uint8_t) (sensor_id) & 0xFF;
tstbuf[i++] = (uint8_t) (sts_sensor_install_height>>8)&0xff; // MSB of sensor height
tstbuf[i++] = (uint8_t) (sts_sensor_install_height)&0xff; // LSB of sensor height
}
/* */
/* for STS_P2, set ppc_config -> door_jam_profile and distance threshold accordingly */
/* */
#ifdef STS_P2
if ((sts_sensor_install_height >= 1500)&&(sts_sensor_install_height<=4000))
{
sts_door_jam_profile = DOOR_JAM_2000; // DOOR_JAM_2000: assume door_jame less 2000mm
@ -1883,6 +1895,7 @@ void STS_SENSOR_Function_Test_Process(void)
sts_door_jam_profile ++; //DOOR_JAM_4000
}
#endif
#endif
#ifdef YUNHORN_STS_O6_ENABLED
tstbuf[i++] = (uint8_t)20; //length of following data
uint8_t self_test_result[10]={0,0,0,0,0, 0,0,0,0,0};

View File

@ -38,6 +38,8 @@ extern "C" {
volatile uint8_t fhmos_fall=0, fhmos_human_movement=0, fhmos_occupancy=0, fhmos_sos_alarm=0;
volatile uint32_t fhmos_fall_counter=0;
volatile sts_fhmos_sensor_config_t sts_fhmos_cfg;
volatile sts_fhmos_sensor_ambient_height_t sts_fhmos_bg={0x0};
extern volatile uint16_t sts_sensor_install_height; //in mm
#endif
#include "stm32wlxx_nucleo.h"
@ -156,6 +158,53 @@ void MX_TOF_Init(void)
/*
* LM background task
*/
void STS_LMZ_Ambient_Height_Scan_Process(void)
{
uint8_t i=0;
uint32_t range_distance =0;
printf("ambient height init...\r\n");
for (i=0; i<64; i++) sts_fhmos_bg.h2cm[i] = 0;
printf("sts sensor install height = %4d \r\n", (int)sts_sensor_install_height);
for (uint8_t k=0; k<10; k++)
{
int status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
for (uint8_t i = 0; i < 64; i++)
{
/* Print distance and status */
if (Result.ZoneResult[i].NumberOfTargets > 0)
{
range_distance = (uint32_t)Result.ZoneResult[i].Distance[0];
if (sts_sensor_install_height > range_distance)
sts_fhmos_bg.h2cm[i] = sts_fhmos_bg.h2cm[i] + ((uint32_t)sts_sensor_install_height - range_distance);
printf("|%4d %4d ", range_distance, sts_fhmos_bg.h2cm[i]);
if (i%8==0) printf("\r\n");
//sts_fhmos_bg.h2cm[i] += ((uint32_t)sts_sensor_install_height - range_distance;
//sts_fhmos_bg.h2cm[i] += ((uint32_t)sts_sensor_install_height - (uint32_t)Result.ZoneResult[i].Distance[0]);
}
else {
sts_fhmos_bg.h2cm[i] += 0;
printf(" .%2d. ", i);
}
}
}
for (i=0; i<64; i++)
{
sts_fhmos_bg.h2cm[i] /= 10;
printf("|%4d ", (uint32_t)sts_fhmos_bg.h2cm[i]);
if (i%8==0) printf("\r\n");
}
}
uint16_t MX_TOF_Ranging_Process(void)
{
@ -167,12 +216,15 @@ uint16_t MX_TOF_Ranging_Process(void)
return (uint16_t) range_distance;
#elif defined(L8)
uint16_t range_distance=0;
uint32_t range_distance=0;
uint8_t center_roi[4] = {27,28,35,36};
uint8_t range_mode = 2; //STS_TOF_LONG_RANGE;
int status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
//int status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
printf("\r| 27 | 28 | 35 | 36 |\r\n");
for (uint8_t k=0; k<10; k++)
{
int status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
for (uint8_t zone_nbr = 0; zone_nbr < 4; zone_nbr++)
{
@ -188,11 +240,14 @@ uint16_t MX_TOF_Ranging_Process(void)
}
range_distance += Result.ZoneResult[center_roi[zone_nbr]].Distance[RANGING_SENSOR_NB_TARGET_PER_ZONE-1];
//printf("| %6d -- ", range_distance);
}
//printf("\n\r");
printf("\n\r");
}
printf("\n\r");
range_distance /=4;
range_distance /=40;
printf("| %u mm\r\n", (uint16_t)range_distance);
return (uint16_t) range_distance;
@ -242,7 +297,7 @@ void STS_TOF_L8_Process(void)
if (status == BSP_ERROR_NONE)
{
print_result(&Result);
//print_result(&Result);
}
}
}

View File

@ -3,13 +3,79 @@
// - bytes is an array of bytes, e.g. [225, 230, 255, 0]
// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string)
// The function must return an object, e.g. {"temperature": 22.5}
// for Yunhorn SmarToilets STS-O7 Occupancy/Fall Detection/Over stay sensor
//
// Yunhorn SmarToilets Sensor R20241119A01
//
function Decode(fPort, data, variables) {
var data = {};
data.length = bytes.length;
switch (fPort) {
// RESPOND PORT --- bottom of swith fport
// case 1:
// break;
// CMD DOWN LINK PORT
case 2:
break;
// STS-R5 (LEGACY, ULTRASONIC WASTE-BIN)
case 3:
break;
// STS-O1/O2/O3/O5 REEDSWITCH, OCCUPANCY LED REPORT
case 4:
data.led_state = bytes[0] == 0x0 ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
data.hw_code = bytes[3];
data.battery_level = bytes[4] + "%";
data.size_value = bytes[5];
data.door_state = (bytes[6] === 0) ? "Door_Closed" : "Door_Open";
return { "Yunhorn_SmarToilets_data": data };
break;
// HEART-BEAT FOR STS-O1/O2/O3/O5 REEDSWITCH, OCCUPANCY LED REPORT
case 5:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-M1 water leakage sensor
case 6:
if (data.length === 2) {
data.led_state = bytes[0] == 0x0 ? "Off" : "On";
data.battery_level = bytes[1] + "%";
} else {
data.led_state = bytes[0] == 0x0 ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
data.hw_code = bytes[3];
//data.battery_level_mV= bytes[4]*100+" mV";
data.battery_level = bytes[4] + " %";
data.size_value = bytes[5];
data.measure_tech = (bytes[6] === 0) ? "Weak Current" : "Other";
data.liquid_level_event = (bytes[7] === 0x1) ? "Leakage Detected" : "No Leakage";
}
return { "Yunhorn_SmarToilets_data": data };
break;
// temp heart-beat for STS-M1
case 66:
if (data.length === 2) {
data.led_state = bytes[0] == 0x0 ? "Off" : "On";
data.battery_level_mV = bytes[1] * 100 + " mV";
return { "Yunhorn_SmarToilets_data": data };
}
break;
// R4 soap/sanitizer sensor
if (fPort === 7) {
data.length = bytes.length;
case 7:
data.led_state = bytes[0] == 0x0 ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
@ -20,8 +86,25 @@ function Decode(fPort, data, variables) {
data.liquid_level_event = (bytes[7] === 0x1) ? "Liquid Detected" : "No Liquid";
return { "Yunhorn_SmarToilets_data": data };
}
else if ((fPort === 10)) { // STS_O2_O6 V3 version 2023,pixel-network version
break;
// STS-R3 soap yes no
case 8:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-M3 water tank or cistern level sensor Ultrasonic
case 9:
break;
// STS_O2_O6 V3 version 2023,pixel-network version
case 10:
switch (bytes[0]) {
case 0x00:
data.LEDcolor = "Dark";
@ -95,11 +178,12 @@ function Decode(fPort, data, variables) {
data.workmode = "Unknown Mode";
break;
}
// select only one below
// For NC(Normal Closed states
// For NC (Normal Closed states)
data.Sensor1_Door_Contact_Open = bytes[2] === 0 ? "Door Closed" : "Door Open";
// For NC(Normal Closed states
// For NC (Normal Closed states)
// data.Sensor1_Door_Contact_Open = bytes[3]===1?"Door Closed":"Door Open";
if (bytes[1] == 0x02) //Hall_element_mode
{
@ -109,8 +193,94 @@ function Decode(fPort, data, variables) {
}
return { "Yunhorn_SmarToilets_data": data };
}
else if ((fPort === 17) || (fPort === 19) || (fPort === 21)) {
break;
// STS R5 waste bin
case 11:
data.LED_State = (bytes[0] === 0) ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
data.hw_code = bytes[3];
data.battery_level = bytes[4] + "%";
// data.battery_level_mV = (bytes[4])*100 + " mV";
data.size_value = bytes[5];
data.distance_1_mm = bytes[6] << 8 | bytes[7];
// data.distance_2_mm = bytes[8]<<8|bytes[9];
// data.distance_3_mm = bytes[10]<<8|bytes[11];
data.distance_unit = "mm";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-M4 water flow sensor
case 12:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-M1A Water mark sensor thermal matrix
case 13:
break;
// STS-M1A Water mark sensor thermal matrix, heart-beat
//case 14:
//break;
// STS-T6 O6T ToF Presence Detection
case 14:
data.LED_State = (bytes[0] & 0x7f === 0) ? "Off" : "On";
data.MTM_Code_1 = bytes[1];
data.MTM_Code_2 = bytes[2];
data.HW_Code = bytes[3];
data.Battery_Level = bytes[4] + " %";
data.Payload_Size = bytes[5];
data.Presence_State = (bytes[6] == 1) ? "Occupied" : "Vacant";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-T6 heart beat
case 15:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
break;
// Multi-Function Sensor for Hong Kong HA.gov.hk
case 16:
data.LED_State = (bytes[0] & 0x7f === 0) ? "Off" : "On";
data.MTM_Code_1 = bytes[1];
data.MTM_Code_2 = bytes[2];
data.HW_Code = bytes[3];
data.Battery_Level = bytes[4] + " %";
data.Payload_Size = bytes[5];
//data.Presence_State = (bytes[6]==1)? "Occupied":"Vacant";
data.MF_Fall = bytes[6];
data.MF_Human_Movement = bytes[7];
data.MF_Occupancy = bytes[8];
data.MF_SOS_Alarm = bytes[9];
return { "Yunhorn_SmarToilets_data": data };
break;
case 18:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
break;
// Heart-beat for STS-O6 occupancy sensor
case 17:
// STS-O7 Fall detection sensor
case 19:
case 21:
{
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
switch (bytes[1]) {
case 0x00:
@ -262,86 +432,315 @@ function Decode(fPort, data, variables) {
}
return { "Yunhorn_SmarToilets_data": data };
}
else if ((fPort === 11) || (fPort === 52)) {
return [
{
led_state: bytes[0] === 0 ? "Off" : "On",
mtm_code_1: bytes[1],
mtm_code_2: bytes[2],
hw_code: bytes[3],
battery_level: bytes[4] + "%",
//battery_level:(bytes[4])*100+" mV",
size_value: bytes[5],
distance_1_mm: bytes[6] << 8 | bytes[7],
//distance_2_mm:bytes[8]<<8|bytes[9],
//distance_3_mm:bytes[10]<<8|bytes[11],
distance_unit: "mm",
}
];
}
break;
break;
// STS-O6 occupancy sensor heart-beat
case 18:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-O7 Fall detection sensor heart-beat
case 20:
break;
// STS-M7 Vibration sensor
case 20:
break;
// STS-R6 Weight Scale Sensor
case 27:
data.LED_State = (bytes[0] & 0x7f === 0) ? "Off" : "On";
data.MTM_Code_1 = bytes[1];
data.MTM_Code_2 = bytes[2];
data.HW_Code = bytes[3];
data.Battery_Level = bytes[4] + " %";
data.Payload_Size = bytes[5];
data.Weight_g = (bytes[6] << 8 | bytes[7]);
data.Tare_g = (bytes[8] << 8 | bytes[9]);
return { "Yunhorn_SmarToilets_data": data };
break;
// STS R3 Soap Yes_No sensor
case 51:
data.LED_State = (bytes[0] === 0) ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
data.hw_code = bytes[3];
data.battery_level = bytes[4] + "%";
// data.battery_level_mV = (bytes[4])*100 + " mV";
data.size_value = bytes[5];
data.Liquid_detected = bytes[6];
data.Detect_method = (bytes[7] === 0) ? "Capacitive" : "ToF";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS R2 Tissue paper sensor
case 52:
data.LED_State = (bytes[0] === 0) ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
data.hw_code = bytes[3];
data.battery_level = bytes[4] + "%";
// data.battery_level_mV = (bytes[4])*100 + " mV";
data.size_value = bytes[5];
data.distance_1_mm = bytes[6] << 8 | bytes[7];
// data.distance_2_mm = bytes[8]<<8|bytes[9];
// data.distance_3_mm = bytes[10]<<8|bytes[11];
data.distance_unit = "mm";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-M8 QUEUE BAR SENSOR
case 55:
// STS-O4 URINAL OCCUPANCY SENSOR
case 56:
break;
// R1D dual roll toilet paper sensor
else if (fPort === 57) {
return [
case 57:
data.LED_State = (bytes[0] === 0) ? "Off" : "On";
data.mtm_code_1 = bytes[1];
data.mtm_code_2 = bytes[2];
data.hw_code = bytes[3];
data.battery_level = bytes[4] + "%";
//data.battery_level_mV = (bytes[4])*100 + " mV";
data.size_value = bytes[5];
data.distance_1_mm = bytes[6] << 8 | bytes[7];
data.distance_2_mm = bytes[8] << 8 | bytes[9];
// data.distance_3_mm = bytes[10]<<8|bytes[11];
data.distance_unit = "mm";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-R1 Single roll toilet paper sensor
case 58:
data.LED_State = (bytes[0] === 0) ? "Off" : "On";
//data.mtm_code_1 = bytes[1];
//data.mtm_code_2 = bytes[2];
//data.hw_code = bytes[3];
//data.battery_level = bytes[1]+"%";
data.battery_level_mV = (bytes[1]) * 100 + " mV";
//data.size_value = bytes[5];
//data.distance_1_mm = bytes[6]<<8|bytes[7];
//data.distance_2_mm = bytes[8]<<8|bytes[9];
// data.distance_3_mm = bytes[10]<<8|bytes[11];
//data.distance_unit = "mm";
return { "Yunhorn_SmarToilets_data": data };
break;
// STS-M2 TOILET CLOGGING SENSOR
case 59:
break;
// STS-E4 PTAQ, ODOR LEVEL Sensor 4-IN-1
case 70:
break;
// STS-E6 PTAQ, ODOR LEVEL Sensor 6-IN-1
case 72:
break;
// STS-E5 PTAQ, ODOR LEVEL Sensor 5-IN-1
case 74:
break;
// STS-E2 PTAQ, ODOR LEVEL Sensor
case 101:
break;
// STS-E1 Smoking Sensor
case 102:
break;
// STS-P1 QUEUEING SENSOR
case 104:
break;
// STS-M6 POWER RELAY SENSOR
case 105:
break;
// STS-P2 IN-OUT PEOPLE COUNTING SENSOR
case 106:
{
led_state: bytes[0] === 0 ? "Off" : "On",
mtm_code_1: bytes[1],
mtm_code_2: bytes[2],
hw_code: bytes[3],
battery_level: bytes[4] + "%",
//battery_level:(bytes[4])*100+" mV",
size_value: bytes[5],
distance_1_mm: bytes[6] << 8 | bytes[7],
distance_2_mm: bytes[8] << 8 | bytes[9],
//distance_3_mm:bytes[10]<<8|bytes[11],
distance_unit: "mm",
}
];
}
else if ((fPort === 106)) { //STS-P2 bi-directional people counting
var counting = {};
var counting_today = {};
// STS-P2 bi-directional people counting
data.LED_State = bytes[0] === 0 ? "Off" : "On";
data.MTM_Code_1 = bytes[1];
data.MTM_Code_2 = bytes[2];
data.HW_Code = bytes[3];
data.Battery_Level = bytes[4] + " %";
data.Payload_Size = bytes[5];
data.Walk_In_People_Count = bytes[6] << 8 | bytes[7];
data.Walk_Out_People_Count = bytes[8] << 8 | bytes[8];
data.Walk_Around_People_Count = bytes[10] << 8 | bytes[11];
//data.Walk_In_People_Count = bytes[6] << 8 | bytes[7];
//data.Walk_Out_People_Count = bytes[8] << 8 | bytes[9];
//data.Walk_Around_People_Count = bytes[10] << 8 | bytes[11];
counting.Walk_In_People_Count = bytes[6] << 8 | bytes[7];
counting.Walk_Out_People_Count = bytes[8] << 8 | bytes[9];
counting.Walk_Around_People_Count = bytes[10] << 8 | bytes[11];
data.Count_Period = bytes[12];
data.Count_Period_Unit = String.fromCharCode(bytes[13]);
data.Sum_Day_Walk_In_People_Count = bytes[14] << 8 | bytes[15];
data.Sum_Day_Walk_Out_People_Count = bytes[16] << 8 | bytes[17];
data.Sum_Day_Walk_Around_People_Count = bytes[18] << 8 | bytes[19];
//data.Sum_Day_Walk_In_People_Count = bytes[14] << 8 | bytes[15];
//data.Sum_Day_Walk_Out_People_Count = bytes[16] << 8 | bytes[17];
//data.Sum_Day_Walk_Around_People_Count = bytes[18] << 8 | bytes[19];
counting_today.Sum_Day_Walk_In_People_Count = bytes[14] << 8 | bytes[15];
counting_today.Sum_Day_Walk_Out_People_Count = bytes[16] << 8 | bytes[17];
counting_today.Sum_Day_Walk_Around_People_Count = bytes[18] << 8 | bytes[19];
data.Count_Valid = (bytes[20] == 0x0) ? "Error" : "OK";
return { "Yunhorn_SmarToilets_data": data };
return { "Yunhorn_SmarToilets_data": data, "Couting_Now": counting, "Counting_today": counting_today };
}
// Heart Beat
else if ((fPort === 8) || (fPort === 12) || (fPort === 20) || (fPort === 18) || (fPort === 5) || (fPort === 107) || (fPort === 58)) {
var data = {};
break;
// HEART-BEAT FOR STS-P2 IN-OUT PEOPLE COUNTING SENSOR
case 107:
//data.led_state=(bytes[0] & 0x7f) === 0 ? "Off" : "On";
data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF";
//data.battery_level = bytes[1] + " %";
data.battery_level = bytes[1] * 100 + "mV";
return { "Yunhorn_SmarToilets_data": data };
}
break;
// UPLINK, RFAC
else if (fPort === 1) {
var data = {};
data.length = bytes.length;
if ((data.length === 10) && (bytes[0] == 0x59) && (bytes[9] == 0x38)) {
data.Yunhorn_PRD = "True";
data.PRD_String = String.fromCharCode(bytes);
}
else if ((data.length === 4) && (bytes[0] == 0x52) && (bytes[1] == 0x46)) //RFAC
{
data.Request_Performed = "OK";
data.RFAC = "OK";
data.AC0 = bytes[0];
data.AC1 = bytes[1];
}
else if ((data.length === 4) && (bytes[0] === 0x50) && (bytes[1] === 0x31) && (bytes[2] === 0x31)) {
// respond port
case 1:
switch (bytes[0]) {
// NVM config 'C'
case 0x43:
// report current nvm config
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.sts_uplink_interval = bytes[5];
data.sts_uplink_interval_unit = String.fromCharCode(bytes[6]);
data.sts_sampling_interval = bytes[7];
data.sts_sampling_interval_unit = String.fromCharCode(bytes[8]);
data.sts_work_mode = bytes[9];
data.sts_service_mask = bytes[10];
data.sts_reserve01 = bytes[11];
data.sts_payload_length = bytes[12];
data.rss_start_distance = bytes[13] * 0.1 + " meter";
data.rss_range_length = bytes[14] * 0.1 + " meter";
data.rss_threshold = bytes[15] * 0.1;
data.rss_receiving_gain = bytes[16] + " %";
data.rss_profile = bytes[17];
data.rss_rate_tracking = bytes[18];
data.rss_rate_presence = bytes[19];
data.rss_HWAAS = bytes[20];
data.rss_nbr_removed_pc = bytes[21];
data.rss_inter_frame_deviation_time_const = bytes[22] * 0.1;
data.rss_inter_frame_fast_cutoff = bytes[23];
data.rss_inter_frame_slow_cutoff = bytes[24];
data.rss_intra_frame_time_const = bytes[25];
data.rss_intra_frame_weight = bytes[26] * 0.1;
data.rss_output_time_const = bytes[27] * 0.1;
data.rss_downsampling_factor = bytes[28];
data.rss_power_saving_mode_active = bytes[29];
data.rss_reserve02 = bytes[30];
data.rss_reserve03 = bytes[31];
data.rss_reserve04 = bytes[32];
data.reserve2 = bytes[33];
data.reserve3 = bytes[34];
data.sensor_install_height = bytes[35] * 10 + " cm";
data.alarm_parameter05 = bytes[36];
data.alarm_mute_expire_timer = bytes[37];
data.alarm_lamp_bar_flashing_color = bytes[38];
data.occupancy_overtime_threshold = bytes[39];
data.motionless_duration_threshold = bytes[40];
data.unconcious_threshold = bytes[41];
data.fall_detection_acc_threshold = bytes[42];
data.fall_detection_depth_threshold = bytes[43];
data.fall_down_confirm_threshold = bytes[44];
break;
// D DISTANCE , INSTALLATION HEIGHT REPORT
case 0x44:
// MEASURE INSTALLATION HEIGHT
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.battery_level = bytes[5];
data.payload_length = bytes[6];
//data.Measure_Distance = String.fromCharCode(bytes[7]) + String.fromCharCode(bytes[8]) + String.fromCharCode(bytes[9]) + String.fromCharCode(bytes[10]);
// update on 2024-11-02
data.Measure_Distance = bytes[7] << 8 | bytes[8];
data.Distance_unit = "mm";
break;
// LoRa Class 'L'
case 0x4c:
// LoRaWAN Class A/B/C
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.LoRaWAN_Class = String.fromCharCode(bytes[4]);
break;
// M 'M' for STS-P2 LOG DATA
case 0x4D:
data.sum_day_in = bytes[1] | bytes[2] << 8;
data.sum_day_out = bytes[3] | bytes[4] << 8;
data.sum_day_around = bytes[5] | bytes[6] << 8;
data.sum_week_in = bytes[7] | bytes[8] << 8;
data.sum_week_out = bytes[9] | bytes[10] << 8;
data.sum_week_around = bytes[11] | bytes[12] << 8;
data.sum_month_in = bytes[13] | bytes[14] << 8;
data.sum_month_out = bytes[15] | bytes[16] << 8;
data.sum_month_around = bytes[17] | bytes[18] << 8;
data.sum_year_in = bytes[19] | bytes[20] << 8;
data.sum_year_out = bytes[21] | bytes[22] << 8;
data.sum_year_around = bytes[23] | bytes[24] << 8;
data.sum_lifeCycle_in = bytes[25] | bytes[26] << 8;
data.sum_lifeCycle_out = bytes[27] | bytes[28] << 8;
data.sum_lifeCycle_around = bytes[29] | bytes[30] << 8;
break;
// CONTROL COMMAND 'P'
case 0x50:
// P-CMD work mode change
switch (data.length) {
case 4:
if ((data.length === 4) && (bytes[1] === 0x31) && (bytes[2] === 0x31)) {
data.Work_Mode_Switch = "OK";
switch (bytes[3] - 0x30) {
case 0x0:
@ -368,23 +767,252 @@ function Decode(fPort, data, variables) {
}
}
if ((bytes[0] === 0x59) && (bytes[1] === 0x44)) //Duration interval
break;
case 7:
if (bytes[3] === 0x46) {
// F --- fall down & unconscious detection threshold
data.FALL_acceleration = (bytes[4] == 0x30 ? "Disabled" : ((bytes[4] - 0x30) * 10) + " mg/s2");
data.FALL_depth_measure = (bytes[5] == 0x30 ? "Disabled" : ((bytes[5] - 0x30) * 10) + " cm");
data.FALL_confirm_threshold = (bytes[6] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 10) + " seconds");
//data.FALL_reserved = (bytes[7]==0x0?"Disabled":((bytes[6]-0x30)*10)+" min");
}
break;
case 8:
if (bytes[3] === 0x4f) {
// O -- over stay, onconscious, long stay
data.OMU_Motionless_duration_in_min = (bytes[4] == 0x30 ? "Disabled" : ((bytes[4] - 0x30)) + " Min");
data.OMU_Long_Occupy_duration_in_Min = (bytes[5] == 0x30 ? "Disabled" : ((bytes[5] - 0x30) * 10) + " Min");
data.OMU_Unconcious_Threshold = (bytes[6] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 100) + "ml");
data.OMU_Alarm_Mute_Reset_Timer = (bytes[7] == 0x30 ? "Disabled" : ((bytes[7] - 0x30) * 10) + " Seconds");
} else if (bytes[3] === 0x46) {
// F --- fall down & unconscious detection threshold
data.FALL_acceleration = (bytes[4] == 0x30 ? "Disabled" : ((bytes[4] - 0x30) * 10) + " mg/s2");
data.FALL_depth_measure = (bytes[5] == 0x30 ? "Disabled" : ((bytes[5] - 0x30) * 10) + " cm");
data.FALL_confirm_threshold = (bytes[6] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 10) + " seconds");
data.FALL_reserved = (bytes[7] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 10) + " min");
}
break;
case 11:
// P 1108201365
data.RSS_SIMPLE_Start = ((bytes[3] - 0x30) * 100 + (bytes[4] - 0x30) * 10) + " cm";
data.RSS_SIMPLE_Length = ((bytes[5] - 0x30) * 100 + (bytes[6] - 0x030) * 10) + " cm";
data.RSS_SIMPLE_Threshold = ((bytes[7] - 0x30) * 1000 + (bytes[8] - 0x30) * 100) + " ml";
data.RSS_SIMPLE_Gain = ((bytes[9] - 0x30) * 10 + (bytes[10] - 0x30)) + " %";
break;
case 33:
// P 11
data.RSS_FULL_Start = ((bytes[3] - 0x30) * 100 + (bytes[4] - 0x30) * 10) + " cm";
data.RSS_FULL_Length = ((bytes[5] - 0x30) * 100 + (bytes[6] - 0x30) * 10) + " cm";
data.RSS_FULL_Threshold = ((bytes[7] - 0x30) * 1000 + (bytes[8] - 0x30) * 100) + " ml";
data.RSS_FULL_Gain = ((bytes[9] - 0x30) * 10 + (bytes[10] - 0x30)) + " %";
data.RSS_FULL_Profile = (bytes[11] - 0x30);
data.RSS_FULL_Rate_Tracking = ((bytes[12] - 0x30) * 10 + (bytes[13] - 0x30));
data.RSS_FULL_Rate_Presence = ((bytes[14] - 0x30) * 10 + (bytes[15] - 0x30));
data.RSS_FULL_HWAAS = ((bytes[16] - 0x30) * 10 + (bytes[17] - 0x30));
data.RSS_FULL_Num_Removed_PC = (bytes[18] - 0x30);
data.RSS_FULL_Inter_Deviation_Time_Const_in_Sec = ((bytes[19] - 0x30) + (bytes[20] - 0x30) * 0.1);
data.RSS_FULL_Inter_Fast_Cut_Off = ((bytes[21] - 0x30) * 10 + (bytes[22] - 0x30));
data.RSS_FULL_Inter_Slow_Cut_Off = ((bytes[23] - 0x30) * 0.1 + (bytes[24] - 0x30) * 0.001);
data.RSS_FULL_Inter_Time_Const_in_Sec = ((bytes[25] - 0x30) * 10 + (bytes[26] - 0x30));
data.RSS_FULL_Inter_Weight = ((bytes[27] - 0x30) + (bytes[28] - 0x30) * 0.1);
data.RSS_FULL_Output_Time_Const_in_Sec = ((bytes[29] - 0x30) + (bytes[30] - 0x30) * 0.1);
data.RSS_FULL_DownSampling_factor = (bytes[31] - 0x30);
data.RSS_FULL_Power_Saving_mode = (bytes[32] - 0x30);
break;
default:
break;
}
break;
// CONTROL COMMAND 'R'
case 0x52:
if (bytes[1] === 0x46) {
data.RFAC_Process_Request = "OK";
data.RFAC_Req = String.fromCharCode(bytes);
}
break;
// Self-Test function 'S'
case 0x53:
// SELF TEST FUNCTION
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.battery_level = bytes[5];
if ((bytes[6] === 0x04)) { // report sensor install height
data.sts_sensor_chip_model_type_ID = (bytes[7] << 8 | bytes[8]);
if ((bytes[7] === 0xF0) && (bytes[8] === 0x0C)) {
data.sts_sensor_chip_model_type = "VL53L8X";
}
else if ((bytes[7] === 0xEA) & (bytes[8] === 0xCC)) {
data.sts_sensor_chip_model_type = "VL53L1X";
}
else if ((bytes[7] === 0xEE) & (bytes[8] === 0xAA)) {
data.sts_sensor_chip_model_type = "VL53L0X";
}
data.sts_sensor_install_height = (bytes[9] << 8 | bytes[10]);
data.sts_sensor_install_height_unit = "mm";
}
else if ((bytes[6] === 0x58)) {
data.sts_Test_Result = "### Motion Sensor Not Detected ###";
} else if ((bytes[6] === 0x0E)) //result length, 10 rss bytes, 4 distance bytes
{
data.sts_Test_Result = "Motion Sensor Test Result:";
data.sts_test_result_length = bytes[6];
data.sts_rss_sub_code1 = bytes[7];
data.sts_rss_sub_code2 = bytes[8];
data.sts_rss_sub_code3 = bytes[9];
data.sts_rss_sub_code4 = bytes[10];
data.sts_rss_sub_code5 = bytes[11];
data.sts_rss_sub_code6 = bytes[12];
data.sts_rss_sub_code7 = bytes[13];
data.sts_rss_sub_code8 = bytes[14];
data.sts_rss_sub_code9 = bytes[15];
data.sts_rss_sub_code10 = bytes[16];
data.sts_sensor_install_height = String.fromCharCode(bytes[17]) + String.fromCharCode(bytes[18]) + String.fromCharCode(bytes[19]) + String.fromCharCode(bytes[20]) + " mm";
}
break;
case 0x54:
//T: date & time
data.L_year = (bytes[1] << 8 | bytes[2]);
data.L_mon = bytes[3];
data.L_day = bytes[4];
data.L_hour = bytes[5];
data.L_min = bytes[6];
data.L_sec = bytes[7];
data.LocalTime_UTC = "UTC: " + data.L_year + "/" + data.L_mon + "/" + data.L_day + " " + data.L_hour + ":" + data.L_min + ":" + data.L_sec;
break;
// Firmware version 'V'
case 0x56:
// FIRMWARE VERSION
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.sts_major = bytes[5];
data.sts_minor = bytes[6];
data.subminor = bytes[7];
if (data.length === 15) {
data.L_year = (bytes[8] << 8 | bytes[9]);
data.L_mon = bytes[10];
data.L_day = bytes[11];
data.L_hour = bytes[12];
data.L_min = bytes[13];
data.L_sec = bytes[14];
data.LocalTime_UTC = "UTC: " + data.L_year + "/" + data.L_mon + "/" + data.L_day + " " + data.L_hour + ":" + data.L_min + ":" + data.L_sec;
data.LocalTime_EST8 = "GMT+8: " + data.L_year + "/" + data.L_mon + "/" + data.L_day + " " + (data.L_hour + 8) + ":" + data.L_min + ":" + data.L_sec;
}
break;
// Respond 'Y'
case 0x59:
switch (bytes[1]) {
// Uplink Duration interval
case 0x44:
data.Uplink_interval = (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30);
data.Uplink_interval_unit = String.fromCharCode(bytes[4]);
break;
// Sampling interval or Heart-beat interval, 'YSaab', 'YLaab'
case 0x4C:
case 0x53:
data.Heart_Beat_interval = (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30);
data.Heart_Beat_interval_unit = String.fromCharCode(bytes[4]);
// if sts_mtm1 == O6/O7 ....TODO XXXX
// data.Wakeup_sampling_interval = (bytes[2]-0x30)*10 + (bytes[3]-0x30);
// data.Unit = String.fromCharCode(bytes[4]);
break;
}
if (bytes[9] == 0x38) {
data.Yunhorn_PRD = "True";
data.PRD_String = String.fromCharCode(bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], bytes[16]);
}
break;
default:
break;
}
switch (data.length) {
// RFAC process
case 4:
if ((bytes[0] == 0x52) && (bytes[1] == 0x46)) {
data.RFAC_Process_Request = "OK";
data.RFAC_Req = String.fromCharCode(bytes);
} else {
if ((bytes[0] === 0x50) && (bytes[1] === 0x31) && (bytes[2] === 0x31)) {
data.Work_Mode_Switch = "OK";
switch (bytes[3] - 0x30) {
case 0x0:
data.workmode = "Network_mode";
break;
case 0x01:
data.workmode = "Wired_Mode";
break;
case 0x02:
data.workmode = "Hall_element_mode";
break;
case 0x03:
data.workmode = "MotionDetect_mode";
break;
case 0x04:
data.workmode = "Dual_mode";
break;
case 0x05:
data.workmode = "Uni_Mode";
break;
default:
data.workmode = "Unknown Mode";
break;
}
} else if ((bytes[0] === 0x59) && (bytes[1] === 0x44)) //Duration interval
{
data.Uplink_interval = (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30);
data.Uplink_interval_unit = String.fromCharCode(bytes[4]);
//data.Heart_beat_Duration = (bytes[2]-0x30)*10 + (bytes[3]-0x30);
//data.Unit = String.fromCharCode(bytes[4]);
}
else if ((bytes[0] === 0x59) && (bytes[1] === 0x53)) //Sampling interval or Heart-beat interval
} else if ((bytes[0] === 0x59) && (bytes[1] === 0x53)) //Sampling interval or Heart-beat interval
{
data.Heart_Beat_interval = (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30);
data.Heart_Beat_interval_unit = String.fromCharCode(bytes[4]);
//data.Wakeup_sampling_interval = (bytes[2]-0x30)*10 + (bytes[3]-0x30);
//data.Unit = String.fromCharCode(bytes[4]);
}
}
break;
else if (bytes[0] === 0x43) { // report current nvm config
// YUNHORN PRD MARK
case 10:
if ((bytes[0] == 0x59) && (bytes[9] == 0x38))
data.Yunhorn_PRD = "True";
data.PRD_String = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6]);
break;
// YUNHORN NVM CONFIG LENGTH
case 44:
if (bytes[0] === 0x43) { // report current nvm config
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
@ -433,135 +1061,18 @@ function Decode(fPort, data, variables) {
data.fall_detection_depth_threshold = bytes[43];
data.fall_down_confirm_threshold = bytes[44];
}
else if (bytes[0] === 0x53) { // SELF TEST FUNCTION
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.battery_level = bytes[5];
if ((bytes[6] === 0x03)) { // report sensor install height
data.sts_sensor_install_height = (bytes[7] << 8 | bytes[8]);
data.sts_sensor_install_height_unit = "mm";
}
else if ((bytes[6] === 0x58)) {
data.sts_Test_Result = "### Motion Sensor Not Detected ###";
} else if ((bytes[6] === 0x0E)) //result length, 10 rss bytes, 4 distance bytes
{
data.sts_Test_Result = "Motion Sensor Test Result:";
data.sts_test_result_length = bytes[6];
data.sts_rss_sub_code1 = bytes[7];
data.sts_rss_sub_code2 = bytes[8];
data.sts_rss_sub_code3 = bytes[9];
data.sts_rss_sub_code4 = bytes[10];
data.sts_rss_sub_code5 = bytes[11];
data.sts_rss_sub_code6 = bytes[12];
data.sts_rss_sub_code7 = bytes[13];
data.sts_rss_sub_code8 = bytes[14];
data.sts_rss_sub_code9 = bytes[15];
data.sts_rss_sub_code10 = bytes[16];
data.sts_sensor_install_height = String.fromCharCode(bytes[17]) + String.fromCharCode(bytes[18]) + String.fromCharCode(bytes[19]) + String.fromCharCode(bytes[20]) + " mm";
}
}
else if (bytes[0] === 0x44) { // MEASURE INSTALLATION HEIGHT
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.battery_level = bytes[5];
data.payload_length = bytes[6];
data.Measure_Distance = String.fromCharCode(bytes[7]) + String.fromCharCode(bytes[8]) + String.fromCharCode(bytes[9]) + String.fromCharCode(bytes[10]);
data.Distance_unit = "mm";
}
else if (bytes[0] === 0x4c) { // LoRaWAN Class A/B/C
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.LoRaWAN_Class = String.fromCharCode(bytes[4]);
}
else if (bytes[0] === 0x56) { // FIRMWARE VERSION
data.mtm_code1 = bytes[1];
data.mtm_code2 = bytes[2];
data.sts_verion = bytes[3];
data.sts_hw_ver = bytes[4];
data.sts_major = bytes[5];
data.sts_minor = bytes[6];
data.subminor = bytes[7];
if (data.length === 15) {
data.L_year = (bytes[8] << 8 | bytes[9]);
data.L_mon = bytes[10];
data.L_day = bytes[11];
data.L_hour = bytes[12];
data.L_min = bytes[13];
data.L_sec = bytes[14];
data.LocalTime_UTC = "UTC: " + data.L_year + "/" + data.L_mon + "/" + data.L_day + " " + data.L_hour + ":" + data.L_min + ":" + data.L_sec;
data.LocalTime_EST8 = "GMT+8: " + data.L_year + "/" + data.L_mon + "/" + data.L_day + " " + (data.L_hour + 8) + ":" + data.L_min + ":" + data.L_sec;
}
}
else if (bytes[0] === 0x54) { //T: date & time
data.L_year = (bytes[1] << 8 | bytes[2]);
data.L_mon = bytes[3];
data.L_day = bytes[4];
data.L_hour = bytes[5];
data.L_min = bytes[6];
data.L_sec = bytes[7];
data.LocalTime_UTC = "UTC: " + data.L_year + "/" + data.L_mon + "/" + data.L_day + " " + data.L_hour + ":" + data.L_min + ":" + data.L_sec;
}
else if (bytes[0] === 0x50) { // P cmd report
if (data.length == 7) {
switch (bytes[3]) {
case 0x46: // F --- fall down & unconscious detection threshold
data.FALL_acceleration = (bytes[4] == 0x30 ? "Disabled" : ((bytes[4] - 0x30) * 10) + " mg/s2");
data.FALL_depth_measure = (bytes[5] == 0x30 ? "Disabled" : ((bytes[5] - 0x30) * 10) + " cm");
data.FALL_confirm_threshold = (bytes[6] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 10) + " seconds");
//data.FALL_reserved = (bytes[7]==0x0?"Disabled":((bytes[6]-0x30)*10)+" min");
break;
} //switch
}
else if (data.length == 8) {
switch (bytes[3]) {
case 0x4f: // O -- over stay, onconscious, long stay
data.OMU_Motionless_duration_in_min = (bytes[4] == 0x30 ? "Disabled" : ((bytes[4] - 0x30)) + " Min");
data.OMU_Long_Occupy_duration_in_Min = (bytes[5] == 0x30 ? "Disabled" : ((bytes[5] - 0x30) * 10) + " Min");
data.OMU_Unconcious_Threshold = (bytes[6] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 100) + "ml");
data.OMU_Alarm_Mute_Reset_Timer = (bytes[7] == 0x30 ? "Disabled" : ((bytes[7] - 0x30) * 10) + " Seconds");
default:
break;
case 0x46: // F --- fall down & unconscious detection threshold
data.FALL_acceleration = (bytes[4] == 0x30 ? "Disabled" : ((bytes[4] - 0x30) * 10) + " mg/s2");
data.FALL_depth_measure = (bytes[5] == 0x30 ? "Disabled" : ((bytes[5] - 0x30) * 10) + " cm");
data.FALL_confirm_threshold = (bytes[6] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 10) + " seconds");
data.FALL_reserved = (bytes[7] == 0x30 ? "Disabled" : ((bytes[6] - 0x30) * 10) + " min");
break;
} //switch
} else if (data.length == 11) { // P 1108201365
data.RSS_SIMPLE_Start = ((bytes[3] - 0x30) * 100 + (bytes[4] - 0x30) * 10) + " cm";
data.RSS_SIMPLE_Length = ((bytes[5] - 0x30) * 100 + (bytes[6] - 0x030) * 10) + " cm";
data.RSS_SIMPLE_Threshold = ((bytes[7] - 0x30) * 1000 + (bytes[8] - 0x30) * 100) + " ml";
data.RSS_SIMPLE_Gain = ((bytes[9] - 0x30) * 10 + (bytes[10] - 0x30)) + " %";
} else if (data.length == 33) { // P 11
data.RSS_FULL_Start = ((bytes[3] - 0x30) * 100 + (bytes[4] - 0x30) * 10) + " cm";
data.RSS_FULL_Length = ((bytes[5] - 0x30) * 100 + (bytes[6] - 0x30) * 10) + " cm";
data.RSS_FULL_Threshold = ((bytes[7] - 0x30) * 1000 + (bytes[8] - 0x30) * 100) + " ml";
data.RSS_FULL_Gain = ((bytes[9] - 0x30) * 10 + (bytes[10] - 0x30)) + " %";
data.RSS_FULL_Profile = (bytes[11] - 0x30);
data.RSS_FULL_Rate_Tracking = ((bytes[12] - 0x30) * 10 + (bytes[13] - 0x30));
data.RSS_FULL_Rate_Presence = ((bytes[14] - 0x30) * 10 + (bytes[15] - 0x30));
data.RSS_FULL_HWAAS = ((bytes[16] - 0x30) * 10 + (bytes[17] - 0x30));
data.RSS_FULL_Num_Removed_PC = (bytes[18] - 0x30);
data.RSS_FULL_Inter_Deviation_Time_Const_in_Sec = ((bytes[19] - 0x30) + (bytes[20] - 0x30) * 0.1);
data.RSS_FULL_Inter_Fast_Cut_Off = ((bytes[21] - 0x30) * 10 + (bytes[22] - 0x30));
data.RSS_FULL_Inter_Slow_Cut_Off = ((bytes[23] - 0x30) * 0.1 + (bytes[24] - 0x30) * 0.001);
data.RSS_FULL_Inter_Time_Const_in_Sec = ((bytes[25] - 0x30) * 10 + (bytes[26] - 0x30));
data.RSS_FULL_Inter_Weight = ((bytes[27] - 0x30) + (bytes[28] - 0x30) * 0.1);
data.RSS_FULL_Output_Time_Const_in_Sec = ((bytes[29] - 0x30) + (bytes[30] - 0x30) * 0.1);
data.RSS_FULL_DownSampling_factor = (bytes[31] - 0x30);
data.RSS_FULL_Power_Saving_mode = (bytes[32] - 0x30);
}
}
return { "Yunhorn_SmarToilets_data": data };
}
}
//
// Yunhorn SmarToilets Sensor Decoder
//