First valid working config with drawing
This commit is contained in:
@@ -16,11 +16,10 @@ The configuration (handmade) on which this generator is based, can be found in t
|
||||
- Notification service: until dismissed, or with timeout
|
||||
- LED effects: flash, breathe
|
||||
- Top level config only for drawing, everything else hidden
|
||||
- back to using packages or includes probably
|
||||
- Allow adding of font and icons easily
|
||||
|
||||
## Missing config
|
||||
- Scripts for updating displays (see scripts.yaml)
|
||||
- Draw routines (see config.yaml)
|
||||
- Event generation (triggers and stuff, see events.yaml)
|
||||
- configurable timing and button events
|
||||
- Always set display to left and right page
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## GPIO Pins
|
||||
|
||||
from enum import StrEnum
|
||||
|
||||
|
||||
GPIO_NEOPIXELS = "GPIO4" #Neopixel LED's
|
||||
GPIO_SPI_MOSI = "GPIO5" #SPI MOSI
|
||||
GPIO_SPI_CLK = "GPIO6" #SPI SCK
|
||||
@@ -10,3 +13,22 @@ GPIO_I2C_BUTTONS_SDA = "GPIO1" #I2C SDA > Buttons
|
||||
GPIO_I2C_BUTTONS_SCL = "GPIO2" #I2C SCL > Buttons
|
||||
GPIO_I2C_SENSORS_SDA = "GPIO47" #I2C SDA > Temperature & Ambient Sensor
|
||||
GPIO_I2C_SENSORS_SCL = "GPIO48" #I2S SCL > Temperature & Ambient Sensor
|
||||
|
||||
class BarSide(StrEnum):
|
||||
LEFT = "left"
|
||||
RIGHT = "right"
|
||||
|
||||
class ClickTypes(StrEnum):
|
||||
SINGLE = "single"
|
||||
DOUBLE = "double"
|
||||
TRIPLE = "triple"
|
||||
HOLD = "hold"
|
||||
|
||||
class YAMLExtend:
|
||||
def __init__(self, value): self.value = value
|
||||
|
||||
class YAMLLambda:
|
||||
def __init__(self, value): self.value = value
|
||||
|
||||
class YAMLSecret:
|
||||
def __init__(self, value): self.value = value
|
||||
@@ -10,26 +10,29 @@ from typing import Any, Dict, List
|
||||
|
||||
import yaml
|
||||
|
||||
from buttonplus_generator.constants import YAMLExtend, YAMLLambda, YAMLSecret
|
||||
from buttonplus_generator.snippets.common import config_common
|
||||
from buttonplus_generator.snippets.display import config_display
|
||||
from buttonplus_generator.merger import deep_merge
|
||||
from buttonplus_generator.snippets.bars import config_bars
|
||||
from buttonplus_generator.snippets.display import config_display
|
||||
#from buttonplus_generator.snippets.events import config_events
|
||||
from buttonplus_generator.merger import deep_merge
|
||||
|
||||
|
||||
def compose_config(device_name: str, version: int, num_bars: int, pages: List[str]) -> Dict[str, Any]:
|
||||
def compose_config(device_name: str, version: int, num_bars: int, pages: List[str], click_types: List[str]) -> Dict[str, Any]:
|
||||
config = config_common(device_name=device_name, version=version, page_names=pages, num_bars=num_bars)
|
||||
|
||||
if(num_bars < 4): # Always assume display if less than 4 bars
|
||||
config = deep_merge(config, config_display(version=version, num_bars=num_bars))
|
||||
config = deep_merge(config, config_display(version=version, num_bars=num_bars, page_names=pages))
|
||||
|
||||
config = deep_merge(config, config_bars(version=version, num_bars=num_bars))
|
||||
config = deep_merge(config, config_bars(version=version, num_bars=num_bars, page_names=pages))
|
||||
#config = deep_merge(config, config_events(version=version, num_bars=num_bars, page_names=pages, click_types=click_types))
|
||||
|
||||
return config
|
||||
|
||||
def yaml_dumper(config: Dict[str, Any], fh) -> str:
|
||||
|
||||
## Handle multiline strings
|
||||
def str_presenter(dumper, data):
|
||||
def represent_multistr(dumper, data):
|
||||
"""configures yaml for dumping multiline strings
|
||||
Ref: https://stackoverflow.com/questions/8640959/how-can-i-control-what-scalar-form-pyyaml-uses-for-my-data
|
||||
"""
|
||||
@@ -37,7 +40,20 @@ def yaml_dumper(config: Dict[str, Any], fh) -> str:
|
||||
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
|
||||
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
|
||||
|
||||
yaml.add_representer(str, str_presenter)
|
||||
def represent_extend(dumper, data):
|
||||
return dumper.represent_scalar('!extend', data.value)
|
||||
|
||||
def represent_lambda(dumper, data):
|
||||
return dumper.represent_scalar('!lambda', data.value, style='"')
|
||||
|
||||
def represent_secret(dumper, data):
|
||||
return dumper.represent_scalar('!secret', data.value, style="'")
|
||||
|
||||
yaml.add_representer(str, represent_multistr)
|
||||
yaml.add_representer(YAMLExtend, represent_extend)
|
||||
yaml.add_representer(YAMLLambda, represent_lambda)
|
||||
yaml.add_representer(YAMLSecret, represent_secret)
|
||||
|
||||
yaml.dump(config, fh, sort_keys=False, encoding="utf-8", default_flow_style=False)
|
||||
|
||||
def main(argv=None) -> int:
|
||||
@@ -47,8 +63,7 @@ def main(argv=None) -> int:
|
||||
)
|
||||
parser.add_argument(
|
||||
"--device-name",
|
||||
"--name",
|
||||
"-n",
|
||||
"-d",
|
||||
default="buttonplus",
|
||||
help="ESPHome device name",
|
||||
)
|
||||
@@ -59,7 +74,7 @@ def main(argv=None) -> int:
|
||||
choices=[1,2],
|
||||
required=True,
|
||||
help="The version of the display and bars. Only V2 PCB is supported.",
|
||||
metavar="VER"
|
||||
metavar="[1|2]"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--bars",
|
||||
@@ -77,6 +92,14 @@ def main(argv=None) -> int:
|
||||
help="List of page names",
|
||||
metavar="NAME"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--click-types",
|
||||
"-c",
|
||||
nargs="+",
|
||||
default=["single", "double", "triple", "hold"],
|
||||
help="List click types buttons, choices are [single|double|triple|hold].",
|
||||
metavar="TYPE"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output", "-o", default="buttonplus.yaml", help="Output file path"
|
||||
)
|
||||
@@ -86,9 +109,10 @@ def main(argv=None) -> int:
|
||||
version: int = args.version
|
||||
num_bars: int = args.bars
|
||||
pages: List[str] = args.pages
|
||||
click_types: List[str] = args.click_types
|
||||
output: str = args.output
|
||||
|
||||
config = compose_config(device_name, version, num_bars, pages)
|
||||
config = compose_config(device_name, version, num_bars, pages, click_types)
|
||||
with open(output, "w", encoding="utf-8") as fh:
|
||||
fh.writelines(
|
||||
[
|
||||
|
||||
@@ -2,18 +2,27 @@ from typing import Dict, Any, List
|
||||
from buttonplus_generator.constants import *
|
||||
from buttonplus_generator.merger import deep_merge
|
||||
|
||||
def config_bars(
|
||||
version: int, num_bars: int
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
def config_bars(version: int, num_bars: int, page_names: List[str]) -> Dict[str, Any]:
|
||||
config = bars_backlight()
|
||||
config = deep_merge(config, bars_setup(num_bars=num_bars))
|
||||
config = deep_merge(config, bars_buttons(num_bars=num_bars))
|
||||
config = deep_merge(config, bars_lights(num_bars=num_bars, display_has_leds=(version == 2 and num_bars < 4)))
|
||||
config = deep_merge(
|
||||
config,
|
||||
bars_lights(
|
||||
num_bars=num_bars, display_has_leds=(version == 2 and num_bars < 4)
|
||||
),
|
||||
)
|
||||
config = deep_merge(config, bars_display_output(num_bars=num_bars))
|
||||
config = deep_merge(config, bars_display())
|
||||
config = deep_merge(config, bars_scripts(num_bars=num_bars))
|
||||
config = deep_merge(
|
||||
config, bars_draw_scripts(num_bars=num_bars, page_names=page_names)
|
||||
)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def bars_backlight() -> Dict[str, Any]:
|
||||
return {
|
||||
"output": [
|
||||
@@ -55,8 +64,10 @@ def bars_setup(num_bars: int = 3) -> Dict[str, Any]:
|
||||
)
|
||||
|
||||
scripts.extend(
|
||||
[{"script.execute": "update_bar1_left"},
|
||||
{"script.execute": "update_bar1_right"}]
|
||||
[
|
||||
{"script.execute": "update_bar1_left"},
|
||||
{"script.execute": "update_bar1_right"},
|
||||
]
|
||||
)
|
||||
|
||||
# At least two bars, in bottom two slots
|
||||
@@ -66,8 +77,10 @@ def bars_setup(num_bars: int = 3) -> Dict[str, Any]:
|
||||
)
|
||||
|
||||
scripts.extend(
|
||||
[{"script.execute": "update_bar2_left"},
|
||||
{"script.execute": "update_bar2_right"}]
|
||||
[
|
||||
{"script.execute": "update_bar2_left"},
|
||||
{"script.execute": "update_bar2_right"},
|
||||
]
|
||||
)
|
||||
|
||||
# At least three bars, in bottom three slots
|
||||
@@ -77,8 +90,10 @@ def bars_setup(num_bars: int = 3) -> Dict[str, Any]:
|
||||
)
|
||||
|
||||
scripts.extend(
|
||||
[{"script.execute": "update_bar3_left"},
|
||||
{"script.execute": "update_bar3_right"}]
|
||||
[
|
||||
{"script.execute": "update_bar3_left"},
|
||||
{"script.execute": "update_bar3_right"},
|
||||
]
|
||||
)
|
||||
|
||||
# No display, only bars, also in top slot
|
||||
@@ -88,8 +103,10 @@ def bars_setup(num_bars: int = 3) -> Dict[str, Any]:
|
||||
)
|
||||
|
||||
scripts.extend(
|
||||
[{"script.execute": "update_bar4_left"},
|
||||
{"script.execute": "update_bar4_right"}]
|
||||
[
|
||||
{"script.execute": "update_bar4_left"},
|
||||
{"script.execute": "update_bar4_right"},
|
||||
]
|
||||
)
|
||||
|
||||
bar_dict["esphome"] = {"on_boot": {"then": scripts}}
|
||||
@@ -169,62 +186,40 @@ def bars_lights(num_bars: int, display_has_leds: bool = True) -> Dict[str, Any]:
|
||||
bar_dict["light"].extend(_bar_lights_entry(3, 8 + display_offset))
|
||||
|
||||
if num_bars > 3:
|
||||
bar_dict["light"].extend(_bar_lights_entry(4, 12)) # no display
|
||||
bar_dict["light"].extend(_bar_lights_entry(4, 12)) # no display
|
||||
|
||||
return bar_dict
|
||||
|
||||
|
||||
def _bar_lights_entry(bar_nr: int, offset: int) -> List[Dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Left RGB Front",
|
||||
"id": f"bar{bar_nr}_left_rgb_front",
|
||||
"segments": [
|
||||
{
|
||||
"id": "neopixels",
|
||||
"from": offset + 0,
|
||||
"to": offset + 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Left RGB Back",
|
||||
"id": f"bar{bar_nr}_left_rgb_back",
|
||||
"segments": [
|
||||
{
|
||||
"id": "neopixels",
|
||||
"from": offset + 1,
|
||||
"to": offset + 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Right RGB Front",
|
||||
"id": f"bar{bar_nr}_right_rgb_front",
|
||||
"segments": [
|
||||
{
|
||||
"id": "neopixels",
|
||||
"from": offset + 2,
|
||||
"to": offset + 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Right RGB Back",
|
||||
"id": f"bar{bar_nr}_right_rgb_back",
|
||||
"segments": [
|
||||
{
|
||||
"id": "neopixels",
|
||||
"from": offset + 3,
|
||||
"to": offset + 3
|
||||
}
|
||||
]
|
||||
},
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Left RGB Front",
|
||||
"id": f"bar{bar_nr}_left_rgb_front",
|
||||
"segments": [{"id": "neopixels", "from": offset + 0, "to": offset + 0}],
|
||||
},
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Left RGB Back",
|
||||
"id": f"bar{bar_nr}_left_rgb_back",
|
||||
"segments": [{"id": "neopixels", "from": offset + 1, "to": offset + 1}],
|
||||
},
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Right RGB Front",
|
||||
"id": f"bar{bar_nr}_right_rgb_front",
|
||||
"segments": [{"id": "neopixels", "from": offset + 2, "to": offset + 2}],
|
||||
},
|
||||
{
|
||||
"platform": "partition",
|
||||
"name": f"BAR {bar_nr} Right RGB Back",
|
||||
"id": f"bar{bar_nr}_right_rgb_back",
|
||||
"segments": [{"id": "neopixels", "from": offset + 3, "to": offset + 3}],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def bars_display_output(num_bars: int = 3) -> Dict[str, Any]:
|
||||
bar_dict = {"output": []}
|
||||
|
||||
@@ -260,9 +255,7 @@ def _bar_display_output_entry(bar_nr: int, base_id: str) -> List[Dict[str, Any]]
|
||||
"pin": {
|
||||
"mcp23xxx": base_id,
|
||||
"number": 5,
|
||||
"mode": {
|
||||
"output": True
|
||||
},
|
||||
"mode": {"output": True},
|
||||
"inverted": True,
|
||||
},
|
||||
},
|
||||
@@ -272,14 +265,13 @@ def _bar_display_output_entry(bar_nr: int, base_id: str) -> List[Dict[str, Any]]
|
||||
"pin": {
|
||||
"mcp23xxx": base_id,
|
||||
"number": 1,
|
||||
"mode": {
|
||||
"output": True
|
||||
},
|
||||
"mode": {"output": True},
|
||||
"inverted": True,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def bars_display() -> Dict[str, Any]:
|
||||
return {
|
||||
"display": [
|
||||
@@ -289,18 +281,168 @@ def bars_display() -> Dict[str, Any]:
|
||||
"model": "ST7735",
|
||||
"color_order": "bgr",
|
||||
"update_interval": "never",
|
||||
"dc_pin": {
|
||||
"number": GPIO_SPI_REG,
|
||||
"allow_other_uses": True
|
||||
},
|
||||
"dc_pin": {"number": GPIO_SPI_REG, "allow_other_uses": True},
|
||||
"invert_colors": False,
|
||||
"show_test_card": False,
|
||||
"auto_clear_enabled": False,
|
||||
"dimensions": {
|
||||
"height": 160,
|
||||
"width": 80,
|
||||
"offset_width": 24
|
||||
}
|
||||
"dimensions": {"height": 160, "width": 80, "offset_width": 24},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def bars_scripts(num_bars: int) -> Dict[str, Any]:
|
||||
bar_dict = {"script": []}
|
||||
|
||||
if num_bars < 1:
|
||||
raise ValueError("At least one bar must be connected!")
|
||||
|
||||
setup_cpp = ""
|
||||
|
||||
if num_bars > 0:
|
||||
bar_dict["script"].append(_bars_script_update_entry(1, BarSide.LEFT, num_bars))
|
||||
bar_dict["script"].append(_bars_script_update_entry(1, BarSide.RIGHT, num_bars))
|
||||
|
||||
setup_cpp += _bars_script_setup_entry(1, BarSide.LEFT)
|
||||
setup_cpp += _bars_script_setup_entry(1, BarSide.RIGHT)
|
||||
|
||||
if num_bars > 1:
|
||||
bar_dict["script"].append(_bars_script_update_entry(2, BarSide.LEFT, num_bars))
|
||||
bar_dict["script"].append(_bars_script_update_entry(2, BarSide.RIGHT, num_bars))
|
||||
|
||||
setup_cpp += _bars_script_setup_entry(2, BarSide.LEFT)
|
||||
setup_cpp += _bars_script_setup_entry(2, BarSide.RIGHT)
|
||||
|
||||
if num_bars > 2:
|
||||
bar_dict["script"].append(_bars_script_update_entry(3, BarSide.LEFT, num_bars))
|
||||
bar_dict["script"].append(_bars_script_update_entry(3, BarSide.RIGHT, num_bars))
|
||||
|
||||
setup_cpp += _bars_script_setup_entry(3, BarSide.LEFT)
|
||||
setup_cpp += _bars_script_setup_entry(3, BarSide.RIGHT)
|
||||
|
||||
if num_bars > 3:
|
||||
bar_dict["script"].append(_bars_script_update_entry(4, BarSide.LEFT, num_bars))
|
||||
bar_dict["script"].append(_bars_script_update_entry(4, BarSide.RIGHT, num_bars))
|
||||
|
||||
setup_cpp += _bars_script_setup_entry(4, BarSide.LEFT)
|
||||
setup_cpp += _bars_script_setup_entry(4, BarSide.RIGHT)
|
||||
|
||||
bar_dict["script"].append(
|
||||
{"id": "setup_bar_displays", "then": [{"lambda": setup_cpp}]}
|
||||
)
|
||||
|
||||
return bar_dict
|
||||
|
||||
|
||||
def _bars_script_update_entry(
|
||||
bar_nr: int, bar_side: BarSide, num_bars: int
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
# Generate all possible bars
|
||||
bars_ids = [
|
||||
f"cs_pin_bar{nr}_{side}"
|
||||
for nr in range(1, num_bars + 1)
|
||||
for side in [BarSide.LEFT, BarSide.RIGHT]
|
||||
]
|
||||
bars_state = [
|
||||
"on" if (nr is bar_nr and side is bar_side) else "off"
|
||||
for nr in range(1, num_bars + 1)
|
||||
for side in [BarSide.LEFT, BarSide.RIGHT]
|
||||
]
|
||||
|
||||
generated_cpp = ""
|
||||
|
||||
for bar, state in zip(bars_ids, bars_state):
|
||||
generated_cpp += f"id({bar}).turn_{state}();\n"
|
||||
|
||||
rotation = "90" if bar_side is BarSide.RIGHT else "270"
|
||||
|
||||
generated_cpp += (
|
||||
"id(bar_display).clear();\n"
|
||||
f"id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_{rotation}_DEGREES);\n"
|
||||
f"id(bar{bar_nr}_{bar_side}_draw).execute();\n"
|
||||
"id(bar_display).update();\n"
|
||||
"delay(1);\n"
|
||||
f"id(cs_pin_bar{bar_nr}_{bar_side}).turn_off();"
|
||||
)
|
||||
|
||||
return {"id": f"update_bar{bar_nr}_{bar_side}", "then": [{"lambda": generated_cpp}]}
|
||||
|
||||
|
||||
def _bars_script_setup_entry(bar_nr: int, bar_side: BarSide) -> str:
|
||||
return (
|
||||
f"id(cs_pin_bar{bar_nr}_{bar_side}).turn_on();\n"
|
||||
"id(bar_display).setup();\n"
|
||||
"delay(5);\n"
|
||||
f"id(cs_pin_bar{bar_nr}_{bar_side}).turn_off();\n"
|
||||
)
|
||||
|
||||
|
||||
def bars_draw_scripts(num_bars: int, page_names: List[str]) -> Dict[str, Any]:
|
||||
bar_dict = {"script": []}
|
||||
|
||||
if num_bars < 1:
|
||||
raise ValueError("At least one bar must be connected!")
|
||||
|
||||
update_list = []
|
||||
|
||||
if num_bars > 0:
|
||||
bar_dict["script"].append(_bars_script_draw_entry(1, BarSide.LEFT, page_names))
|
||||
bar_dict["script"].append(_bars_script_draw_entry(1, BarSide.RIGHT, page_names))
|
||||
|
||||
update_list.extend(_bars_script_execute_entry(1, BarSide.LEFT))
|
||||
update_list.extend(_bars_script_execute_entry(1, BarSide.RIGHT))
|
||||
|
||||
if num_bars > 1:
|
||||
bar_dict["script"].append(_bars_script_draw_entry(2, BarSide.LEFT, page_names))
|
||||
bar_dict["script"].append(_bars_script_draw_entry(2, BarSide.RIGHT, page_names))
|
||||
|
||||
update_list.extend(_bars_script_execute_entry(2, BarSide.LEFT))
|
||||
update_list.extend(_bars_script_execute_entry(2, BarSide.RIGHT))
|
||||
|
||||
if num_bars > 2:
|
||||
bar_dict["script"].append(_bars_script_draw_entry(3, BarSide.LEFT, page_names))
|
||||
bar_dict["script"].append(_bars_script_draw_entry(3, BarSide.RIGHT, page_names))
|
||||
|
||||
update_list.extend(_bars_script_execute_entry(3, BarSide.LEFT))
|
||||
update_list.extend(_bars_script_execute_entry(3, BarSide.RIGHT))
|
||||
|
||||
if num_bars > 3:
|
||||
bar_dict["script"].append(_bars_script_draw_entry(4, BarSide.LEFT, page_names))
|
||||
bar_dict["script"].append(_bars_script_draw_entry(4, BarSide.RIGHT, page_names))
|
||||
|
||||
update_list.extend(_bars_script_execute_entry(3, BarSide.LEFT))
|
||||
update_list.extend(_bars_script_execute_entry(3, BarSide.RIGHT))
|
||||
|
||||
bar_dict["script"].append({"id": "update_bars", "then": update_list[:-1]})
|
||||
|
||||
return bar_dict
|
||||
|
||||
|
||||
def _bars_script_draw_entry(
|
||||
bar_nr: int, bar_side: BarSide, page_names: List[str]
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
generated_cpp = "switch (id(active_page_nr)){\n"
|
||||
|
||||
for page_num in range(0, len(page_names)):
|
||||
generated_cpp += (
|
||||
f" // Page {page_num} - {page_names[page_num]}\n"
|
||||
f" case {page_num}:\n"
|
||||
f' id(bar_display).printf(80, 0, id(font_arial20), id(accent), TextAlign::TOP_CENTER , "Bar {bar_nr} {bar_side}");\n'
|
||||
f' id(bar_display).printf(80, 80, id(font_arial20), id(white), TextAlign::BOTTOM_CENTER , "Page {page_num}");\n'
|
||||
f" break;\n"
|
||||
)
|
||||
|
||||
generated_cpp += "}\n"
|
||||
|
||||
return {"id": f"bar{bar_nr}_{bar_side}_draw", "then": [{"lambda": generated_cpp}]}
|
||||
|
||||
|
||||
def _bars_script_execute_entry(bar_nr: int, bar_side: BarSide) -> List[Dict[str, str]]:
|
||||
return [
|
||||
{
|
||||
"script.execute": f"update_bar{bar_nr}_{bar_side}",
|
||||
},
|
||||
{"delay": "0.1s"},
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@ def config_common(
|
||||
config = deep_merge(config, i2c())
|
||||
config = deep_merge(config, spi())
|
||||
config = deep_merge(
|
||||
config, sensors(ambient_gain="auto", extra_ambient_sensors=False)
|
||||
config, sensors(ambient_gain="96x", extra_ambient_sensors=False)
|
||||
)
|
||||
|
||||
num_leds = 0
|
||||
@@ -32,6 +32,7 @@ def config_common(
|
||||
num_leds = 17 #no display
|
||||
|
||||
config = deep_merge(config, neopixels(num_leds=num_leds))
|
||||
config = deep_merge(config, update_scripts(num_bars=num_bars))
|
||||
|
||||
return config
|
||||
|
||||
@@ -54,12 +55,12 @@ def base_config(device_name: str) -> Dict[str, Any]:
|
||||
},
|
||||
"psram": {"mode": "octal", "speed": "80MHz"},
|
||||
"wifi": {
|
||||
"ssid": "!secret wifi_ssid",
|
||||
"password": "!secret wifi_password",
|
||||
"ssid": YAMLSecret("wifi_ssid"),
|
||||
"password": YAMLSecret("wifi_password"),
|
||||
},
|
||||
"logger": {"level": "DEBUG"},
|
||||
"api": {"encryption": {"key": "!secret encryption_key"}},
|
||||
"ota": [{"platform": "esphome", "password": "!secret ota_password"}],
|
||||
"api": {"encryption": {"key": YAMLSecret("encryption_key")}},
|
||||
"ota": [{"platform": "esphome", "password": YAMLSecret("ota_password")}],
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +102,7 @@ def pages(nr_of_pages: int, page_names: List[str]) -> Dict[str, Any]:
|
||||
{"id": "active_page_nr", "type": "int", "initial_value": "0"},
|
||||
{"id": "active_page_name", "type": "std::string", "initial_value": ""},
|
||||
],
|
||||
"sensors": [
|
||||
"sensor": [
|
||||
{
|
||||
"platform": "template",
|
||||
"name": "Active Page Number",
|
||||
@@ -170,14 +171,14 @@ def pages(nr_of_pages: int, page_names: List[str]) -> Dict[str, Any]:
|
||||
},
|
||||
{
|
||||
"sensor.template.publish": {
|
||||
"id": "active_page_id_ha",
|
||||
"state": "return id(active_page_nr);",
|
||||
"id": "active_page_nr_ha",
|
||||
"state": YAMLLambda("return id(active_page_nr);"),
|
||||
}
|
||||
},
|
||||
{
|
||||
"text_sensor.template.publish": {
|
||||
"id": "active_page_name_ha",
|
||||
"state": "return id(active_page_name);",
|
||||
"state": YAMLLambda("return id(active_page_name);"),
|
||||
}
|
||||
},
|
||||
{"script.execute": "update_all"},
|
||||
@@ -189,7 +190,7 @@ def pages(nr_of_pages: int, page_names: List[str]) -> Dict[str, Any]:
|
||||
{
|
||||
"number.set": {
|
||||
"id": "pageselector",
|
||||
"value": "return id(active_page_nr);",
|
||||
"value": YAMLLambda("return id(active_page_nr);"),
|
||||
}
|
||||
},
|
||||
{"script.execute": "set_page"},
|
||||
@@ -325,3 +326,25 @@ def sensors(ambient_gain: str, extra_ambient_sensors: bool) -> Dict[str, Any]:
|
||||
}
|
||||
|
||||
return sensors_dict
|
||||
|
||||
def update_scripts(num_bars: int) -> Dict[str, Any]:
|
||||
common_dict = {"script": []}
|
||||
|
||||
update_list = [
|
||||
{
|
||||
"script.execute": "update_bars",
|
||||
},
|
||||
{"delay": "0.1s"},
|
||||
]
|
||||
|
||||
if num_bars < 4:
|
||||
update_list.extend([
|
||||
{
|
||||
"script.execute": "update_main",
|
||||
},
|
||||
{"delay": "0.1s"},
|
||||
])
|
||||
|
||||
common_dict["script"].append({"id": "update_all", "then": update_list[:-1]})
|
||||
|
||||
return common_dict
|
||||
@@ -1,15 +1,17 @@
|
||||
from typing import Dict, Any
|
||||
from typing import Dict, Any, List
|
||||
from buttonplus_generator.constants import *
|
||||
from buttonplus_generator.utils import get_display_id, get_display_address
|
||||
from buttonplus_generator.merger import deep_merge
|
||||
|
||||
def config_display(
|
||||
version: int, num_bars: int
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
def config_display(version: int, num_bars: int, page_names: List[str]) -> Dict[str, Any]:
|
||||
config = display_backlight(num_bars=num_bars)
|
||||
config = deep_merge(config, display_setup(num_bars=num_bars))
|
||||
config = deep_merge(config, display_buttons(num_bars=num_bars))
|
||||
config = deep_merge(config, display_lights(num_bars=num_bars, display_has_leds=(version == 2)))
|
||||
config = deep_merge(
|
||||
config, display_lights(num_bars=num_bars, display_has_leds=(version == 2))
|
||||
)
|
||||
config = deep_merge(config, update_scripts(page_names=page_names))
|
||||
|
||||
return config
|
||||
|
||||
@@ -44,24 +46,17 @@ def display_backlight(num_bars: int) -> Dict[str, Any]:
|
||||
"invert_colors": False,
|
||||
"color_order": "rgb",
|
||||
"update_interval": "30s",
|
||||
"dc_pin": {
|
||||
"number": GPIO_SPI_REG,
|
||||
"allow_other_uses": True
|
||||
},
|
||||
"dc_pin": {"number": GPIO_SPI_REG, "allow_other_uses": True},
|
||||
"cs_pin": {
|
||||
"mcp23xxx": get_display_id(num_bars),
|
||||
"number": 5,
|
||||
"mode": {
|
||||
"output": True
|
||||
},
|
||||
"inverted": False
|
||||
"mode": {"output": True},
|
||||
"inverted": False,
|
||||
},
|
||||
"show_test_card": False,
|
||||
"dimensions": {
|
||||
"height": 240,
|
||||
"width": 320
|
||||
},
|
||||
"rotation": 180
|
||||
"dimensions": {"height": 240, "width": 320},
|
||||
"rotation": 180,
|
||||
"lambda": "id(main_draw).execute();"
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -150,3 +145,50 @@ def display_lights(num_bars: int, display_has_leds: bool = True) -> Dict[str, An
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def update_scripts(page_names: List[str]) -> Dict[str, Any]:
|
||||
display_dict = {"script": []}
|
||||
|
||||
display_dict["script"].append(
|
||||
{
|
||||
"id": "update_main",
|
||||
"then": [
|
||||
{
|
||||
"component.update": "main_display",
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
generated_cpp = (
|
||||
"// All pages\n"
|
||||
"id(main_display).image(0, 235, id(icon_prev_page), ImageAlign::BOTTOM_LEFT, id(grey));\n"
|
||||
"id(main_display).image(320, 235, id(icon_next_page), ImageAlign::BOTTOM_RIGHT, id(grey));\n"
|
||||
"\n"
|
||||
"id(main_display).strftime(160, 5, id(font_arial20), TextAlign::TOP_CENTER, \"%H:%M\", id(datetime).now());\n"
|
||||
"id(main_display).strftime(160, 80, id(font_arial20), TextAlign::TOP_CENTER, \"%d-%m-%Y\", id(datetime).now());\n"
|
||||
"\n"
|
||||
"switch (id(active_page_nr)){\n"
|
||||
)
|
||||
|
||||
for page_num in range(0, len(page_names)):
|
||||
generated_cpp += (
|
||||
f" // Page {page_num} - {page_names[page_num]}\n"
|
||||
f" case {page_num}:\n"
|
||||
f" id(main_display).print(160, 235, id(font_arial20), id(white), TextAlign::BOTTOM_CENTER, id(active_page_name).c_str());\n"
|
||||
f" break;\n"
|
||||
)
|
||||
|
||||
generated_cpp += "}\n"
|
||||
|
||||
display_dict["script"].append(
|
||||
{
|
||||
"id": "main_draw",
|
||||
"then": [
|
||||
{"lambda": generated_cpp}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
return display_dict
|
||||
|
||||
Reference in New Issue
Block a user