substitutions: device_name: "espblueconnect" friendly_name: "ESP BlueConnect" description: "ESP BlueConnect Proxy" device_area: "Locale Piscina" board: m5stack-atom blueriiot_mac: !secret blueriiot_mac blueriiot_name_prefix: !secret blueriiot_nameprefix blueriiot_id_prefix: !secret blueriiot_idprefix # send true 0x01 to this service ID blueriiot_send_service_uuid: 'F3300001-F0A2-9B06-0C59-1BC4763B5C00' blueriiot_send_characteristic_uuid: 'F3300002-F0A2-9B06-0C59-1BC4763B5C00' # notification is received on this Service ID blueriiot_receive_service_uuid: 'F3300001-F0A2-9B06-0C59-1BC4763B5C00' blueriiot_receive_characteristic_uuid: 'F3300003-F0A2-9B06-0C59-1BC4763B5C00' esphome: name: ${device_name} friendly_name: ${friendly_name} area: ${device_area} esp32: board: ${board} framework: type: arduino # type: esp-idf wifi: ssid: !secret wifi_ssid password: !secret wifi_password domain: !secret wifi_domain # enable_btm: True # enable_rrm: True # Enable fallback hotspot (captive portal) in case wifi connection fails # ap: # ssid: "Blueriiot Fallback Hotspot" # password: !secret blueriiot_fallback # Time sync with Home Assistant time: - platform: homeassistant id: homeassistant_time timezone: Europe/Rome on_time_sync: then: - logger.log: format: "Synchronized system clock with HA" level: "INFO" # Enable logging logger: # level: VERY_VERBOSE level: DEBUG # Enable Home Assistant API api: encryption: key: !secret esphome_ha_api_key ota: - platform: esphome password: !secret esphome_ota_key esp32_ble_tracker: scan_parameters: active: false interval: 1000ms window: 700ms on_ble_advertise: - mac_address: ${blueriiot_mac} then: - lambda: |- ESP_LOGD("ble_adv", "New BLE device"); ESP_LOGD("ble_adv", " address: %s", x.address_str().c_str()); ESP_LOGD("ble_adv", " name: %s", x.get_name().c_str()); if(x.get_ibeacon().has_value()) { auto ibeacon = x.get_ibeacon().value(); ESP_LOGD("ble_adv", " ibeacon: %s", ibeacon.get_uuid().to_string().c_str()); } ESP_LOGD("ble_adv", " Advertised service UUIDs:"); for (auto uuid : x.get_service_uuids()) { ESP_LOGD("ble_adv", " - %s", uuid.to_string().c_str()); } ESP_LOGD("ble_adv", " Advertised service data:"); for (auto data : x.get_service_datas()) { ESP_LOGD("ble_adv", " - %s: (length %i)", data.uuid.to_string().c_str(), data.data.size()); } ESP_LOGD("ble_adv", " Advertised manufacturer data:"); for (auto data : x.get_manufacturer_datas()) { ESP_LOGD("ble_adv", " - %s: ", format_hex_pretty(data.data).c_str()); } ble_client: - mac_address: ${blueriiot_mac} id: ble_client_${blueriiot_id_prefix} on_connect: then: - logger.log: format: "Connected to Blueconnect" level: "INFO" - lambda: "id(binary_sensor_${blueriiot_id_prefix}_connected).publish_state(true);" - delay: 2s - button.press: button_${blueriiot_id_prefix}_read_sensors on_disconnect: [lambda: "id(binary_sensor_${blueriiot_id_prefix}_connected).publish_state(false);"] # Blue Connect button: - platform: template id: button_${blueriiot_id_prefix}_read_sensors name: "${blueriiot_name_prefix} Read Sensors" internal: true on_press: then: - logger.log: format: "Reading Blueconnect" level: "INFO" - ble_client.ble_write: id: ble_client_${blueriiot_id_prefix} service_uuid: ${blueriiot_send_service_uuid} characteristic_uuid: ${blueriiot_send_characteristic_uuid} # A lambda returning an std::vector. value: !lambda |- return {0x01}; switch: - platform: ble_client ble_client_id: ble_client_${blueriiot_id_prefix} id: switch_${blueriiot_id_prefix}_read_sensors name: "${blueriiot_name_prefix} Read Sensors" restore_mode: always_off binary_sensor: - platform: template id: binary_sensor_${blueriiot_id_prefix}_connected name: "${blueriiot_name_prefix} Connection State" device_class: "connectivity" entity_category: "diagnostic" - platform: template id: binary_sensor_${blueriiot_id_prefix}_ph name: "${blueriiot_name_prefix} pH State" device_class: "problem" entity_category: "diagnostic" - platform: template id: binary_sensor_${blueriiot_id_prefix}_orp name: "${blueriiot_name_prefix} ORP State" device_class: "problem" entity_category: "diagnostic" sensor: - platform: template id: sensor_${blueriiot_id_prefix}_temperature name: "${blueriiot_name_prefix} Temperature" unit_of_measurement: "°C" icon: "mdi:thermometer-water" device_class: "temperature" state_class: "measurement" accuracy_decimals: 1 - platform: template id: sensor_${blueriiot_id_prefix}_ph name: "${blueriiot_name_prefix} pH" unit_of_measurement: "pH" icon: "mdi:ph" state_class: "measurement" device_class: "ph" accuracy_decimals: 1 on_value_range: - above: 7.2 below: 7.6 then: - binary_sensor.template.publish: id: binary_sensor_${blueriiot_id_prefix}_ph state: OFF - below: 7.2 then: - binary_sensor.template.publish: id: binary_sensor_${blueriiot_id_prefix}_ph state: ON - above: 7.6 then: - binary_sensor.template.publish: id: binary_sensor_${blueriiot_id_prefix}_ph state: ON - platform: template id: sensor_${blueriiot_id_prefix}_orp name: "${blueriiot_name_prefix} ORP" unit_of_measurement: "mV" icon: "mdi:water-sync" device_class: "voltage" state_class: "measurement" accuracy_decimals: 1 on_value_range: - above: 630 below: 730 then: - binary_sensor.template.publish: id: binary_sensor_${blueriiot_id_prefix}_orp state: OFF - below: 630 then: - binary_sensor.template.publish: id: binary_sensor_${blueriiot_id_prefix}_orp state: ON - above: 730 then: - binary_sensor.template.publish: id: binary_sensor_${blueriiot_id_prefix}_orp state: ON - platform: template id: sensor_${blueriiot_id_prefix}_bat name: "${blueriiot_name_prefix} Battery" unit_of_measurement: "%" icon: "mdi:battery-bluetooth-variant" device_class: "battery" state_class: "measurement" accuracy_decimals: 1 - platform: template id: sensor_${blueriiot_id_prefix}_salt name: "${blueriiot_name_prefix} Salinity" unit_of_measurement: "g/L" icon: "phu:pool-salinty" state_class: "measurement" accuracy_decimals: 1 - platform: template id: sensor_${blueriiot_id_prefix}_cond name: "${blueriiot_name_prefix} Conductivity" unit_of_measurement: "µS/cm" icon: "mdi:water-sync" state_class: "measurement" accuracy_decimals: 1 text_sensor: - platform: template id: sensor_${blueriiot_id_prefix}_last_update name: "${blueriiot_name_prefix} Last Update" icon: "mdi:clock-start" update_interval: never - platform: ble_client id: ${blueriiot_id_prefix}_reading_data name: "${blueriiot_name_prefix} reading data" internal: true ble_client_id: ble_client_${blueriiot_id_prefix} service_uuid: ${blueriiot_receive_service_uuid} characteristic_uuid: ${blueriiot_receive_characteristic_uuid} notify: true update_interval: never on_notify: then: # @Peerke https://community.home-assistant.io/t/blue-connect-pool-measurements/118901/349 # float salt = (float)( (int16_t) (x[8]<< 8) + x[7]) / 25.0; # @ST8 https://community.home-assistant.io/t/blue-connect-pool-measurements/118901/354 # float salt = (float)( -1.828 * log(( ((int16_t)(x[8]<< 8) + x[7]) * log(temperature)) - 197.369) + 14.076 ); - lambda: |- std::string rawhex = format_hex_pretty((uint8_t *) x.c_str(), x.size()).c_str(); ESP_LOGD("raw_hex", "%s", rawhex.c_str()); float temperature = (float)((int16_t)(x[2]<< 8) + x[1])/100; ESP_LOGD("temp", "%f", temperature); id(sensor_${blueriiot_id_prefix}_temperature).publish_state(temperature); float raw_ph = (float)( (int16_t) (x[4]<< 8) + x[3]) ; float ph = (float)( (int16_t) (2048 - raw_ph)) / 232 + 7 ; ESP_LOGD("ph", "%f", ph); id(sensor_${blueriiot_id_prefix}_ph).publish_state(ph); float orp = (float)( (int16_t) (x[6]<< 8) + x[5]) / 3.86 - 21.57826; ESP_LOGD("orp", "%f", orp); id(sensor_${blueriiot_id_prefix}_orp).publish_state(orp); float salt = (float)( -1.828 * log(( ((int16_t)(x[8]<< 8) + x[7]) * log(temperature)) - 197.369) + 14.076 ); ESP_LOGD("salt", "%f", salt); id(sensor_${blueriiot_id_prefix}_salt).publish_state(salt); float cond = (float)( (int16_t) (x[10]<< 8) + x[9]) / 0.4134; ESP_LOGD("cond", "%f", cond); id(sensor_${blueriiot_id_prefix}_cond).publish_state(cond); float bat = (float)( (int16_t) x[11]) / 36 * 100; ESP_LOGD("bat", "%f", bat); id(sensor_${blueriiot_id_prefix}_bat).publish_state(bat); id(switch_${blueriiot_id_prefix}_read_sensors).turn_off(); - text_sensor.template.publish: id: sensor_${blueriiot_id_prefix}_last_update state: !lambda |- return id(homeassistant_time).now().strftime("%Y-%m-%d %H.%M");