diff --git a/STM32CubeIDE/Release/WLE5CC_NODE_STS.elf b/STM32CubeIDE/Release/WLE5CC_NODE_STS.elf index 1c13d32..cfbb94a 100644 Binary files a/STM32CubeIDE/Release/WLE5CC_NODE_STS.elf and b/STM32CubeIDE/Release/WLE5CC_NODE_STS.elf differ diff --git a/STS/Core/Inc/yunhorn_sts_sensors.h b/STS/Core/Inc/yunhorn_sts_sensors.h index 37818a9..11605e3 100644 --- a/STS/Core/Inc/yunhorn_sts_sensors.h +++ b/STS/Core/Inc/yunhorn_sts_sensors.h @@ -164,7 +164,7 @@ typedef struct sts_cfg_nvm { uint8_t p[STS_CFG_PCFG_SIZE]; uint8_t color_occupy_vacant; // occupy color and vacant color define, C_OCCUPY<<4|C_VACANT - uint8_t reserve03; + uint8_t sts_door_jam_profile; uint8_t sensor_install_height_in_10cm; uint8_t alarm_parameter05; uint8_t alarm_mute_reset_timer_in_10sec; //60(0x3C) sec alarm_mute_or_reset_expire_timer_in_sec diff --git a/STS/Core/Src/yunhorn_sts_process.c b/STS/Core/Src/yunhorn_sts_process.c index fb3ec65..35f4738 100644 --- a/STS/Core/Src/yunhorn_sts_process.c +++ b/STS/Core/Src/yunhorn_sts_process.c @@ -109,8 +109,8 @@ volatile sts_cfg_nvm_t sts_cfg_nvm = { #endif }, // above 20 bytes 0x20, // color occupy (red:2) | color vacant (green:1) or other 0x20 occupy(red:2) | color vacant (dark:0) for ATAL-HK 20241230 - 0x00, //reserve3 - 0x20, //sensor install height in dm =10 cm, default 32*10=320cm, 3.2meter + 0x06, // sts_door_jam_profile for O6T + 0x20, // sensor install height in dm =10 cm, default 32*10=320cm, 3.2meter 0x00, //reserve5 alarm_parameter05 0x06, //reserve6 alarm_mute_or_reset_expire_timer_in_10sec, 60 seconds @@ -1099,6 +1099,11 @@ void USER_APP_AUTO_RESPONDER_Parse(uint8_t *parse_buffer, uint8_t parse_buffer_s STS_SENSOR_Function_Test_Process(); #if defined(STS_T6) ppc_cfg_parameter_update(); + sts_cfg_nvm.sensor_install_height_in_10cm = sts_sensor_install_height/100; //in 10 cm, say 4500mm=450cm=45 dm + sts_cfg_nvm.sts_door_jam_profile = sts_door_jam_profile; + APP_LOG(TS_OFF, VLEVEL_M, "\n STS CFG NVM -> SENSOR INSTALL HEIGHT STORED = %d dm(10cm)\n", sts_cfg_nvm.sensor_install_height_in_10cm); + OnStoreSTSCFGContextRequest(); + #endif break; @@ -1126,6 +1131,7 @@ void USER_APP_AUTO_RESPONDER_Parse(uint8_t *parse_buffer, uint8_t parse_buffer_s if (range_distance == 0 ) { sts_cfg_nvm.sensor_install_height_in_10cm = sts_sensor_install_height/100; //in 10 cm, say 4500mm=450cm=45 dm + APP_LOG(TS_OFF, VLEVEL_M, "\n STS CFG NVM -> SENSOR INSTALL HEIGHT STORED = %d dm(10cm)\n", sts_cfg_nvm.sensor_install_height_in_10cm); OnStoreSTSCFGContextRequest(); outbuf[i++] = (uint8_t)(2); //two bytes for distance @@ -1607,7 +1613,7 @@ void OnStoreSTSCFGContextRequest(void) } to_store__value[i++] = sts_cfg_nvm.color_occupy_vacant; - to_store__value[i++] = sts_cfg_nvm.reserve03; + to_store__value[i++] = sts_cfg_nvm.sts_door_jam_profile; to_store__value[i++] = sts_cfg_nvm.sensor_install_height_in_10cm; to_store__value[i++] = sts_cfg_nvm.alarm_parameter05; to_store__value[i++] = sts_cfg_nvm.alarm_mute_reset_timer_in_10sec; @@ -1704,7 +1710,7 @@ void STS_REBOOT_CONFIG_Init(void) } sts_cfg_nvm.color_occupy_vacant =(uint8_t)nvm_store_value[NVM_RESERVE02]; - sts_cfg_nvm.reserve03 =(uint8_t)nvm_store_value[NVM_RESERVE03]; + sts_cfg_nvm.sts_door_jam_profile =(uint8_t)nvm_store_value[NVM_RESERVE03]; sts_cfg_nvm.sensor_install_height_in_10cm =(uint8_t)nvm_store_value[NVM_SENSOR_INSTALL_HEIGHT]; sts_cfg_nvm.alarm_parameter05 =(uint8_t)nvm_store_value[NVM_ALARM_PARAMETER05]; sts_cfg_nvm.alarm_mute_reset_timer_in_10sec = (uint8_t)nvm_store_value[NVM_ALARM_MUTE_RESET_TIMER]; @@ -1788,6 +1794,7 @@ void OnRestoreSTSCFGContextProcess(void) sts_work_mode = sts_cfg_nvm.work_mode; sts_service_mask = sts_cfg_nvm.sts_service_mask; + sts_door_jam_profile = sts_cfg_nvm.sts_door_jam_profile; sts_color_occupy_vacant = sts_cfg_nvm.color_occupy_vacant; APP_LOG(TS_OFF, VLEVEL_M, "\r\n Color Occupy =%02x, VACANT =%02x \r\n",((sts_color_occupy_vacant>>4)&0x0f), sts_color_occupy_vacant&0x0f ); @@ -1868,8 +1875,8 @@ void ppc_cfg_parameter_update(void) ppc_cfg[DOOR_JAM_NOW].profile_name = DOOR_JAM_NOW; ppc_cfg[DOOR_JAM_NOW].distance_array_size = DISTANCES_ARRAY_SIZE; ppc_cfg[DOOR_JAM_NOW].max_distance = sts_sensor_install_height; - ppc_cfg[DOOR_JAM_NOW].min_distance = MAX(0,(sts_sensor_install_height-1800)); - ppc_cfg[DOOR_JAM_NOW].dist_threshold = MAX(500,sts_sensor_install_height - 500); + ppc_cfg[DOOR_JAM_NOW].min_distance = MAX((sts_sensor_install_height*0.2), 200); // 500 mm for toilet seat height + ppc_cfg[DOOR_JAM_NOW].dist_threshold = MAX((sts_sensor_install_height - 500),sts_sensor_install_height*0.8); ppc_cfg[DOOR_JAM_NOW].rows_of_SPADS = ROWS_OF_SPADS; ppc_cfg[DOOR_JAM_NOW].timing_budget = 100; // TIMING_BUDGET, in ms possible values [15, 20, 33, 50, 100, 200, 500] ppc_cfg[DOOR_JAM_NOW].distance_mode = 2; /* 1=short, 2=long, DISTANCE_MODE */ diff --git a/STS/TOF/App/app_tof_peoplecount.c b/STS/TOF/App/app_tof_peoplecount.c index d73847e..2b51115 100644 --- a/STS/TOF/App/app_tof_peoplecount.c +++ b/STS/TOF/App/app_tof_peoplecount.c @@ -794,7 +794,7 @@ int sts_tof_vl53lx_presence_detection_start(void) status = VL53L1X_CheckForDataReady(dev, &dataReady); HAL_Delay(1); wordData++; - if (wordData > 30) return -1; // 50 ms timer, so make this 60% to fail back + if (wordData > 500) return -1; // 50 ms timer, so make this 60% to fail back } status = 0; diff --git a/hk_as923_decoder.js b/hk_as923_decoder.js index 3467a07..c997766 100644 --- a/hk_as923_decoder.js +++ b/hk_as923_decoder.js @@ -4,12 +4,15 @@ // - 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} // -// Yunhorn SmarToilets Sensor R20241104A01 +// Yunhorn SmarToilets Sensor R20241230A01 // function Decode(fPort, data, variables) { var data = {}; data.length = bytes.length; + var code2color = { "0": "Dark", "1": "Green", "2": "Red", "3": "Blue", "4": "Yellow", "5": "Pink", "6": "Cyan", "7": "White" }; + var code2workmode = { "0": "Network_mode", "1": "Wired_mode", "2": "Hall_element_mode", "3": "Motion_detect_mode", "4": "Dual_mode" }; + switch (fPort) { // RESPOND PORT --- bottom of swith fport // case 1: @@ -238,6 +241,9 @@ function Decode(fPort, data, variables) { data.Battery_Level = bytes[4] + " %"; data.Payload_Size = bytes[5]; data.Presence_State = (bytes[6] == 1) ? "Occupied" : "Vacant"; + data.Motion_state_PIR = (bytes[7] == 1) ? "Motion" : "Motionless"; v + data.Lamp_bar_color_code = bytes[8]; + data.Presence_Distance_cm = bytes[9] * 10 + " cm"; return { "Yunhorn_SmarToilets_data": data }; break; @@ -249,8 +255,21 @@ function Decode(fPort, data, variables) { 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: @@ -262,10 +281,64 @@ function Decode(fPort, data, variables) { break; + case 19: + data.header_board_led = bytes[0] & 0x7f; + data.header_mtm1 = bytes[1]; + data.header_mtm2 = bytes[2]; + data.header_fw = bytes[3]; + data.header_battery_level = bytes[4] + " %"; + data.payload_size = bytes[5]; + data.payload_type = bytes[6]; + switch (bytes[6]) // fall/movement/occupancy/sos status + { + case 0x01: + data.fhmos_state_fall = bytes[7]; + data.fhmos_state_human_movement = bytes[8]; + data.fhmos_state_occupancy = bytes[9]; + data.fhmos_state_sosbutton = bytes[10]; + data.lamp_bar_color = bytes[11]; + data.sensor1_state = bytes[12]; + data.sensor2_state = bytes[13]; + data.sensor3_PIR_state = bytes[14]; + break; + case 0x02: // fall gesture map + data.fhmos_gesture_head_height_cm = bytes[7]; + data.fhmos_gesture_head_x_y = bytes[8]; + data.fhmos_gesture_map1 = String.fromCharCode(bytes[9]); + data.fhmos_gesture_map2 = String.fromCharCode(bytes[10]); + data.fhmos_gesture_map3 = String.fromCharCode(bytes[11]); + data.fhmos_gesture_map4 = String.fromCharCode(bytes[12]); + data.fhmos_gesture_map5 = String.fromCharCode(bytes[13]); + data.fhmos_gesture_map6 = String.fromCharCode(bytes[14]); + data.fhmos_gesture_map7 = String.fromCharCode(bytes[15]); + data.fhmos_gesture_map8 = String.fromCharCode(bytes[16]); + var my_time_zone = 8 * 60 * 60; // (8*60*60) + data.fhmos_fall_event_utc_time = bytes[17] << 24 | bytes[18] << 16 | bytes[19] << 8 | bytes[20]; + data.fhmos_fall_event_time = data.fhmos_fall_event_utc_time + my_time_zone; + var dev_date = new Date(data.fhmos_fall_event_time * 1000); + data.fhmos_fall_event_time_stamp = dev_date.getHours() + ":" + dev_date.getMinutes(); + data.fhmos_fall_event_date_stamp = dev_date.getDate() + "." + (dev_date.getMonth() + 1) + "." + dev_date.getFullYear(); + + break; + case 0x03: // Background mask off map + data.fhmos_gesture_map1 = String.fromCharCode(bytes[7]); + data.fhmos_gesture_map2 = String.fromCharCode(bytes[8]); + data.fhmos_gesture_map3 = String.fromCharCode(bytes[9]); + data.fhmos_gesture_map4 = String.fromCharCode(bytes[10]); + data.fhmos_gesture_map5 = String.fromCharCode(bytes[11]); + data.fhmos_gesture_map6 = String.fromCharCode(bytes[12]); + data.fhmos_gesture_map7 = String.fromCharCode(bytes[13]); + data.fhmos_gesture_map8 = String.fromCharCode(bytes[14]); + break; + } + 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"; @@ -338,6 +411,16 @@ function Decode(fPort, data, variables) { case 0x05: data.workmode = "Uni_Mode"; break; + case 0x06: + data.workmode = "STS_REMOTE_REED_RSS_MODE"; + break; + case 0x07: + data.workmode = "STS_DUAL_RSS_MODE"; + break; + + case 0x08: + data.workmode = "STS_TOF_LMZ_RSS_MODE" + break; default: data.workmode = "Unknown Mode"; break; @@ -445,6 +528,18 @@ function Decode(fPort, data, variables) { 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] << 24 | bytes[7]) << 16 | bytes[8] << 8 + bytes[9] + bytes[10]; + data.Weight_g = (bytes[6] << 24 | bytes[7]) << bytes[8] + bytes[9]; + return { "Yunhorn_SmarToilets_data": data }; + break; @@ -609,6 +704,12 @@ function Decode(fPort, data, variables) { // respond port case 1: switch (bytes[0]) { + //AC CODE RESPONSE + case 0x41: + if ((bytes[1] == 0x43) && (data.length == 22)) + data.RFAC_RESULT = "SUCCESS"; + break; + // NVM config 'C' case 0x43: // report current nvm config @@ -677,7 +778,90 @@ function Decode(fPort, data, variables) { data.Distance_unit = "mm"; break; + // G Fall down Gesture bitmap REPORT + case 0x47: + data.head_level_cm = bytes[7]; + data.head_coordination = "X: " + bytes[8] / 8 + " Y:" + bytes[8] % 8; + var mmm = bytes[11]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix01 = matrix0; + mmm = bytes[12]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix02 = matrix0; + mmm = bytes[13]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix03 = matrix0; + mmm = bytes[14]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix04 = matrix0; + + mmm = bytes[15]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix05 = matrix0; + + mmm = bytes[16]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix06 = matrix0; + + mmm = bytes[17]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix07 = matrix0; + + mmm = bytes[18]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix08 = matrix0; + + return + break; // LoRa Class 'L' case 0x4c: // LoRaWAN Class A/B/C @@ -742,6 +926,12 @@ function Decode(fPort, data, variables) { } } + break; + case 6: + data.P_cmd = "Change Lamp Bar color config"; + data.workmode = code2workmode[bytes[3] - 0x30]; + data.color_occupy = code2color[bytes[4] - 0x30]; + data.color_vacant = code2color[bytes[5] - 0x30]; break; case 7: if (bytes[3] === 0x46) { @@ -823,12 +1013,107 @@ function Decode(fPort, data, variables) { 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]); + if ((bytes[6] === 0x0C) || (bytes[6] === 0x04)) { // report sensor install height and bitmap + 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"; + //data.maskoff_bitmap= String.fromCharCode(bytes[11])+String.fromCharCode(bytes[12])+String.fromCharCode(bytes[13])+String.fromCharCode(bytes[14])+String.fromCharCode(bytes[15])+String.fromCharCode(bytes[16])+String.fromCharCode(bytes[17])+String.fromCharCode(bytes[18]); + if (bytes[6] === 0x0c) { + var mmm = bytes[11]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix01 = matrix0; + mmm = bytes[12]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix02 = matrix0; + + mmm = bytes[13]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix03 = matrix0; + mmm = bytes[14]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix04 = matrix0; + + mmm = bytes[15]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix05 = matrix0; + + mmm = bytes[16]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix06 = matrix0; + + mmm = bytes[17]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix07 = matrix0; + + mmm = bytes[18]; + var con = 0x30; + var matrix0 = " [ "; + for (i = 0; i < 8; i++) { + con += ((mmm >> i) & 0x01); + matrix0 += (String.fromCharCode(con) + "__"); + con = 0x30; + } + data.matrix08 = matrix0; + } + } + else if ((bytes[6] === 0x58)) { data.sts_Test_Result = "### Motion Sensor Not Detected ###"; + } else if ((bytes[6] === 0x78)) { + data.sts_Test_Result = "### Motion Sensor Detected, Yet Not Stable ###"; } else if ((bytes[6] === 0x0E)) //result length, 10 rss bytes, 4 distance bytes { data.sts_Test_Result = "Motion Sensor Test Result:";