myhomeiot-esphome-components/examples/ble_client/delonghi.yaml

187 lines
7.6 KiB
YAML

# BLE Client Delonghi PrimaDonna example
# Tested with Delonghi PrimaDonna Elite Experience ECAM 650.85.MS
#
# Useful links:
# https://github.com/Arbuzov/home_assistant_delonghi_primadonna
# https://github.com/manekinekko/cafy
# https://community.smartthings.com/t/controlling-delonghi-primadonna-elite-through-st/138402/41
# https://github.com/jatty/coffee-link/blob/main/start-delonghi
substitutions:
delonghi_mac: !secret delonghi_mac
delonghi_name_prefix: Coffee Machine
delonghi_id_prefix: coffee_machine
delonghi_service_uuid: 00035B03-58E6-07DD-021A-08123A000300
delonghi_characteristic_uuid: 00035B03-58E6-07DD-021A-08123A000301
delonghi_update_interval: '5000'
globals:
- id: delonghi_millis
type: uint32_t
restore_value: false
initial_value: '0'
esphome:
on_loop:
then:
- lambda: |-
if (!id(delonghi_millis)) {
id(binary_sensor_${delonghi_id_prefix}_connected).publish_initial_state(false);
id(binary_sensor_${delonghi_id_prefix}).publish_initial_state(false);
id(delonghi_millis) = millis();
}
static unsigned char CMD_HEALTH_CHECK[] = {0x0D, 0x05, 0x75, 0x0F, 0xDA, 0x25};
if (id(binary_sensor_${delonghi_id_prefix}_connected).state && (millis() - id(delonghi_millis) > ${delonghi_update_interval})) {
auto chr = id(ble_client_${delonghi_id_prefix}).get_characteristic(
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_service_uuid}"),
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_characteristic_uuid}"));
if (chr) {
ESP_LOGD("${delonghi_id_prefix}", ">>> %s", format_hex_pretty(CMD_HEALTH_CHECK, sizeof(CMD_HEALTH_CHECK)).c_str());
chr->write_value(CMD_HEALTH_CHECK, sizeof(CMD_HEALTH_CHECK));
}
id(delonghi_millis) = millis();
}
esp32_ble_tracker:
ble_client:
- mac_address: ${delonghi_mac}
id: ble_client_${delonghi_id_prefix}
on_connect: [lambda: "id(binary_sensor_${delonghi_id_prefix}_connected).publish_state(true);"]
on_disconnect: [lambda: "id(binary_sensor_${delonghi_id_prefix}_connected).publish_state(false);"]
binary_sensor:
- platform: template
id: binary_sensor_${delonghi_id_prefix}_connected
name: ${delonghi_name_prefix}
device_class: connectivity
entity_category: diagnostic
- platform: template
id: binary_sensor_${delonghi_id_prefix}
internal: true
sensor:
- platform: template
id: sensor_${delonghi_id_prefix}_alarm
name: ${delonghi_name_prefix} Alarm
icon: mdi:alert
state_class: measurement
accuracy_decimals: 0
switch:
- platform: ble_client
id: switch_${delonghi_id_prefix}_enable
name: ${delonghi_name_prefix} Enable
ble_client_id: ble_client_${delonghi_id_prefix}
disabled_by_default: true
entity_category: config
- platform: template
id: switch_${delonghi_id_prefix}
name: ${delonghi_name_prefix}
icon: mdi:coffee
lambda: return id(binary_sensor_${delonghi_id_prefix}).state;
turn_on_action:
- lambda: |-
if (!id(binary_sensor_${delonghi_id_prefix}_connected).state)
return;
static unsigned char CMD_POWER_ON[] = {0x0D, 0x07, 0x84, 0x0F, 0x02, 0x01, 0x55, 0x12};
auto chr = id(ble_client_${delonghi_id_prefix}).get_characteristic(
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_service_uuid}"),
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_characteristic_uuid}"));
if (chr)
chr->write_value(CMD_POWER_ON, sizeof(CMD_POWER_ON));
button:
- platform: template
id: button_${delonghi_id_prefix}_americano
name: ${delonghi_name_prefix} Americano
icon: mdi:coffee-to-go-outline
on_press:
then:
- lambda: |-
if (!id(binary_sensor_${delonghi_id_prefix}_connected).state)
return;
static unsigned char CMD_AMERICANO_ON[] = {0x0D, 0x12, 0x83, 0xF0, 0x06, 0x01, 0x01, 0x00, 0x28, 0x02, 0x03, 0x0F, 0x00, 0x6E, 0x00, 0x00, 0x06, 0x47, 0x8B};
static unsigned char CMD_AMERICANO_OFF[] = {0x0D, 0x08, 0x83, 0xF0, 0x06, 0x02, 0x06, 0x18, 0x71};
auto chr = id(ble_client_${delonghi_id_prefix}).get_characteristic(
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_service_uuid}"),
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_characteristic_uuid}"));
if (chr)
chr->write_value(CMD_AMERICANO_ON, sizeof(CMD_AMERICANO_ON));
- platform: template
id: button_${delonghi_id_prefix}_coffe
name: ${delonghi_name_prefix} Coffe
icon: mdi:coffee-to-go-outline
on_press:
then:
- lambda: |-
if (!id(binary_sensor_${delonghi_id_prefix}_connected).state)
return;
static unsigned char COFFE_ON[] = {0x0D, 0x0F, 0x83, 0xF0, 0x02, 0x01, 0x01, 0x00, 0x67, 0x02, 0x02, 0x00, 0x00, 0x06, 0x77, 0xFF};
static unsigned char COFFE_OFF[] = {0x0D, 0x08, 0x83, 0xF0, 0x02, 0x02, 0x06, 0xC4, 0xB1};
auto chr = id(ble_client_${delonghi_id_prefix}).get_characteristic(
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_service_uuid}"),
esp32_ble_tracker::ESPBTUUID::from_raw("${delonghi_characteristic_uuid}"));
if (chr)
chr->write_value(COFFE_ON, sizeof(COFFE_ON));
text_sensor:
- platform: ble_client
id: text_sensor_${delonghi_id_prefix}
internal: true
ble_client_id: ble_client_${delonghi_id_prefix}
service_uuid: ${delonghi_service_uuid}
characteristic_uuid: ${delonghi_characteristic_uuid}
notify: true
update_interval: never
on_notify:
then:
lambda: |-
static unsigned char packet[19];
static uint8_t index = 0;
id(delonghi_millis) = millis();
ESP_LOGD("${delonghi_id_prefix}", "%s", format_hex_pretty((uint8_t *) x.c_str(), x.size()).c_str());
if (index + x.size() > sizeof(packet))
ESP_LOGE("${delonghi_id_prefix}", "Packet longer than (%d) bytes", sizeof(packet));
else {
memcpy(&packet[index], x.c_str(), x.size());
index += x.size();
if (index > 0 && packet[0] != 0xD0)
ESP_LOGE("${delonghi_id_prefix}", "Packet has wrong signature (0x%02X)", packet[0]);
else if (index >= 2 && index >= packet[1] + 1) {
ESP_LOGD("${delonghi_id_prefix}", "<<< %s", format_hex_pretty(packet, index).c_str());
uint16_t deviser = 0x1D0F, i3, i4, i5, crc = packet[index - 2] << 8 | packet[index - 1];
for (int i = 0; i < index - 2; i++) {
i3 = (((deviser << 8) | (deviser >> 8)) & 0x0000FFFF) ^ packet[i];
i4 = i3 ^ ((i3 & 0xFF) >> 4);
i5 = i4 ^ ((i4 << 12) & 0x0000FFFF);
deviser = i5 ^ (((i5 & 0xFF) << 5) & 0x0000FFFF);
}
if (deviser != crc)
ESP_LOGE("${delonghi_id_prefix}", "CRC error, expected (0x%04X) received (0x%04X)", deviser, crc);
else {
switch (packet[2]) {
case 0x75:
id(binary_sensor_${delonghi_id_prefix}).publish_state(packet[9] != 0);
id(sensor_${delonghi_id_prefix}_alarm).publish_state((int32_t) packet[7] +
(int32_t)(packet[8] << 8) + (int32_t)(packet[12] << 16) + (int32_t)(packet[13] << 24));
break;
default:
ESP_LOGW("${delonghi_id_prefix}", "Unknown packet type (0x%02X)", packet[2]);
}
}
}
else
return;
}
index = 0;