1
0
mirror of https://github.com/esphome/esphome.git synced 2025-07-15 19:43:08 +01:00
Files
.devcontainer
.github
.vscode
docker
esphome
components
a01nyub
a02yyuw
a4988
absolute_humidity
ac_dimmer
adalight
adc
adc128s102
addressable_light
ade7880
ade7953
ade7953_base
ade7953_i2c
ade7953_spi
ads1115
ads1118
ags10
aht10
aic3204
airthings_ble
airthings_wave_base
airthings_wave_mini
airthings_wave_plus
alarm_control_panel
alpha3
am2315c
am2320
am43
analog_threshold
animation
anova
apds9306
apds9960
api
as3935
as3935_i2c
as3935_spi
as5600
as7341
async_tcp
at581x
atc_mithermometer
atm90e26
atm90e32
audio
audio_dac
axs15231
b_parasite
ballu
bang_bang
bedjet
beken_spi_led_strip
bh1750
binary
binary_sensor
binary_sensor_map
bk72xx
bl0906
bl0939
bl0940
bl0942
ble_client
ble_presence
ble_rssi
ble_scanner
bluetooth_proxy
bme280_base
bme280_i2c
bme280_spi
bme680
bme680_bsec
bme68x_bsec2
bme68x_bsec2_i2c
bmi160
bmp085
bmp280
bmp280_base
bmp280_i2c
bmp280_spi
bmp3xx
bmp3xx_base
bmp3xx_i2c
bmp3xx_spi
bmp581
bp1658cj
bp5758d
button
canbus
cap1188
captive_portal
ccs811
cd74hc4067
ch422g
climate
climate_ir
climate_ir_lg
color
color_temperature
combination
coolix
copy
cover
cs5460a
cse7761
cse7766
cst226
cst816
ct_clamp
current_based
custom
custom_component
cwww
dac7678
daikin
daikin_arc
daikin_brc
dallas
dallas_temp
daly_bms
dashboard_import
datetime
debug
deep_sleep
delonghi
demo
dfplayer
dfrobot_sen0395
dht
dht12
display
display_menu_base
dps310
ds1307
dsmr
duty_cycle
duty_time
e131
ee895
ektf2232
emc2101
emmeti
endstop
ens160
ens160_base
ens160_i2c
ens160_spi
ens210
esp32
esp32_ble
esp32_ble_beacon
esp32_ble_client
esp32_ble_server
esp32_ble_tracker
esp32_camera
esp32_camera_web_server
esp32_can
esp32_dac
esp32_hall
esp32_improv
esp32_rmt
esp32_rmt_led_strip
esp32_touch
esp8266
esp8266_pwm
esphome
ethernet
ethernet_info
event
exposure_notifications
external_components
ezo
ezo_pmp
factory_reset
fan
fastled_base
fastled_clockless
fastled_spi
feedback
fingerprint_grow
font
fs3000
ft5x06
ft63x6
fujitsu_general
gcja5
gdk101
globals
gp2y1010au0f
gp8403
gpio
gpio_expander
gps
graph
graphical_display_menu
gree
grove_gas_mc_v2
grove_tb6612fng
growatt_solar
gt911
haier
havells_solar
hbridge
hdc1080
he60r
heatpumpir
hitachi_ac344
hitachi_ac424
hlw8012
hm3301
hmac_md5
hmc5883l
homeassistant
honeywell_hih_i2c
honeywellabp
honeywellabp2_i2c
host
hrxl_maxsonar_wr
hte501
http_request
htu21d
htu31d
hx711
hydreon_rgxx
hyt271
i2c
i2c_device
i2s_audio
iaqcore
ili9341
ili9xxx
image
improv_base
improv_serial
ina219
ina226
ina260
ina2xx_base
ina2xx_i2c
ina2xx_spi
ina3221
inkbird_ibsth1_mini
inkplate6
integration
internal_temperature
interval
jsn_sr04t
json
kalman_combinator
kamstrup_kmp
key_collector
key_provider
kmeteriso
kuntze
lcd_base
lcd_gpio
lcd_menu
lcd_pcf8574
ld2410
ld2420
ledc
libretiny
libretiny_pwm
light
lightwaverf
lilygo_t5_47
lock
logger
ltr390
ltr501
ltr_als_ps
lvgl
m5stack_8angle
matrix_keypad
max17043
max31855
max31856
max31865
max44009
max6675
max6956
max7219
max7219digit
max9611
mcp23008
mcp23016
mcp23017
mcp23s08
mcp23s17
mcp23x08_base
mcp23x17_base
mcp23xxx_base
mcp2515
mcp3008
mcp3204
mcp4725
mcp4728
mcp47a1
mcp9600
mcp9808
md5
mdns
media_player
mhz19
micro_wake_word
micronova
microphone
mics_4514
midea
midea_ac
midea_ir
mitsubishi
mlx90393
mlx90614
mmc5603
mmc5983
modbus
modbus_controller
monochromatic
mopeka_ble
mopeka_pro_check
mopeka_std_check
mpl3115a2
mpr121
mpu6050
mpu6886
mqtt
mqtt_subscribe
ms5611
ms8607
my9231
nau7802
neopixelbus
network
nextion
nfc
noblex
npi19
ntc
number
one_wire
online_image
opentherm
sensor
__init__.py
const.py
generate.py
hub.cpp
hub.h
opentherm.cpp
opentherm.h
opentherm_macros.h
schema.py
validate.py
ota
output
packages
partition
pca6416a
pca9554
pca9685
pcd8544
pcf85063
pcf8563
pcf8574
pid
pipsolar
pm1006
pmsa003i
pmsx003
pmwcs3
pn532
pn532_i2c
pn532_spi
pn7150
pn7150_i2c
pn7160
pn7160_i2c
pn7160_spi
power_supply
preferences
prometheus
psram
pulse_counter
pulse_meter
pulse_width
pvvx_mithermometer
pylontech
pzem004t
pzemac
pzemdc
qmc5883l
qmp6988
qr_code
qspi_amoled
qspi_dbi
qwiic_pir
radon_eye_ble
radon_eye_rd200
rc522
rc522_i2c
rc522_spi
rdm6300
remote_base
remote_receiver
remote_transmitter
resistance
resistance_sampler
restart
rf_bridge
rgb
rgbct
rgbw
rgbww
rotary_encoder
rp2040
rp2040_pio
rp2040_pio_led_strip
rp2040_pwm
rpi_dpi_rgb
rtl87xx
rtttl
ruuvi_ble
ruuvitag
safe_mode
scd30
scd4x
script
sdl
sdm_meter
sdp3x
sds011
seeed_mr24hpc1
selec_meter
select
sen0321
sen21231
sen5x
senseair
sensirion_common
sensor
servo
sfa30
sgp30
sgp40
sgp4x
shelly_dimmer
sht3xd
sht4x
shtcx
shutdown
sigma_delta_output
sim800l
slow_pwm
sm10bit_base
sm16716
sm2135
sm2235
sm2335
sm300d2
sml
smt100
sn74hc165
sn74hc595
sntp
socket
sonoff_d1
speaker
speed
spi
spi_device
spi_led_strip
sprinkler
sps30
ssd1306_base
ssd1306_i2c
ssd1306_spi
ssd1322_base
ssd1322_spi
ssd1325_base
ssd1325_spi
ssd1327_base
ssd1327_i2c
ssd1327_spi
ssd1331_base
ssd1331_spi
ssd1351_base
ssd1351_spi
st7567_base
st7567_i2c
st7567_spi
st7701s
st7735
st7789v
st7920
statsd
status
status_led
stepper
sts3x
substitutions
sun
sun_gtil2
switch
sx1509
t6615
tc74
tca9548a
tca9555
tcl112
tcs34725
tee501
teleinfo
tem3200
template
text
text_sensor
thermostat
time
time_based
tlc59208f
tlc5947
tlc5971
tm1621
tm1637
tm1638
tm1651
tmp102
tmp1075
tmp117
tof10120
toshiba
total_daily_energy
touchscreen
tsl2561
tsl2591
tt21100
ttp229_bsf
ttp229_lsf
tuya
tx20
uart
udp
ufire_ec
ufire_ise
uln2003
ultrasonic
update
uponor_smatrix
uptime
valve
vbus
veml3235
veml7700
version
vl53l0x
voice_assistant
voltage_sampler
wake_on_lan
watchdog
waveshare_epaper
web_server
web_server_base
web_server_idf
weikai
weikai_i2c
weikai_spi
whirlpool
whynter
wiegand
wifi
wifi_info
wifi_signal
wireguard
wk2132_i2c
wk2132_spi
wk2168_i2c
wk2168_spi
wk2204_i2c
wk2204_spi
wk2212_i2c
wk2212_spi
wl_134
wled
x9c
xgzp68xx
xiaomi_ble
xiaomi_cgd1
xiaomi_cgdk2
xiaomi_cgg1
xiaomi_cgpr1
xiaomi_gcls002
xiaomi_hhccjcy01
xiaomi_hhccjcy10
xiaomi_hhccpot002
xiaomi_jqjcy01ym
xiaomi_lywsd02
xiaomi_lywsd02mmc
xiaomi_lywsd03mmc
xiaomi_lywsdcgq
xiaomi_mhoc303
xiaomi_mhoc401
xiaomi_miscale
xiaomi_miscale2
xiaomi_mjyd02yla
xiaomi_mue4094rt
xiaomi_rtcgq02lm
xiaomi_wx08zm
xl9535
xpt2046
yashima
zhlt01
zio_ultrasonic
zyaura
__init__.py
core
dashboard
__init__.py
__main__.py
automation.py
codegen.py
config.py
config_helpers.py
config_validation.py
const.py
coroutine.py
cpp_generator.py
cpp_helpers.py
cpp_types.py
espota2.py
external_files.py
final_validate.py
git.py
helpers.py
idf_component.yml
loader.py
log.py
mqtt.py
pins.py
platformio_api.py
schema_extractors.py
storage_json.py
types.py
util.py
voluptuous_schema.py
vscode.py
wizard.py
writer.py
yaml_util.py
zeroconf.py
script
tests
.clang-format
.clang-tidy
.coveragerc
.dockerignore
.editorconfig
.flake8
.gitattributes
.gitignore
.pre-commit-config.yaml
.yamllint
CODEOWNERS
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE
MANIFEST.in
README.md
platformio.ini
pyproject.toml
requirements.txt
requirements_dev.txt
requirements_optional.txt
requirements_test.txt
sdkconfig.defaults
esphome/esphome/components/opentherm/generate.py
2024-10-25 15:00:28 +13:00

141 lines
5.0 KiB
Python

from collections.abc import Awaitable
from typing import Any, Callable
import esphome.codegen as cg
from esphome.const import CONF_ID
from . import const
from .schema import TSchema
opentherm_ns = cg.esphome_ns.namespace("opentherm")
OpenthermHub = opentherm_ns.class_("OpenthermHub", cg.Component)
def define_has_component(component_type: str, keys: list[str]) -> None:
cg.add_define(
f"OPENTHERM_{component_type.upper()}_LIST(F, sep)",
cg.RawExpression(
" sep ".join(map(lambda key: f"F({key}_{component_type.lower()})", keys))
),
)
for key in keys:
cg.add_define(f"OPENTHERM_HAS_{component_type.upper()}_{key}")
def define_message_handler(
component_type: str, keys: list[str], schemas: dict[str, TSchema]
) -> None:
# The macros defined here should be able to generate things like this:
# // Parsing a message and publishing to sensors
# case MessageId::Message:
# // Can have multiple sensors here, for example for a Status message with multiple flags
# this->thing_binary_sensor->publish_state(parse_flag8_lb_0(response));
# this->other_binary_sensor->publish_state(parse_flag8_lb_1(response));
# break;
# // Building a message for a write request
# case MessageId::Message: {
# unsigned int data = 0;
# data = write_flag8_lb_0(some_input_switch->state, data); // Where input_sensor can also be a number/output/switch
# data = write_u8_hb(some_number->state, data);
# return opentherm_->build_request_(MessageType::WriteData, MessageId::Message, data);
# }
messages: dict[str, list[tuple[str, str]]] = {}
for key in keys:
msg = schemas[key].message
if msg not in messages:
messages[msg] = []
messages[msg].append((key, schemas[key].message_data))
cg.add_define(
f"OPENTHERM_{component_type.upper()}_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)",
cg.RawExpression(
" msg_sep ".join(
[
f"MESSAGE({msg}) "
+ " entity_sep ".join(
[
f"ENTITY({key}_{component_type.lower()}, {msg_data})"
for key, msg_data in keys
]
)
+ " postscript"
for msg, keys in messages.items()
]
)
),
)
def define_readers(component_type: str, keys: list[str]) -> None:
for key in keys:
cg.add_define(
f"OPENTHERM_READ_{key}",
cg.RawExpression(f"this->{key}_{component_type.lower()}->state"),
)
def add_messages(hub: cg.MockObj, keys: list[str], schemas: dict[str, TSchema]):
messages: set[tuple[str, bool]] = set()
for key in keys:
messages.add((schemas[key].message, schemas[key].keep_updated))
for msg, keep_updated in messages:
msg_expr = cg.RawExpression(f"esphome::opentherm::MessageId::{msg}")
if keep_updated:
cg.add(hub.add_repeating_message(msg_expr))
else:
cg.add(hub.add_initial_message(msg_expr))
def add_property_set(var: cg.MockObj, config_key: str, config: dict[str, Any]) -> None:
if config_key in config:
cg.add(getattr(var, f"set_{config_key}")(config[config_key]))
Create = Callable[[dict[str, Any], str, cg.MockObj], Awaitable[cg.Pvariable]]
def create_only_conf(
create: Callable[[dict[str, Any]], Awaitable[cg.Pvariable]]
) -> Create:
return lambda conf, _key, _hub: create(conf)
async def component_to_code(
component_type: str,
schemas: dict[str, TSchema],
type: cg.MockObjClass,
create: Create,
config: dict[str, Any],
) -> list[str]:
"""Generate the code for each configured component in the schema of a component type.
Parameters:
- component_type: The type of component, e.g. "sensor" or "binary_sensor"
- schema_: The schema for that component type, a list of available components
- type: The type of the component, e.g. sensor.Sensor or OpenthermOutput
- create: A constructor function for the component, which receives the config,
the key and the hub and should asynchronously return the new component
- config: The configuration for this component type
Returns: The list of keys for the created components
"""
cg.add_define(f"OPENTHERM_USE_{component_type.upper()}")
hub = await cg.get_variable(config[const.CONF_OPENTHERM_ID])
keys: list[str] = []
for key, conf in config.items():
if not isinstance(conf, dict):
continue
id = conf[CONF_ID]
if id and id.type == type:
entity = await create(conf, key, hub)
cg.add(getattr(hub, f"set_{key}_{component_type.lower()}")(entity))
keys.append(key)
define_has_component(component_type, keys)
define_message_handler(component_type, keys, schemas)
add_messages(hub, keys, schemas)
return keys