Skip to content

Instantly share code, notes, and snippets.

@Tmbao
Created October 3, 2023 22:27
Show Gist options
  • Select an option

  • Save Tmbao/5e45203a6b9cf560f48842c2623baba7 to your computer and use it in GitHub Desktop.

Select an option

Save Tmbao/5e45203a6b9cf560f48842c2623baba7 to your computer and use it in GitHub Desktop.
Holman BX1 ESP Adapter
esphome:
name: irrigation-controller
friendly_name: Irrigation Controller
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "<TODO>"
services:
- service: start_garden_tap
variables:
running_time_mins: int
then:
- if:
condition:
lambda: return running_time_mins <= 0 || running_time_mins >= 60;
then:
- logger.log:
level: ERROR
format: "Invalid running time minutes: %d"
args: [running_time_mins]
else:
- lambda: id(watering_triggered_min) = running_time_mins;
- esp32_ble_tracker.start_scan:
- service: stop_garden_tap
then:
- lambda: id(watering_triggered_min) = -1;
- esp32_ble_tracker.start_scan:
ota:
password: "<TODO>"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Irrigation-Controller"
password: "<TODO>"
globals:
# -1 for OFF, 0 for NO_ACTION, 1 for ON
- id: watering_triggered_min
type: int
restore_value: no
initial_value: '0'
captive_portal:
esp32_ble:
io_capability: keyboard_display
esp32_ble_tracker:
scan_parameters:
interval: 5s
window: 2s
active: false
ble_client:
- mac_address: "<TODO> - Find this in the holman app"
id: garden_bx1_tap
on_passkey_request:
then:
- ble_client.passkey_reply:
id: garden_bx1_tap
passkey: 174142
on_numeric_comparison_request:
then:
- logger.log:
format: "Compare this passkey with the one on your BLE device: %06d"
args: [ passkey ]
- ble_client.numeric_comparison_reply:
id: garden_bx1_tap
accept: True
on_connect:
then:
- wait_until: # wait until characteristic is discovered
condition:
lambda: |-
esphome::ble_client::BLEClient* client = id(garden_bx1_tap);
esphome::ble_client::BLECharacteristic* chr_passcode = client->get_characteristic(0x21);
esphome::ble_client::BLECharacteristic* chr_watering = client->get_characteristic(0x18);
return chr_passcode != nullptr && chr_watering != nullptr;
timeout: 5s
- lambda: |-
ESP_LOGD("ble_client_lambda", "Connected to Garden-BX1");
esphome::ble_client::BLEClient* client = id(garden_bx1_tap);
if (id(watering_triggered_min) == 0) {
ESP_LOGI("main", "Setting up passcode to stop advertising!");
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(0x21);
if (chr == nullptr) {
ESP_LOGW("main", "[0x21] Characteristic not found. State update can not be written.");
} else {
unsigned char val[2] = {
0xae, 0x8e
};
int status = esp_ble_gattc_write_char(
client->get_gattc_if(),
client->get_conn_id(),
chr->handle,
sizeof(val),
val,
ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_AUTH_REQ_NONE
);
if (status) {
ESP_LOGW("main", "Error settting up passcode, status=%d", status);
} else {
ESP_LOGI("main", "Passcode setup successfully");
}
}
} else if (id(watering_triggered_min) > 0) {
ESP_LOGI("main", "Starting tap!");
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(0x18);
if (chr == nullptr) {
ESP_LOGW("main", "[0x18] Characteristic not found. State update can not be written.");
} else {
unsigned char val[10] = {
0x01, 0x00, 0x00, (char) id(watering_triggered_min), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int status = esp_ble_gattc_write_char(
client->get_gattc_if(),
client->get_conn_id(),
chr->handle,
sizeof(val),
val,
ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_AUTH_REQ_NONE
);
if (status) {
ESP_LOGW("main", "Error sending write value to BLE gattc server, status=%d", status);
} else {
ESP_LOGI("main", "Tap started successfully!");
}
}
id(watering_triggered_min) = 0;
} else {
ESP_LOGI("main", "Stopping tap!");
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(0x18);
if (chr == nullptr) {
ESP_LOGW("main", "[0x18] Characteristic not found. State update can not be written.");
} else {
unsigned char val[10] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int status = esp_ble_gattc_write_char(
client->get_gattc_if(),
client->get_conn_id(),
chr->handle,
sizeof(val),
val,
ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_AUTH_REQ_NONE
);
if (status) {
ESP_LOGW("main", "Error sending write value to BLE gattc server, status=%d", status);
} else {
ESP_LOGI("main", "Tap stopped successfully!");
}
}
id(watering_triggered_min) = 0;
}
- esp32_ble_tracker.stop_scan:
sensor:
- platform: internal_temperature
name: "Irrigation Controller Internal Temperature"
@ModLogNet
Copy link

Hi I'm adapting this to work with the BX4's as well, I noticed that you have this listed as private, would you prefer I not release my changes?

@Tmbao
Copy link
Author

Tmbao commented May 6, 2024

Hi @ModLogNet I think this script is not well polished enough, and people should take extra precautious when using, so I'm reluctant to make this a proper repository, maybe you can create your own gist for BX4 and we can link each other's gist so that other people can find them :). But I've made it public just in case your BX4 change is also compatible with BX1, then you're welcome to update this :)

@PBMikeW
Copy link

PBMikeW commented Jan 12, 2025

@Tmbao You are a legend, I had my device running in 5 minutes with this. Spent ages trying to get it running with Tuya ble to no avail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment