Files
homeassistant-config/esphome/lab-ble-proxy.yaml
T

523 lines
13 KiB
YAML

# Derived work based on https://github.com/reaper7/M5Stack_BLE_client_Owon_B35T by reaper7.
# AI (ChatGPT (GPT5.5), Qwen3.6) has been used to adopt the Arduino sketch to ESPHome.
# Ported to M5Stack Core2 due to memory constraints.
# Integrated atorch ble proxy functionality from https://github.com/syssi/esphome-atorch-dl24 by syssi.
substitutions:
name: "lab-ble-proxy"
friendly_name: "Lab BLE Proxy"
device_description: "M5Stack Core2 BLE client for OWON B35T/B35T+ multimeter and Atorch DL24 DC load"
owon_mac_address: !secret owon_b35t_mac_address
dl24_mac_address: !secret dl24_mac_address
external_components_source: github://syssi/esphome-atorch-dl24@main
atorch_project_version: "2.1.0"
esphome:
name: ${name}
friendly_name: ${friendly_name}
comment: ${device_description}
min_version: 2024.6.0
includes:
- lab-ble-proxy.h
on_boot:
priority: 850
then:
- lambda: |-
owon_b35t::core2_axp192_init(id(core2_i2c));
project:
name: "custom.lab-ble-proxy-m5stack-core2"
version: "1.0"
esp32:
board: m5stack-core2
flash_size: 16MB
framework:
type: esp-idf
advanced:
minimum_chip_revision: "3.1"
sram1_as_iram: true
psram:
mode: quad
speed: 80MHz
external_components:
- source: ${external_components_source}
refresh: 0s
logger:
level: INFO
api:
encryption:
key: !secret apikey
ota:
platform: esphome
password: !secret ota
wifi:
ssid: "Voltage-legacy"
password: !secret voltage_legacy_psk
#use_address: ${name}.home
power_save_mode: none
fast_connect: on
min_auth_mode: WPA2
ap:
ssid: "Lab BLE Proxy Fallback Hotspot"
password: !secret fallback_psk
captive_portal:
globals:
- id: display_page
type: int
initial_value: "0"
restore_value: no
- id: atorch_connected
type: bool
initial_value: "false"
restore_value: no
interval:
- interval: 10s
then:
- lambda: |-
ESP_LOGI("mem", "heap free=%u min_free=%u internal_free=%u internal_largest=%u dma_free=%u dma_largest=%u psram_free=%u psram_largest=%u",
static_cast<unsigned>(esp_get_free_heap_size()),
static_cast<unsigned>(esp_get_minimum_free_heap_size()),
static_cast<unsigned>(heap_caps_get_free_size(MALLOC_CAP_INTERNAL)),
static_cast<unsigned>(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL)),
static_cast<unsigned>(heap_caps_get_free_size(MALLOC_CAP_DMA)),
static_cast<unsigned>(heap_caps_get_largest_free_block(MALLOC_CAP_DMA)),
static_cast<unsigned>(heap_caps_get_free_size(MALLOC_CAP_SPIRAM)),
static_cast<unsigned>(heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM)));
esp32_ble_tracker:
scan_parameters:
active: true
continuous: true
ble_client:
- mac_address: ${owon_mac_address}
id: owon_ble_client
on_connect:
then:
- lambda: |-
owon_meter.on_connect();
id(display_page) = 0;
id(lcd).update();
on_disconnect:
then:
- lambda: |-
owon_meter.on_disconnect();
if (id(display_page) == 0 && id(atorch_connected)) {
id(display_page) = 1;
}
id(lcd).update();
- mac_address: ${dl24_mac_address}
id: atorch_ble_client
on_connect:
then:
- lambda: |-
id(atorch_connected) = true;
id(display_page) = 1;
id(lcd).update();
on_disconnect:
then:
- lambda: |-
id(atorch_connected) = false;
if (id(display_page) == 1 && owon_meter.connected) {
id(display_page) = 0;
}
id(lcd).update();
atorch_dl24:
- id: atorch0
ble_client_id: atorch_ble_client
check_crc: false
throttle: 0s
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
i2c:
id: core2_i2c
sda: GPIO21
scl: GPIO22
scan: true
output:
- platform: template
type: float
id: lcd_backlight
write_action:
- lambda: |-
owon_b35t::core2_axp192_set_backlight(state);
light:
- platform: monochromatic
output: lcd_backlight
name: "${friendly_name} Backlight"
id: backlight
restore_mode: ALWAYS_ON
font:
- file: "fonts/Roboto-Regular.ttf"
id: meter_font
size: 15
glyphs:
[
" ",
"!",
"%",
"+",
"-",
".",
"/",
":",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"<",
">",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"L",
"M",
"N",
"O",
"P",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"k",
"l",
"m",
"n",
"o",
"p",
"r",
"s",
"t",
"u",
"v",
"w",
"y",
"z",
"°",
"µ",
"Ω",
]
- file: "fonts/Roboto-Medium.ttf"
id: atorch_value_font
size: 22
glyphs:
[
" ",
"+",
"-",
".",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"A",
"C",
"V",
"W",
"h",
"°",
]
display:
- platform: mipi_spi
id: lcd
model: M5CORE2
update_interval: 500ms
lambda: |-
owon_meter.render(
it,
id(meter_font),
id(atorch_value_font),
id(display_page),
id(atorch_connected),
id(atorch_voltage).has_state() ? id(atorch_voltage).state : NAN,
id(atorch_current).has_state() ? id(atorch_current).state : NAN,
id(atorch_power).has_state() ? id(atorch_power).state : NAN,
id(atorch_capacity).has_state() ? id(atorch_capacity).state : NAN,
id(atorch_temperature).has_state() ? id(atorch_temperature).state : NAN
);
touchscreen:
- platform: ft63x6
id: touch
display: lcd
binary_sensor:
- platform: touchscreen
touchscreen_id: touch
id: btn_toggle_page
x_min: 70
x_max: 250
y_min: 45
y_max: 195
on_press:
then:
- lambda: |-
id(display_page) = 1 - id(display_page);
id(lcd).update();
- platform: touchscreen
id: button_a
touchscreen_id: touch
x_min: 34
x_max: 74
y_min: 212
y_max: 240
internal: true
on_press:
then:
- lambda: |-
owon_meter.previous_button();
- platform: touchscreen
id: button_b
touchscreen_id: touch
x_min: 108
x_max: 208
y_min: 212
y_max: 240
internal: true
on_click:
- min_length: 50ms
max_length: 1500ms
then:
- logger.log:
level: INFO
format: "OWON short press: %s"
args: ["owon_meter.selected_button_name()"]
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda |-
std::vector<uint8_t> data = {owon_meter.selected_button, 0x01};
return data;
- min_length: 1500ms
max_length: 5000ms
then:
- logger.log:
level: INFO
format: "OWON long press: %s"
args: ["owon_meter.selected_button_name()"]
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda |-
uint8_t press_type = (owon_meter.selected_button == 1 || owon_meter.selected_button == 5) ? 0x01 : 0x00;
std::vector<uint8_t> data = {owon_meter.selected_button, press_type};
return data;
- platform: touchscreen
id: button_c
touchscreen_id: touch
x_min: 242
x_max: 282
y_min: 212
y_max: 240
internal: true
on_press:
then:
- lambda: |-
owon_meter.next_button();
- platform: template
name: "${friendly_name} OWON Connected"
lambda: |-
return owon_meter.connected;
- platform: template
name: "${friendly_name} OWON Overload"
lambda: |-
return owon_meter.overload;
- platform: template
name: "${friendly_name} OWON Low Battery"
lambda: |-
return owon_meter.low_battery;
- platform: template
name: "${friendly_name} Atorch Connected"
device_class: connectivity
lambda: |-
return id(atorch_connected);
sensor:
- platform: ble_client
type: characteristic
ble_client_id: owon_ble_client
id: owon_notify_source
internal: true
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff4-0000-1000-8000-00805f9b34fb"
notify: true
update_interval: never
lambda: |-
owon_meter.handle_notify(x);
return owon_meter.value();
- platform: wifi_signal
name: "${friendly_name} WiFi Signal"
update_interval: 60s
- platform: atorch_dl24
atorch_dl24_id: atorch0
voltage:
name: "${friendly_name} Atorch Voltage"
id: atorch_voltage
current:
name: "${friendly_name} Atorch Current"
id: atorch_current
power:
name: "${friendly_name} Atorch Power"
id: atorch_power
capacity:
name: "${friendly_name} Atorch Capacity"
id: atorch_capacity
temperature:
name: "${friendly_name} Atorch Temperature"
id: atorch_temperature
dim_backlight:
name: "${friendly_name} Atorch Dim Backlight"
id: atorch_dim_backlight
text_sensor:
- platform: template
name: "${friendly_name} OWON Reading"
update_interval: 1s
lambda: |-
return owon_meter.reading_text();
- platform: template
name: "${friendly_name} OWON Unit"
update_interval: 1s
lambda: |-
return std::string(owon_meter.scale()) + owon_meter.unit();
- platform: template
name: "${friendly_name} OWON Mode"
update_interval: 1s
lambda: |-
return owon_meter.mode_text();
button:
- platform: atorch_dl24
atorch_dl24_id: atorch0
reset_energy:
name: "${friendly_name} Atorch Reset Energy"
reset_capacity:
name: "${friendly_name} Atorch Reset Capacity"
reset_runtime:
name: "${friendly_name} Atorch Reset Runtime"
reset_all:
name: "${friendly_name} Atorch Reset All"
usb_plus:
name: "${friendly_name} Atorch Plus"
usb_minus:
name: "${friendly_name} Atorch Minus"
setup:
name: "${friendly_name} Atorch Setup"
enter:
name: "${friendly_name} Atorch Enter"
- platform: template
name: "OWON SELECT"
id: owon_btn_select
on_press:
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda "return std::vector<uint8_t>({1, 0x01});"
- platform: template
name: "OWON RANGE"
id: owon_btn_range
on_press:
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda "return std::vector<uint8_t>({2, 0x01});"
- platform: template
name: "OWON HOLD | LIGHT"
id: owon_btn_hold
on_press:
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda "return std::vector<uint8_t>({3, 0x01});"
- platform: template
name: "OWON RELATIVE | BT"
id: owon_btn_rel
on_press:
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda "return std::vector<uint8_t>({4, 0x01});"
- platform: template
name: "OWON HZ | DUTY"
id: owon_btn_hz
on_press:
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda "return std::vector<uint8_t>({5, 0x01});"
- platform: template
name: "OWON MAX | MIN"
id: owon_btn_maxmin
on_press:
- ble_client.ble_write:
id: owon_ble_client
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
value: !lambda "return std::vector<uint8_t>({6, 0x01});"