From 1529329949d12806a6783d784d6be9ce0ba2e6cc Mon Sep 17 00:00:00 2001 From: KipK Date: Wed, 30 Jan 2019 22:52:52 +0100 Subject: [PATCH 1/3] Added support to Beewi Smart Door as broadcaster. As ble2mqtt default tries to connect to ble device, Beewi device needs to be blacklisted in "ble/services" or device will not broadcast data anymore. --- main/broadcasters.c | 67 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/main/broadcasters.c b/main/broadcasters.c index 4ef4a71..8f8c8d4 100644 --- a/main/broadcasters.c +++ b/main/broadcasters.c @@ -356,7 +356,6 @@ static void mijia_temp_hum_metadata_get(uint8_t *adv_data, size_t adv_data_len, uint8_t len; mijia_temp_hum_t *mijia_temp_hum = mijia_temp_hum_data_get(adv_data, adv_data_len, &len); - cb("MACAddress", _mactoa(mijia_temp_hum->mac), ctx); sprintf(s, "%hhu", mijia_temp_hum->message_counter); cb("MessageCounter", s, ctx); @@ -389,12 +388,78 @@ static broadcaster_ops_t mijia_temp_hum_ops = { .is_broadcaster = mijia_temp_hum_is_broadcaster, .metadata_get = mijia_temp_hum_metadata_get, }; +/* Beewi Smart Door */ +#define BEEWI_SMART_DOOR_COMPANY_ID 0x000D +#define BEEWI_SMART_DOOR_SERVICE_ID 0x08 +#define BEEWI_SMART_DOOR_DATA_TYPE_STAT 0x0C +#define BEEWI_SMART_DOOR_DATA_TYPE_BATT 0x06 + + +typedef struct { + uint16_t company_id; + uint8_t service_id; + uint8_t type_stat; + uint8_t status; + uint8_t type_batt; + uint8_t battery; +} __attribute__((packed)) beewi_smart_door_t; + +static beewi_smart_door_t *beewi_smart_door_data_get(uint8_t *adv_data, uint8_t adv_data_len, + uint8_t *beewi_smart_door_len) +{ + uint8_t len; + uint8_t *data = esp_ble_resolve_adv_data(adv_data, + ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE, &len); + + if (beewi_smart_door_len) + *beewi_smart_door_len = len; + + return (beewi_smart_door_t *)data; +} + +static int beewi_smart_door_is_broadcaster(uint8_t *adv_data, size_t adv_data_len) +{ + uint8_t len; + beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, adv_data_len, &len); + + if (!beewi_smart_door || len != sizeof(beewi_smart_door_t)) + return 0; + + /* Technically, we should also prevent connecting to the device, as it stops broadcasting + then. Or just once to get device name, and other static infos. Interesting data as opening status & battery are broadcasted. + Battery data is also available as characteristic, but not the essential data, the door status. + Also it seems to lock the device ( todo: see wtf happening. ) + Needs to blacklist the mac in service config to make this working*/ + + return le16toh(beewi_smart_door->company_id) == BEEWI_SMART_DOOR_COMPANY_ID; +} + +static void beewi_smart_door_metadata_get(uint8_t *adv_data, size_t adv_data_len, + int rssi, broadcaster_meta_data_cb_t cb, void *ctx) +{ + char s[6]; + beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, adv_data_len, NULL); + if ((beewi_smart_door->service_id == BEEWI_SMART_DOOR_SERVICE_ID) && + (beewi_smart_door->type_stat == BEEWI_SMART_DOOR_DATA_TYPE_STAT)) { + sprintf(s,"%i",beewi_smart_door->status ); + cb("Status", s, ctx); + sprintf(s,"%i",beewi_smart_door->battery); + cb("Battery", s, ctx); + } +} + +static broadcaster_ops_t beewi_smart_door_ops = { + .name = "Beewi", + .is_broadcaster = beewi_smart_door_is_broadcaster, + .metadata_get = beewi_smart_door_metadata_get, +}; /* Common */ static broadcaster_ops_t *broadcaster_ops[] = { &ibeacon_ops, &eddystone_ops, &mijia_temp_hum_ops, + &beewi_smart_door_ops, NULL }; From fc557a6d3a4063ec7850cc7c69c6762f8935619e Mon Sep 17 00:00:00 2001 From: KipK Date: Thu, 31 Jan 2019 12:55:20 +0100 Subject: [PATCH 2/3] BeeWi Smart Door: some fixes and clean-up --- README.md | 3 +- main/broadcasters.c | 77 +++++++++++++++++++++++++++------------------ main/broadcasters.h | 2 +- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 2225330..40963df 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,8 @@ is published. * `TLM` frames: `Voltage`, `Temperature`, `Count` and `Uptime` * For MiJia temperature and humidity sensors: `MACAddress`, `MessageCounter`, `Temperature`, `Humidity` and `BatteryLevel` - +* For BeeWi Smart Door sensors: `Status` (opening door state) and `Battery` + **Note:** Broadcaster topics are published without the retained flag regardless of what's defined in the configuration file. diff --git a/main/broadcasters.c b/main/broadcasters.c index 8f8c8d4..7004f22 100644 --- a/main/broadcasters.c +++ b/main/broadcasters.c @@ -356,6 +356,7 @@ static void mijia_temp_hum_metadata_get(uint8_t *adv_data, size_t adv_data_len, uint8_t len; mijia_temp_hum_t *mijia_temp_hum = mijia_temp_hum_data_get(adv_data, adv_data_len, &len); + cb("MACAddress", _mactoa(mijia_temp_hum->mac), ctx); sprintf(s, "%hhu", mijia_temp_hum->message_counter); cb("MessageCounter", s, ctx); @@ -389,67 +390,81 @@ static broadcaster_ops_t mijia_temp_hum_ops = { .metadata_get = mijia_temp_hum_metadata_get, }; /* Beewi Smart Door */ -#define BEEWI_SMART_DOOR_COMPANY_ID 0x000D -#define BEEWI_SMART_DOOR_SERVICE_ID 0x08 -#define BEEWI_SMART_DOOR_DATA_TYPE_STAT 0x0C -#define BEEWI_SMART_DOOR_DATA_TYPE_BATT 0x06 +#define BEEWI_SMART_DOOR_COMPANY_ID 0x000D +#define BEEWI_SMART_DOOR_SERVICE_ID 0x08 +#define BEEWI_SMART_DOOR_DATA_TBD1 0x0C +#define BEEWI_SMART_DOOR_DATA_TBD2 0x06 //unused here typedef struct { uint16_t company_id; uint8_t service_id; - uint8_t type_stat; + uint8_t tbd1; uint8_t status; - uint8_t type_batt; - uint8_t battery; + uint8_t tbd2; + uint8_t battery; } __attribute__((packed)) beewi_smart_door_t; -static beewi_smart_door_t *beewi_smart_door_data_get(uint8_t *adv_data, uint8_t adv_data_len, - uint8_t *beewi_smart_door_len) +static beewi_smart_door_t *beewi_smart_door_data_get(uint8_t *adv_data, + uint8_t adv_data_len, uint8_t *beewi_smart_door_len) { + + uint8_t name_len; uint8_t len; + char *name = (char *)esp_ble_resolve_adv_data(adv_data, + ESP_BLE_AD_TYPE_NAME_CMPL, &name_len); + if (strncmp(name, "BeeWi Smart Door", name_len) != 0) + return NULL; + uint8_t *data = esp_ble_resolve_adv_data(adv_data, ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE, &len); - + if (beewi_smart_door_len) *beewi_smart_door_len = len; return (beewi_smart_door_t *)data; } -static int beewi_smart_door_is_broadcaster(uint8_t *adv_data, size_t adv_data_len) +static int beewi_smart_door_is_broadcaster(uint8_t *adv_data, + size_t adv_data_len) { uint8_t len; - beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, adv_data_len, &len); - + //char dev_name[16]; + //uint8_t dev_len = (uint8_t)sizeof(dev_name); + + beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, + adv_data_len, &len); + + /* Technically, we should also prevent connecting to the device, as it stops broadcasting + then. Or just once to get device name, and other static infos. Interesting data as opening status & battery are broadcasted. + Battery data is also available as characteristic, but not the essential data, the door status. + Needs to blacklist the mac in service config to make this working*/ + + if (!beewi_smart_door || len != sizeof(beewi_smart_door_t)) return 0; - /* Technically, we should also prevent connecting to the device, as it stops broadcasting - then. Or just once to get device name, and other static infos. Interesting data as opening status & battery are broadcasted. - Battery data is also available as characteristic, but not the essential data, the door status. - Also it seems to lock the device ( todo: see wtf happening. ) - Needs to blacklist the mac in service config to make this working*/ - - return le16toh(beewi_smart_door->company_id) == BEEWI_SMART_DOOR_COMPANY_ID; + else return 1; + } -static void beewi_smart_door_metadata_get(uint8_t *adv_data, size_t adv_data_len, - int rssi, broadcaster_meta_data_cb_t cb, void *ctx) +static void beewi_smart_door_metadata_get(uint8_t *adv_data, + size_t adv_data_len, int rssi, broadcaster_meta_data_cb_t cb, void *ctx) { char s[6]; - beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, adv_data_len, NULL); - if ((beewi_smart_door->service_id == BEEWI_SMART_DOOR_SERVICE_ID) && - (beewi_smart_door->type_stat == BEEWI_SMART_DOOR_DATA_TYPE_STAT)) { - sprintf(s,"%i",beewi_smart_door->status ); + beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, + adv_data_len, NULL); + + if (beewi_smart_door->tbd1 == BEEWI_SMART_DOOR_DATA_TBD1) { + sprintf(s,"%hhu",beewi_smart_door->status ); cb("Status", s, ctx); - sprintf(s,"%i",beewi_smart_door->battery); - cb("Battery", s, ctx); - } + sprintf(s,"%hhu",beewi_smart_door->battery); + cb("Battery", s, ctx); + } } static broadcaster_ops_t beewi_smart_door_ops = { - .name = "Beewi", + .name = "BeeWi Smart Door", .is_broadcaster = beewi_smart_door_is_broadcaster, .metadata_get = beewi_smart_door_metadata_get, }; @@ -459,7 +474,7 @@ static broadcaster_ops_t *broadcaster_ops[] = { &ibeacon_ops, &eddystone_ops, &mijia_temp_hum_ops, - &beewi_smart_door_ops, + &beewi_smart_door_ops, NULL }; diff --git a/main/broadcasters.h b/main/broadcasters.h index 3e0e627..0084d1b 100644 --- a/main/broadcasters.h +++ b/main/broadcasters.h @@ -4,7 +4,7 @@ #include #include -#define MAX_BROADCASTER_NAME 16 +#define MAX_BROADCASTER_NAME 17 /* Event callback types */ typedef void (*broadcaster_meta_data_cb_t)(char *name, char *val, void *ctx); From 695f117e904086f6a4106aac0e39ad829e64a775 Mon Sep 17 00:00:00 2001 From: KipK Date: Thu, 31 Jan 2019 13:33:07 +0100 Subject: [PATCH 3/3] Beewi Smart Door: device detection in beewi_smart_door_is_broadcaster --- main/broadcasters.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/main/broadcasters.c b/main/broadcasters.c index 7004f22..b728bf7 100644 --- a/main/broadcasters.c +++ b/main/broadcasters.c @@ -408,14 +408,7 @@ typedef struct { static beewi_smart_door_t *beewi_smart_door_data_get(uint8_t *adv_data, uint8_t adv_data_len, uint8_t *beewi_smart_door_len) { - - uint8_t name_len; uint8_t len; - char *name = (char *)esp_ble_resolve_adv_data(adv_data, - ESP_BLE_AD_TYPE_NAME_CMPL, &name_len); - if (strncmp(name, "BeeWi Smart Door", name_len) != 0) - return NULL; - uint8_t *data = esp_ble_resolve_adv_data(adv_data, ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE, &len); @@ -428,10 +421,14 @@ static beewi_smart_door_t *beewi_smart_door_data_get(uint8_t *adv_data, static int beewi_smart_door_is_broadcaster(uint8_t *adv_data, size_t adv_data_len) { - uint8_t len; - //char dev_name[16]; - //uint8_t dev_len = (uint8_t)sizeof(dev_name); + uint8_t name_len; + char *name = (char *)esp_ble_resolve_adv_data(adv_data, + ESP_BLE_AD_TYPE_NAME_CMPL, &name_len); + if (strncmp(name, "BeeWi Smart Door", name_len) != 0) + return 0 + ; + uint8_t len; beewi_smart_door_t *beewi_smart_door = beewi_smart_door_data_get(adv_data, adv_data_len, &len);