1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-01 19:02:18 +01:00

Merge remote-tracking branch 'upstream/proxy_configured_mode' into integration

This commit is contained in:
J. Nick Koston
2025-08-29 10:48:51 -05:00
29 changed files with 358 additions and 160 deletions

View File

@@ -11,7 +11,7 @@ ci:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.10
rev: v0.12.11
hooks:
# Run the linter.
- id: ruff

View File

@@ -61,11 +61,10 @@ void AbsoluteHumidityComponent::loop() {
ESP_LOGW(TAG, "No valid state from temperature sensor!");
}
if (no_humidity) {
ESP_LOGW(TAG, "No valid state from temperature sensor!");
ESP_LOGW(TAG, "No valid state from humidity sensor!");
}
ESP_LOGW(TAG, "Unable to calculate absolute humidity.");
this->publish_state(NAN);
this->status_set_warning();
this->status_set_warning("Unable to calculate absolute humidity.");
return;
}
@@ -87,9 +86,8 @@ void AbsoluteHumidityComponent::loop() {
es = es_wobus(temperature_c);
break;
default:
ESP_LOGE(TAG, "Invalid saturation vapor pressure equation selection!");
this->publish_state(NAN);
this->status_set_error();
this->status_set_error("Invalid saturation vapor pressure equation selection!");
return;
}
ESP_LOGD(TAG, "Saturation vapor pressure %f kPa", es);

View File

@@ -1712,6 +1712,7 @@ message BluetoothScannerStateResponse {
BluetoothScannerState state = 1;
BluetoothScannerMode mode = 2;
BluetoothScannerMode configured_mode = 3;
}
message BluetoothScannerSetModeRequest {

View File

@@ -2153,10 +2153,12 @@ void BluetoothDeviceClearCacheResponse::calculate_size(ProtoSize &size) const {
void BluetoothScannerStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, static_cast<uint32_t>(this->state));
buffer.encode_uint32(2, static_cast<uint32_t>(this->mode));
buffer.encode_uint32(3, static_cast<uint32_t>(this->configured_mode));
}
void BluetoothScannerStateResponse::calculate_size(ProtoSize &size) const {
size.add_uint32(1, static_cast<uint32_t>(this->state));
size.add_uint32(1, static_cast<uint32_t>(this->mode));
size.add_uint32(1, static_cast<uint32_t>(this->configured_mode));
}
bool BluetoothScannerSetModeRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {

View File

@@ -2214,12 +2214,13 @@ class BluetoothDeviceClearCacheResponse final : public ProtoMessage {
class BluetoothScannerStateResponse final : public ProtoMessage {
public:
static constexpr uint8_t MESSAGE_TYPE = 126;
static constexpr uint8_t ESTIMATED_SIZE = 4;
static constexpr uint8_t ESTIMATED_SIZE = 6;
#ifdef HAS_PROTO_MESSAGE_DUMP
const char *message_name() const override { return "bluetooth_scanner_state_response"; }
#endif
enums::BluetoothScannerState state{};
enums::BluetoothScannerMode mode{};
enums::BluetoothScannerMode configured_mode{};
void encode(ProtoWriteBuffer buffer) const override;
void calculate_size(ProtoSize &size) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP

View File

@@ -1704,6 +1704,7 @@ void BluetoothScannerStateResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothScannerStateResponse");
dump_field(out, "state", static_cast<enums::BluetoothScannerState>(this->state));
dump_field(out, "mode", static_cast<enums::BluetoothScannerMode>(this->mode));
dump_field(out, "configured_mode", static_cast<enums::BluetoothScannerMode>(this->configured_mode));
}
void BluetoothScannerSetModeRequest::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "BluetoothScannerSetModeRequest");

View File

@@ -24,6 +24,9 @@ void BluetoothProxy::setup() {
this->connections_free_response_.limit = BLUETOOTH_PROXY_MAX_CONNECTIONS;
this->connections_free_response_.free = BLUETOOTH_PROXY_MAX_CONNECTIONS;
// Capture the configured scan mode from YAML before any API changes
this->configured_scan_active_ = this->parent_->get_scan_active();
this->parent_->add_scanner_state_callback([this](esp32_ble_tracker::ScannerState state) {
if (this->api_connection_ != nullptr) {
this->send_bluetooth_scanner_state_(state);
@@ -36,6 +39,9 @@ void BluetoothProxy::send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerSta
resp.state = static_cast<api::enums::BluetoothScannerState>(state);
resp.mode = this->parent_->get_scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
resp.configured_mode = this->configured_scan_active_
? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
this->api_connection_->send_message(resp, api::BluetoothScannerStateResponse::MESSAGE_TYPE);
}

View File

@@ -161,7 +161,8 @@ class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener, publ
// Group 4: 1-byte types grouped together
bool active_;
uint8_t connection_count_{0};
// 2 bytes used, 2 bytes padding
bool configured_scan_active_{false}; // Configured scan mode from YAML
// 3 bytes used, 1 byte padding
};
extern BluetoothProxy *global_bluetooth_proxy; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)

View File

@@ -451,6 +451,7 @@ CONF_GRID_ROWS = "grid_rows"
CONF_HEADER_MODE = "header_mode"
CONF_HOME = "home"
CONF_INITIAL_FOCUS = "initial_focus"
CONF_SELECTED_DIGIT = "selected_digit"
CONF_KEY_CODE = "key_code"
CONF_KEYPADS = "keypads"
CONF_LAYOUT = "layout"

View File

@@ -4,49 +4,112 @@ from esphome.yaml_util import parse_yaml
CONFIG = """
- obj:
radius: 0
id: hello_world_card_
pad_all: 12
bg_color: 0xFFFFFF
bg_color: white
height: 100%
width: 100%
scrollable: false
widgets:
- spinner:
id: hello_world_spinner_
align: center
indicator:
arc_color: tomato
height: 100
width: 100
spin_time: 2s
arc_length: 60deg
- label:
id: hello_world_label_
text: "Hello World!"
- obj:
align: top_mid
outline_width: 0
border_width: 0
pad_all: 4
scrollable: false
height: size_content
width: 100%
layout:
type: flex
flex_flow: row
flex_align_cross: center
flex_align_track: start
flex_align_main: space_between
widgets:
- button:
checkable: true
radius: 4
text_font: montserrat_20
on_click:
lvgl.label.update:
id: hello_world_label_
text: "Clicked!"
widgets:
- label:
text: "Button"
- label:
id: hello_world_title_
text: ESPHome
text_font: montserrat_20
width: 100%
text_align: center
on_boot:
lvgl.widget.refresh: hello_world_title_
hidden: !lambda |-
return lv_obj_get_width(lv_scr_act()) < 400;
- checkbox:
text: Checkbox
id: hello_world_checkbox_
on_boot:
lvgl.widget.refresh: hello_world_checkbox_
hidden: !lambda |-
return lv_obj_get_width(lv_scr_act()) < 240;
on_click:
lvgl.label.update:
id: hello_world_label_
text: "Checked!"
- obj:
id: hello_world_container_
align: center
y: 14
pad_all: 0
outline_width: 0
border_width: 0
width: 100%
height: size_content
scrollable: false
on_click:
lvgl.spinner.update:
id: hello_world_spinner_
arc_color: springgreen
- checkbox:
pad_all: 8
text: Checkbox
align: top_right
on_click:
lvgl.label.update:
id: hello_world_label_
text: "Checked!"
- button:
pad_all: 8
checkable: true
align: top_left
text_font: montserrat_20
on_click:
lvgl.label.update:
id: hello_world_label_
text: "Clicked!"
layout:
type: flex
flex_flow: row_wrap
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- label:
text: "Button"
- spinner:
id: hello_world_spinner_
indicator:
arc_color: tomato
height: 100
width: 100
spin_time: 2s
arc_length: 60deg
widgets:
- label:
id: hello_world_label_
text: "Hello World!"
align: center
- obj:
id: hello_world_qrcode_
outline_width: 0
border_width: 0
hidden: !lambda |-
return lv_obj_get_width(lv_scr_act()) < 300 && lv_obj_get_height(lv_scr_act()) < 400;
widgets:
- label:
text_font: montserrat_14
text: esphome.io
align: top_mid
- qrcode:
text: "https://esphome.io"
size: 80
align: bottom_mid
on_boot:
lvgl.widget.refresh: hello_world_qrcode_
- slider:
width: 80%
align: bottom_mid

View File

@@ -67,7 +67,6 @@ class Widget:
self.type = wtype
self.config = config
self.scale = 1.0
self.step = 1.0
self.range_from = -sys.maxsize
self.range_to = sys.maxsize
if wtype.is_compound():

View File

@@ -11,6 +11,7 @@ from ..defines import (
CONF_ROLLOVER,
CONF_SCROLLBAR,
CONF_SELECTED,
CONF_SELECTED_DIGIT,
CONF_TEXTAREA_PLACEHOLDER,
)
from ..lv_validation import lv_bool, lv_float
@@ -38,18 +39,24 @@ def validate_spinbox(config):
min_val = -1 - max_val
range_from = int(config[CONF_RANGE_FROM])
range_to = int(config[CONF_RANGE_TO])
step = int(config[CONF_STEP])
step = config[CONF_SELECTED_DIGIT]
digits = config[CONF_DIGITS]
if (
range_from > max_val
or range_from < min_val
or range_to > max_val
or range_to < min_val
):
raise cv.Invalid("Range outside allowed limits")
if step <= 0 or step >= (range_to - range_from) / 2:
raise cv.Invalid("Invalid step value")
if config[CONF_DIGITS] <= config[CONF_DECIMAL_PLACES]:
raise cv.Invalid("Number of digits must exceed number of decimal places")
raise cv.Invalid("Range outside allowed limits", path=[CONF_RANGE_FROM])
if digits <= config[CONF_DECIMAL_PLACES]:
raise cv.Invalid(
"Number of digits must exceed number of decimal places", path=[CONF_DIGITS]
)
if step >= digits:
raise cv.Invalid(
"Initial selected digit must be less than number of digits",
path=[CONF_SELECTED_DIGIT],
)
return config
@@ -59,7 +66,10 @@ SPINBOX_SCHEMA = cv.Schema(
cv.Optional(CONF_RANGE_FROM, default=0): cv.float_,
cv.Optional(CONF_RANGE_TO, default=100): cv.float_,
cv.Optional(CONF_DIGITS, default=4): cv.int_range(1, 10),
cv.Optional(CONF_STEP, default=1.0): cv.positive_float,
cv.Optional(CONF_STEP): cv.invalid(
f"{CONF_STEP} has been replaced by {CONF_SELECTED_DIGIT}"
),
cv.Optional(CONF_SELECTED_DIGIT, default=0): cv.positive_int,
cv.Optional(CONF_DECIMAL_PLACES, default=0): cv.int_range(0, 6),
cv.Optional(CONF_ROLLOVER, default=False): lv_bool,
}
@@ -93,13 +103,12 @@ class SpinboxType(WidgetType):
scale = 10 ** config[CONF_DECIMAL_PLACES]
range_from = int(config[CONF_RANGE_FROM]) * scale
range_to = int(config[CONF_RANGE_TO]) * scale
step = int(config[CONF_STEP]) * scale
step = config[CONF_SELECTED_DIGIT]
w.scale = scale
w.step = step
w.range_to = range_to
w.range_from = range_from
lv.spinbox_set_range(w.obj, range_from, range_to)
await w.set_property(CONF_STEP, step)
await w.set_property("step", 10**step)
await w.set_property(CONF_ROLLOVER, config)
lv.spinbox_set_digit_format(
w.obj, digits, digits - config[CONF_DECIMAL_PLACES]
@@ -120,7 +129,7 @@ class SpinboxType(WidgetType):
return config[CONF_RANGE_FROM]
def get_step(self, config: dict):
return config[CONF_STEP]
return 10 ** config[CONF_SELECTED_DIGIT]
spinbox_spec = SpinboxType()

View File

@@ -10,7 +10,8 @@ from esphome.loader import get_component
CODEOWNERS = ["@clydebarrow"]
MULTI_CONF = True
map_ = cg.std_ns.class_("map")
mapping_ns = cg.esphome_ns.namespace("mapping")
mapping_class = mapping_ns.class_("Mapping")
CONF_ENTRIES = "entries"
CONF_CLASS = "class"
@@ -29,7 +30,11 @@ class IndexType:
INDEX_TYPES = {
"int": IndexType(cv.int_, cg.int_, int),
"string": IndexType(cv.string, cg.std_string, str),
"string": IndexType(
cv.string,
cg.std_string,
str,
),
}
@@ -47,7 +52,7 @@ def to_schema(value):
BASE_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.declare_id(map_),
cv.Required(CONF_ID): cv.declare_id(mapping_class),
cv.Required(CONF_FROM): cv.one_of(*INDEX_TYPES, lower=True),
cv.Required(CONF_TO): cv.string,
},
@@ -123,12 +128,15 @@ async def to_code(config):
if list(entries.values())[0].op != ".":
value_type = value_type.operator("ptr")
varid = config[CONF_ID]
varid.type = map_.template(index_type, value_type)
varid.type = mapping_class.template(
index_type,
value_type,
)
var = MockObj(varid, ".")
decl = VariableDeclarationExpression(varid.type, "", varid)
add_global(decl)
CORE.register_variable(varid, var)
for key, value in entries.items():
cg.add(var.insert((key, value)))
cg.add(var.set(key, value))
return var

View File

@@ -0,0 +1,69 @@
#pragma once
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include <map>
#include <string>
namespace esphome::mapping {
using alloc_string_t = std::basic_string<char, std::char_traits<char>, RAMAllocator<char>>;
/**
*
* Mapping class with custom allocator.
* Additionally, when std::string is used as key or value, it will be replaced with a custom string type
* that uses RAMAllocator.
* @tparam K The type of the key in the mapping.
* @tparam V The type of the value in the mapping. Should be a basic type or pointer.
*/
static const char *const TAG = "mapping";
template<typename K, typename V> class Mapping {
public:
// Constructor
Mapping() = default;
using key_t = const std::conditional_t<std::is_same_v<K, std::string>,
alloc_string_t, // if K is std::string, custom string type
K>;
using value_t = std::conditional_t<std::is_same_v<V, std::string>,
alloc_string_t, // if V is std::string, custom string type
V>;
void set(const K &key, const V &value) { this->map_[key_t{key}] = value; }
V get(const K &key) const {
auto it = this->map_.find(key_t{key});
if (it != this->map_.end()) {
return V{it->second};
}
if constexpr (std::is_pointer_v<K>) {
esph_log_e(TAG, "Key '%p' not found in mapping", key);
} else if constexpr (std::is_same_v<K, std::string>) {
esph_log_e(TAG, "Key '%s' not found in mapping", key.c_str());
} else {
esph_log_e(TAG, "Key '%s' not found in mapping", to_string(key).c_str());
}
return {};
}
// index map overload
V operator[](K key) { return this->get(key); }
// convenience function for strings to get a C-style string
template<typename T = V, std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
const char *operator[](K key) const {
auto it = this->map_.find(key_t{key});
if (it != this->map_.end()) {
return it->second.c_str(); // safe since value remains in map
}
return "";
}
protected:
std::map<key_t, value_t, std::less<key_t>, RAMAllocator<std::pair<key_t, value_t>>> map_;
};
} // namespace esphome::mapping

View File

@@ -198,7 +198,7 @@ uint16_t Mcp4461Component::get_wiper_level_(Mcp4461WiperIdx wiper) {
uint16_t Mcp4461Component::read_wiper_level_(uint8_t wiper_idx) {
uint8_t addr = this->get_wiper_address_(wiper_idx);
uint8_t reg = addr | static_cast<uint8_t>(Mcp4461Commands::INCREMENT);
uint8_t reg = addr | static_cast<uint8_t>(Mcp4461Commands::READ);
if (wiper_idx > 3) {
if (!this->is_eeprom_ready_for_writing_(true)) {
return 0;

View File

@@ -65,26 +65,47 @@ ACCELERATION_MODES = {
"high": RhtAccelerationMode.HIGH_ACCELERATION,
}
GAS_SENSOR = cv.Schema(
{
cv.Optional(CONF_ALGORITHM_TUNING): cv.Schema(
{
cv.Optional(CONF_INDEX_OFFSET, default=100): cv.int_range(1, 250),
cv.Optional(CONF_LEARNING_TIME_OFFSET_HOURS, default=12): cv.int_range(
1, 1000
),
cv.Optional(CONF_LEARNING_TIME_GAIN_HOURS, default=12): cv.int_range(
1, 1000
),
cv.Optional(
CONF_GATING_MAX_DURATION_MINUTES, default=720
): cv.int_range(0, 3000),
cv.Optional(CONF_STD_INITIAL, default=50): cv.int_,
cv.Optional(CONF_GAIN_FACTOR, default=230): cv.int_range(1, 1000),
}
)
}
)
def _gas_sensor(
*,
index_offset: int,
learning_time_offset: int,
learning_time_gain: int,
gating_max_duration: int,
std_initial: int,
gain_factor: int,
) -> cv.Schema:
return sensor.sensor_schema(
icon=ICON_RADIATOR,
accuracy_decimals=0,
device_class=DEVICE_CLASS_AQI,
state_class=STATE_CLASS_MEASUREMENT,
).extend(
{
cv.Optional(CONF_ALGORITHM_TUNING): cv.Schema(
{
cv.Optional(CONF_INDEX_OFFSET, default=index_offset): cv.int_range(
1, 250
),
cv.Optional(
CONF_LEARNING_TIME_OFFSET_HOURS, default=learning_time_offset
): cv.int_range(1, 1000),
cv.Optional(
CONF_LEARNING_TIME_GAIN_HOURS, default=learning_time_gain
): cv.int_range(1, 1000),
cv.Optional(
CONF_GATING_MAX_DURATION_MINUTES, default=gating_max_duration
): cv.int_range(0, 3000),
cv.Optional(CONF_STD_INITIAL, default=std_initial): cv.int_range(
10, 5000
),
cv.Optional(CONF_GAIN_FACTOR, default=gain_factor): cv.int_range(
1, 1000
),
}
)
}
)
def float_previously_pct(value):
@@ -127,18 +148,22 @@ CONFIG_SCHEMA = (
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_AUTO_CLEANING_INTERVAL): cv.update_interval,
cv.Optional(CONF_VOC): sensor.sensor_schema(
icon=ICON_RADIATOR,
accuracy_decimals=0,
device_class=DEVICE_CLASS_AQI,
state_class=STATE_CLASS_MEASUREMENT,
).extend(GAS_SENSOR),
cv.Optional(CONF_NOX): sensor.sensor_schema(
icon=ICON_RADIATOR,
accuracy_decimals=0,
device_class=DEVICE_CLASS_AQI,
state_class=STATE_CLASS_MEASUREMENT,
).extend(GAS_SENSOR),
cv.Optional(CONF_VOC): _gas_sensor(
index_offset=100,
learning_time_offset=12,
learning_time_gain=12,
gating_max_duration=180,
std_initial=50,
gain_factor=230,
),
cv.Optional(CONF_NOX): _gas_sensor(
index_offset=1,
learning_time_offset=12,
learning_time_gain=12,
gating_max_duration=720,
std_initial=50,
gain_factor=230,
),
cv.Optional(CONF_STORE_BASELINE, default=True): cv.boolean,
cv.Optional(CONF_VOC_BASELINE): cv.hex_uint16_t,
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
@@ -194,16 +219,15 @@ async def to_code(config):
await i2c.register_i2c_device(var, config)
for key, funcName in SETTING_MAP.items():
if key in config:
cg.add(getattr(var, funcName)(config[key]))
if cfg := config.get(key):
cg.add(getattr(var, funcName)(cfg))
for key, funcName in SENSOR_MAP.items():
if key in config:
sens = await sensor.new_sensor(config[key])
if cfg := config.get(key):
sens = await sensor.new_sensor(cfg)
cg.add(getattr(var, funcName)(sens))
if CONF_VOC in config and CONF_ALGORITHM_TUNING in config[CONF_VOC]:
cfg = config[CONF_VOC][CONF_ALGORITHM_TUNING]
if cfg := config.get(CONF_VOC, {}).get(CONF_ALGORITHM_TUNING):
cg.add(
var.set_voc_algorithm_tuning(
cfg[CONF_INDEX_OFFSET],
@@ -214,8 +238,7 @@ async def to_code(config):
cfg[CONF_GAIN_FACTOR],
)
)
if CONF_NOX in config and CONF_ALGORITHM_TUNING in config[CONF_NOX]:
cfg = config[CONF_NOX][CONF_ALGORITHM_TUNING]
if cfg := config.get(CONF_NOX, {}).get(CONF_ALGORITHM_TUNING):
cg.add(
var.set_nox_algorithm_tuning(
cfg[CONF_INDEX_OFFSET],
@@ -225,12 +248,12 @@ async def to_code(config):
cfg[CONF_GAIN_FACTOR],
)
)
if CONF_TEMPERATURE_COMPENSATION in config:
if cfg := config.get(CONF_TEMPERATURE_COMPENSATION):
cg.add(
var.set_temperature_compensation(
config[CONF_TEMPERATURE_COMPENSATION][CONF_OFFSET],
config[CONF_TEMPERATURE_COMPENSATION][CONF_NORMALIZED_OFFSET_SLOPE],
config[CONF_TEMPERATURE_COMPENSATION][CONF_TIME_CONSTANT],
cfg[CONF_OFFSET],
cfg[CONF_NORMALIZED_OFFSET_SLOPE],
cfg[CONF_TIME_CONSTANT],
)
)

View File

@@ -11,7 +11,7 @@ pyserial==3.5
platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile
esptool==5.0.2
click==8.1.7
esphome-dashboard==20250814.0
esphome-dashboard==20250828.0
aioesphomeapi==39.0.0
zeroconf==0.147.0
puremagic==1.30

View File

@@ -1,6 +1,6 @@
pylint==3.3.8
flake8==7.3.0 # also change in .pre-commit-config.yaml when updating
ruff==0.12.10 # also change in .pre-commit-config.yaml when updating
ruff==0.12.11 # also change in .pre-commit-config.yaml when updating
pyupgrade==3.20.0 # also change in .pre-commit-config.yaml when updating
pre-commit

View File

@@ -684,7 +684,7 @@ lvgl:
width: 120
range_from: -10
range_to: 1000
step: 5.0
selected_digit: 2
rollover: false
digits: 6
decimal_places: 2

View File

@@ -0,0 +1 @@
*.ttf -text

View File

@@ -50,6 +50,14 @@ mapping:
red: red_id
blue: blue_id
green: green_id
- id: string_map_2
from: string
to: string
entries:
one: "one"
two: "two"
three: "three"
seventy-seven: "seventy-seven"
color:
- id: red_id
@@ -65,7 +73,14 @@ color:
green: 0.0
blue: 1.0
font:
- file: "$component_dir/helvetica.ttf"
id: font_id
size: 20
display:
lambda: |-
it.image(0, 0, id(weather_map)[0]);
it.image(0, 100, id(weather_map)[1]);
std::string value = id(int_map)[2];
it.print(0, 0, id(font_id), TextAlign::TOP_LEFT, value.c_str());
it.image(0, 0, id(weather_map)["clear-night"]);
it.image(0, 100, id(weather_map)["sunny"]);

Binary file not shown.

View File

@@ -4,14 +4,14 @@ spi:
mosi_pin: 17
miso_pin: 15
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false
packages:
map: !include common.yaml
display:
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 5
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 5
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 15
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 12
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 5
dc_pin: 15
reset_pin: 16
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 5
dc_pin: 15
reset_pin: 16
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -1,12 +1,12 @@
display:
- platform: sdl
id: sdl_display
update_interval: 1s
auto_clear_enabled: false
show_test_card: true
dimensions:
width: 450
height: 600
platform: sdl
id: sdl_display
update_interval: 1s
auto_clear_enabled: false
show_test_card: true
dimensions:
width: 450
height: 600
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 4
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 20
dc_pin: 21
reset_pin: 22
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 20
dc_pin: 21
reset_pin: 22
invert_colors: false
packages:
map: !include common.yaml