@@ -763,12 +763,90 @@ static broadcaster_ops_t atc1441_temp_hum_ops = {
763
763
.metadata_get = atc1441_temp_hum_metadata_get ,
764
764
};
765
765
766
+ /* PVVX Firmware for the Xiaomi Thermometer LYWSD03MMC Temperature and
767
+ * Humidity Sensor, see: https://github.com/pvvx/ATC_MiThermometer */
768
+
769
+ #define PVVX_TEMP_HUM_SERVICE_UUID 0x181A
770
+
771
+ typedef struct {
772
+ // uint16_t not_used;
773
+ uint16_t service_uuid ;
774
+ mac_addr_t mac ;
775
+ int16_t temp ;
776
+ uint16_t humid ;
777
+ uint16_t battery_mv ;
778
+ uint8_t battery_percent ;
779
+ uint8_t message_counter ;
780
+ uint8_t flags ;
781
+ } __attribute__((packed )) pvvx_temp_hum_t ;
782
+
783
+ static pvvx_temp_hum_t * pvvx_temp_hum_data_get (uint8_t * adv_data ,
784
+ uint8_t adv_data_len , uint8_t * pvvx_temp_hum_len )
785
+ {
786
+ uint8_t len ;
787
+ uint8_t * data = esp_ble_resolve_adv_data (adv_data ,
788
+ ESP_BLE_AD_TYPE_SERVICE_DATA , & len );
789
+
790
+ if (pvvx_temp_hum_len )
791
+ * pvvx_temp_hum_len = len ;
792
+
793
+ return (pvvx_temp_hum_t * )data ;
794
+ }
795
+ static int pvvx_temp_hum_is_broadcaster (uint8_t * adv_data ,
796
+ size_t adv_data_len )
797
+ {
798
+ uint8_t len ;
799
+ pvvx_temp_hum_t * pvvx_data = pvvx_temp_hum_data_get (adv_data ,
800
+ adv_data_len , & len );
801
+
802
+ if (len < sizeof (pvvx_temp_hum_t ) ||
803
+ le16toh (pvvx_data -> service_uuid ) != PVVX_TEMP_HUM_SERVICE_UUID )
804
+ {
805
+ return 0 ;
806
+ }
807
+
808
+ return 1 ;
809
+ }
810
+
811
+ static void pvvx_temp_hum_metadata_get (uint8_t * adv_data ,
812
+ size_t adv_data_len , int rssi , broadcaster_meta_data_cb_t cb , void * ctx )
813
+ {
814
+ char s [32 ];
815
+ uint8_t len ;
816
+ pvvx_temp_hum_t * pvvx_data = pvvx_temp_hum_data_get (adv_data ,
817
+ adv_data_len , & len );
818
+
819
+ cb ("MACAddress" , _mactoa (pvvx_data -> mac ), ctx );
820
+
821
+ sprintf (s , "%hhu" , pvvx_data -> message_counter );
822
+ cb ("MessageCounter" , s , ctx );
823
+
824
+ sprintf (s , "%.2f" , pvvx_data -> temp / 100.0 );
825
+ cb ("Temperature" , s , ctx );
826
+
827
+ sprintf (s , "%.2f" , pvvx_data -> humid / 100.0 );
828
+ cb ("Humidity" , s , ctx );
829
+
830
+ sprintf (s , "%u" , pvvx_data -> battery_percent );
831
+ cb ("BatteryLevel" , s , ctx );
832
+
833
+ sprintf (s , "%.3f" , pvvx_data -> battery_mv / 1000.0 );
834
+ cb ("BatteryVolts" , s , ctx );
835
+ }
836
+
837
+ static broadcaster_ops_t pvvx_temp_hum_ops = {
838
+ .name = "PVVX" ,
839
+ .is_broadcaster = pvvx_temp_hum_is_broadcaster ,
840
+ .metadata_get = pvvx_temp_hum_metadata_get ,
841
+ };
842
+
766
843
/* Common */
767
844
static broadcaster_ops_t * broadcaster_ops [] = {
768
845
& ibeacon_ops ,
769
846
& eddystone_ops ,
770
847
& mijia_sensor_ops ,
771
848
& beewi_smart_door_ops ,
849
+ & pvvx_temp_hum_ops ,
772
850
& atc1441_temp_hum_ops ,
773
851
NULL
774
852
};
0 commit comments