diff --git a/LoRaWAN/App/lora_app.c b/LoRaWAN/App/lora_app.c index ee0c256..10f4c98 100644 --- a/LoRaWAN/App/lora_app.c +++ b/LoRaWAN/App/lora_app.c @@ -418,7 +418,9 @@ void LoRaWAN_Init(void) /* USER CODE BEGIN LoRaWAN_Init_LV */ uint32_t feature_version = 0UL; /* USER CODE END LoRaWAN_Init_LV */ - + APP_LOG(TS_OFF, VLEVEL_M, "\n\n# YUNHORN SMARTOILETS: MTM:%d.%d HWFW:%d.%d V:%d.%d.%d #\n\n", + (uint8_t)sts_mtmcode1, (uint8_t)sts_mtmcode2,(uint8_t)sts_hardware_ver,(uint8_t)FirmwareVersion, + (uint8_t)MajorVer,(uint8_t)MinorVer,(uint8_t)SubMinorVer); /* USER CODE BEGIN LoRaWAN_Init_1 */ /* Get LoRaWAN APP version*/ @@ -789,7 +791,7 @@ static void SendTxData(void) #endif #ifdef STS_P2 - AppData.Port = 106; /* STS-P2 Data Port */ + AppData.Port = YUNHORN_STS_P2_LORA_APP_DATA_PORT; /* STS-P2 Data Port */ #endif #ifdef CAYENNE_LPP @@ -867,8 +869,10 @@ static void SendTxData(void) #endif #endif //VL53L0 +#ifdef STS_P2 #ifdef VL53LX // VL53L1X + AppData.Buffer[i++] = (uint8_t) 15; //sum of below AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Walk_In_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Walk_In_People_Count & 0xFF); @@ -894,6 +898,7 @@ static void SendTxData(void) AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Count_Valid & 0xFF); #endif // VL53L1X +#endif //STS_P2 AppData.BufferSize = i; @@ -1313,8 +1318,25 @@ static void OnYunhornSTSHeartBeatTimerEvent(void *context) { // UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventRFAC), CFG_SEQ_Prio_0); UTIL_TIMER_Stop(&YunhornSTSHeartBeatTimer); -#if 1 + uint8_t appHeartBeatDataPort, appHeartBeatBufferSize, appHeartBeatDataBuffer[32]; + + if ((rfac_timer <(STS_BURN_IN_RFAC+3))&&(sts_cfg_nvm.ac[0]==0x0)&&(sts_cfg_nvm.ac[19]==0x0)) + { + //APP_LOG(TS_OFF, VLEVEL_M, "\n\n RFAC_TIMER = %d\n\n", rfac_timer); + + //STS_YunhornSTSEventRFAC_Process(); + // the following doesn't executed +#if 1 + //APP_LOG(TS_OFF, VLEVEL_M, "\n Start send RFAC request \n"); + appHeartBeatBufferSize = 4; + UTIL_MEM_cpy_8((uint8_t*)appHeartBeatDataBuffer,"RFAC",4); + STS_SENSOR_Upload_Message(YUNHORN_STS_USER_APP_CTRL_REPLY_PORT, appHeartBeatBufferSize, (uint8_t*)appHeartBeatDataBuffer); +#endif + rfac_timer ++; + } else { // normal heart-beat process + +#if 1 #ifdef STS_P2 appHeartBeatDataPort = YUNHORN_STS_P2_LORA_APP_HTBT_PORT; #elif defined(STS_R1) @@ -1330,23 +1352,11 @@ static void OnYunhornSTSHeartBeatTimerEvent(void *context) appHeartBeatDataBuffer[1]=(uint8_t)(SYS_GetBatteryLevel()/100); //TODO XXX change to battery level in mV STS_SENSOR_Upload_Message(appHeartBeatDataPort, appHeartBeatBufferSize, (uint8_t*)appHeartBeatDataBuffer); + #endif - if (rfac_timer <20) - { - STS_YunhornSTSEventRFAC_Process(); - rfac_timer ++; + } -#if 0 - if ((sts_cfg_nvm.ac[0]==0x0) && (sts_cfg_nvm.ac[19]==0x0)) /* simple validation of non-empty ac code */ - { - /* RFAC Challenge */ - if (rfac_timer < (STS_BURN_IN_RFAC+3)) { - rfac_timer ++; - } - APP_LOG(TS_OFF, VLEVEL_M, "\n Start send RFAC request \n"); - STS_SENSOR_Upload_Message(YUNHORN_STS_USER_APP_CTRL_REPLY_PORT, 4, (uint8_t*)"RFAC"); - } -#endif + UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); } diff --git a/STM32CubeIDE/.project b/STM32CubeIDE/.project index 1ea12e6..36390bc 100644 --- a/STM32CubeIDE/.project +++ b/STM32CubeIDE/.project @@ -37,6 +37,11 @@ 1 copy_PARENT/README.md + + Doc/hk_as923_decoder.js + 1 + copy_PARENT/hk_as923_decoder.js + Utilities/stm32_adv_trace.c 1 @@ -567,11 +572,6 @@ 1 copy_PARENT/STS/Core/Src/yunhorn_sts_process.c - - Application/User/STS/TOF/App/X-WL55_WLE5_53L0X.c - 1 - copy_PARENT/STS/TOF/App/X-WL55_WLE5_53L0X.c - Application/User/STS/TOF/App/app_tof.c 1 diff --git a/STS/Core/Inc/sts_cmox_hmac_sha.h b/STS/Core/Inc/sts_cmox_hmac_sha.h index 2ff2aae..a8a475b 100644 --- a/STS/Core/Inc/sts_cmox_hmac_sha.h +++ b/STS/Core/Inc/sts_cmox_hmac_sha.h @@ -31,7 +31,7 @@ typedef struct { uint8_t ac_pass; } hmac_result_t; -void STS_HMAC_TESTING(void); + uint32_t sts_hmac_sha1(const uint8_t *Key, int key_length, const uint8_t *Message, int message_length, hmac_result_t *hmac_result); uint32_t sts_hmac_verify(void); diff --git a/STS/Core/Src/sts_cmox_hmac_sha.c b/STS/Core/Src/sts_cmox_hmac_sha.c index be5bcce..20eb025 100644 --- a/STS/Core/Src/sts_cmox_hmac_sha.c +++ b/STS/Core/Src/sts_cmox_hmac_sha.c @@ -43,12 +43,12 @@ uint32_t sts_hmac_verify(void) ret = sts_hmac_sha1((const uint8_t *) mKey, sizeof(mKey), (const uint8_t*)(uid+4), 4, &hmac_result); ret = memcmp(hmac_result.hmac_tag, (void *)sts_ac_code, sizeof(sts_ac_code)); - APP_LOG(TS_OFF, VLEVEL_M, "\n STS_AC_CODE \n"); + //APP_LOG(TS_OFF, VLEVEL_M, "\n STS_AC_CODE \n"); - for (uint8_t k=0; k (STS_BURN_IN_RFAC + 3))) { APP_LOG(TS_OFF, VLEVEL_M, "\r\n -Verify RFAC Success or Not\r\n"); @@ -1227,7 +1225,7 @@ void USER_APP_AUTO_RESPONDER_Parse(uint8_t *parse_buffer, uint8_t parse_buffer_s STS_YunhornAuthenticationCode_Process(); - if ((hmac_result.ac_pass == 1U)) + if ((hmac_result.ac_pass == 1U)) // good ac code { //UTIL_MEM_cpy_8(sts_cfg_nvm.ac, sts_ac_code,YUNHORN_STS_AC_CODE_SIZE); @@ -1244,7 +1242,8 @@ void USER_APP_AUTO_RESPONDER_Parse(uint8_t *parse_buffer, uint8_t parse_buffer_s } else { sts_service_mask = STS_SERVICE_MASK_L2; - + sts_ac_code[0] =0x0; + sts_ac_code[19] =0x0; } i=0; @@ -1466,7 +1465,7 @@ void STS_REBOOT_CONFIG_Init(void) } } - STS_Show_STS_CFG_NVM((uint8_t*)nvm_store_value); + //STS_Show_STS_CFG_NVM((uint8_t*)nvm_store_value); OnRestoreSTSCFGContextProcess(); /* USER CODE END OnRestoreContextRequest_Last */ diff --git a/STS/TOF/App/app_tof_peoplecount.c b/STS/TOF/App/app_tof_peoplecount.c index 618c10f..08b1f59 100644 --- a/STS/TOF/App/app_tof_peoplecount.c +++ b/STS/TOF/App/app_tof_peoplecount.c @@ -355,7 +355,7 @@ void STS_people_count_sensor_Read(sts_people_count_sensor_data_t *sts_p2_sensor_ void STS_TOF_VL53LX_PeopleCounting_Process_Init(void) { - APP_LOG(TS_OFF, VLEVEL_M,"############### TOF VL53LX_ PEOPLE COUNTING PROCESS INITIALIZATION\r\n"); + APP_LOG(TS_OFF, VLEVEL_L,"\n\n# YUNHORN STS-P2 PEOPLE COUNTING PROCESS #\r\n"); sts_tof_vl53lx_peoplecount_init(); } @@ -389,9 +389,9 @@ int sts_tof_vl53lx_peoplecount_init(void) /* Initialize all configured peripherals */ - APP_LOG(TS_OFF, VLEVEL_L,"XNUCLEO53L1A1_Init Start .......... \r\n"); + //APP_LOG(TS_OFF, VLEVEL_H,"XNUCLEO53L1A1_Init Start .......... \r\n"); status = XNUCLEO53L1A1_Init(); - APP_LOG(TS_OFF, VLEVEL_L,"XNUCLEO53L1A1_Init Status : %X\n", status); + //APP_LOG(TS_OFF, VLEVEL_H,"XNUCLEO53L1A1_Init Status : %X\n", status); status = XNUCLEO53L1A1_ResetId(XNUCLEO53L1A1_DEV_CENTER, 0); // Reset ToF sensor @@ -401,11 +401,11 @@ int sts_tof_vl53lx_peoplecount_init(void) // Those basic I2C read functions can be used to check your own I2C functions */ status = VL53L1_RdByte(dev, 0x010F, &byteData); - APP_LOG(TS_OFF, VLEVEL_L,"VL53L1X Model_ID: %X\n", byteData); + //APP_LOG(TS_OFF, VLEVEL_H,"VL53L1X Model_ID: %X\n", byteData); status = VL53L1_RdByte(dev, 0x0110, &byteData); - APP_LOG(TS_OFF, VLEVEL_L,"VL53L1X Module_Type: %X\n", byteData); + //APP_LOG(TS_OFF, VLEVEL_H,"VL53L1X Module_Type: %X\n", byteData); status = VL53L1_RdWord(dev, 0x010F, &wordData); - APP_LOG(TS_OFF, VLEVEL_L,"VL53L1X: %X\n", wordData); + //APP_LOG(TS_OFF, VLEVEL_H,"VL53L1X: %X\n", wordData); sensor_id = wordData; wordData = 0; while (sensorState == 0) { @@ -413,11 +413,11 @@ int sts_tof_vl53lx_peoplecount_init(void) HAL_Delay(2); wordData ++; if (wordData > 8000) { - APP_LOG(TS_OFF, VLEVEL_L,"\n\n ***Failed to boot Chip***\n\n\n"); + APP_LOG(TS_OFF, VLEVEL_H,"\n\n ***Failed to boot Chip***\n\n\n"); return status; } } - APP_LOG(TS_OFF, VLEVEL_L,"\nChip booted\n\n"); + //APP_LOG(TS_OFF, VLEVEL_H,"\nChip booted\n\n"); /* Initialize and configure the device according to people counting need */ status = VL53L1X_SensorInit(dev); @@ -428,14 +428,14 @@ int sts_tof_vl53lx_peoplecount_init(void) center[0]=ppc_cfg[sts_distance_mode].front_zone_center; center[1]=ppc_cfg[sts_distance_mode].back_zone_center; if (status != 0) { - APP_LOG(TS_OFF, VLEVEL_L,"Initialization or configuration of the device\n"); + APP_LOG(TS_OFF, VLEVEL_H,"Initialization or configuration of the device\n"); return (-1); } - APP_LOG(TS_OFF, VLEVEL_L,"\n\nStart counting people with profile : %s...\n\n", PROFILE_STRING); + //APP_LOG(TS_OFF, VLEVEL_H,"\n\nStart counting people with profile : %s...\n\n", PROFILE_STRING); status = VL53L1X_StartRanging(dev); /* This function has to be called to enable the ranging */ if (status != 0) { - APP_LOG(TS_OFF, VLEVEL_L,"Error in start ranging\n"); + APP_LOG(TS_OFF, VLEVEL_H,"Error in start ranging\n"); return (-1); } return 0; diff --git a/STS/TOF/vl53l1x_uld/X-NUCLEO-53L1A1.c b/STS/TOF/vl53l1x_uld/X-NUCLEO-53L1A1.c index 769aed0..eaa0778 100644 --- a/STS/TOF/vl53l1x_uld/X-NUCLEO-53L1A1.c +++ b/STS/TOF/vl53l1x_uld/X-NUCLEO-53L1A1.c @@ -310,63 +310,6 @@ done: return status; } -#if 0 -void VL53L1A1_EXTI_IOConfigure(int DevNo, int IntPriority, int SubPriority){ - GPIO_InitTypeDef GPIO_InitStruct; - - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; - GPIO_InitStruct.Pull = VL53L1A1_INTR_PIN_PUPD; - - switch (DevNo ) { - case XNUCLEO53L1A1_DEV_CENTER: - case 'c': - VL53L1A1_GPIO1_C_CLK_ENABLE(); - /*Configure GPIO pin : PA4 */ - GPIO_InitStruct.Pin = VL53L1A1_GPIO1_C_GPIO_PIN; - - XNUCLEO53L1A1_SetIntrStateId(1,XNUCLEO53L1A1_DEV_CENTER); - HAL_GPIO_Init(VL53L1A1_GPIO1_C_GPIO_PORT, &GPIO_InitStruct); - HAL_NVIC_SetPriority((IRQn_Type)VL53L1A1_GPIO1_C_GPIO_PIN, IntPriority, SubPriority); - break; - -#if VL53L1A1_GPIO1_SHARED == 0 - case XNUCLEO53L1A1_DEV_LEFT: - case 'l': - break; - - case XNUCLEO53L1A1_DEV_RIGHT: - break; -#endif - } -} - -void VL53L1A1_EXTI_IOUnconfigure(int DevNo){ - switch (DevNo ) { - case XNUCLEO53L1A1_DEV_CENTER: - case 'c': - //XNUCLEO53L1A1_SetIntrStateId(0,XNUCLEO53L1A1_DEV_TOP); - HAL_GPIO_DeInit(VL53L1A1_GPIO1_C_GPIO_PORT, VL53L1A1_GPIO1_C_GPIO_PIN); - __HAL_GPIO_EXTI_CLEAR_IT(VL53L1A1_GPIO1_C_GPIO_PIN); - break; - -#if VL53L1A1_GPIO1_SHARED == 0 - case XNUCLEO53L1A1_DEV_LEFT: - case 'l': - // XNUCLEO53L1A1_SetIntrStateId(0,XNUCLEO53L1A1_DEV_LEFT); - HAL_GPIO_DeInit(VL53L1A1_GPIO1_L_GPIO_PORT, VL53L1A1_GPIO1_L_GPIO_PIN); - __HAL_GPIO_EXTI_CLEAR_IT(VL53L1A1_GPIO1_L_GPIO_PIN); - break; - - case XNUCLEO53L1A1_DEV_RIGHT: - case 'r': - HAL_GPIO_DeInit(VL53L1A1_GPIO1_R_GPIO_PORT, VL53L1A1_GPIO1_R_GPIO_PIN); - __HAL_GPIO_EXTI_CLEAR_IT(VL53L1A1_GPIO1_R_GPIO_PIN); - //XNUCLEO53L1A1_SetIntrStateId(0,XNUCLEO53L1A1_DEV_RIGHT); - break; -#endif - } -} -#endif /** * Set all i2c expended gpio in one go * @return i/o operation status @@ -426,183 +369,6 @@ static int _ExpanderWR(int I2cExpAddr, int index, uint8_t *data, int n_data) { return status; } -#if 0 -/** - * @defgroup XNUCLEO53L1A1_7Segment 7 segment display - * - * macro use for human readable segment building - * @code - * --s0-- - * s s - * 5 1 - * --s6-- - * s s - * 4 2 - * --s3-- . s7 (dp) - * @endcode - * - * @{ - */ -/** decimal point bit mapping* */ -#define DP (1<<7) - -//VL6180 shield -//#define S0 (1<<0) -//#define S1 (1<<1) -//#define S2 (1<<2) -//#define S3 (1<<3) -//#define S4 (1<<4) -//#define S5 (1<<5) -//#define S6 (1<<6) - -/** sgement s0 bit mapping*/ -#define S0 (1<<3) -/** sgement s1 bit mapping*/ -#define S1 (1<<5) -/** sgement s2 bit mapping*/ -#define S2 (1<<6) -/** sgement s3 bit mapping*/ -#define S3 (1<<4) -/** sgement s4 bit mapping*/ -#define S4 (1<<0) -/** sgement s5 bit mapping*/ -#define S5 (1<<1) -/** sgement s6 bit mapping*/ -#define S6 (1<<2) - -/** - * build a character by defining the non lighted segment (not one and no DP) - * - * @param ... literal sum and or combine of any macro to define any segment #S0 .. #S6 - * - * example '9' is all segment on but S4 - * @code - * ['9']= NOT_7_NO_DP(S4), - * @endcode - */ -#define NOT_7_NO_DP( ... ) (uint8_t) ~( __VA_ARGS__ + DP ) - -/** - * Ascii to 7 segment lookup table - * - * Most common character are supported and follow http://www.twyman.org.uk/Fonts/ - * few extra special \@ ^~ ... etc are present for specific demo purpose - */ -static const uint8_t ascii_to_display_lut[256]={ - [' ']= 0, - ['-']= S6, - ['_']= S3, - ['=']= S3+S6, - ['~']= S0+S3+S6, /* 3 h bar */ - ['^']= S0, /* use as top bar */ - - ['?']= NOT_7_NO_DP(S5+S3+S2), - ['*']= NOT_7_NO_DP(), - ['[']= S0+S3+S4+S5, - [']']= S0+S3+S2+S1, - ['@']= S0+S3, - - ['0']= NOT_7_NO_DP(S6), - ['1']= S1+S2, - ['2']= S0+S1+S6+S4+S3, - ['3']= NOT_7_NO_DP(S4+S5), - ['4']= S5+S1+S6+S2, - ['5']= NOT_7_NO_DP(S1+S4), - ['6']= NOT_7_NO_DP(S1), - ['7']= S0+S1+S2, - ['8']= NOT_7_NO_DP(0), - ['9']= NOT_7_NO_DP(S4), - - ['a']= S2+ S3+ S4+ S6 , - ['b']= NOT_7_NO_DP(S0+S1), - ['c']= S6+S4+S3, - ['d']= NOT_7_NO_DP(S0+S5), - ['e']= NOT_7_NO_DP(S2), - ['f']= S6+S5+S4+S0, /* same as F */ - ['g']= NOT_7_NO_DP(S4), /* same as 9 */ - ['h']= S6+S5+S4+S2, - ['i']= S4, - ['j']= S1+S2+S3+S4, - ['k']= S6+S5+S4+S2, /* a h */ - ['l']= S3+S4, - ['m']= S0+S4+S2, /* same as */ - ['n']= S2+S4+S6, - ['o']= S6+S4+S3+S2, - ['p']= NOT_7_NO_DP(S3+S2), // same as P - ['q']= S0+S1+S2+S5+S6, - ['r']= S4+S6, - ['s']= NOT_7_NO_DP(S1+S4), - ['t']= NOT_7_NO_DP(S0+S1+S2), - ['u']= S4+S3+S2+S5+S1, // U - ['v']= S4+S3+S2, // is u but u use U - ['w']= S1+S3+S5, - ['x']= NOT_7_NO_DP(S0+S3), // similar to H - ['y']= NOT_7_NO_DP(S0+S4), - ['z']= S0+S1+S6+S4+S3, // same as 2 - - ['A']= NOT_7_NO_DP(S3), - ['B']= NOT_7_NO_DP(S0+S1), /* as b */ - ['C']= S0+S3+S4+S5, // same as [ - ['E']= NOT_7_NO_DP(S1+S2), - ['F']= S6+S5+S4+S0, - ['G']= NOT_7_NO_DP(S4), /* same as 9 */ - ['H']= NOT_7_NO_DP(S0+S3), - ['I']= S1+S2, - ['J']= S1+S2+S3+S4, - ['K']= NOT_7_NO_DP(S0+S3), /* same as H */ - ['L']= S3+S4+S5, - ['M']= S0+S4+S2, /* same as m*/ - ['N']= S2+S4+S6, /* same as n*/ - ['O']= NOT_7_NO_DP(S6), - ['P']= NOT_7_NO_DP(S3+S2), - ['Q']= NOT_7_NO_DP(S3+S2), - ['R']= S4+S6, - ['S']= NOT_7_NO_DP(S1+S4), /* sasme as 5 */ - ['T']= NOT_7_NO_DP(S0+S1+S2), /* sasme as t */ - ['U']= NOT_7_NO_DP(S6+S0), - ['V']= S4+S3+S2, // is u but u use U - ['W']= S1+S3+S5, - ['X']= NOT_7_NO_DP(S0+S3), // similar to H - ['Y']= NOT_7_NO_DP(S0+S4), - ['Z']= S0+S1+S6+S4+S3, // same as 2 -}; - -#undef S0 -#undef S1 -#undef S2 -#undef S3 -#undef S4 -#undef S5 -#undef S6 -#undef DP -#endif -/** @} */ -#if 0 -int XNUCLEO53L1A1_SetDisplayString(const char *str) { - int status; - uint32_t Segments; - int BitPos; - int i; - - for( i=0; i<4 && str[i]!=0; i++){ - Segments = (uint32_t)ascii_to_display_lut[(uint8_t)str[i]]; - Segments =(~Segments)&0x7F; - BitPos=DisplayBitPos[i]; - CurIOVal.u32 &=~(0x7F< 0x02) { + data.Sensor2_Motion_Detected = bytes[3] === 0 ? "No Motion" : "Motion Detected"; + } + + return { "Yunhorn_SmarToilets_data": data }; + } + else if ((fPort === 17) || (fPort === 19) || (fPort === 21)) { + data.BoardLED = ((bytes[0] & 0x7F) === 0x01) ? "ON" : "OFF"; + switch (bytes[1]) { + case 0x00: + data.LEDcolor = "Dark"; + break; + case 0x01: + data.LEDcolor = "Green"; + data.cubicleOccupyStatus = "Vacant"; + break; + case 0x02: + data.LEDcolor = "Red"; + data.cubicleOccupyStatus = "Occupied"; + break; + case 0x03: + data.LEDcolor = "Blue"; + data.cubicleOccupyStatus = "Maintenance"; + break; + case 0x04: + data.LEDcolor = "Yellow"; + data.cubicleOccupyStatus = "TBD"; + break; + case 0x05: + data.LEDcolor = "Pink"; + data.cubicleOccupyStatus = "TBD"; + break; + case 0x06: + data.LEDcolor = "Cyan"; + data.cubicleOccupyStatus = "TBD"; + break; + case 0x07: + data.LEDcolor = "White"; + data.cubicleOccupyStatus = "TBD"; + break; + case 0x08: + data.LEDcolor = "Red_Blue"; + data.cubicleOccupyStatus = "EMERGENCY"; + break; + case 0x23: + data.LEDcolor = "Red_Blue"; + data.cubicleOccupyStatus = "EMERGENCY"; + break; + case 0x20: + data.LEDcolor = "Red_Flash"; + data.cubicleOccupyStatus = "EMERGENCY"; + break; + default: + data.LEDcolor = "TBD_COLOR"; + data.cubicleOccupyStatus = "TBD_status"; + break; + } + + switch (bytes[2]) { + 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; + } + // select only one below + // For NC(Normal Closed states + data.Sensor1_Door_Contact_Open = bytes[3] === 0 ? "Door Closed" : "Door Open"; + + // For NC(Normal Closed states + //data.Sensor1_Door_Contact_Open = bytes[3]===1?"Door Closed":"Door Open"; + data.Sensor2_Emergency_Button = bytes[4] === 0 ? "Alarm Push Down" : "No Alarm, Released"; + data.Sensor3_Motion_Detected = bytes[5] === 0 ? "No Motion" : "Motion Detected"; + + data.length = bytes.length; + if (data.length === 9) { + data.Over_stay_state = (bytes[6] === 0) ? "False" : "True"; + data.Over_Stay_duration_in_Seconds = (bytes[7] << 8 | bytes[8]); + + return { "Yunhorn_SmarToilets_data": data }; + } + else if (data.length > 9) { + data.Sensor4_ALARM_MUTE = (bytes[6] === 0) ? "Down Mute" : "No Mute"; + data.Sensor5_ALARM_RESET = (bytes[7] === 0) ? "Down RESET" : "NO Reset"; + data.Distance_in_mm = (bytes[8] << 8 | bytes[9]); + data.MotionLevel = (bytes[10] << 8 | bytes[11]); + + data.Unconcious_State = (bytes[12] == 0) ? "False" : "True"; + + switch (bytes[13]) { + case 0x0: + data.Fall_Down_Detected_State = "Presence_Normal"; + break; + case 0x01: + data.Fall_Down_Detected_State = "Presence_Fall_Down"; + break; + case 0x02: + data.Fall_Down_Detected_State = "Presence_Rising_Up"; + break; + case 0x03: + data.Fall_Down_Detected_State = "Presence_LayDown"; + break; + case 0x04: + data.Fall_Down_Detected_State = "Presence_Unconcious"; + break; + case 0x05: + data.Fall_Down_Detected_State = "Presence_Stay_Still"; + break; + default: + data.Fall_Down_Detected_State = "Presence_Normal"; + break; + } + data.OverStay_Detected_State = (bytes[14] == 0x0) ? "False" : "True"; + data.OverStay_Duration_in_Seconds = (bytes[15] << 8 | bytes[16]); + data.No_Movement_Duration_in_Seconds = (bytes[17] << 8 | bytes[18]); + data.Unconcious_Duration_in_Seconds = (bytes[17] << 8 | bytes[18]); + data.Fall_Down_Speed_in_m_per_s = (bytes[19]); + data.Fall_Down_Gravity_in_g = (bytes[20]); + data.SOS_PushDown_Stamp = (bytes[21] << 24 | bytes[22] << 16 | bytes[23] << 8 | bytes[24]); + if (data.SOS_PushDown_Stamp != 0) { + var sos_start = new Date(1000 * data.SOS_PushDown_Stamp); + data.SOS_PushDown_Time = "[" + sos_start.getDate() + "." + (sos_start.getMonth() + 1) + "." + (sos_start.getFullYear()) + "] " + sos_start.getHours() + ":" + sos_start.getMinutes() + ":" + sos_start.getSeconds(); + } else data.SOS_PushDown_Time = "N/A"; + data.SOS_ReleaseUP_Stamp = (bytes[25] << 24 | bytes[26] << 16 | bytes[27] << 8 | bytes[28]); + if (data.SOS_ReleaseUP_Stamp != 0) { + var sos_stop = new Date(1000 * data.SOS_ReleaseUP_Stamp); + data.SOS_ReleaseUP_Time = "[" + sos_stop.getDate() + "." + (sos_stop.getMonth() + 1) + "." + (sos_stop.getFullYear()) + "] " + sos_stop.getHours() + ":" + sos_stop.getMinutes() + ":" + sos_stop.getSeconds(); + } else data.SOS_ReleaseUP_Time = "N/A"; + + data.Fall_Down_Stamp = (bytes[29] << 24 | bytes[30] << 16 | bytes[31] << 8 | bytes[32]); + if (data.Fall_Down_Stamp != 0) { + var fall_start = new Date(1000 * data.Fall_Down_Stamp); + data.Fall_Down_Time = "[" + fall_start.getDate() + "." + (fall_start.getMonth() + 1) + "." + (fall_start.getFullYear()) + "] " + fall_start.getHours() + ":" + fall_start.getMinutes() + ":" + fall_start.getSeconds(); + } else data.Fall_RiseUp_Stamp = "N/A"; + data.Fall_RiseUp_Stamp = (bytes[33] << 24 | bytes[34] << 16 | bytes[35] << 8 | bytes[36]); + if (data.Fall_RiseUp_Stamp != 0) { + var fall_stop = new Date(1000 * data.Fall_RiseUp_Stamp); + data.Fall_RiseUp_Time = "[" + fall_stop.getDate() + "." + (fall_stop.getMonth() + 1) + "." + (fall_stop.getFullYear()) + "] " + fall_stop.getHours() + ":" + fall_stop.getMinutes() + ":" + fall_stop.getSeconds(); + } else data.Fall_RiseUp_Time = "N/A"; + } + 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", + } + ]; + } + // R1D dual roll toilet paper sensor + else if (fPort === 57) { + 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", + } + ]; + } + else if ((fPort === 106)) { //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.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.Count_Valid = (bytes[20] == 0x0) ? "Error" : "OK"; + + return { "Yunhorn_SmarToilets_data": data }; + } + // Heart Beat + else if ((fPort === 12) || (fPort === 20) || (fPort === 18) || (fPort === 5) || (fPort === 107) || (fPort === 58)) { + var data = {}; + //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 }; + } + + // UPLINK, RFAC + else if (fPort === 1) { + var data = {}; + data.length = bytes.length; + + 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)) { + 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; + } + } + + + if ((bytes[0] === 0x59) && (bytes[1] === 0x44)) //Duration interval + { + 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 + { + data.Wakeup_sampling_interval = (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30); + data.Unit = String.fromCharCode(bytes[4]); + } + + else if (bytes[0] === 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]; + } + 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"); + 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 }; + } +} \ No newline at end of file