Closed samip5 closed 2 years ago
See https://github.com/esphome/feature-requests/issues/454.
We didn't make any progress yet, so if you are able to help, all help is welcome. 😉
Almost there https://github.com/esphome/esphome/pull/3398
Should be working now? It would be awesome if this would be intergraded into ESPHome for updates and editing.
@robbinonline yes it is working. not merged yet but with this branch and this config
ble_client:
- mac_address: XX:XX:XX:XX:XX:XX
id: cover
maintain_connection: false
cover:
- platform: template
name: cover_test
optimistic: true
open_action:
- ble_client.ble_write:
id: cover
service_uuid: CBA20D00-224D-11E6-9FB8-0002A5D5C51B
characteristic_uuid: CBA20002-224D-11E6-9FB8-0002A5D5C51B
# List of bytes to write.
value: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00]
close_action:
- ble_client.ble_write:
id: cover
service_uuid: CBA20D00-224D-11E6-9FB8-0002A5D5C51B
characteristic_uuid: CBA20002-224D-11E6-9FB8-0002A5D5C51B
# List of bytes to write.
value: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64]
stop_action:
- ble_client.ble_write:
id: cover
service_uuid: CBA20D00-224D-11E6-9FB8-0002A5D5C51B
characteristic_uuid: CBA20002-224D-11E6-9FB8-0002A5D5C51B
# List of bytes to write.
value: [0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF]
Works great!
@ppanagiotis Thanks! I have to found out how to use this branch in hacs and then give it a try!
@robbinonline I don't know if you've figured it out, but I created a quick repo with those changes that you can use directly from your esphome config :
external_components:
- source:
type: git
url: https://github.com/Ulrar/esphome-temp.git
ref: ble_write_action
components: [ ble_client ]
The only change I made myself is hardcoding the const.py change so it can be imported as an external components while we wait for it to be merged. Seems to work well with switchbot curtains so far for me.
I'll add that you probably want some extra code to parse the BLE advertisements sent by the curtains for both the battery level and the current status (open / close), here's what my config looks like for that :
sensor:
- platform: template
name: $sbcbw Right Battery
id: ${sbcbw_nospace}_right_battery
unit_of_measurement: '%'
device_class: battery
accuracy_decimals: 0
icon: "mdi:battery"
update_interval: 180s
- platform: template
name: $sbcbw Left Battery
id: ${sbcbw_nospace}_left_battery
unit_of_measurement: '%'
device_class: battery
accuracy_decimals: 0
icon: "mdi:battery"
update_interval: 180s
esp32_ble_tracker:
id: $device_name
scan_parameters:
interval: 320ms
window: 320ms
on_ble_advertise:
- mac_address: !secret curtain_bay_window_mac
then:
- lambda: |-
switchbot_curtain( &x
, id(${sbcbw_nospace}_cover)
, id(${sbcbw_nospace}_left_battery)
);
- mac_address: !secret curtain2_bay_window_mac
then:
- lambda: |-
switchbot_battery_only(&x, id(${sbcbw_nospace}_right_battery));
ble_client:
- mac_address: !secret curtain_bay_window_mac
id: ${sbcbw_nospace}
maintain_connection: false
cover:
- platform: template
id: ${sbcbw_nospace}_cover
device_class: curtain
name: ${sbcbw}
optimistic: true
has_position: true
open_action:
- ble_client.ble_write:
id: ${sbcbw_nospace}
service_uuid: CBA20D00-224D-11E6-9FB8-0002A5D5C51B
characteristic_uuid: CBA20002-224D-11E6-9FB8-0002A5D5C51B
value: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00]
close_action:
- ble_client.ble_write:
id: ${sbcbw_nospace}
service_uuid: CBA20D00-224D-11E6-9FB8-0002A5D5C51B
characteristic_uuid: CBA20002-224D-11E6-9FB8-0002A5D5C51B
value: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64]
position_action:
- ble_client.ble_write:
id: ${sbcbw_nospace}
service_uuid: cba20d00-224d-11e6-9fb8-0002a5d5c51b
characteristic_uuid: cba20002-224d-11e6-9fb8-0002a5d5c51b
value: !lambda |-
uint8_t byte_position = 100 * (1.0f - pos);
ESP_LOGW("POS: ", "pos: %f, byte_position: %d", pos, byte_position);
return {0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, byte_position};
And here's the code for those two functions called from the lambdas :
void switchbot_battery_only( const esp32_ble_tracker::ESPBTDevice *x
, esphome::template_::TemplateSensor* batteryEnt
)
{
for (auto data : x->get_service_datas())
{
batteryEnt->publish_state(data.data[2] & 0b01111111);
}
}
void switchbot_curtain( const esp32_ble_tracker::ESPBTDevice *x
, esphome::template_::TemplateCover *curtainEnt
, esphome::template_::TemplateSensor* batteryEnt
)
{
for (auto data : x->get_service_datas())
{
if(data.data.size() == 6)
{
int8_t battLevel = 0;
int8_t position = 0;
battLevel = data.data[2] & 0b01111111;
position = data.data[3] & 0b01111111;
curtainEnt->position = (100 - position) / 100;
curtainEnt->publish_state();
batteryEnt->publish_state(battLevel);
}
}
}
This is all very much a work in progress but with that I have proper cover entities working (and displaying their open/close status correctly in home assistant) for the curtains, and I'm getting the battery level for both switchbots.
The switchbot app doesn't display the mac address of the second curtain bot when they're groupped for one window, I used nRF Connect on my phone to find it. Another option would be to ungroup them, write it down then re-group them I guess.
I have more code to handle contact sensors as well, if anyone is interested. I wonder what it'd take to make all of this into a generic switchbot component, it'd depend on rbaron's PRs getting merged but it would be nice.
For anyone following this I've updated my branch with @rbaron's latest changes, and updated my comment above to add the position action. Switchbots can now be set to any % using the slider in home assistant, thanks rbaron !
I'm intrigued by this piece of software, and I would love to be able to integrate it into my CC2652 POE Coordinator, that's running ESP32 with a CC2652 Zigbee module in it as well.
Has anyone attempted this yet?