328 lines
9.9 KiB
Python
328 lines
9.9 KiB
Python
from typing import Dict, Any, List
|
|
from buttonplus_generator.merger import deep_merge
|
|
from buttonplus_generator.utils import slugify, array_to_cpp_vector
|
|
from buttonplus_generator.constants import *
|
|
|
|
|
|
def config_common(
|
|
device_name: str, version: int, page_names: List[str], num_bars: int
|
|
) -> Dict[str, Any]:
|
|
config = base_config(device_name=device_name)
|
|
config = deep_merge(config, colors(accent_color="FF0000"))
|
|
config = deep_merge(config, font())
|
|
config = deep_merge(
|
|
config, pages(nr_of_pages=len(page_names), page_names=page_names)
|
|
)
|
|
config = deep_merge(config, time())
|
|
config = deep_merge(config, i2c())
|
|
config = deep_merge(config, spi())
|
|
config = deep_merge(
|
|
config, sensors(ambient_gain="auto", extra_ambient_sensors=False)
|
|
)
|
|
|
|
num_leds = 0
|
|
display_add = 0 if version == 1 else 4
|
|
if num_bars > 0:
|
|
num_leds = 5 + display_add
|
|
if num_bars > 1:
|
|
num_leds = 9 + display_add
|
|
if num_bars > 2:
|
|
num_leds = 13 + display_add
|
|
if num_bars > 3:
|
|
num_leds = 17 #no display
|
|
|
|
config = deep_merge(config, neopixels(num_leds=num_leds))
|
|
|
|
return config
|
|
|
|
|
|
def base_config(device_name: str) -> Dict[str, Any]:
|
|
return {
|
|
"esphome": {
|
|
"name": slugify(device_name),
|
|
"friendly_name": device_name,
|
|
"on_boot": {
|
|
"priority": -100,
|
|
"then": [{"script.execute": "setup_bar_displays"}],
|
|
},
|
|
},
|
|
"esp32": {
|
|
"variant": "ESP32S3",
|
|
"board": "esp32-s3-devkitc1-n16r8",
|
|
"flash_size": "16MB",
|
|
"framework": {"type": "esp-idf"},
|
|
},
|
|
"psram": {"mode": "octal", "speed": "80MHz"},
|
|
"wifi": {
|
|
"ssid": "!secret wifi_ssid",
|
|
"password": "!secret wifi_password",
|
|
},
|
|
"logger": {"level": "DEBUG"},
|
|
"api": {"encryption": {"key": "!secret encryption_key"}},
|
|
"ota": [{"platform": "esphome", "password": "!secret ota_password"}],
|
|
}
|
|
|
|
|
|
def colors(accent_color: str) -> Dict[str, Any]:
|
|
return {
|
|
"color": [
|
|
{"id": "accent", "hex": accent_color},
|
|
{"id": "white", "hex": "FFFFFF"},
|
|
{"id": "grey", "hex": "A6A6A6"},
|
|
],
|
|
}
|
|
|
|
|
|
def font() -> Dict[str, Any]:
|
|
return {
|
|
"font": [
|
|
{
|
|
"file": {
|
|
"url": "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf",
|
|
"type": "web",
|
|
},
|
|
"id": "font_arial20",
|
|
"size": 20,
|
|
"bpp": 4,
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
def pages(nr_of_pages: int, page_names: List[str]) -> Dict[str, Any]:
|
|
page_dict = {
|
|
"globals": [
|
|
{"id": "nr_of_pages", "type": "int", "initial_value": str(nr_of_pages)},
|
|
{
|
|
"id": "page_names",
|
|
"type": "std::vector<std::string>",
|
|
"initial_value": array_to_cpp_vector(page_names),
|
|
},
|
|
{"id": "active_page_nr", "type": "int", "initial_value": "0"},
|
|
{"id": "active_page_name", "type": "std::string", "initial_value": ""},
|
|
],
|
|
"sensors": [
|
|
{
|
|
"platform": "template",
|
|
"name": "Active Page Number",
|
|
"icon": "mdi:order-numeric-ascending",
|
|
"id": "active_page_nr_ha",
|
|
"update_interval": "never",
|
|
"accuracy_decimals": 0,
|
|
}
|
|
],
|
|
"text_sensor": [
|
|
{
|
|
"platform": "template",
|
|
"name": "Active Page Name",
|
|
"icon": "mdi:order-alphabetical-ascending",
|
|
"id": "active_page_name_ha",
|
|
"update_interval": "never",
|
|
}
|
|
],
|
|
}
|
|
|
|
if nr_of_pages > 1:
|
|
page_dict["number"] = [
|
|
{
|
|
"platform": "template",
|
|
"name": "Page Selector",
|
|
"id": "pageselector",
|
|
"optimistic": True,
|
|
"min_value": 0,
|
|
"max_value": nr_of_pages - 1,
|
|
"step": 1,
|
|
"on_value": {
|
|
"then": [
|
|
{
|
|
"lambda": "if(id(pageselector).state >= id(nr_of_pages)) {\n id(active_page_nr) = id(nr_of_pages)-1;\n} else {\n id(active_page_nr) = id(pageselector).state;\n}"
|
|
},
|
|
{"script.execute": "set_page"},
|
|
]
|
|
},
|
|
}
|
|
]
|
|
|
|
page_dict["script"] = [
|
|
{
|
|
"id": "next_page",
|
|
"then": [
|
|
{
|
|
"lambda": "id(active_page_nr) = id(active_page_nr) + 1;\nif(id(active_page_nr) >= id(nr_of_pages)) {\n id(active_page_nr) = 0;\n}"
|
|
},
|
|
{"script.execute": "update_page"},
|
|
],
|
|
},
|
|
{
|
|
"id": "prev_page",
|
|
"then": [
|
|
{
|
|
"lambda": "id(active_page_nr) = id(active_page_nr) - 1;\nif(id(active_page_nr) < 0) {\n id(active_page_nr) = id(nr_of_pages) - 1;\n}"
|
|
},
|
|
{"script.execute": "update_page"},
|
|
],
|
|
},
|
|
{
|
|
"id": "set_page",
|
|
"then": [
|
|
{
|
|
"lambda": "id(active_page_name) = id(page_names)[id(active_page_nr)];"
|
|
},
|
|
{
|
|
"sensor.template.publish": {
|
|
"id": "active_page_id_ha",
|
|
"state": "return id(active_page_nr);",
|
|
}
|
|
},
|
|
{
|
|
"text_sensor.template.publish": {
|
|
"id": "active_page_name_ha",
|
|
"state": "return id(active_page_name);",
|
|
}
|
|
},
|
|
{"script.execute": "update_all"},
|
|
],
|
|
},
|
|
{
|
|
"id": "update_page",
|
|
"then": [
|
|
{
|
|
"number.set": {
|
|
"id": "pageselector",
|
|
"value": "return id(active_page_nr);",
|
|
}
|
|
},
|
|
{"script.execute": "set_page"},
|
|
],
|
|
},
|
|
]
|
|
|
|
page_dict["image"] = [
|
|
{
|
|
"file": "mdi:chevron-right",
|
|
"id": "icon_next_page",
|
|
"resize": "30x30",
|
|
"type": "BINARY",
|
|
},
|
|
{
|
|
"file": "mdi:chevron-left",
|
|
"id": "icon_prev_page",
|
|
"resize": "30x30",
|
|
"type": "BINARY",
|
|
},
|
|
]
|
|
|
|
return page_dict
|
|
|
|
|
|
def time() -> Dict[str, Any]:
|
|
return {"time": [{"platform": "homeassistant", "id": "datetime"}]}
|
|
|
|
|
|
def i2c() -> Dict[str, Any]:
|
|
return {
|
|
"i2c": [
|
|
{
|
|
"id": "buttons",
|
|
"sda": GPIO_I2C_BUTTONS_SDA,
|
|
"scl": GPIO_I2C_BUTTONS_SCL,
|
|
"frequency": "50khz",
|
|
},
|
|
{
|
|
"id": "sensors",
|
|
"sda": GPIO_I2C_SENSORS_SDA,
|
|
"scl": GPIO_I2C_SENSORS_SCL,
|
|
"frequency": "50khz",
|
|
},
|
|
],
|
|
}
|
|
|
|
|
|
def spi() -> Dict[str, Any]:
|
|
return {
|
|
"spi": {"clk_pin": GPIO_SPI_CLK, "mosi_pin": GPIO_SPI_MOSI},
|
|
}
|
|
|
|
|
|
def neopixels(num_leds: int) -> Dict[str, Any]:
|
|
return {
|
|
"light": [
|
|
{
|
|
"platform": "esp32_rmt_led_strip",
|
|
"id": "neopixels",
|
|
"rgb_order": "RGB",
|
|
"chipset": "ws2812",
|
|
"pin": GPIO_NEOPIXELS,
|
|
"num_leds": num_leds,
|
|
},
|
|
]
|
|
}
|
|
|
|
|
|
def sensors(ambient_gain: str, extra_ambient_sensors: bool) -> Dict[str, Any]:
|
|
sensors_dict = {
|
|
"sensor": [
|
|
{
|
|
"platform": "sts3x",
|
|
"address": 0x4A,
|
|
"id": "buttonplus_temperature",
|
|
"i2c_id": "sensors",
|
|
"name": "Temperature",
|
|
"update_interval": "10s",
|
|
"unit_of_measurement": "°C",
|
|
"icon": "mdi:thermometer",
|
|
"device_class": "temperature",
|
|
"state_class": "measurement",
|
|
"accuracy_decimals": 1,
|
|
},
|
|
{
|
|
"platform": "ltr_als_ps",
|
|
"address": 0x29,
|
|
"i2c_id": "sensors",
|
|
"update_interval": "10s",
|
|
"type": "ALS",
|
|
"auto_mode": False,
|
|
"gain": ambient_gain,
|
|
"ambient_light": {
|
|
"name": "Ambient Light",
|
|
"id": "buttonplus_ambientlight",
|
|
"unit_of_measurement": "lx",
|
|
"icon": "mdi:brightness-6",
|
|
"device_class": "illuminance",
|
|
"state_class": "measurement",
|
|
"accuracy_decimals": 1,
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
if extra_ambient_sensors:
|
|
sensors_dict["sensor"][2]["infrared_counts"] = {
|
|
"name": "Infrared Counts",
|
|
"id": "buttonplus_infraredcounts",
|
|
"unit_of_measurement": "#",
|
|
"icon": "mdi:brightness-5",
|
|
"accuracy_decimals": 0,
|
|
}
|
|
sensors_dict["sensor"][2]["full_spectrum_counts"] = {
|
|
"name": "Full Spectrum Counts",
|
|
"id": "buttonplus_fullspectrumcounts",
|
|
"unit_of_measurement": "#",
|
|
"icon": "mdi:brightness-7",
|
|
"accuracy_decimals": 0,
|
|
}
|
|
sensors_dict["sensor"][2]["actual_gain"] = {
|
|
"name": "Actual Gain",
|
|
"id": "buttonplus_actualgain",
|
|
"icon": "mdi:multiplication",
|
|
"accuracy_decimals": 0,
|
|
}
|
|
sensors_dict["sensor"][2]["actual_integration_time "] = {
|
|
"name": "Actual Integration Time",
|
|
"id": "buttonplus_actualintegration",
|
|
"icon": "mdi:timer-outline",
|
|
"accuracy_decimals": 0,
|
|
}
|
|
|
|
return sensors_dict
|