686 lines
21 KiB
YAML
686 lines
21 KiB
YAML
# Connects to an OWON BT35T/BT35T+ multimeter and an Atorch DL24 dc-load and mirrors their
|
|
# displays. Also sends those values to Home Assistant for logging and dashboard display.
|
|
# Also exposes actionable buttons to HA to control the devices.
|
|
#
|
|
# Derived work based on https://github.com/reaper7/M5Stack_BLE_client_Owon_B35T by reaper7.
|
|
# AI (ChatGPT (GPT5.5) 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.
|
|
# Soft buttons work as indicated for OWON meter. Left/right so select action, middle to execute.
|
|
# Long-press is supported. Display switches to last connected device, tap center of screen to
|
|
# switch. The dc-load has no on-device buttons, but both are available from HA.
|
|
|
|
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:
|
|
# The Core2 LCD/backlight rails are controlled by the AXP192 PMIC. ESPHome's
|
|
# stock M5CORE2 display setup does not initialize those rails here, so the
|
|
# custom header performs the M5Stack-specific power sequencing once I2C exists.
|
|
- 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:
|
|
# 0 = OWON meter page, 1 = Atorch DL24 page. This is intentionally volatile so
|
|
# every boot starts with the multimeter view until one device connects.
|
|
- id: display_page
|
|
type: int
|
|
initial_value: "0"
|
|
restore_value: no
|
|
# The Atorch external component does not expose a simple connected flag that the
|
|
# display lambda can query, so BLE callbacks maintain this state explicitly.
|
|
- id: atorch_connected
|
|
type: bool
|
|
initial_value: "false"
|
|
restore_value: no
|
|
|
|
script:
|
|
- id: wake_backlight
|
|
mode: restart
|
|
then:
|
|
- script.stop: backlight_idle
|
|
- light.turn_on:
|
|
id: backlight
|
|
brightness: 100%
|
|
- id: backlight_idle
|
|
mode: restart
|
|
then:
|
|
- delay: 2min
|
|
- if:
|
|
condition:
|
|
# Only dim when both BLE devices are disconnected; active lab instruments
|
|
# keep the display fully lit so readings remain visible at a glance.
|
|
lambda: |-
|
|
return !owon_meter.connected && !id(atorch_connected);
|
|
then:
|
|
- light.turn_on:
|
|
id: backlight
|
|
brightness: 70%
|
|
- delay: 3min
|
|
- if:
|
|
condition:
|
|
# Re-check before turning the backlight off, because a connection may
|
|
# have been established during the preceding delay.
|
|
lambda: |-
|
|
return !owon_meter.connected && !id(atorch_connected);
|
|
then:
|
|
- light.turn_off: backlight
|
|
|
|
interval:
|
|
- interval: 10s
|
|
then:
|
|
# Periodic memory telemetry is useful on the Core2 because BLE, PSRAM, the
|
|
# MIPI framebuffer, and external components can fragment different heap pools.
|
|
- 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:
|
|
- script.execute: wake_backlight
|
|
# Notify the custom parser/display object and switch to the meter page when
|
|
# the OWON connects, so the on-device screen follows the active instrument.
|
|
- lambda: |-
|
|
owon_meter.on_connect();
|
|
id(display_page) = 0;
|
|
id(lcd).update();
|
|
on_disconnect:
|
|
then:
|
|
# Keep the UI useful after a disconnect: if the Atorch is still online,
|
|
# automatically fall back from the OWON page to the Atorch page.
|
|
- lambda: |-
|
|
owon_meter.on_disconnect();
|
|
if (id(display_page) == 0 && id(atorch_connected)) {
|
|
id(display_page) = 1;
|
|
}
|
|
id(lcd).update();
|
|
- if:
|
|
condition:
|
|
# Start the idle timer only after both BLE clients are gone; otherwise
|
|
# the remaining connected instrument still deserves an active display.
|
|
lambda: |-
|
|
return !owon_meter.connected && !id(atorch_connected);
|
|
then:
|
|
- script.execute: backlight_idle
|
|
|
|
- mac_address: ${dl24_mac_address}
|
|
id: atorch_ble_client
|
|
on_connect:
|
|
then:
|
|
- script.execute: wake_backlight
|
|
# The Atorch component handles measurements, while this explicit flag/page
|
|
# switch keeps the shared display state synchronized with the BLE client.
|
|
- lambda: |-
|
|
id(atorch_connected) = true;
|
|
id(display_page) = 1;
|
|
id(lcd).update();
|
|
on_disconnect:
|
|
then:
|
|
# If the load disconnects while the meter is still connected, move the
|
|
# physical display back to the meter instead of leaving a stale load page.
|
|
- lambda: |-
|
|
id(atorch_connected) = false;
|
|
if (id(display_page) == 1 && owon_meter.connected) {
|
|
id(display_page) = 0;
|
|
}
|
|
id(lcd).update();
|
|
- if:
|
|
condition:
|
|
# Same idle rule as OWON disconnect: only dim/off when neither BLE
|
|
# target is connected anymore.
|
|
lambda: |-
|
|
return !owon_meter.connected && !id(atorch_connected);
|
|
then:
|
|
- script.execute: backlight_idle
|
|
|
|
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:
|
|
# Bridge ESPHome's generic monochromatic light level to the Core2-specific
|
|
# AXP192 backlight voltage helper implemented in lab-ble-proxy.h.
|
|
- 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 are whitelisted to save flash/RAM; include symbols used by units,
|
|
# status labels, soft-button names, and Atorch metric text.
|
|
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
|
|
# Larger Atorch value font only needs numeric characters and measurement units.
|
|
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
|
|
# Rendering is delegated to the custom C++ helper because ESPHome display YAML
|
|
# primitives would be unwieldy for the OWON seven-segment clone and Atorch dashboard.
|
|
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_energy_calculated).has_state() ? id(atorch_energy_calculated).state : NAN,
|
|
id(atorch_temperature).has_state() ? id(atorch_temperature).state : NAN
|
|
);
|
|
|
|
touchscreen:
|
|
- platform: ft63x6
|
|
id: touch
|
|
display: lcd
|
|
on_touch:
|
|
then:
|
|
- script.execute: wake_backlight
|
|
- if:
|
|
condition:
|
|
# Touching an idle/disconnected unit wakes the display briefly, then
|
|
# restarts the idle timer if no BLE target is available.
|
|
lambda: |-
|
|
return !owon_meter.connected && !id(atorch_connected);
|
|
then:
|
|
- script.execute: backlight_idle
|
|
|
|
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:
|
|
# The large middle touch zone toggles between the two custom render pages.
|
|
- 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:
|
|
# Left soft button changes which OWON remote command the center button will send.
|
|
- 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"
|
|
# OWON remote-control payload: first byte selects the meter button,
|
|
# second byte selects the normal/short-press action variant.
|
|
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"
|
|
# Long-press encoding is not uniform: SELECT and HZ/DUTY still use
|
|
# 0x01, while RANGE/HOLD/REL/MAX-MIN use 0x00 for their alternate action.
|
|
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:
|
|
# Right soft button advances to the next OWON command label.
|
|
- lambda: |-
|
|
owon_meter.next_button();
|
|
|
|
- platform: template
|
|
name: "${friendly_name} OWON Connected"
|
|
icon: "mdi:bluetooth-connect"
|
|
# Template binary sensors expose state maintained by the custom OWON parser object.
|
|
lambda: |-
|
|
return owon_meter.connected;
|
|
- platform: template
|
|
name: "${friendly_name} OWON Overload"
|
|
icon: "mdi:debug-step-over"
|
|
lambda: |-
|
|
return owon_meter.overload;
|
|
- platform: template
|
|
name: "${friendly_name} OWON Low Battery"
|
|
icon: "mdi:battery-low"
|
|
lambda: |-
|
|
return owon_meter.low_battery;
|
|
- platform: template
|
|
name: "${friendly_name} Atorch Connected"
|
|
device_class: connectivity
|
|
icon: "mdi:bluetooth-connect"
|
|
lambda: |-
|
|
return id(atorch_connected);
|
|
|
|
sensor:
|
|
# This hidden characteristic sensor is the bridge from OWON BLE notifications into
|
|
# custom C++ parsing. The returned float becomes the source numeric meter reading.
|
|
- 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
|
|
|
|
# The DL24 component exposes power, but this config computes Wh locally so the
|
|
# accumulated energy can be restored and reset alongside Atorch's own counters.
|
|
- platform: integration
|
|
name: "${friendly_name} Atorch Energy"
|
|
id: atorch_energy_calculated
|
|
sensor: atorch_power
|
|
time_unit: h
|
|
unit_of_measurement: "Wh"
|
|
icon: "mdi:lightning-bolt"
|
|
device_class: energy
|
|
state_class: total_increasing
|
|
accuracy_decimals: 3
|
|
restore: true
|
|
integration_method: trapezoid
|
|
|
|
text_sensor:
|
|
- platform: template
|
|
name: "${friendly_name} OWON Reading"
|
|
update_interval: 1s
|
|
icon: "mdi:gauge"
|
|
# Human-readable mirror of the meter LCD, including waiting/disconnected/OL states.
|
|
lambda: |-
|
|
return owon_meter.reading_text();
|
|
- platform: template
|
|
name: "${friendly_name} OWON Unit"
|
|
update_interval: 1s
|
|
icon: "mdi:ruler"
|
|
# Combines SI prefix and unit into one HA text entity, e.g. mV, kΩ, µA, %.
|
|
lambda: |-
|
|
return std::string(owon_meter.scale()) + owon_meter.unit();
|
|
- platform: template
|
|
name: "${friendly_name} OWON Mode"
|
|
icon: "mdi:knob"
|
|
update_interval: 1s
|
|
# Exposes decoded annunciators such as AC/DC, AUTO, HOLD, REL, MIN/MAX.
|
|
lambda: |-
|
|
return owon_meter.mode_text();
|
|
|
|
button:
|
|
- platform: atorch_dl24
|
|
atorch_dl24_id: atorch0
|
|
reset_energy:
|
|
name: "${friendly_name} Atorch Reset Energy"
|
|
on_press:
|
|
- sensor.integration.reset: atorch_energy_calculated
|
|
reset_capacity:
|
|
name: "${friendly_name} Atorch Reset Capacity"
|
|
reset_runtime:
|
|
name: "${friendly_name} Atorch Reset Runtime"
|
|
reset_all:
|
|
name: "${friendly_name} Atorch Reset All"
|
|
on_press:
|
|
# Keep the locally integrated Wh counter in sync with the DL24 reset-all command.
|
|
- sensor.integration.reset: atorch_energy_calculated
|
|
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"
|
|
# Home Assistant button entities for direct OWON remote commands. The payloads
|
|
# are the same two-byte command format used by the touchscreen soft buttons.
|
|
- 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"
|
|
# SELECT normal press.
|
|
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"
|
|
# RANGE normal press.
|
|
value: !lambda "return std::vector<uint8_t>({2, 0x01});"
|
|
|
|
- platform: template
|
|
name: "OWON HOLD "
|
|
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"
|
|
# HOLD is the short/normal action on the shared HLD/LIG physical key.
|
|
value: !lambda "return std::vector<uint8_t>({3, 0x01});"
|
|
|
|
- platform: template
|
|
name: "OWON LIGHT"
|
|
id: owon_btn_light
|
|
on_press:
|
|
- ble_client.ble_write:
|
|
id: owon_ble_client
|
|
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
|
|
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
|
|
# LIGHT is the alternate/long action on the same HLD/LIG key.
|
|
value: !lambda "return std::vector<uint8_t>({3, 0x00});"
|
|
|
|
- platform: template
|
|
name: "OWON RELATIVE"
|
|
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"
|
|
# RELATIVE is the short/normal action on the shared REL/BT key.
|
|
value: !lambda "return std::vector<uint8_t>({4, 0x01});"
|
|
|
|
- platform: template
|
|
name: "OWON BT"
|
|
id: owon_btn_bt
|
|
on_press:
|
|
- ble_client.ble_write:
|
|
id: owon_ble_client
|
|
service_uuid: "0000fff0-0000-1000-8000-00805f9b34fb"
|
|
characteristic_uuid: "0000fff3-0000-1000-8000-00805f9b34fb"
|
|
# BT is the alternate/long action on the same REL/BT key.
|
|
value: !lambda "return std::vector<uint8_t>({4, 0x00});"
|
|
|
|
- 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"
|
|
# HZ/DUTY command uses the normal action variant.
|
|
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"
|
|
# MAX/MIN command uses the normal action variant.
|
|
value: !lambda "return std::vector<uint8_t>({6, 0x01});"
|