Merge branch 'dev' into jesserockz-2024-087

This commit is contained in:
Jesse Hills 2024-04-22 16:23:57 +12:00
commit 92b474b5cf
No known key found for this signature in database
GPG Key ID: BEAAE804EFD8E83A
100 changed files with 1262 additions and 867 deletions

View File

@ -472,6 +472,7 @@ jobs:
- compile-tests
- clang-tidy
- test-build-components
- list-components
if: always()
steps:
- name: Success
@ -479,4 +480,8 @@ jobs:
run: exit 0
- name: Failure
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1
env:
JSON_DOC: ${{ toJSON(needs) }}
run: |
echo $JSON_DOC | jq
exit 1

View File

@ -17,14 +17,16 @@ jobs:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.tag.outputs.tag }}
branch_build: ${{ steps.tag.outputs.branch_build }}
steps:
- uses: actions/checkout@v4.1.1
- name: Get tag
id: tag
# yamllint disable rule:line-length
run: |
if [[ "$GITHUB_EVENT_NAME" = "release" ]]; then
TAG="${GITHUB_REF#refs/tags/}"
if [[ "${{ github.event_name }}" = "release" ]]; then
TAG="${{ github.event.release.tag_name}}"
BRANCH_BUILD="false"
else
TAG=$(cat esphome/const.py | sed -n -E "s/^__version__\s+=\s+\"(.+)\"$/\1/p")
today="$(date --utc '+%Y%m%d')"
@ -32,15 +34,22 @@ jobs:
BRANCH=${GITHUB_REF#refs/heads/}
if [[ "$BRANCH" != "dev" ]]; then
TAG="${TAG}-${BRANCH}"
BRANCH_BUILD="true"
else
BRANCH_BUILD="false"
fi
fi
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "branch_build=${BRANCH_BUILD}" >> $GITHUB_OUTPUT
# yamllint enable rule:line-length
deploy-pypi:
name: Build and publish to PyPi
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4.1.1
- name: Set up Python
@ -50,16 +59,11 @@ jobs:
- name: Set up python environment
env:
ESPHOME_NO_VENV: 1
run: |
script/setup
pip install twine
run: script/setup
- name: Build
run: python setup.py sdist bdist_wheel
- name: Upload
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: twine upload dist/*
- name: Publish
uses: pypa/gh-action-pypi-publish@v1.8.14
deploy-docker:
name: Build ESPHome ${{ matrix.platform }}
@ -197,22 +201,28 @@ jobs:
$(printf '${{ steps.tags.outputs.image }}@sha256:%s ' *)
deploy-ha-addon-repo:
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
if: github.repository == 'esphome/esphome' && needs.init.outputs.branch_build == 'false'
runs-on: ubuntu-latest
needs: [deploy-manifest]
needs:
- init
- deploy-manifest
steps:
- name: Trigger Workflow
uses: actions/github-script@v7.0.1
with:
github-token: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
script: |
let description = "ESPHome";
if (context.eventName == "release") {
description = ${{ toJSON(github.event.release.body) }};
}
github.rest.actions.createWorkflowDispatch({
owner: "esphome",
repo: "home-assistant-addon",
workflow_id: "bump-version.yml",
ref: "main",
inputs: {
version: "${{ github.event.release.tag_name }}",
content: ${{ toJSON(github.event.release.body) }}
version: "${{ needs.init.outputs.tag }}",
content: description
}
})

View File

@ -24,7 +24,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5.1.0
with:
python-version: 3.11
python-version: 3.12
- name: Install Home Assistant
run: |
@ -36,7 +36,7 @@ jobs:
python ./script/sync-device_class.py
- name: Commit changes
uses: peter-evans/create-pull-request@v6.0.2
uses: peter-evans/create-pull-request@v6.0.4
with:
commit-message: "Synchronise Device Classes from Home Assistant"
committer: esphomebot <esphome@nabucasa.com>

View File

@ -27,7 +27,7 @@ repos:
- --branch=release
- --branch=beta
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.1
rev: v3.15.2
hooks:
- id: pyupgrade
args: [--py39-plus]

View File

@ -0,0 +1,47 @@
#!/usr/bin/with-contenv bashio
# ==============================================================================
# This file installs the user ESPHome fork if specified.
# The fork must be up to date with the latest ESPHome dev branch
# and have no conflicts.
# This config option only exists in the ESPHome Dev add-on.
# ==============================================================================
declare esphome_fork
if bashio::config.has_value 'esphome_fork'; then
esphome_fork=$(bashio::config 'esphome_fork')
# format: [username][/repository]:ref
if [[ "$esphome_fork" =~ ^(([^/]+)(/([^:]+))?:)?([^:/]+)$ ]]; then
username="${BASH_REMATCH[2]:-esphome}"
repository="${BASH_REMATCH[4]:-esphome}"
ref="${BASH_REMATCH[5]}"
else
bashio::exit.nok "Invalid esphome_fork format: $esphome_fork"
fi
full_url="https://github.com/${username}/${repository}/archive/${ref}.tar.gz"
bashio::log.info "Checking forked ESPHome"
dev_version=$(python3 -c "from esphome.const import __version__; print(__version__)")
bashio::log.info "Downloading ESPHome from fork '${esphome_fork}' (${full_url})..."
curl -L -o /tmp/esphome.tar.gz "${full_url}" -qq ||
bashio::exit.nok "Failed downloading ESPHome fork."
bashio::log.info "Installing ESPHome from fork '${esphome_fork}' (${full_url})..."
rm -rf /esphome || bashio::exit.nok "Failed to remove ESPHome."
mkdir /esphome
tar -zxf /tmp/esphome.tar.gz -C /esphome --strip-components=1 ||
bashio::exit.nok "Failed installing ESPHome from fork."
pip install -U -e /esphome || bashio::exit.nok "Failed installing ESPHome from fork."
rm -f /tmp/esphome.tar.gz
fork_version=$(python3 -c "from esphome.const import __version__; print(__version__)")
if [[ "$fork_version" != "$dev_version" ]]; then
bashio::log.error "############################"
bashio::log.error "Uninstalled fork as version does not match"
bashio::log.error "Update (or ask the author to update) the branch"
bashio::log.error "This is important as the dev addon and the dev ESPHome"
bashio::log.error "branch can have changes that are not compatible with old forks"
bashio::log.error "and get reported as bugs which we cannot solve easily."
bashio::log.error "############################"
bashio::exit.nok
fi
bashio::log.info "Installed ESPHome from fork '${esphome_fork}' (${full_url})..."
fi

View File

@ -785,6 +785,7 @@ def parse_args(argv):
parser_logs = subparsers.add_parser(
"logs",
help="Validate the configuration and show all logs.",
aliases=["log"],
parents=[mqtt_options],
)
parser_logs.add_argument(

View File

@ -244,122 +244,150 @@ async def setup_climate_core_(var, config):
await setup_entity(var, config)
visual = config[CONF_VISUAL]
if CONF_MIN_TEMPERATURE in visual:
cg.add(var.set_visual_min_temperature_override(visual[CONF_MIN_TEMPERATURE]))
if CONF_MAX_TEMPERATURE in visual:
cg.add(var.set_visual_max_temperature_override(visual[CONF_MAX_TEMPERATURE]))
if CONF_TEMPERATURE_STEP in visual:
if (min_temp := visual.get(CONF_MIN_TEMPERATURE)) is not None:
cg.add(var.set_visual_min_temperature_override(min_temp))
if (max_temp := visual.get(CONF_MAX_TEMPERATURE)) is not None:
cg.add(var.set_visual_max_temperature_override(max_temp))
if (temp_step := visual.get(CONF_TEMPERATURE_STEP)) is not None:
cg.add(
var.set_visual_temperature_step_override(
visual[CONF_TEMPERATURE_STEP][CONF_TARGET_TEMPERATURE],
visual[CONF_TEMPERATURE_STEP][CONF_CURRENT_TEMPERATURE],
temp_step[CONF_TARGET_TEMPERATURE],
temp_step[CONF_CURRENT_TEMPERATURE],
)
)
if CONF_MIN_HUMIDITY in visual:
cg.add(var.set_visual_min_humidity_override(visual[CONF_MIN_HUMIDITY]))
if CONF_MAX_HUMIDITY in visual:
cg.add(var.set_visual_max_humidity_override(visual[CONF_MAX_HUMIDITY]))
if (min_humidity := visual.get(CONF_MIN_HUMIDITY)) is not None:
cg.add(var.set_visual_min_humidity_override(min_humidity))
if (max_humidity := visual.get(CONF_MAX_HUMIDITY)) is not None:
cg.add(var.set_visual_max_humidity_override(max_humidity))
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if CONF_ACTION_STATE_TOPIC in config:
cg.add(mqtt_.set_custom_action_state_topic(config[CONF_ACTION_STATE_TOPIC]))
if CONF_AWAY_COMMAND_TOPIC in config:
cg.add(mqtt_.set_custom_away_command_topic(config[CONF_AWAY_COMMAND_TOPIC]))
if CONF_AWAY_STATE_TOPIC in config:
cg.add(mqtt_.set_custom_away_state_topic(config[CONF_AWAY_STATE_TOPIC]))
if CONF_CURRENT_TEMPERATURE_STATE_TOPIC in config:
if (action_state_topic := config.get(CONF_ACTION_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_action_state_topic(action_state_topic))
if (away_command_topic := config.get(CONF_AWAY_COMMAND_TOPIC)) is not None:
cg.add(mqtt_.set_custom_away_command_topic(away_command_topic))
if (away_state_topic := config.get(CONF_AWAY_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_away_state_topic(away_state_topic))
if (
current_temperature_state_topic := config.get(
CONF_CURRENT_TEMPERATURE_STATE_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_current_temperature_state_topic(
config[CONF_CURRENT_TEMPERATURE_STATE_TOPIC]
current_temperature_state_topic
)
)
if CONF_CURRENT_HUMIDITY_STATE_TOPIC in config:
if (
current_humidity_state_topic := config.get(
CONF_CURRENT_HUMIDITY_STATE_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_current_humidity_state_topic(
config[CONF_CURRENT_HUMIDITY_STATE_TOPIC]
current_humidity_state_topic
)
)
if CONF_FAN_MODE_COMMAND_TOPIC in config:
cg.add(
mqtt_.set_custom_fan_mode_command_topic(
config[CONF_FAN_MODE_COMMAND_TOPIC]
)
if (
fan_mode_command_topic := config.get(CONF_FAN_MODE_COMMAND_TOPIC)
) is not None:
cg.add(mqtt_.set_custom_fan_mode_command_topic(fan_mode_command_topic))
if (fan_mode_state_topic := config.get(CONF_FAN_MODE_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_fan_mode_state_topic(fan_mode_state_topic))
if (mode_command_topic := config.get(CONF_MODE_COMMAND_TOPIC)) is not None:
cg.add(mqtt_.set_custom_mode_command_topic(mode_command_topic))
if (mode_state_topic := config.get(CONF_MODE_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_mode_state_topic(mode_state_topic))
if (preset_command_topic := config.get(CONF_PRESET_COMMAND_TOPIC)) is not None:
cg.add(mqtt_.set_custom_preset_command_topic(preset_command_topic))
if (preset_state_topic := config.get(CONF_PRESET_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_preset_state_topic(preset_state_topic))
if (
swing_mode_command_topic := config.get(CONF_SWING_MODE_COMMAND_TOPIC)
) is not None:
cg.add(mqtt_.set_custom_swing_mode_command_topic(swing_mode_command_topic))
if (
swing_mode_state_topic := config.get(CONF_SWING_MODE_STATE_TOPIC)
) is not None:
cg.add(mqtt_.set_custom_swing_mode_state_topic(swing_mode_state_topic))
if (
target_temperature_command_topic := config.get(
CONF_TARGET_TEMPERATURE_COMMAND_TOPIC
)
if CONF_FAN_MODE_STATE_TOPIC in config:
cg.add(
mqtt_.set_custom_fan_mode_state_topic(config[CONF_FAN_MODE_STATE_TOPIC])
)
if CONF_MODE_COMMAND_TOPIC in config:
cg.add(mqtt_.set_custom_mode_command_topic(config[CONF_MODE_COMMAND_TOPIC]))
if CONF_MODE_STATE_TOPIC in config:
cg.add(mqtt_.set_custom_mode_state_topic(config[CONF_MODE_STATE_TOPIC]))
if CONF_PRESET_COMMAND_TOPIC in config:
cg.add(
mqtt_.set_custom_preset_command_topic(config[CONF_PRESET_COMMAND_TOPIC])
)
if CONF_PRESET_STATE_TOPIC in config:
cg.add(mqtt_.set_custom_preset_state_topic(config[CONF_PRESET_STATE_TOPIC]))
if CONF_SWING_MODE_COMMAND_TOPIC in config:
cg.add(
mqtt_.set_custom_swing_mode_command_topic(
config[CONF_SWING_MODE_COMMAND_TOPIC]
)
)
if CONF_SWING_MODE_STATE_TOPIC in config:
cg.add(
mqtt_.set_custom_swing_mode_state_topic(
config[CONF_SWING_MODE_STATE_TOPIC]
)
)
if CONF_TARGET_TEMPERATURE_COMMAND_TOPIC in config:
) is not None:
cg.add(
mqtt_.set_custom_target_temperature_command_topic(
config[CONF_TARGET_TEMPERATURE_COMMAND_TOPIC]
target_temperature_command_topic
)
)
if CONF_TARGET_TEMPERATURE_STATE_TOPIC in config:
if (
target_temperature_state_topic := config.get(
CONF_TARGET_TEMPERATURE_STATE_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_target_temperature_state_topic(
config[CONF_TARGET_TEMPERATURE_STATE_TOPIC]
target_temperature_state_topic
)
)
if CONF_TARGET_TEMPERATURE_HIGH_COMMAND_TOPIC in config:
if (
target_temperature_high_command_topic := config.get(
CONF_TARGET_TEMPERATURE_HIGH_COMMAND_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_target_temperature_high_command_topic(
config[CONF_TARGET_TEMPERATURE_HIGH_COMMAND_TOPIC]
target_temperature_high_command_topic
)
)
if CONF_TARGET_TEMPERATURE_HIGH_STATE_TOPIC in config:
if (
target_temperature_high_state_topic := config.get(
CONF_TARGET_TEMPERATURE_HIGH_STATE_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_target_temperature_high_state_topic(
config[CONF_TARGET_TEMPERATURE_HIGH_STATE_TOPIC]
target_temperature_high_state_topic
)
)
if CONF_TARGET_TEMPERATURE_LOW_COMMAND_TOPIC in config:
if (
target_temperature_low_command_topic := config.get(
CONF_TARGET_TEMPERATURE_LOW_COMMAND_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_target_temperature_low_command_topic(
config[CONF_TARGET_TEMPERATURE_LOW_COMMAND_TOPIC]
target_temperature_low_command_topic
)
)
if CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC in config:
if (
target_temperature_low_state_topic := config.get(
CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_target_temperature_state_topic(
config[CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC]
target_temperature_low_state_topic
)
)
if CONF_TARGET_HUMIDITY_COMMAND_TOPIC in config:
if (
target_humidity_command_topic := config.get(
CONF_TARGET_HUMIDITY_COMMAND_TOPIC
)
) is not None:
cg.add(
mqtt_.set_custom_target_humidity_command_topic(
config[CONF_TARGET_HUMIDITY_COMMAND_TOPIC]
target_humidity_command_topic
)
)
if CONF_TARGET_HUMIDITY_STATE_TOPIC in config:
if (
target_humidity_state_topic := config.get(CONF_TARGET_HUMIDITY_STATE_TOPIC)
) is not None:
cg.add(
mqtt_.set_custom_target_humidity_state_topic(
config[CONF_TARGET_HUMIDITY_STATE_TOPIC]
target_humidity_state_topic
)
)
@ -411,45 +439,35 @@ CLIMATE_CONTROL_ACTION_SCHEMA = cv.Schema(
async def climate_control_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_MODE in config:
template_ = await cg.templatable(config[CONF_MODE], args, ClimateMode)
if (mode := config.get(CONF_MODE)) is not None:
template_ = await cg.templatable(mode, args, ClimateMode)
cg.add(var.set_mode(template_))
if CONF_TARGET_TEMPERATURE in config:
template_ = await cg.templatable(config[CONF_TARGET_TEMPERATURE], args, float)
if (target_temp := config.get(CONF_TARGET_TEMPERATURE)) is not None:
template_ = await cg.templatable(target_temp, args, float)
cg.add(var.set_target_temperature(template_))
if CONF_TARGET_TEMPERATURE_LOW in config:
template_ = await cg.templatable(
config[CONF_TARGET_TEMPERATURE_LOW], args, float
)
if (target_temp_low := config.get(CONF_TARGET_TEMPERATURE_LOW)) is not None:
template_ = await cg.templatable(target_temp_low, args, float)
cg.add(var.set_target_temperature_low(template_))
if CONF_TARGET_TEMPERATURE_HIGH in config:
template_ = await cg.templatable(
config[CONF_TARGET_TEMPERATURE_HIGH], args, float
)
if (target_temp_high := config.get(CONF_TARGET_TEMPERATURE_HIGH)) is not None:
template_ = await cg.templatable(target_temp_high, args, float)
cg.add(var.set_target_temperature_high(template_))
if CONF_TARGET_HUMIDITY in config:
template_ = await cg.templatable(config[CONF_TARGET_HUMIDITY], args, float)
if (target_humidity := config.get(CONF_TARGET_HUMIDITY)) is not None:
template_ = await cg.templatable(target_humidity, args, float)
cg.add(var.set_target_humidity(template_))
if CONF_FAN_MODE in config:
template_ = await cg.templatable(config[CONF_FAN_MODE], args, ClimateFanMode)
if (fan_mode := config.get(CONF_FAN_MODE)) is not None:
template_ = await cg.templatable(fan_mode, args, ClimateFanMode)
cg.add(var.set_fan_mode(template_))
if CONF_CUSTOM_FAN_MODE in config:
template_ = await cg.templatable(
config[CONF_CUSTOM_FAN_MODE], args, cg.std_string
)
if (custom_fan_mode := config.get(CONF_CUSTOM_FAN_MODE)) is not None:
template_ = await cg.templatable(custom_fan_mode, args, cg.std_string)
cg.add(var.set_custom_fan_mode(template_))
if CONF_PRESET in config:
template_ = await cg.templatable(config[CONF_PRESET], args, ClimatePreset)
if (preset := config.get(CONF_PRESET)) is not None:
template_ = await cg.templatable(preset, args, ClimatePreset)
cg.add(var.set_preset(template_))
if CONF_CUSTOM_PRESET in config:
template_ = await cg.templatable(
config[CONF_CUSTOM_PRESET], args, cg.std_string
)
if (custom_preset := config.get(CONF_CUSTOM_PRESET)) is not None:
template_ = await cg.templatable(custom_preset, args, cg.std_string)
cg.add(var.set_custom_preset(template_))
if CONF_SWING_MODE in config:
template_ = await cg.templatable(
config[CONF_SWING_MODE], args, ClimateSwingMode
)
if (swing_mode := config.get(CONF_SWING_MODE)) is not None:
template_ = await cg.templatable(swing_mode, args, ClimateSwingMode)
cg.add(var.set_swing_mode(template_))
return var

View File

@ -122,8 +122,8 @@ COVER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).ex
async def setup_cover_core_(var, config):
await setup_entity(var, config)
if CONF_DEVICE_CLASS in config:
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
for conf in config.get(CONF_ON_OPEN, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
@ -132,24 +132,20 @@ async def setup_cover_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if CONF_POSITION_STATE_TOPIC in config:
cg.add(
mqtt_.set_custom_position_state_topic(config[CONF_POSITION_STATE_TOPIC])
)
if CONF_POSITION_COMMAND_TOPIC in config:
cg.add(
mqtt_.set_custom_position_command_topic(
config[CONF_POSITION_COMMAND_TOPIC]
)
)
if CONF_TILT_STATE_TOPIC in config:
cg.add(mqtt_.set_custom_tilt_state_topic(config[CONF_TILT_STATE_TOPIC]))
if CONF_TILT_COMMAND_TOPIC in config:
cg.add(mqtt_.set_custom_tilt_command_topic(config[CONF_TILT_COMMAND_TOPIC]))
if (position_state_topic := config.get(CONF_POSITION_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_position_state_topic(position_state_topic))
if (
position_command_topic := config.get(CONF_POSITION_COMMAND_TOPIC)
) is not None:
cg.add(mqtt_.set_custom_position_command_topic(position_command_topic))
if (tilt_state_topic := config.get(CONF_TILT_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_tilt_state_topic(tilt_state_topic))
if (tilt_command_topic := config.get(CONF_TILT_COMMAND_TOPIC)) is not None:
cg.add(mqtt_.set_custom_tilt_command_topic(tilt_command_topic))
async def register_cover(var, config):
@ -205,17 +201,17 @@ COVER_CONTROL_ACTION_SCHEMA = cv.Schema(
async def cover_control_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_STOP in config:
template_ = await cg.templatable(config[CONF_STOP], args, bool)
if (stop := config.get(CONF_STOP)) is not None:
template_ = await cg.templatable(stop, args, bool)
cg.add(var.set_stop(template_))
if CONF_STATE in config:
template_ = await cg.templatable(config[CONF_STATE], args, float)
if (state := config.get(CONF_STATE)) is not None:
template_ = await cg.templatable(state, args, float)
cg.add(var.set_position(template_))
if CONF_POSITION in config:
template_ = await cg.templatable(config[CONF_POSITION], args, float)
if (position := config.get(CONF_POSITION)) is not None:
template_ = await cg.templatable(position, args, float)
cg.add(var.set_position(template_))
if CONF_TILT in config:
template_ = await cg.templatable(config[CONF_TILT], args, float)
if (tilt := config.get(CONF_TILT)) is not None:
template_ = await cg.templatable(tilt, args, float)
cg.add(var.set_tilt(template_))
return var

View File

@ -125,8 +125,8 @@ def datetime_schema(class_: MockObjClass) -> cv.Schema:
async def setup_datetime_core_(var, config):
await setup_entity(var, config)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)

View File

@ -2,6 +2,7 @@
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include "esphome/core/helpers.h"
#include <array>
@ -248,11 +249,11 @@ class ESP32BLETracker : public Component,
SemaphoreHandle_t scan_result_lock_;
SemaphoreHandle_t scan_end_lock_;
size_t scan_result_index_{0};
#if CONFIG_SPIRAM
#ifdef USE_PSRAM
const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 32;
#else
const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 16;
#endif // CONFIG_SPIRAM
#endif // USE_PSRAM
esp_ble_gap_cb_param_t::ble_scan_result_evt_param *scan_result_buffer_;
esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS};
esp_bt_status_t scan_set_param_failed_{ESP_BT_STATUS_SUCCESS};

View File

@ -340,6 +340,11 @@ network::IPAddresses EthernetComponent::get_ip_addresses() {
return addresses;
}
network::IPAddress EthernetComponent::get_dns_address(uint8_t num) {
const ip_addr_t *dns_ip = dns_getserver(num);
return dns_ip;
}
void EthernetComponent::eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event, void *event_data) {
const char *event_name;

View File

@ -70,6 +70,7 @@ class EthernetComponent : public Component {
void set_manual_ip(const ManualIP &manual_ip);
network::IPAddresses get_ip_addresses();
network::IPAddress get_dns_address(uint8_t num);
std::string get_use_address() const;
void set_use_address(const std::string &use_address);
bool powerdown();

View File

@ -9,6 +9,7 @@ namespace ethernet_info {
static const char *const TAG = "ethernet_info";
void IPAddressEthernetInfo::dump_config() { LOG_TEXT_SENSOR("", "EthernetInfo IPAddress", this); }
void DNSAddressEthernetInfo::dump_config() { LOG_TEXT_SENSOR("", "EthernetInfo DNS Address", this); }
} // namespace ethernet_info
} // namespace esphome

View File

@ -38,6 +38,27 @@ class IPAddressEthernetInfo : public PollingComponent, public text_sensor::TextS
std::array<text_sensor::TextSensor *, 5> ip_sensors_;
};
class DNSAddressEthernetInfo : public PollingComponent, public text_sensor::TextSensor {
public:
void update() override {
auto dns_one = ethernet::global_eth_component->get_dns_address(0);
auto dns_two = ethernet::global_eth_component->get_dns_address(1);
std::string dns_results = dns_one.str() + " " + dns_two.str();
if (dns_results != this->last_results_) {
this->last_results_ = dns_results;
this->publish_state(dns_results);
}
}
float get_setup_priority() const override { return setup_priority::ETHERNET; }
std::string unique_id() override { return get_mac_address() + "-ethernetinfo-dns"; }
void dump_config() override;
protected:
std::string last_results_;
};
} // namespace ethernet_info
} // namespace esphome

View File

@ -3,6 +3,7 @@ import esphome.config_validation as cv
from esphome.components import text_sensor
from esphome.const import (
CONF_IP_ADDRESS,
CONF_DNS_ADDRESS,
ENTITY_CATEGORY_DIAGNOSTIC,
)
@ -10,14 +11,18 @@ DEPENDENCIES = ["ethernet"]
ethernet_info_ns = cg.esphome_ns.namespace("ethernet_info")
IPAddressEsthernetInfo = ethernet_info_ns.class_(
IPAddressEthernetInfo = ethernet_info_ns.class_(
"IPAddressEthernetInfo", text_sensor.TextSensor, cg.PollingComponent
)
DNSAddressEthernetInfo = ethernet_info_ns.class_(
"DNSAddressEthernetInfo", text_sensor.TextSensor, cg.PollingComponent
)
CONFIG_SCHEMA = cv.Schema(
{
cv.Optional(CONF_IP_ADDRESS): text_sensor.text_sensor_schema(
IPAddressEsthernetInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
IPAddressEthernetInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
)
.extend(cv.polling_component_schema("1s"))
.extend(
@ -27,7 +32,10 @@ CONFIG_SCHEMA = cv.Schema(
)
for x in range(5)
}
)
),
cv.Optional(CONF_DNS_ADDRESS): text_sensor.text_sensor_schema(
DNSAddressEthernetInfo, entity_category=ENTITY_CATEGORY_DIAGNOSTIC
).extend(cv.polling_component_schema("1s")),
}
)
@ -40,3 +48,6 @@ async def to_code(config):
if sensor_conf := conf.get(f"address_{x}"):
sens = await text_sensor.new_text_sensor(sensor_conf)
cg.add(ip_info.add_ip_sensors(x, sens))
if conf := config.get(CONF_DNS_ADDRESS):
dns_info = await text_sensor.new_text_sensor(config[CONF_DNS_ADDRESS])
await cg.register_component(dns_info, config[CONF_DNS_ADDRESS])

View File

@ -180,40 +180,34 @@ async def setup_fan_core_(var, config):
cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE]))
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if CONF_OSCILLATION_STATE_TOPIC in config:
if (
oscillation_state_topic := config.get(CONF_OSCILLATION_STATE_TOPIC)
) is not None:
cg.add(mqtt_.set_custom_oscillation_state_topic(oscillation_state_topic))
if (
oscillation_command_topic := config.get(CONF_OSCILLATION_COMMAND_TOPIC)
) is not None:
cg.add(
mqtt_.set_custom_oscillation_state_topic(
config[CONF_OSCILLATION_STATE_TOPIC]
)
mqtt_.set_custom_oscillation_command_topic(oscillation_command_topic)
)
if CONF_OSCILLATION_COMMAND_TOPIC in config:
if (
speed_level_state_topic := config.get(CONF_SPEED_LEVEL_STATE_TOPIC)
) is not None:
cg.add(mqtt_.set_custom_speed_level_state_topic(speed_level_state_topic))
if (
speed_level_command_topic := config.get(CONF_SPEED_LEVEL_COMMAND_TOPIC)
) is not None:
cg.add(
mqtt_.set_custom_oscillation_command_topic(
config[CONF_OSCILLATION_COMMAND_TOPIC]
)
)
if CONF_SPEED_LEVEL_STATE_TOPIC in config:
cg.add(
mqtt_.set_custom_speed_level_state_topic(
config[CONF_SPEED_LEVEL_STATE_TOPIC]
)
)
if CONF_SPEED_LEVEL_COMMAND_TOPIC in config:
cg.add(
mqtt_.set_custom_speed_level_command_topic(
config[CONF_SPEED_LEVEL_COMMAND_TOPIC]
)
)
if CONF_SPEED_STATE_TOPIC in config:
cg.add(mqtt_.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
if CONF_SPEED_COMMAND_TOPIC in config:
cg.add(
mqtt_.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])
mqtt_.set_custom_speed_level_command_topic(speed_level_command_topic)
)
if (speed_state_topic := config.get(CONF_SPEED_STATE_TOPIC)) is not None:
cg.add(mqtt_.set_custom_speed_state_topic(speed_state_topic))
if (speed_command_topic := config.get(CONF_SPEED_COMMAND_TOPIC)) is not None:
cg.add(mqtt_.set_custom_speed_command_topic(speed_command_topic))
for conf in config.get(CONF_ON_STATE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
@ -288,14 +282,14 @@ async def fan_turn_off_to_code(config, action_id, template_arg, args):
async def fan_turn_on_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_OSCILLATING in config:
template_ = await cg.templatable(config[CONF_OSCILLATING], args, bool)
if (oscillating := config.get(CONF_OSCILLATING)) is not None:
template_ = await cg.templatable(oscillating, args, bool)
cg.add(var.set_oscillating(template_))
if CONF_SPEED in config:
template_ = await cg.templatable(config[CONF_SPEED], args, int)
if (speed := config.get(CONF_SPEED)) is not None:
template_ = await cg.templatable(speed, args, int)
cg.add(var.set_speed(template_))
if CONF_DIRECTION in config:
template_ = await cg.templatable(config[CONF_DIRECTION], args, FanDirection)
if (direction := config.get(CONF_DIRECTION)) is not None:
template_ = await cg.templatable(direction, args, FanDirection)
cg.add(var.set_direction(template_))
return var

View File

@ -400,8 +400,7 @@ class BitmapFontWrapper:
for glyph in glyphs:
mask = self.getmask(glyph, mode="1")
_, height = mask.size
if height > max_height:
max_height = height
max_height = max(max_height, height)
return (max_height, 0)

View File

@ -32,7 +32,7 @@ void FT63X6Touchscreen::setup() {
if (this->interrupt_pin_ != nullptr) {
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
this->interrupt_pin_->setup();
this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_ANY_EDGE);
}
if (this->reset_pin_ != nullptr) {
@ -78,13 +78,12 @@ void FT63X6Touchscreen::update_touches() {
uint16_t touch_id, x, y;
uint8_t touches = this->read_touch_number_();
ESP_LOGV(TAG, "Touches found: %d", touches);
if ((touches == 0x00) || (touches == 0xff)) {
// ESP_LOGD(TAG, "No touches detected");
return;
}
ESP_LOGV(TAG, "Touches found: %d", touches);
for (auto point = 0; point < touches; point++) {
if (((this->read_touch_event_(point)) & 0x01) == 0) { // checking event flag bit 6 if it is null
touch_id = this->read_touch_id_(point); // id1 = 0 or 1

View File

@ -76,12 +76,27 @@ void HTU21DComponent::update() {
float humidity = (float(raw_humidity & 0xFFFC)) * 125.0f / 65536.0f - 6.0f;
int8_t heater_level = this->get_heater_level();
ESP_LOGD(TAG, "Got Humidity=%.1f%% Heater Level=%d", humidity, heater_level);
ESP_LOGD(TAG, "Got Humidity=%.1f%%", humidity);
if (this->humidity_ != nullptr)
this->humidity_->publish_state(humidity);
int8_t heater_level;
// HTU21D does have a heater module but does not have heater level
// Setting heater level to 1 in case the heater is ON
if (this->sensor_model_ == HTU21D_SENSOR_MODEL_HTU21D) {
if (this->is_heater_enabled()) {
heater_level = 1;
} else {
heater_level = 0;
}
} else {
heater_level = this->get_heater_level();
}
ESP_LOGD(TAG, "Heater Level=%d", heater_level);
if (this->heater_ != nullptr)
this->heater_->publish_state(heater_level);
this->status_clear_warning();

View File

@ -8,6 +8,8 @@
namespace esphome {
namespace htu21d {
enum HTU21DSensorModels { HTU21D_SENSOR_MODEL_HTU21D = 0, HTU21D_SENSOR_MODEL_SI7021, HTU21D_SENSOR_MODEL_SHT21 };
class HTU21DComponent : public PollingComponent, public i2c::I2CDevice {
public:
void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; }
@ -17,6 +19,7 @@ class HTU21DComponent : public PollingComponent, public i2c::I2CDevice {
/// Setup (reset) the sensor and check connection.
void setup() override;
void dump_config() override;
void set_sensor_model(HTU21DSensorModels sensor_model) { sensor_model_ = sensor_model; }
/// Update the sensor values (temperature+humidity).
void update() override;
@ -31,6 +34,7 @@ class HTU21DComponent : public PollingComponent, public i2c::I2CDevice {
sensor::Sensor *temperature_{nullptr};
sensor::Sensor *humidity_{nullptr};
sensor::Sensor *heater_{nullptr};
HTU21DSensorModels sensor_model_{HTU21D_SENSOR_MODEL_HTU21D};
};
template<typename... Ts> class SetHeaterLevelAction : public Action<Ts...>, public Parented<HTU21DComponent> {

View File

@ -5,6 +5,7 @@ from esphome import automation
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,
CONF_MODEL,
CONF_TEMPERATURE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
@ -23,10 +24,15 @@ htu21d_ns = cg.esphome_ns.namespace("htu21d")
HTU21DComponent = htu21d_ns.class_(
"HTU21DComponent", cg.PollingComponent, i2c.I2CDevice
)
SetHeaterLevelAction = htu21d_ns.class_("SetHeaterLevelAction", automation.Action)
SetHeaterAction = htu21d_ns.class_("SetHeaterAction", automation.Action)
HTU21DSensorModels = htu21d_ns.enum("HTU21DSensorModels")
MODELS = {
"HTU21D": HTU21DSensorModels.HTU21D_SENSOR_MODEL_HTU21D,
"SI7021": HTU21DSensorModels.HTU21D_SENSOR_MODEL_SI7021,
"SHT21": HTU21DSensorModels.HTU21D_SENSOR_MODEL_SHT21,
}
CONFIG_SCHEMA = (
cv.Schema(
@ -49,6 +55,7 @@ CONFIG_SCHEMA = (
accuracy_decimals=1,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_MODEL, default="HTU21D"): cv.enum(MODELS, upper=True),
}
)
.extend(cv.polling_component_schema("60s"))
@ -73,6 +80,8 @@ async def to_code(config):
sens = await sensor.new_sensor(config[CONF_HEATER])
cg.add(var.set_heater(sens))
cg.add(var.set_sensor_model(config[CONF_MODEL]))
@automation.register_action(
"htu21d.set_heater_level",

View File

@ -137,18 +137,16 @@ async def setup_light_core_(light_var, output_var, config):
cg.add(light_var.set_restore_mode(config[CONF_RESTORE_MODE]))
if CONF_DEFAULT_TRANSITION_LENGTH in config:
cg.add(
light_var.set_default_transition_length(
config[CONF_DEFAULT_TRANSITION_LENGTH]
)
)
if CONF_FLASH_TRANSITION_LENGTH in config:
cg.add(
light_var.set_flash_transition_length(config[CONF_FLASH_TRANSITION_LENGTH])
)
if CONF_GAMMA_CORRECT in config:
cg.add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
if (
default_transition_length := config.get(CONF_DEFAULT_TRANSITION_LENGTH)
) is not None:
cg.add(light_var.set_default_transition_length(default_transition_length))
if (
flash_transition_length := config.get(CONF_FLASH_TRANSITION_LENGTH)
) is not None:
cg.add(light_var.set_flash_transition_length(flash_transition_length))
if (gamma_correct := config.get(CONF_GAMMA_CORRECT)) is not None:
cg.add(light_var.set_gamma_correct(gamma_correct))
effects = await cg.build_registry_list(
EFFECTS_REGISTRY, config.get(CONF_EFFECTS, [])
)
@ -164,15 +162,15 @@ async def setup_light_core_(light_var, output_var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], light_var)
await auto.build_automation(trigger, [], conf)
if CONF_COLOR_CORRECT in config:
cg.add(output_var.set_correction(*config[CONF_COLOR_CORRECT]))
if (color_correct := config.get(CONF_COLOR_CORRECT)) is not None:
cg.add(output_var.set_correction(*color_correct))
if CONF_POWER_SUPPLY in config:
var_ = await cg.get_variable(config[CONF_POWER_SUPPLY])
if (power_supply_id := config.get(CONF_POWER_SUPPLY)) is not None:
var_ = await cg.get_variable(power_supply_id)
cg.add(output_var.set_power_supply(var_))
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], light_var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, light_var)
await mqtt.register_mqtt_component(mqtt_, config)

View File

@ -57,8 +57,8 @@ async def setup_lock_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if mqtt_id := config.get(CONF_MQTT_ID):
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)

View File

@ -120,30 +120,28 @@ void Logger::pre_setup() {
switch (this->uart_) {
case UART_SELECTION_UART0:
this->uart_num_ = UART_NUM_0;
init_uart(this->uart_num_, baud_rate_, tx_buffer_size_);
break;
case UART_SELECTION_UART1:
this->uart_num_ = UART_NUM_1;
init_uart(this->uart_num_, baud_rate_, tx_buffer_size_);
break;
#ifdef USE_ESP32_VARIANT_ESP32
case UART_SELECTION_UART2:
this->uart_num_ = UART_NUM_2;
init_uart(this->uart_num_, baud_rate_, tx_buffer_size_);
break;
#endif
#ifdef USE_LOGGER_USB_CDC
case UART_SELECTION_USB_CDC:
this->uart_num_ = -1;
break;
#endif
#ifdef USE_LOGGER_USB_SERIAL_JTAG
case UART_SELECTION_USB_SERIAL_JTAG:
this->uart_num_ = -1;
init_usb_serial_jtag_();
break;
#endif
}
if (this->uart_num_ >= 0) {
init_uart(this->uart_num_, baud_rate_, tx_buffer_size_);
}
#endif // USE_ESP_IDF
}

View File

@ -27,7 +27,7 @@ void NextionBinarySensor::process_touch(uint8_t page_id, uint8_t component_id, b
}
void NextionBinarySensor::update() {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
if (this->variable_name_.empty()) // This is a touch component
@ -37,7 +37,7 @@ void NextionBinarySensor::update() {
}
void NextionBinarySensor::set_state(bool state, bool publish, bool send_to_nextion) {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
if (this->component_id_ == 0) // This is a legacy touch component

View File

@ -68,8 +68,8 @@ CONFIG_SCHEMA = (
}
),
cv.Optional(CONF_TOUCH_SLEEP_TIMEOUT): cv.int_range(min=3, max=65535),
cv.Optional(CONF_WAKE_UP_PAGE): cv.positive_int,
cv.Optional(CONF_START_UP_PAGE): cv.positive_int,
cv.Optional(CONF_WAKE_UP_PAGE): cv.uint8_t,
cv.Optional(CONF_START_UP_PAGE): cv.uint8_t,
cv.Optional(CONF_AUTO_WAKE_ON_TOUCH, default=True): cv.boolean,
cv.Optional(CONF_EXIT_REPARSE_ON_START, default=False): cv.boolean,
}

View File

@ -138,11 +138,11 @@ void Nextion::dump_config() {
}
if (this->wake_up_page_ != -1) {
ESP_LOGCONFIG(TAG, " Wake Up Page: %d", this->wake_up_page_);
ESP_LOGCONFIG(TAG, " Wake Up Page: %" PRId16, this->wake_up_page_);
}
if (this->start_up_page_ != -1) {
ESP_LOGCONFIG(TAG, " Start Up Page: %d", this->start_up_page_);
ESP_LOGCONFIG(TAG, " Start Up Page: %" PRId16, this->start_up_page_);
}
}
@ -194,6 +194,17 @@ void Nextion::update_all_components() {
}
}
bool Nextion::send_command(const char *command) {
if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping())
return false;
if (this->send_command_(command)) {
this->add_no_result_to_queue_("send_command");
return true;
}
return false;
}
bool Nextion::send_command_printf(const char *format, ...) {
if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping())
return false;
@ -1024,23 +1035,23 @@ bool Nextion::add_no_result_to_queue_with_printf_(const std::string &variable_na
* @param is_sleep_safe The command is safe to send when the Nextion is sleeping
*/
void Nextion::add_no_result_to_queue_with_set(NextionComponentBase *component, int state_value) {
void Nextion::add_no_result_to_queue_with_set(NextionComponentBase *component, int32_t state_value) {
this->add_no_result_to_queue_with_set(component->get_variable_name(), component->get_variable_name_to_send(),
state_value);
}
void Nextion::add_no_result_to_queue_with_set(const std::string &variable_name,
const std::string &variable_name_to_send, int state_value) {
const std::string &variable_name_to_send, int32_t state_value) {
this->add_no_result_to_queue_with_set_internal_(variable_name, variable_name_to_send, state_value);
}
void Nextion::add_no_result_to_queue_with_set_internal_(const std::string &variable_name,
const std::string &variable_name_to_send, int state_value,
const std::string &variable_name_to_send, int32_t state_value,
bool is_sleep_safe) {
if ((!this->is_setup() && !this->ignore_is_setup_) || (!is_sleep_safe && this->is_sleeping()))
return;
this->add_no_result_to_queue_with_ignore_sleep_printf_(variable_name, "%s=%d", variable_name_to_send.c_str(),
this->add_no_result_to_queue_with_ignore_sleep_printf_(variable_name, "%s=%" PRId32, variable_name_to_send.c_str(),
state_value);
}
@ -1137,5 +1148,7 @@ void Nextion::set_writer(const nextion_writer_t &writer) { this->writer_ = write
ESPDEPRECATED("set_wait_for_ack(bool) is deprecated and has no effect", "v1.20")
void Nextion::set_wait_for_ack(bool wait_for_ack) { ESP_LOGE(TAG, "This command is deprecated"); }
bool Nextion::is_updating() { return this->is_updating_; }
} // namespace nextion
} // namespace esphome

View File

@ -50,6 +50,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will set the `txt` property of the component `textview` to `Hello World`.
*/
void set_component_text(const char *component, const char *text);
/**
* Set the text of a component to a formatted string
* @param component The component name.
@ -66,6 +67,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* For example when `uptime_sensor` = 506, then, `The uptime is: 506` will be displayed.
*/
void set_component_text_printf(const char *component, const char *format, ...) __attribute__((format(printf, 3, 4)));
/**
* Set the integer value of a component
* @param component The component name.
@ -78,7 +80,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*
* This will change the property `value` of the component `gauge` to 50.
*/
void set_component_value(const char *component, int value);
void set_component_value(const char *component, int32_t value);
/**
* Set the picture of an image component.
* @param component The component name.
@ -92,6 +95,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will change the image of the component `pic` to the image with ID `4`.
*/
void set_component_picture(const char *component, uint8_t picture_id);
/**
* Set the background color of a component.
* @param component The component name.
@ -107,6 +111,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Nextion HMI colors.
*/
void set_component_background_color(const char *component, uint16_t color);
/**
* Set the background color of a component.
* @param component The component name.
@ -121,6 +126,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void set_component_background_color(const char *component, const char *color);
/**
* Set the background color of a component.
* @param component The component name.
@ -135,6 +141,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will change the background color of the component `button` to blue.
*/
void set_component_background_color(const char *component, Color color) override;
/**
* Set the pressed background color of a component.
* @param component The component name.
@ -151,6 +158,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Nextion HMI colors.
*/
void set_component_pressed_background_color(const char *component, uint16_t color);
/**
* Set the pressed background color of a component.
* @param component The component name.
@ -166,6 +174,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void set_component_pressed_background_color(const char *component, const char *color);
/**
* Set the pressed background color of a component.
* @param component The component name.
@ -181,6 +190,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* is shown when the component is pressed.
*/
void set_component_pressed_background_color(const char *component, Color color) override;
/**
* Set the foreground color of a component.
* @param component The component name.
@ -196,6 +206,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Nextion HMI colors.
*/
void set_component_foreground_color(const char *component, uint16_t color);
/**
* Set the foreground color of a component.
* @param component The component name.
@ -210,6 +221,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void set_component_foreground_color(const char *component, const char *color);
/**
* Set the foreground color of a component.
* @param component The component name.
@ -223,6 +235,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will change the foreground color of the component `button` to black.
*/
void set_component_foreground_color(const char *component, Color color) override;
/**
* Set the pressed foreground color of a component.
* @param component The component name.
@ -239,6 +252,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Nextion HMI colors.
*/
void set_component_pressed_foreground_color(const char *component, uint16_t color);
/**
* Set the pressed foreground color of a component.
* @param component The component name.
@ -254,6 +268,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void set_component_pressed_foreground_color(const char *component, const char *color);
/**
* Set the pressed foreground color of a component.
* @param component The component name.
@ -283,6 +298,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will change the picture id of the component `textview`.
*/
void set_component_pic(const char *component, uint8_t pic_id);
/**
* Set the background picture id of component.
* @param component The component name.
@ -312,6 +328,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Nextion HMI colors.
*/
void set_component_font_color(const char *component, uint16_t color);
/**
* Set the font color of a component.
* @param component The component name.
@ -326,6 +343,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void set_component_font_color(const char *component, const char *color);
/**
* Set the font color of a component.
* @param component The component name.
@ -339,6 +357,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will change the font color of the component `textview` to black.
*/
void set_component_font_color(const char *component, Color color) override;
/**
* Set the pressed font color of a component.
* @param component The component name.
@ -354,6 +373,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Nextion HMI colors.
*/
void set_component_pressed_font_color(const char *component, uint16_t color);
/**
* Set the pressed font color of a component.
* @param component The component name.
@ -368,6 +388,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void set_component_pressed_font_color(const char *component, const char *color);
/**
* Set the pressed font color of a component.
* @param component The component name.
@ -381,6 +402,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* This will change the pressed font color of the component `button` to black.
*/
void set_component_pressed_font_color(const char *component, Color color) override;
/**
* Set the coordinates of a component on screen.
* @param component The component name.
@ -394,7 +416,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*
* This will move the position of the component `pic` to the x coordinate `55` and y coordinate `100`.
*/
void set_component_coordinates(const char *component, int x, int y);
void set_component_coordinates(const char *component, uint16_t x, uint16_t y);
/**
* Set the font id for a component.
* @param component The component name.
@ -408,6 +431,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Changes the font of the component named `textveiw`. Font IDs are set in the Nextion Editor.
*/
void set_component_font(const char *component, uint8_t font_id) override;
/**
* Send the current time to the nextion display.
* @param time The time instance to send (get this with id(my_time).now() ).
@ -426,6 +450,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Switches to the page named `main`. Pages are named in the Nextion Editor.
*/
void goto_page(const char *page);
/**
* Show the page with a given id.
* @param page The id of the page.
@ -438,6 +463,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Switches to the page named `main`. Pages are named in the Nextion Editor.
*/
void goto_page(uint8_t page);
/**
* Hide a component.
* @param component The component name.
@ -450,6 +476,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Hides the component named `button`.
*/
void hide_component(const char *component) override;
/**
* Show a component.
* @param component The component name.
@ -462,6 +489,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Shows the component named `button`.
*/
void show_component(const char *component) override;
/**
* Enable touch for a component.
* @param component The component name.
@ -474,6 +502,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Enables touch for component named `button`.
*/
void enable_component_touch(const char *component);
/**
* Disable touch for a component.
* @param component The component name.
@ -486,14 +515,17 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Disables touch for component named `button`.
*/
void disable_component_touch(const char *component);
/**
* Add waveform data to a waveform component
* @param component_id The integer component id.
* @param channel_number The channel number to write to.
* @param value The value to write.
*/
void add_waveform_data(int component_id, uint8_t channel_number, uint8_t value);
void open_waveform_channel(int component_id, uint8_t channel_number, uint8_t value);
void add_waveform_data(uint8_t component_id, uint8_t channel_number, uint8_t value);
void open_waveform_channel(uint8_t component_id, uint8_t channel_number, uint8_t value);
/**
* Display a picture at coordinates.
* @param picture_id The picture id.
@ -507,7 +539,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*
* Displays the picture who has the id `2` at the x coordinates `15` and y coordinates `25`.
*/
void display_picture(int picture_id, int x_start, int y_start);
void display_picture(uint16_t picture_id, uint16_t x_start, uint16_t y_start);
/**
* Fill a rectangle with a color.
* @param x1 The starting x coordinate.
@ -526,7 +559,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use this [color picker](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to convert color codes to
* Nextion HMI colors.
*/
void fill_area(int x1, int y1, int width, int height, uint16_t color);
void fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t color);
/**
* Fill a rectangle with a color.
* @param x1 The starting x coordinate.
@ -544,7 +578,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* the red color.
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void fill_area(int x1, int y1, int width, int height, const char *color);
void fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, const char *color);
/**
* Fill a rectangle with a color.
* @param x1 The starting x coordinate.
@ -562,7 +597,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Fills an area that starts at x coordinate `50` and y coordinate `50` with a height of `100` and width of `100` with
* blue color.
*/
void fill_area(int x1, int y1, int width, int height, Color color);
void fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, Color color);
/**
* Draw a line on the screen.
* @param x1 The starting x coordinate.
@ -581,7 +617,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use this [color picker](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to convert color codes to
* Nextion HMI colors.
*/
void line(int x1, int y1, int x2, int y2, uint16_t color);
void line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
/**
* Draw a line on the screen.
* @param x1 The starting x coordinate.
@ -599,7 +636,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* `75` with the blue color.
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void line(int x1, int y1, int x2, int y2, const char *color);
void line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, const char *color);
/**
* Draw a line on the screen.
* @param x1 The starting x coordinate.
@ -617,7 +655,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Makes a line that starts at x coordinate `50` and y coordinate `50` and ends at x coordinate `75` and y coordinate
* `75` with blue color.
*/
void line(int x1, int y1, int x2, int y2, Color color);
void line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, Color color);
/**
* Draw a rectangle outline.
* @param x1 The starting x coordinate.
@ -636,7 +675,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use this [color picker](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to convert color codes to
* Nextion HMI colors.
*/
void rectangle(int x1, int y1, int width, int height, uint16_t color);
void rectangle(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t color);
/**
* Draw a rectangle outline.
* @param x1 The starting x coordinate.
@ -654,7 +694,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* length of `50` with the blue color.
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void rectangle(int x1, int y1, int width, int height, const char *color);
void rectangle(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, const char *color);
/**
* Draw a rectangle outline.
* @param x1 The starting x coordinate.
@ -672,7 +713,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Makes a outline of a rectangle that starts at x coordinate `25` and y coordinate `35` and has a width of `40` and a
* length of `50` with blue color.
*/
void rectangle(int x1, int y1, int width, int height, Color color);
void rectangle(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, Color color);
/**
* Draw a circle outline
* @param center_x The center x coordinate.
@ -682,7 +724,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use this [color picker](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to convert color codes to
* Nextion HMI colors.
*/
void circle(int center_x, int center_y, int radius, uint16_t color);
void circle(uint16_t center_x, uint16_t center_y, uint16_t radius, uint16_t color);
/**
* Draw a circle outline
* @param center_x The center x coordinate.
@ -691,7 +734,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* @param color The color to draw with (as a string).
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void circle(int center_x, int center_y, int radius, const char *color);
void circle(uint16_t center_x, uint16_t center_y, uint16_t radius, const char *color);
/**
* Draw a circle outline
* @param center_x The center x coordinate.
@ -699,7 +743,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* @param radius The circle radius.
* @param color The color to draw with (as Color).
*/
void circle(int center_x, int center_y, int radius, Color color);
void circle(uint16_t center_x, uint16_t center_y, uint16_t radius, Color color);
/**
* Draw a filled circled.
* @param center_x The center x coordinate.
@ -716,7 +761,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Use this [color picker](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to convert color codes to
* Nextion HMI colors.
*/
void filled_circle(int center_x, int center_y, int radius, uint16_t color);
void filled_circle(uint16_t center_x, uint16_t center_y, uint16_t radius, uint16_t color);
/**
* Draw a filled circled.
* @param center_x The center x coordinate.
@ -732,7 +778,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Makes a filled circle at the x coordinate `25` and y coordinate `25` with a radius of `10` with the blue color.
* Use [Nextion Instruction Set](https://nextion.tech/instruction-set/#s5) for a list of Nextion HMI colors constants.
*/
void filled_circle(int center_x, int center_y, int radius, const char *color);
void filled_circle(uint16_t center_x, uint16_t center_y, uint16_t radius, const char *color);
/**
* Draw a filled circled.
* @param center_x The center x coordinate.
@ -748,7 +795,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*
* Makes a filled circle at the x coordinate `25` and y coordinate `25` with a radius of `10` with blue color.
*/
void filled_circle(int center_x, int center_y, int radius, Color color);
void filled_circle(uint16_t center_x, uint16_t center_y, uint16_t radius, Color color);
/**
* Draws a QR code in the screen
@ -768,8 +815,9 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*
* Draws a QR code with a Wi-Fi network credentials starting at the given coordinates (25,25).
*/
void qrcode(int x1, int y1, const char *content, int size = 200, uint16_t background_color = 65535,
uint16_t foreground_color = 0, int logo_pic = -1, uint8_t border_width = 8);
void qrcode(uint16_t x1, uint16_t y1, const char *content, uint16_t size = 200, uint16_t background_color = 65535,
uint16_t foreground_color = 0, uint8_t logo_pic = -1, uint8_t border_width = 8);
/**
* Draws a QR code in the screen
* @param x1 The top left x coordinate to start the QR code.
@ -791,8 +839,9 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Draws a QR code with a Wi-Fi network credentials starting at the given coordinates (25,25) with size of 150px in
* red on a blue background.
*/
void qrcode(int x1, int y1, const char *content, int size, Color background_color = Color(255, 255, 255),
Color foreground_color = Color(0, 0, 0), int logo_pic = -1, uint8_t border_width = 8);
void qrcode(uint16_t x1, uint16_t y1, const char *content, uint16_t size,
Color background_color = Color(255, 255, 255), Color foreground_color = Color(0, 0, 0),
uint8_t logo_pic = -1, uint8_t border_width = 8);
/** Set the brightness of the backlight.
*
@ -806,6 +855,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Changes the brightness of the display to 30%.
*/
void set_backlight_brightness(float brightness);
/**
* Set the touch sleep timeout of the display.
* @param timeout Timeout in seconds.
@ -819,6 +869,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* `thup`.
*/
void set_touch_sleep_timeout(uint16_t timeout);
/**
* Sets which page Nextion loads when exiting sleep mode. Note this can be set even when Nextion is in sleep mode.
* @param page_id The page id, from 0 to the lage page in Nextion. Set 255 (not set to any existing page) to
@ -832,6 +883,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* The display will wake up to page 2.
*/
void set_wake_up_page(uint8_t page_id = 255);
/**
* Sets which page Nextion loads when connecting to ESPHome.
* @param page_id The page id, from 0 to the lage page in Nextion. Set 255 (not set to any existing page) to
@ -859,6 +911,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* The display will wake up by touch.
*/
void set_auto_wake_on_touch(bool auto_wake);
/**
* Sets if Nextion should exit the active reparse mode before the "connect" command is sent
* @param exit_reparse True or false. When exit_reparse is true, the exit reparse command
@ -872,18 +925,32 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* The display will be requested to leave active reparse mode before setup.
*/
void set_exit_reparse_on_start(bool exit_reparse);
/**
* Sets Nextion mode between sleep and awake
* @param True or false. Sleep=true to enter sleep mode or sleep=false to exit sleep mode.
*/
void sleep(bool sleep);
/**
* Sets Nextion Protocol Reparse mode between active or passive
* @param True or false.
* active_mode=true to enter active protocol reparse mode
* active_mode=false to enter passive protocol reparse mode.
* @brief Sets the Nextion display's protocol reparse mode.
*
* This function toggles the Nextion display's protocol reparse mode between active and passive.
* In active mode, the display actively parses incoming data.
* In passive mode, it does not parse data unless specifically instructed to do so.
* This is useful for managing how the Nextion display interprets incoming commands,
* especially during initialization or in scenarios where precise control over command processing is needed.
*
* @param active_mode A boolean value indicating the desired reparse mode.
* - true to set the display to active protocol reparse mode, where it actively parses incoming commands.
* - false to set the display to passive protocol reparse mode, where command parsing is done only on explicit
* instruction.
*
* @return bool Returns true if all commands were sent successfully to the Nextion display, indicating that the mode
* was set as expected. Returns false if any of the commands failed to send, indicating that the desired reparse mode
* may not be correctly set.
*/
void set_protocol_reparse_mode(bool active_mode);
bool set_protocol_reparse_mode(bool active_mode);
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
@ -903,6 +970,12 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
// This function has been deprecated
void set_wait_for_ack(bool wait_for_ack);
/**
* Manually send a raw command to the display.
* @param command The pcommand, like "page 0"
* @return Whether the send was successful.
*/
bool send_command(const char *command);
/**
* Manually send a raw formatted command to the display.
* @param format The printf-style command format, like "vis %s,0"
@ -916,7 +989,6 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* Set the tft file URL. https seems problematic with arduino..
*/
void set_tft_url(const std::string &tft_url) { this->tft_url_ = tft_url; }
#endif
/**
@ -980,9 +1052,9 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
void set_nextion_sensor_state(NextionQueueType queue_type, const std::string &name, float state);
void set_nextion_text_state(const std::string &name, const std::string &state);
void add_no_result_to_queue_with_set(NextionComponentBase *component, int state_value) override;
void add_no_result_to_queue_with_set(NextionComponentBase *component, int32_t state_value) override;
void add_no_result_to_queue_with_set(const std::string &variable_name, const std::string &variable_name_to_send,
int state_value) override;
int32_t state_value) override;
void add_no_result_to_queue_with_set(NextionComponentBase *component, const std::string &state_value) override;
void add_no_result_to_queue_with_set(const std::string &variable_name, const std::string &variable_name_to_send,
@ -1019,6 +1091,26 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*/
size_t queue_size() { return this->nextion_queue_.size(); }
/**
* @brief Check if the TFT update process is currently running.
*
* This method provides a way to determine if the Nextion display is in the
* process of updating its TFT firmware. When a TFT update is in progress,
* certain operations or commands may be restricted or could interfere with the
* update process. By checking the state of the update process, the system can
* make informed decisions about performing actions that involve communication
* with the Nextion display.
*
* @return true if the TFT update process is active, indicating that the Nextion
* display is currently updating its firmware. This implies that caution
* should be taken with commands sent to the display to avoid interrupting
* the update process.
* @return false if the TFT update process is not active, indicating that the Nextion
* display is not currently updating its firmware and is in a normal operational
* state, ready to receive and process commands as usual.
*/
bool is_updating() override;
protected:
std::deque<NextionQueue *> nextion_queue_;
std::deque<NextionQueue *> waveform_queue_;
@ -1038,8 +1130,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
void process_serial_();
bool is_updating_ = false;
uint32_t touch_sleep_timeout_ = 0;
int wake_up_page_ = -1;
int start_up_page_ = -1;
int16_t wake_up_page_ = -1;
int16_t start_up_page_ = -1;
bool auto_wake_on_touch_ = true;
bool exit_reparse_on_start_ = false;
@ -1057,7 +1149,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
__attribute__((format(printf, 3, 4)));
void add_no_result_to_queue_with_set_internal_(const std::string &variable_name,
const std::string &variable_name_to_send, int state_value,
const std::string &variable_name_to_send, int32_t state_value,
bool is_sleep_safe = false);
void add_no_result_to_queue_with_set_internal_(const std::string &variable_name,
@ -1067,13 +1159,21 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
void check_pending_waveform_();
#ifdef USE_NEXTION_TFT_UPLOAD
uint32_t content_length_ = 0;
int tft_size_ = 0;
uint32_t original_baud_rate_ = 0;
bool upload_first_chunk_sent_ = false;
std::string tft_url_;
uint8_t *transfer_buffer_{nullptr};
size_t transfer_buffer_size_;
#ifdef USE_ESP8266
WiFiClient *wifi_client_{nullptr};
BearSSL::WiFiClientSecure *wifi_client_secure_{nullptr};
WiFiClient *get_wifi_client_();
#endif
int content_length_ = 0;
int tft_size_ = 0;
#ifdef ARDUINO
/**
* will request chunk_size chunks from the web server
@ -1146,13 +1246,6 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
void remove_front_no_sensors_();
#ifdef USE_NEXTION_TFT_UPLOAD
std::string tft_url_;
uint8_t *transfer_buffer_{nullptr};
size_t transfer_buffer_size_;
bool upload_first_chunk_sent_ = false;
#endif
#ifdef NEXTION_PROTOCOL_LOG
void print_queue_members_();
#endif
@ -1160,8 +1253,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
std::string command_data_;
bool is_connected_ = false;
uint32_t startup_override_ms_ = 8000;
uint32_t max_q_age_ms_ = 8000;
const uint16_t startup_override_ms_ = 8000;
const uint16_t max_q_age_ms_ = 8000;
uint32_t started_ms_ = 0;
bool sent_setup_commands_ = false;
};

View File

@ -24,9 +24,9 @@ class NextionBase;
class NextionBase {
public:
virtual void add_no_result_to_queue_with_set(NextionComponentBase *component, int state_value) = 0;
virtual void add_no_result_to_queue_with_set(NextionComponentBase *component, int32_t state_value) = 0;
virtual void add_no_result_to_queue_with_set(const std::string &variable_name,
const std::string &variable_name_to_send, int state_value) = 0;
const std::string &variable_name_to_send, int32_t state_value) = 0;
virtual void add_no_result_to_queue_with_set(NextionComponentBase *component, const std::string &state_value) = 0;
virtual void add_no_result_to_queue_with_set(const std::string &variable_name,
@ -48,6 +48,8 @@ class NextionBase {
virtual void show_component(const char *component) = 0;
virtual void hide_component(const char *component) = 0;
virtual bool is_updating() { return false; }
bool is_sleeping() { return this->is_sleeping_; }
bool is_setup() { return this->is_setup_; }
bool is_detected() { return this->is_detected_; }

View File

@ -36,22 +36,23 @@ void Nextion::sleep(bool sleep) {
// End sleep safe commands
// Protocol reparse mode
void Nextion::set_protocol_reparse_mode(bool active_mode) {
const uint8_t to_send[3] = {0xFF, 0xFF, 0xFF};
bool Nextion::set_protocol_reparse_mode(bool active_mode) {
ESP_LOGV(TAG, "Set Nextion protocol reparse mode: %s", YESNO(active_mode));
this->ignore_is_setup_ = true; // if not in reparse mode setup will fail, so it should be ignored
bool all_commands_sent = true;
if (active_mode) { // Sets active protocol reparse mode
this->write_str(
"recmod=1"); // send_command_ cannot be used as Nextion might not be setup if incorrect reparse mode
this->write_array(to_send, sizeof(to_send));
} else { // Sets passive protocol reparse mode
this->write_str("DRAKJHSUYDGBNCJHGJKSHBDN"); // To exit active reparse mode this sequence must be sent
this->write_array(to_send, sizeof(to_send));
this->write_str("recmod=0"); // Sending recmode=0 twice is recommended
this->write_array(to_send, sizeof(to_send));
this->write_str("recmod=0");
this->write_array(to_send, sizeof(to_send));
all_commands_sent &= this->send_command_("recmod=1");
} else { // Sets passive protocol reparse mode
all_commands_sent &=
this->send_command_("DRAKJHSUYDGBNCJHGJKSHBDN"); // To exit active reparse mode this sequence must be sent
all_commands_sent &= this->send_command_("recmod=0"); // Sending recmode=0 twice is recommended
all_commands_sent &= this->send_command_("recmod=0");
}
this->write_str("connect");
this->write_array(to_send, sizeof(to_send));
if (!this->nextion_reports_is_setup_) { // No need to connect if is already setup
all_commands_sent &= this->send_command_("connect");
}
this->ignore_is_setup_ = false;
return all_commands_sent;
}
void Nextion::set_exit_reparse_on_start(bool exit_reparse) { this->exit_reparse_on_start_ = exit_reparse; }
@ -143,11 +144,11 @@ void Nextion::set_component_pressed_font_color(const char *component, Color colo
// Set picture
void Nextion::set_component_pic(const char *component, uint8_t pic_id) {
this->add_no_result_to_queue_with_printf_("set_component_pic", "%s.pic=%d", component, pic_id);
this->add_no_result_to_queue_with_printf_("set_component_pic", "%s.pic=%" PRIu8, component, pic_id);
}
void Nextion::set_component_picc(const char *component, uint8_t pic_id) {
this->add_no_result_to_queue_with_printf_("set_component_pic", "%s.picc=%d", component, pic_id);
this->add_no_result_to_queue_with_printf_("set_component_pic", "%s.picc=%" PRIu8, component, pic_id);
}
void Nextion::set_component_text_printf(const char *component, const char *format, ...) {
@ -178,7 +179,7 @@ void Nextion::set_auto_wake_on_touch(bool auto_wake) {
// General Component
void Nextion::set_component_font(const char *component, uint8_t font_id) {
this->add_no_result_to_queue_with_printf_("set_component_font", "%s.font=%d", component, font_id);
this->add_no_result_to_queue_with_printf_("set_component_font", "%s.font=%" PRIu8, component, font_id);
}
void Nextion::hide_component(const char *component) {
@ -198,113 +199,130 @@ void Nextion::disable_component_touch(const char *component) {
}
void Nextion::set_component_picture(const char *component, uint8_t picture_id) {
this->add_no_result_to_queue_with_printf_("set_component_picture", "%s.pic=%d", component, picture_id);
this->add_no_result_to_queue_with_printf_("set_component_picture", "%s.pic=%" PRIu8, component, picture_id);
}
void Nextion::set_component_text(const char *component, const char *text) {
this->add_no_result_to_queue_with_printf_("set_component_text", "%s.txt=\"%s\"", component, text);
}
void Nextion::set_component_value(const char *component, int value) {
this->add_no_result_to_queue_with_printf_("set_component_value", "%s.val=%d", component, value);
void Nextion::set_component_value(const char *component, int32_t value) {
this->add_no_result_to_queue_with_printf_("set_component_value", "%s.val=%" PRId32, component, value);
}
void Nextion::add_waveform_data(int component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("add_waveform_data", "add %d,%u,%u", component_id, channel_number, value);
void Nextion::add_waveform_data(uint8_t component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("add_waveform_data", "add %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id,
channel_number, value);
}
void Nextion::open_waveform_channel(int component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("open_waveform_channel", "addt %d,%u,%u", component_id, channel_number,
value);
void Nextion::open_waveform_channel(uint8_t component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("open_waveform_channel", "addt %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id,
channel_number, value);
}
void Nextion::set_component_coordinates(const char *component, int x, int y) {
this->add_no_result_to_queue_with_printf_("set_component_coordinates command 1", "%s.xcen=%d", component, x);
this->add_no_result_to_queue_with_printf_("set_component_coordinates command 2", "%s.ycen=%d", component, y);
void Nextion::set_component_coordinates(const char *component, uint16_t x, uint16_t y) {
this->add_no_result_to_queue_with_printf_("set_component_coordinates command 1", "%s.xcen=%" PRIu16, component, x);
this->add_no_result_to_queue_with_printf_("set_component_coordinates command 2", "%s.ycen=%" PRIu16, component, y);
}
// Drawing
void Nextion::display_picture(int picture_id, int x_start, int y_start) {
this->add_no_result_to_queue_with_printf_("display_picture", "pic %d, %d, %d", x_start, y_start, picture_id);
void Nextion::display_picture(uint16_t picture_id, uint16_t x_start, uint16_t y_start) {
this->add_no_result_to_queue_with_printf_("display_picture", "pic %" PRIu16 ", %" PRIu16 ", %" PRIu16, x_start,
y_start, picture_id);
}
void Nextion::fill_area(int x1, int y1, int width, int height, uint16_t color) {
this->add_no_result_to_queue_with_printf_("fill_area", "fill %d,%d,%d,%d,%" PRIu16, x1, y1, width, height, color);
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t color) {
this->add_no_result_to_queue_with_printf_(
"fill_area", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1, y1, width, height, color);
}
void Nextion::fill_area(int x1, int y1, int width, int height, const char *color) {
this->add_no_result_to_queue_with_printf_("fill_area", "fill %d,%d,%d,%d,%s", x1, y1, width, height, color);
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, const char *color) {
this->add_no_result_to_queue_with_printf_("fill_area", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", x1,
y1, width, height, color);
}
void Nextion::fill_area(int x1, int y1, int width, int height, Color color) {
this->add_no_result_to_queue_with_printf_("fill_area", "fill %d,%d,%d,%d,%d", x1, y1, width, height,
display::ColorUtil::color_to_565(color));
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, Color color) {
this->add_no_result_to_queue_with_printf_("fill_area",
"fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1, y1,
width, height, display::ColorUtil::color_to_565(color));
}
void Nextion::line(int x1, int y1, int x2, int y2, uint16_t color) {
this->add_no_result_to_queue_with_printf_("line", "line %d,%d,%d,%d,%" PRIu16, x1, y1, x2, y2, color);
void Nextion::line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
this->add_no_result_to_queue_with_printf_("line", "line %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1,
y1, x2, y2, color);
}
void Nextion::line(int x1, int y1, int x2, int y2, const char *color) {
this->add_no_result_to_queue_with_printf_("line", "line %d,%d,%d,%d,%s", x1, y1, x2, y2, color);
void Nextion::line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, const char *color) {
this->add_no_result_to_queue_with_printf_("line", "line %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", x1, y1,
x2, y2, color);
}
void Nextion::line(int x1, int y1, int x2, int y2, Color color) {
this->add_no_result_to_queue_with_printf_("line", "line %d,%d,%d,%d,%d", x1, y1, x2, y2,
display::ColorUtil::color_to_565(color));
void Nextion::line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, Color color) {
this->add_no_result_to_queue_with_printf_("line", "line %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1,
y1, x2, y2, display::ColorUtil::color_to_565(color));
}
void Nextion::rectangle(int x1, int y1, int width, int height, uint16_t color) {
this->add_no_result_to_queue_with_printf_("draw", "draw %d,%d,%d,%d,%" PRIu16, x1, y1, x1 + width, y1 + height,
void Nextion::rectangle(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t color) {
this->add_no_result_to_queue_with_printf_("draw", "draw %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1,
y1, static_cast<uint16_t>(x1 + width), static_cast<uint16_t>(y1 + height),
color);
}
void Nextion::rectangle(int x1, int y1, int width, int height, const char *color) {
this->add_no_result_to_queue_with_printf_("draw", "draw %d,%d,%d,%d,%s", x1, y1, x1 + width, y1 + height, color);
void Nextion::rectangle(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, const char *color) {
this->add_no_result_to_queue_with_printf_("draw", "draw %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", x1, y1,
static_cast<uint16_t>(x1 + width), static_cast<uint16_t>(y1 + height),
color);
}
void Nextion::rectangle(int x1, int y1, int width, int height, Color color) {
this->add_no_result_to_queue_with_printf_("draw", "draw %d,%d,%d,%d,%d", x1, y1, x1 + width, y1 + height,
void Nextion::rectangle(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, Color color) {
this->add_no_result_to_queue_with_printf_("draw", "draw %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1,
y1, static_cast<uint16_t>(x1 + width), static_cast<uint16_t>(y1 + height),
display::ColorUtil::color_to_565(color));
}
void Nextion::circle(int center_x, int center_y, int radius, uint16_t color) {
this->add_no_result_to_queue_with_printf_("cir", "cir %d,%d,%d,%" PRIu16, center_x, center_y, radius, color);
void Nextion::circle(uint16_t center_x, uint16_t center_y, uint16_t radius, uint16_t color) {
this->add_no_result_to_queue_with_printf_("cir", "cir %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, center_x,
center_y, radius, color);
}
void Nextion::circle(int center_x, int center_y, int radius, const char *color) {
this->add_no_result_to_queue_with_printf_("cir", "cir %d,%d,%d,%s", center_x, center_y, radius, color);
void Nextion::circle(uint16_t center_x, uint16_t center_y, uint16_t radius, const char *color) {
this->add_no_result_to_queue_with_printf_("cir", "cir %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", center_x, center_y,
radius, color);
}
void Nextion::circle(int center_x, int center_y, int radius, Color color) {
this->add_no_result_to_queue_with_printf_("cir", "cir %d,%d,%d,%d", center_x, center_y, radius,
display::ColorUtil::color_to_565(color));
void Nextion::circle(uint16_t center_x, uint16_t center_y, uint16_t radius, Color color) {
this->add_no_result_to_queue_with_printf_("cir", "cir %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, center_x,
center_y, radius, display::ColorUtil::color_to_565(color));
}
void Nextion::filled_circle(int center_x, int center_y, int radius, uint16_t color) {
this->add_no_result_to_queue_with_printf_("cirs", "cirs %d,%d,%d,%" PRIu16, center_x, center_y, radius, color);
void Nextion::filled_circle(uint16_t center_x, uint16_t center_y, uint16_t radius, uint16_t color) {
this->add_no_result_to_queue_with_printf_("cirs", "cirs %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, center_x,
center_y, radius, color);
}
void Nextion::filled_circle(int center_x, int center_y, int radius, const char *color) {
this->add_no_result_to_queue_with_printf_("cirs", "cirs %d,%d,%d,%s", center_x, center_y, radius, color);
void Nextion::filled_circle(uint16_t center_x, uint16_t center_y, uint16_t radius, const char *color) {
this->add_no_result_to_queue_with_printf_("cirs", "cirs %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", center_x, center_y,
radius, color);
}
void Nextion::filled_circle(int center_x, int center_y, int radius, Color color) {
this->add_no_result_to_queue_with_printf_("cirs", "cirs %d,%d,%d,%d", center_x, center_y, radius,
display::ColorUtil::color_to_565(color));
void Nextion::filled_circle(uint16_t center_x, uint16_t center_y, uint16_t radius, Color color) {
this->add_no_result_to_queue_with_printf_("cirs", "cirs %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, center_x,
center_y, radius, display::ColorUtil::color_to_565(color));
}
void Nextion::qrcode(int x1, int y1, const char *content, int size, uint16_t background_color,
uint16_t foreground_color, int logo_pic, uint8_t border_width) {
this->add_no_result_to_queue_with_printf_("qrcode", "qrcode %d,%d,%d,%d,%d,%d,%d,\"%s\"", x1, y1, size,
background_color, foreground_color, logo_pic, border_width, content);
}
void Nextion::qrcode(int x1, int y1, const char *content, int size, Color background_color, Color foreground_color,
int logo_pic, uint8_t border_width) {
void Nextion::qrcode(uint16_t x1, uint16_t y1, const char *content, uint16_t size, uint16_t background_color,
uint16_t foreground_color, uint8_t logo_pic, uint8_t border_width) {
this->add_no_result_to_queue_with_printf_(
"qrcode", "qrcode %d,%d,%d,%d,%d,%d,%d,\"%s\"", x1, y1, size, display::ColorUtil::color_to_565(background_color),
display::ColorUtil::color_to_565(foreground_color), logo_pic, border_width, content);
"qrcode", "qrcode %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu8 ",%" PRIu8 ",\"%s\"", x1,
y1, size, background_color, foreground_color, logo_pic, border_width, content);
}
void Nextion::qrcode(uint16_t x1, uint16_t y1, const char *content, uint16_t size, Color background_color,
Color foreground_color, uint8_t logo_pic, uint8_t border_width) {
this->add_no_result_to_queue_with_printf_(
"qrcode", "qrcode %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu8 ",%" PRIu8 ",\"%s\"", x1,
y1, size, display::ColorUtil::color_to_565(background_color), display::ColorUtil::color_to_565(foreground_color),
logo_pic, border_width, content);
}
void Nextion::set_nextion_rtc_time(ESPTime time) {

View File

@ -30,7 +30,7 @@ void NextionSensor::add_to_wave_buffer(float state) {
}
void NextionSensor::update() {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
if (this->wave_chan_id_ == UINT8_MAX) {
@ -45,7 +45,7 @@ void NextionSensor::update() {
}
void NextionSensor::set_state(float state, bool publish, bool send_to_nextion) {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
if (std::isnan(state))

View File

@ -18,13 +18,13 @@ void NextionSwitch::process_bool(const std::string &variable_name, bool on) {
}
void NextionSwitch::update() {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
this->nextion_->add_to_get_queue(this);
}
void NextionSwitch::set_state(bool state, bool publish, bool send_to_nextion) {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
if (send_to_nextion) {

View File

@ -16,13 +16,13 @@ void NextionTextSensor::process_text(const std::string &variable_name, const std
}
void NextionTextSensor::update() {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
this->nextion_->add_to_get_queue(this);
}
void NextionTextSensor::set_state(const std::string &state, bool publish, bool send_to_nextion) {
if (!this->nextion_->is_setup())
if (!this->nextion_->is_setup() || this->nextion_->is_updating())
return;
if (send_to_nextion) {

View File

@ -239,13 +239,14 @@ async def setup_number_core_(
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
if CONF_UNIT_OF_MEASUREMENT in config:
cg.add(var.traits.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (unit_of_measurement := config.get(CONF_UNIT_OF_MEASUREMENT)) is not None:
cg.add(var.traits.set_unit_of_measurement(unit_of_measurement))
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.traits.set_device_class(device_class))
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if CONF_DEVICE_CLASS in config:
cg.add(var.traits.set_device_class(config[CONF_DEVICE_CLASS]))
async def register_number(
@ -284,10 +285,10 @@ async def number_in_range_to_code(config, condition_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(condition_id, template_arg, paren)
if CONF_ABOVE in config:
cg.add(var.set_min(config[CONF_ABOVE]))
if CONF_BELOW in config:
cg.add(var.set_max(config[CONF_BELOW]))
if (above := config.get(CONF_ABOVE)) is not None:
cg.add(var.set_min(above))
if (below := config.get(CONF_BELOW)) is not None:
cg.add(var.set_max(below))
return var
@ -391,14 +392,14 @@ async def number_set_to_code(config, action_id, template_arg, args):
async def number_to_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_OPERATION in config:
to_ = await cg.templatable(config[CONF_OPERATION], args, NumberOperation)
if (operation := config.get(CONF_OPERATION)) is not None:
to_ = await cg.templatable(operation, args, NumberOperation)
cg.add(var.set_operation(to_))
if CONF_CYCLE in config:
cycle_ = await cg.templatable(config[CONF_CYCLE], args, bool)
cg.add(var.set_cycle(cycle_))
if CONF_MODE in config:
cg.add(var.set_operation(NUMBER_OPERATION_OPTIONS[config[CONF_MODE]]))
if CONF_CYCLE in config:
cg.add(var.set_cycle(config[CONF_CYCLE]))
if (cycle := config.get(CONF_CYCLE)) is not None:
template_ = await cg.templatable(cycle, args, bool)
cg.add(var.set_cycle(template_))
if (mode := config.get(CONF_MODE)) is not None:
cg.add(var.set_operation(NUMBER_OPERATION_OPTIONS[mode]))
if (cycle := config.get(CONF_CYCLE)) is not None:
cg.add(var.set_cycle(cycle))
return var

View File

@ -54,5 +54,7 @@ async def to_code(config):
if CONF_SPEED in config:
add_idf_sdkconfig_option(f"{SPIRAM_SPEEDS[config[CONF_SPEED]]}", True)
cg.add_define("USE_PSRAM")
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)

View File

@ -95,8 +95,8 @@ async def setup_select_core_(var, config, *, options: list[str]):
trigger, [(cg.std_string, "x"), (cg.size_t, "i")], conf
)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
@ -223,14 +223,14 @@ async def select_set_index_to_code(config, action_id, template_arg, args):
async def select_operation_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_OPERATION in config:
op_ = await cg.templatable(config[CONF_OPERATION], args, SelectOperation)
if (operation := config.get(CONF_OPERATION)) is not None:
op_ = await cg.templatable(operation, args, SelectOperation)
cg.add(var.set_operation(op_))
if CONF_CYCLE in config:
cycle_ = await cg.templatable(config[CONF_CYCLE], args, bool)
cg.add(var.set_cycle(cycle_))
if CONF_MODE in config:
cg.add(var.set_operation(SELECT_OPERATION_OPTIONS[config[CONF_MODE]]))
if CONF_CYCLE in config:
cg.add(var.set_cycle(config[CONF_CYCLE]))
if (cycle := config.get(CONF_CYCLE)) is not None:
template_ = await cg.templatable(cycle, args, bool)
cg.add(var.set_cycle(template_))
if (mode := config.get(CONF_MODE)) is not None:
cg.add(var.set_operation(SELECT_OPERATION_OPTIONS[mode]))
if (cycle := config.get(CONF_CYCLE)) is not None:
cg.add(var.set_cycle(cycle))
return var

View File

@ -12,7 +12,7 @@ void Select::publish_state(const std::string &state) {
if (index.has_value()) {
this->has_state_ = true;
this->state = state;
ESP_LOGD(TAG, "'%s': Sending state %s (index %d)", name, state.c_str(), index.value());
ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", name, state.c_str(), index.value());
this->state_callback_.call(state, index.value());
} else {
ESP_LOGE(TAG, "'%s': invalid state for publish_state(): %s", name, state.c_str());

View File

@ -71,7 +71,7 @@ void SelectCall::perform() {
return;
}
if (this->index_.value() >= options.size()) {
ESP_LOGW(TAG, "'%s' - Index value %d out of bounds", name, this->index_.value());
ESP_LOGW(TAG, "'%s' - Index value %zu out of bounds", name, this->index_.value());
return;
}
target_value = options[this->index_.value()];

View File

@ -732,14 +732,14 @@ async def build_filters(config):
async def setup_sensor_core_(var, config):
await setup_entity(var, config)
if CONF_DEVICE_CLASS in config:
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
if CONF_STATE_CLASS in config:
cg.add(var.set_state_class(config[CONF_STATE_CLASS]))
if CONF_UNIT_OF_MEASUREMENT in config:
cg.add(var.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
if CONF_ACCURACY_DECIMALS in config:
cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
if (state_class := config.get(CONF_STATE_CLASS)) is not None:
cg.add(var.set_state_class(state_class))
if (unit_of_measurement := config.get(CONF_UNIT_OF_MEASUREMENT)) is not None:
cg.add(var.set_unit_of_measurement(unit_of_measurement))
if (accuracy_decimals := config.get(CONF_ACCURACY_DECIMALS)) is not None:
cg.add(var.set_accuracy_decimals(accuracy_decimals))
cg.add(var.set_force_update(config[CONF_FORCE_UPDATE]))
if config.get(CONF_FILTERS): # must exist and not be empty
filters = await build_filters(config[CONF_FILTERS])
@ -754,23 +754,23 @@ async def setup_sensor_core_(var, config):
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if CONF_ABOVE in conf:
template_ = await cg.templatable(conf[CONF_ABOVE], [(float, "x")], float)
if (above := conf.get(CONF_ABOVE)) is not None:
template_ = await cg.templatable(above, [(float, "x")], float)
cg.add(trigger.set_min(template_))
if CONF_BELOW in conf:
template_ = await cg.templatable(conf[CONF_BELOW], [(float, "x")], float)
if (below := conf.get(CONF_BELOW)) is not None:
template_ = await cg.templatable(below, [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if CONF_EXPIRE_AFTER in config:
if config[CONF_EXPIRE_AFTER] is None:
if (expire_after := config.get(CONF_EXPIRE_AFTER, _UNDEF)) is not _UNDEF:
if expire_after is None:
cg.add(mqtt_.disable_expire_after())
else:
cg.add(mqtt_.set_expire_after(config[CONF_EXPIRE_AFTER]))
cg.add(mqtt_.set_expire_after(expire_after))
async def register_sensor(var, config):
@ -803,10 +803,10 @@ async def sensor_in_range_to_code(config, condition_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(condition_id, template_arg, paren)
if CONF_ABOVE in config:
cg.add(var.set_min(config[CONF_ABOVE]))
if CONF_BELOW in config:
cg.add(var.set_max(config[CONF_BELOW]))
if (above := config.get(CONF_ABOVE)) is not None:
cg.add(var.set_min(above))
if (below := config.get(CONF_BELOW)) is not None:
cg.add(var.set_max(below))
return var

View File

@ -79,7 +79,7 @@ SkipInitialFilter::SkipInitialFilter(size_t num_to_ignore) : num_to_ignore_(num_
optional<float> SkipInitialFilter::new_value(float value) {
if (num_to_ignore_ > 0) {
num_to_ignore_--;
ESP_LOGV(TAG, "SkipInitialFilter(%p)::new_value(%f) SKIPPING, %u left", this, value, num_to_ignore_);
ESP_LOGV(TAG, "SkipInitialFilter(%p)::new_value(%f) SKIPPING, %zu left", this, value, num_to_ignore_);
return {};
}

View File

@ -106,23 +106,23 @@ void SM2135::loop() {
delay(1);
this->sm2135_start_();
this->write_byte_(SM2135_ADDR_C);
this->write_byte_(this->pwm_amounts_[4]); // Warm
this->write_byte_(this->pwm_amounts_[3]); // Cold
this->write_byte_(this->pwm_amounts_[3]);
this->write_byte_(this->pwm_amounts_[4]);
} else {
// Color
this->write_byte_(SM2135_RGB);
this->write_byte_(this->pwm_amounts_[1]); // Green
this->write_byte_(this->pwm_amounts_[0]); // Red
this->write_byte_(this->pwm_amounts_[2]); // Blue
this->write_byte_(this->pwm_amounts_[0]);
this->write_byte_(this->pwm_amounts_[1]);
this->write_byte_(this->pwm_amounts_[2]);
}
} else {
this->write_byte_(SM2135_RGB);
this->write_byte_(this->pwm_amounts_[1]); // Green
this->write_byte_(this->pwm_amounts_[0]); // Red
this->write_byte_(this->pwm_amounts_[2]); // Blue
this->write_byte_(this->pwm_amounts_[4]); // Warm
this->write_byte_(this->pwm_amounts_[3]); // Cold
this->write_byte_(this->pwm_amounts_[0]);
this->write_byte_(this->pwm_amounts_[1]);
this->write_byte_(this->pwm_amounts_[2]);
this->write_byte_(this->pwm_amounts_[3]);
this->write_byte_(this->pwm_amounts_[4]);
}
this->sm2135_stop_();

View File

@ -138,8 +138,8 @@ SWITCH_SCHEMA = switch_schema() # for compatibility
async def setup_switch_core_(var, config):
await setup_entity(var, config)
if CONF_INVERTED in config:
cg.add(var.set_inverted(config[CONF_INVERTED]))
if (inverted := config.get(CONF_INVERTED)) is not None:
cg.add(var.set_inverted(inverted))
for conf in config.get(CONF_ON_TURN_ON, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
@ -147,12 +147,12 @@ async def setup_switch_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if CONF_DEVICE_CLASS in config:
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE]))

View File

@ -73,8 +73,8 @@ async def setup_text_core_(
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)

View File

@ -186,8 +186,8 @@ async def build_filters(config):
async def setup_text_sensor_core_(var, config):
await setup_entity(var, config)
if CONF_DEVICE_CLASS in config:
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
if config.get(CONF_FILTERS): # must exist and not be empty
filters = await build_filters(config[CONF_FILTERS])
@ -201,8 +201,8 @@ async def setup_text_sensor_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)

View File

@ -49,7 +49,7 @@ def _load_tzdata(iana_key: str) -> Optional[bytes]:
package = "tzdata.zoneinfo." + package_loc.replace("/", ".")
try:
return resources.read_binary(package, resource)
return (resources.files(package) / resource).read_bytes()
except (FileNotFoundError, ModuleNotFoundError):
return None

View File

@ -28,23 +28,24 @@ void TMP102Component::dump_config() {
}
void TMP102Component::update() {
int16_t raw_temperature;
if (this->write(&TMP102_REGISTER_TEMPERATURE, 1) != i2c::ERROR_OK) {
this->status_set_warning();
return;
}
delay(50); // NOLINT
if (this->read(reinterpret_cast<uint8_t *>(&raw_temperature), 2) != i2c::ERROR_OK) {
this->status_set_warning();
return;
}
raw_temperature = i2c::i2ctohs(raw_temperature);
raw_temperature = raw_temperature >> 4;
float temperature = raw_temperature * TMP102_CONVERSION_FACTOR;
ESP_LOGD(TAG, "Got Temperature=%.1f°C", temperature);
this->set_timeout("read_temp", 50, [this]() {
int16_t raw_temperature;
if (this->read(reinterpret_cast<uint8_t *>(&raw_temperature), 2) != i2c::ERROR_OK) {
this->status_set_warning();
return;
}
raw_temperature = i2c::i2ctohs(raw_temperature);
raw_temperature = raw_temperature >> 4;
float temperature = raw_temperature * TMP102_CONVERSION_FACTOR;
ESP_LOGD(TAG, "Got Temperature=%.1f°C", temperature);
this->publish_state(temperature);
this->status_clear_warning();
this->publish_state(temperature);
this->status_clear_warning();
});
}
float TMP102Component::get_setup_priority() const { return setup_priority::DATA; }

View File

@ -208,7 +208,7 @@ async def to_code(config):
cg.add(var.set_switch_id(switch_datapoint))
if active_state_config := config.get(CONF_ACTIVE_STATE):
cg.add(var.set_active_state_id(CONF_DATAPOINT))
cg.add(var.set_active_state_id(active_state_config.get(CONF_DATAPOINT)))
if (heating_value := active_state_config.get(CONF_HEATING_VALUE)) is not None:
cg.add(var.set_active_state_heating_value(heating_value))
if (cooling_value := active_state_config.get(CONF_COOLING_VALUE)) is not None:
@ -219,14 +219,10 @@ async def to_code(config):
cg.add(var.set_active_state_fanonly_value(fanonly_value))
else:
if heating_state_pin_config := config.get(CONF_HEATING_STATE_PIN):
heating_state_pin = await cg.gpio_pin_expression(
config(heating_state_pin_config)
)
heating_state_pin = await cg.gpio_pin_expression(heating_state_pin_config)
cg.add(var.set_heating_state_pin(heating_state_pin))
if cooling_state_pin_config := config.get(CONF_COOLING_STATE_PIN):
cooling_state_pin = await cg.gpio_pin_expression(
config(cooling_state_pin_config)
)
cooling_state_pin = await cg.gpio_pin_expression(cooling_state_pin_config)
cg.add(var.set_cooling_state_pin(cooling_state_pin))
if target_temperature_datapoint := config.get(CONF_TARGET_TEMPERATURE_DATAPOINT):
@ -254,11 +250,11 @@ async def to_code(config):
if preset_config := config.get(CONF_PRESET, {}):
if eco_config := preset_config.get(CONF_ECO, {}):
cg.add(var.set_eco_id(CONF_DATAPOINT))
cg.add(var.set_eco_id(eco_config.get(CONF_DATAPOINT)))
if eco_temperature := eco_config.get(CONF_TEMPERATURE):
cg.add(var.set_eco_temperature(eco_temperature))
if CONF_SLEEP in preset_config:
cg.add(var.set_sleep_id(CONF_DATAPOINT))
if sleep_config := preset_config.get(CONF_SLEEP, {}):
cg.add(var.set_sleep_id(sleep_config.get(CONF_DATAPOINT)))
if swing_mode_config := config.get(CONF_SWING_MODE):
if swing_vertical_datapoint := swing_mode_config.get(CONF_VERTICAL_DATAPOINT):
@ -268,7 +264,7 @@ async def to_code(config):
):
cg.add(var.set_swing_horizontal_id(swing_horizontal_datapoint))
if fan_mode_config := config.get(CONF_FAN_MODE):
cg.add(var.set_fan_speed_id(CONF_DATAPOINT))
cg.add(var.set_fan_speed_id(fan_mode_config.get(CONF_DATAPOINT)))
if (fan_auto_value := fan_mode_config.get(CONF_AUTO_VALUE)) is not None:
cg.add(var.set_fan_speed_auto_value(fan_auto_value))
if (fan_low_value := fan_mode_config.get(CONF_LOW_VALUE)) is not None:

View File

@ -729,6 +729,7 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
}
void VoiceAssistant::on_audio(const api::VoiceAssistantAudio &msg) {
#ifdef USE_SPEAKER // We should never get to this function if there is no speaker anyway
if (this->speaker_buffer_index_ + msg.data.length() < SPEAKER_BUFFER_SIZE) {
memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data.data(), msg.data.length());
this->speaker_buffer_index_ += msg.data.length();
@ -737,6 +738,7 @@ void VoiceAssistant::on_audio(const api::VoiceAssistantAudio &msg) {
} else {
ESP_LOGE(TAG, "Cannot receive audio, buffer is full");
}
#endif
}
VoiceAssistant *global_voice_assistant = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)

View File

@ -39,15 +39,10 @@ class IPAddressWiFiInfo : public PollingComponent, public text_sensor::TextSenso
class DNSAddressWifiInfo : public PollingComponent, public text_sensor::TextSensor {
public:
void update() override {
std::string dns_results;
auto dns_one = wifi::global_wifi_component->get_dns_address(0);
auto dns_two = wifi::global_wifi_component->get_dns_address(1);
dns_results += "DNS1: ";
dns_results += dns_one.str();
dns_results += " DNS2: ";
dns_results += dns_two.str();
std::string dns_results = dns_one.str() + " " + dns_two.str();
if (dns_results != this->last_results_) {
this->last_results_ = dns_results;

View File

@ -333,10 +333,11 @@ class LoadValidationStep(ConfigValidationStep):
if load not in result:
result.add_validation_step(AutoLoadValidationStep(load))
result.add_validation_step(
MetadataValidationStep([self.domain], self.domain, self.conf, component)
)
if not component.is_platform_component:
result.add_validation_step(
MetadataValidationStep([self.domain], self.domain, self.conf, component)
)
return
# This is a platform component, proceed to reading platform entries
@ -520,8 +521,6 @@ class SchemaValidationStep(ConfigValidationStep):
self.comp = comp
def run(self, result: Config) -> None:
if self.comp.config_schema is None:
return
token = path_context.set(self.path)
with result.catch_error(self.path):
if self.comp.is_platform:
@ -536,7 +535,7 @@ class SchemaValidationStep(ConfigValidationStep):
validated["platform"] = platform_val
validated.move_to_end("platform", last=False)
result.set_by_path(self.path, validated)
else:
elif self.comp.config_schema is not None:
schema = cv.Schema(self.comp.config_schema)
validated = schema(self.conf)
result.set_by_path(self.path, validated)

View File

@ -1590,6 +1590,10 @@ def typed_schema(schemas, **kwargs):
"""Create a schema that has a key to distinguish between schemas"""
key = kwargs.pop("key", CONF_TYPE)
default_schema_option = kwargs.pop("default_type", None)
enum_mapping = kwargs.pop("enum", None)
if enum_mapping is not None:
assert isinstance(enum_mapping, dict)
assert set(enum_mapping.keys()) == set(schemas.keys())
key_validator = one_of(*schemas, **kwargs)
def validator(value):
@ -1600,6 +1604,9 @@ def typed_schema(schemas, **kwargs):
if schema_option is None:
raise Invalid(f"{key} not specified!")
key_v = key_validator(schema_option)
if enum_mapping is not None:
key_v = add_class_to_obj(key_v, core.EnumValue)
key_v.enum_value = enum_mapping[key_v]
value = Schema(schemas[key_v])(value)
value[key] = key_v
return value

View File

@ -134,7 +134,7 @@ class ProjectUpdateTrigger : public Trigger<std::string>, public Component {
uint32_t hash = fnv1_hash(ESPHOME_PROJECT_NAME);
ESPPreferenceObject pref = global_preferences->make_preference<char[30]>(hash, true);
char previous_version[30];
char current_version[30] = ESPHOME_PROJECT_VERSION;
char current_version[30] = ESPHOME_PROJECT_VERSION_30;
if (pref.load(&previous_version)) {
int cmp = strcmp(previous_version, current_version);
if (cmp < 0) {

View File

@ -394,6 +394,7 @@ async def to_code(config):
if project_conf := config.get(CONF_PROJECT):
cg.add_define("ESPHOME_PROJECT_NAME", project_conf[CONF_NAME])
cg.add_define("ESPHOME_PROJECT_VERSION", project_conf[CONF_VERSION])
cg.add_define("ESPHOME_PROJECT_VERSION_30", project_conf[CONF_VERSION][:30])
for conf in project_conf.get(CONF_ON_UPDATE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
await cg.register_component(trigger, conf)

View File

@ -11,6 +11,7 @@
#define ESPHOME_BOARD "dummy_board"
#define ESPHOME_PROJECT_NAME "dummy project"
#define ESPHOME_PROJECT_VERSION "v2"
#define ESPHOME_PROJECT_VERSION_30 "v2"
#define ESPHOME_VARIANT "ESP32"
// Feature flags

View File

@ -23,7 +23,9 @@ class FileResource:
resource: str
def path(self) -> ContextManager[Path]:
return importlib.resources.path(self.package, self.resource)
return importlib.resources.as_file(
importlib.resources.files(self.package) / self.resource
)
class ComponentManifest:
@ -101,10 +103,15 @@ class ComponentManifest:
loaded .py file (does not look through subdirectories)
"""
ret = []
for resource in importlib.resources.contents(self.package):
for resource in (
r.name
for r in importlib.resources.files(self.package).iterdir()
if r.is_file()
):
if Path(resource).suffix not in SOURCE_FILE_EXTENSIONS:
continue
if not importlib.resources.is_resource(self.package, resource):
if not importlib.resources.files(self.package).joinpath(resource).is_file():
# Not a resource = this is a directory (yeah this is confusing)
continue
ret.append(FileResource(self.package, resource))

View File

@ -12,9 +12,9 @@ pyserial==3.5
platformio==6.1.13 # When updating platformio, also update Dockerfile
esptool==4.7.0
click==8.1.7
esphome-dashboard==20240319.0
aioesphomeapi==23.2.0
zeroconf==0.131.0
esphome-dashboard==20240412.0
aioesphomeapi==24.0.0
zeroconf==0.132.2
python-magic==0.4.27
ruamel.yaml==0.18.6 # dashboard_import

View File

@ -1,13 +1,13 @@
pylint==3.0.3
pylint==3.1.0
flake8==7.0.0 # also change in .pre-commit-config.yaml when updating
black==24.2.0 # also change in .pre-commit-config.yaml when updating
pyupgrade==3.15.1 # also change in .pre-commit-config.yaml when updating
black==24.4.0 # also change in .pre-commit-config.yaml when updating
pyupgrade==3.15.2 # also change in .pre-commit-config.yaml when updating
pre-commit
# Unit tests
pytest==8.1.1
pytest-cov==4.1.0
pytest-mock==3.12.0
pytest-mock==3.14.0
pytest-asyncio==0.23.6
asyncmock==0.4.2
hypothesis==6.92.1

View File

@ -58,7 +58,7 @@ file_types = (
)
cpp_include = ("*.h", "*.c", "*.cpp", "*.tcc")
py_include = ("*.py",)
ignore_types = (".ico", ".png", ".woff", ".woff2", "")
ignore_types = (".ico", ".png", ".woff", ".woff2", "", ".ttf", ".otf")
LINT_FILE_CHECKS = []
LINT_CONTENT_CHECKS = []

View File

@ -15,3 +15,5 @@ text_sensor:
- platform: ethernet_info
ip_address:
name: IP Address
dns_address:
name: DNS Address

View File

@ -15,3 +15,5 @@ text_sensor:
- platform: ethernet_info
ip_address:
name: IP Address
dns_address:
name: DNS Address

Binary file not shown.

View File

@ -0,0 +1,38 @@
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
glyphs: "0123456789."
extras:
- file: "gfonts://Roboto"
glyphs: ["\u00C4", "\u00C5", "\U000000C7"]
- file: "gfonts://Roboto"
id: roboto_web
size: 20
- file: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf"
id: monocraft
size: 20
- file:
type: web
url: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf"
id: monocraft2
size: 24
- file: $component_dir/Monocraft.ttf
id: monocraft3
size: 28
i2c:
scl: ${i2c_scl}
sda: ${i2c_sda}
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: ${display_reset_pin}
lambda: |-
it.print(0, 0, id(roboto), "Hello, World!");
it.print(0, 20, id(roboto_web), "Hello, World!");
it.print(0, 40, id(monocraft), "Hello, World!");
it.print(0, 60, id(monocraft2), "Hello, World!");
it.print(0, 80, id(monocraft3), "Hello, World!");

View File

@ -1,19 +1,7 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
substitutions:
i2c_scl: GPIO5
i2c_sda: GPIO4
display_reset_pin: GPIO3
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
packages:
common: !include common.yaml

View File

@ -1,19 +1,7 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
substitutions:
i2c_scl: GPIO5
i2c_sda: GPIO4
display_reset_pin: GPIO3
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
packages:
common: !include common.yaml

View File

@ -1,19 +1,7 @@
i2c:
- id: i2c_font
scl: 16
sda: 17
substitutions:
i2c_scl: GPIO16
i2c_sda: GPIO17
display_reset_pin: GPIO13
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 13
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
packages:
common: !include common.yaml

View File

@ -1,38 +1,7 @@
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
glyphs: "0123456789."
extras:
- file: "gfonts://Roboto"
glyphs: ["\u00C4", "\u00C5", "\U000000C7"]
- file: "gfonts://Roboto"
id: roboto_web
size: 20
- file: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf"
id: monocraft
size: 20
- file:
type: web
url: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf"
id: monocraft2
size: 24
spi:
clk_pin: 14
mosi_pin: 13
display:
- id: my_display
platform: ili9xxx
dimensions: 480x320
model: ST7796
cs_pin: 15
dc_pin: 21
reset_pin: 22
transform:
swap_xy: true
mirror_x: true
mirror_y: true
auto_clear_enabled: false
substitutions:
i2c_scl: GPIO16
i2c_sda: GPIO17
display_reset_pin: GPIO13
packages:
common: !include common.yaml

View File

@ -1,19 +1,7 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
substitutions:
i2c_scl: GPIO5
i2c_sda: GPIO4
display_reset_pin: GPIO3
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
packages:
common: !include common.yaml

View File

@ -1,19 +1,7 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
substitutions:
i2c_scl: GPIO5
i2c_sda: GPIO4
display_reset_pin: GPIO3
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20
packages:
common: !include common.yaml

View File

@ -0,0 +1,67 @@
esphome:
on_boot:
then:
- homeassistant.event:
event: esphome.button_pressed
data:
message: Button was pressed
- homeassistant.event:
event: esphome.html5
data:
message: New Humidity
data_template:
message: The humidity is {{ my_variable }}%.
variables:
my_variable: "return id(ha_hello_world_temperature).state;"
- homeassistant.service:
service: notify.html5
data:
message: Button was pressed
- homeassistant.service:
service: notify.html5
data:
title: New Humidity
data_template:
message: The humidity is {{ my_variable }}%.
variables:
my_variable: "return id(ha_hello_world_temperature).state;"
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00

View File

@ -0,0 +1,2 @@
packages:
common: !include common.yaml

View File

@ -1,39 +1,2 @@
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00
packages:
common: !include common.yaml

View File

@ -1,39 +1,2 @@
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00
packages:
common: !include common.yaml

View File

@ -1,39 +1,2 @@
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00
packages:
common: !include common.yaml

View File

@ -1,39 +1,2 @@
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00
packages:
common: !include common.yaml

View File

@ -1,39 +1,2 @@
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00
packages:
common: !include common.yaml

View File

@ -1,39 +1,2 @@
wifi:
ssid: MySSID
password: password1
api:
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.hello_world
id: ha_hello_world_binary
- platform: homeassistant
entity_id: binary_sensor.hello
attribute: world
id: ha_hello_world_binary_attribute
sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world
- platform: homeassistant
entity_id: climate.living_room
attribute: temperature
id: ha_hello_world_temperature
text_sensor:
- platform: homeassistant
entity_id: sensor.hello_world
id: ha_hello_world_text
- platform: homeassistant
entity_id: sensor.hello_world1
id: ha_hello_world_text2
attribute: some_attribute
time:
- platform: homeassistant
on_time:
- at: "16:00:00"
then:
- logger.log: It's 16:00
packages:
common: !include common.yaml

View File

@ -0,0 +1,37 @@
esphome:
on_boot:
then:
- http_request.get:
url: https://esphome.io
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- logger.log:
format: 'Response status: %d, Duration: %u ms'
args:
- status_code
- duration_ms
- http_request.post:
url: https://esphome.io
headers:
Content-Type: application/json
json:
key: value
verify_ssl: false
- http_request.send:
method: PUT
url: https://esphome.io
headers:
Content-Type: application/json
body: "Some data"
verify_ssl: false
wifi:
ssid: MySSID
password: password1
http_request:
useragent: esphome/tagreader
timeout: 10s

View File

@ -1,7 +1,2 @@
wifi:
ssid: MySSID
password: password1
http_request:
useragent: esphome/tagreader
timeout: 10s
packages:
common: !include common.yaml

View File

@ -1,7 +1,2 @@
wifi:
ssid: MySSID
password: password1
http_request:
useragent: esphome/tagreader
timeout: 10s
packages:
common: !include common.yaml

View File

@ -1,7 +1,2 @@
wifi:
ssid: MySSID
password: password1
http_request:
useragent: esphome/tagreader
timeout: 10s
packages:
common: !include common.yaml

View File

@ -5,6 +5,7 @@ i2c:
sensor:
- platform: htu21d
model: htu21d
temperature:
name: Temperature
humidity:

View File

@ -5,6 +5,7 @@ i2c:
sensor:
- platform: htu21d
model: htu21d
temperature:
name: Temperature
humidity:

View File

@ -5,6 +5,7 @@ i2c:
sensor:
- platform: htu21d
model: htu21d
temperature:
name: Temperature
humidity:

View File

@ -5,6 +5,7 @@ i2c:
sensor:
- platform: htu21d
model: htu21d
temperature:
name: Temperature
humidity:

View File

@ -5,6 +5,7 @@ i2c:
sensor:
- platform: htu21d
model: htu21d
temperature:
name: Temperature
humidity:

View File

@ -5,6 +5,7 @@ i2c:
sensor:
- platform: htu21d
model: htu21d
temperature:
name: Temperature
humidity:

View File

@ -3,12 +3,146 @@ remote_receiver:
pin: ${pin}
rmt_channel: ${rmt_channel}
dump: all
on_abbwelcome:
then:
- logger.log:
format: "on_abbwelcome: %u"
args: ["x.data()[0]"]
on_aeha:
then:
- logger.log:
format: "on_aeha: %u %u"
args: ["x.address", "x.data.front()"]
on_byronsx:
then:
- logger.log:
format: "on_byronsx: %u %u"
args: ["x.address", "x.command"]
on_canalsat:
then:
- logger.log:
format: "on_canalsat: %u %u"
args: ["x.address", "x.command"]
# on_canalsatld:
# then:
# - logger.log:
# format: "on_canalsatld: %u %u"
# args: ["x.address", "x.command"]
on_coolix:
then:
delay: !lambda "return x.first + x.second;"
- logger.log:
format: "on_coolix: %u %u"
args: ["x.first", "x.second"]
on_dish:
then:
- logger.log:
format: "on_dish: %u %u"
args: ["x.address", "x.command"]
on_dooya:
then:
- logger.log:
format: "on_dooya: %u %u %u"
args: ["x.channel", "x.button", "x.check"]
on_drayton:
then:
- logger.log:
format: "on_drayton: %u %u %u"
args: ["x.address", "x.channel", "x.command"]
on_jvc:
then:
- logger.log:
format: "on_jvc: %u"
args: ["x.data"]
on_keeloq:
then:
- logger.log:
format: "on_keeloq: %u %u %u"
args: ["x.encrypted", "x.address", "x.command"]
on_haier:
then:
- logger.log:
format: "on_haier: %u"
args: ["x.data.front()"]
on_lg:
then:
- logger.log:
format: "on_lg: %u %u"
args: ["x.data", "x.nbits"]
on_magiquest:
then:
- logger.log:
format: "on_magiquest: %u %u"
args: ["x.magnitude", "x.wand_id"]
on_midea:
then:
- logger.log:
format: "on_midea: %u %u"
args: ["x.size()", "x.data()[0]"]
on_nec:
then:
- logger.log:
format: "on_nec: %u %u"
args: ["x.address", "x.command"]
on_nexa:
then:
- logger.log:
format: "on_nexa: %u %u %u %u %u"
args: ["x.device", "x.group", "x.state", "x.channel", "x.level"]
on_panasonic:
then:
- logger.log:
format: "on_panasonic: %u %u"
args: ["x.address", "x.command"]
on_pioneer:
then:
- logger.log:
format: "on_pioneer: %u %u"
args: ["x.rc_code_1", "x.rc_code_2"]
on_pronto:
then:
- logger.log:
format: "on_pronto: %s"
args: ["x.data.c_str()"]
on_raw:
then:
- logger.log:
format: "on_raw: %u"
args: ["x.front()"]
on_rc5:
then:
- logger.log:
format: "on_rc5: %u %u"
args: ["x.address", "x.command"]
on_rc6:
then:
- logger.log:
format: "on_rc6: %u %u"
args: ["x.address", "x.command"]
on_rc_switch:
then:
delay: !lambda "return uint32_t(x.code) + x.protocol;"
- logger.log:
format: "on_rc_switch: %llu %u"
args: ["x.code", "x.protocol"]
on_samsung:
then:
- logger.log:
format: "on_samsung: %llu %u"
args: ["x.data", "x.nbits"]
on_samsung36:
then:
- logger.log:
format: "on_samsung36: %u %u"
args: ["x.address", "x.command"]
on_sony:
then:
- logger.log:
format: "on_sony: %u %u"
args: ["x.data", "x.nbits"]
on_toshiba_ac:
then:
- logger.log:
format: "on_toshiba_ac: %llu %llu"
args: ["x.rc_code_1", "x.rc_code_2"]
binary_sensor:
- platform: remote_receiver

View File

@ -2,12 +2,146 @@ remote_receiver:
id: rcvr
pin: GPIO5
dump: all
on_abbwelcome:
then:
- logger.log:
format: "on_abbwelcome: %u"
args: ["x.data()[0]"]
on_aeha:
then:
- logger.log:
format: "on_aeha: %u %u"
args: ["x.address", "x.data.front()"]
on_byronsx:
then:
- logger.log:
format: "on_byronsx: %u %u"
args: ["x.address", "x.command"]
on_canalsat:
then:
- logger.log:
format: "on_canalsat: %u %u"
args: ["x.address", "x.command"]
# on_canalsatld:
# then:
# - logger.log:
# format: "on_canalsatld: %u %u"
# args: ["x.address", "x.command"]
on_coolix:
then:
delay: !lambda "return x.first + x.second;"
- logger.log:
format: "on_coolix: %u %u"
args: ["x.first", "x.second"]
on_dish:
then:
- logger.log:
format: "on_dish: %u %u"
args: ["x.address", "x.command"]
on_dooya:
then:
- logger.log:
format: "on_dooya: %u %u %u"
args: ["x.channel", "x.button", "x.check"]
on_drayton:
then:
- logger.log:
format: "on_drayton: %u %u %u"
args: ["x.address", "x.channel", "x.command"]
on_jvc:
then:
- logger.log:
format: "on_jvc: %u"
args: ["x.data"]
on_keeloq:
then:
- logger.log:
format: "on_keeloq: %u %u %u"
args: ["x.encrypted", "x.address", "x.command"]
on_haier:
then:
- logger.log:
format: "on_haier: %u"
args: ["x.data.front()"]
on_lg:
then:
- logger.log:
format: "on_lg: %u %u"
args: ["x.data", "x.nbits"]
on_magiquest:
then:
- logger.log:
format: "on_magiquest: %u %u"
args: ["x.magnitude", "x.wand_id"]
on_midea:
then:
- logger.log:
format: "on_midea: %u %u"
args: ["x.size()", "x.data()[0]"]
on_nec:
then:
- logger.log:
format: "on_nec: %u %u"
args: ["x.address", "x.command"]
on_nexa:
then:
- logger.log:
format: "on_nexa: %u %u %u %u %u"
args: ["x.device", "x.group", "x.state", "x.channel", "x.level"]
on_panasonic:
then:
- logger.log:
format: "on_panasonic: %u %u"
args: ["x.address", "x.command"]
on_pioneer:
then:
- logger.log:
format: "on_pioneer: %u %u"
args: ["x.rc_code_1", "x.rc_code_2"]
on_pronto:
then:
- logger.log:
format: "on_pronto: %s"
args: ["x.data.c_str()"]
on_raw:
then:
- logger.log:
format: "on_raw: %u"
args: ["x.front()"]
on_rc5:
then:
- logger.log:
format: "on_rc5: %u %u"
args: ["x.address", "x.command"]
on_rc6:
then:
- logger.log:
format: "on_rc6: %u %u"
args: ["x.address", "x.command"]
on_rc_switch:
then:
delay: !lambda "return uint32_t(x.code) + x.protocol;"
- logger.log:
format: "on_rc_switch: %llu %u"
args: ["x.code", "x.protocol"]
on_samsung:
then:
- logger.log:
format: "on_samsung: %llu %u"
args: ["x.data", "x.nbits"]
on_samsung36:
then:
- logger.log:
format: "on_samsung36: %u %u"
args: ["x.address", "x.command"]
on_sony:
then:
- logger.log:
format: "on_sony: %u %u"
args: ["x.data", "x.nbits"]
on_toshiba_ac:
then:
- logger.log:
format: "on_toshiba_ac: %llu %llu"
args: ["x.rc_code_1", "x.rc_code_2"]
binary_sensor:
- platform: remote_receiver

View File

@ -0,0 +1,19 @@
esphome:
name: componenttestespbk72xx
friendly_name: $component_name
bk72xx:
board: cb3s
logger:
level: VERY_VERBOSE
packages:
component_under_test: !include
file: $component_test_file
vars:
component_name: $component_name
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -18,3 +18,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -18,3 +18,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -18,3 +18,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -18,3 +18,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -19,3 +19,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -19,3 +19,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -19,3 +19,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -19,3 +19,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -16,3 +16,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -16,3 +16,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"

View File

@ -19,3 +19,4 @@ packages:
test_name: $test_name
target_platform: $target_platform
component_test_file: $component_test_file
component_dir: "../../components/$component_name"