mirror of
https://github.com/esphome/esphome.git
synced 2024-11-24 16:08:10 +01:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
09f04b77ac
50 changed files with 1181 additions and 466 deletions
14
.github/actions/build-image/action.yaml
vendored
14
.github/actions/build-image/action.yaml
vendored
|
@ -34,6 +34,16 @@ runs:
|
||||||
echo $l >> $GITHUB_OUTPUT
|
echo $l >> $GITHUB_OUTPUT
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# set cache-to only if dev branch
|
||||||
|
- id: cache-to
|
||||||
|
shell: bash
|
||||||
|
run: |-
|
||||||
|
if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
|
||||||
|
echo "value=type=gha,mode=max" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "value=" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Build and push to ghcr by digest
|
- name: Build and push to ghcr by digest
|
||||||
id: build-ghcr
|
id: build-ghcr
|
||||||
uses: docker/build-push-action@v5.3.0
|
uses: docker/build-push-action@v5.3.0
|
||||||
|
@ -43,7 +53,7 @@ runs:
|
||||||
platforms: ${{ inputs.platform }}
|
platforms: ${{ inputs.platform }}
|
||||||
target: ${{ inputs.target }}
|
target: ${{ inputs.target }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: ${{ steps.cache-to.outputs.value }}
|
||||||
build-args: |
|
build-args: |
|
||||||
BASEIMGTYPE=${{ inputs.baseimg }}
|
BASEIMGTYPE=${{ inputs.baseimg }}
|
||||||
BUILD_VERSION=${{ inputs.version }}
|
BUILD_VERSION=${{ inputs.version }}
|
||||||
|
@ -66,7 +76,7 @@ runs:
|
||||||
platforms: ${{ inputs.platform }}
|
platforms: ${{ inputs.platform }}
|
||||||
target: ${{ inputs.target }}
|
target: ${{ inputs.target }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: ${{ steps.cache-to.outputs.value }}
|
||||||
build-args: |
|
build-args: |
|
||||||
BASEIMGTYPE=${{ inputs.baseimg }}
|
BASEIMGTYPE=${{ inputs.baseimg }}
|
||||||
BUILD_VERSION=${{ inputs.version }}
|
BUILD_VERSION=${{ inputs.version }}
|
||||||
|
|
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
|
@ -364,12 +364,20 @@ jobs:
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||||
|
|
||||||
- name: Cache platformio
|
- name: Cache platformio
|
||||||
|
if: github.ref == 'refs/heads/dev'
|
||||||
uses: actions/cache@v4.0.2
|
uses: actions/cache@v4.0.2
|
||||||
with:
|
with:
|
||||||
path: ~/.platformio
|
path: ~/.platformio
|
||||||
# yamllint disable-line rule:line-length
|
key: platformio-${{ matrix.pio_cache_key }}
|
||||||
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
|
|
||||||
|
- name: Cache platformio
|
||||||
|
if: github.ref != 'refs/heads/dev'
|
||||||
|
uses: actions/cache/restore@v4.0.2
|
||||||
|
with:
|
||||||
|
path: ~/.platformio
|
||||||
|
key: platformio-${{ matrix.pio_cache_key }}
|
||||||
|
|
||||||
- name: Install clang-tidy
|
- name: Install clang-tidy
|
||||||
run: sudo apt-get install clang-tidy-14
|
run: sudo apt-get install clang-tidy-14
|
||||||
|
|
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
|
@ -132,10 +132,16 @@ jobs:
|
||||||
suffix: lint
|
suffix: lint
|
||||||
version: ${{ needs.init.outputs.tag }}
|
version: ${{ needs.init.outputs.tag }}
|
||||||
|
|
||||||
|
- name: Sanitize platform name
|
||||||
|
id: sanitize
|
||||||
|
run: |
|
||||||
|
echo "${{ matrix.platform }}" | sed 's|/|-|g' > /tmp/platform
|
||||||
|
echo name=$(cat /tmp/platform) >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Upload digests
|
- name: Upload digests
|
||||||
uses: actions/upload-artifact@v4.3.3
|
uses: actions/upload-artifact@v4.3.3
|
||||||
with:
|
with:
|
||||||
name: digests-${{ matrix.platform }}
|
name: digests-${{ steps.sanitize.outputs.name }}
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
|
|
|
@ -40,3 +40,10 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
types_or: [c, c++]
|
types_or: [c, c++]
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: pylint
|
||||||
|
name: pylint
|
||||||
|
entry: pylint
|
||||||
|
language: system
|
||||||
|
types: [python]
|
||||||
|
|
|
@ -136,6 +136,7 @@ esphome/components/fs3000/* @kahrendt
|
||||||
esphome/components/ft5x06/* @clydebarrow
|
esphome/components/ft5x06/* @clydebarrow
|
||||||
esphome/components/ft63x6/* @gpambrozio
|
esphome/components/ft63x6/* @gpambrozio
|
||||||
esphome/components/gcja5/* @gcormier
|
esphome/components/gcja5/* @gcormier
|
||||||
|
esphome/components/gdk101/* @Szewcson
|
||||||
esphome/components/globals/* @esphome/core
|
esphome/components/globals/* @esphome/core
|
||||||
esphome/components/gp8403/* @jesserockz
|
esphome/components/gp8403/* @jesserockz
|
||||||
esphome/components/gpio/* @esphome/core
|
esphome/components/gpio/* @esphome/core
|
||||||
|
|
|
@ -6,16 +6,6 @@
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
#ifdef USE_ARDUINO
|
|
||||||
#include "mbedtls/aes.h"
|
|
||||||
#include "mbedtls/base64.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ESP_IDF
|
|
||||||
#define MBEDTLS_AES_ALT
|
|
||||||
#include <aes_alt.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ble_presence {
|
namespace ble_presence {
|
||||||
|
|
||||||
|
@ -72,7 +62,7 @@ class BLEPresenceDevice : public binary_sensor::BinarySensorInitiallyOff,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MATCH_BY_IRK:
|
case MATCH_BY_IRK:
|
||||||
if (resolve_irk_(device.address_uint64(), this->irk_)) {
|
if (device.resolve_irk(this->irk_)) {
|
||||||
this->set_found_(true);
|
this->set_found_(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -142,43 +132,6 @@ class BLEPresenceDevice : public binary_sensor::BinarySensorInitiallyOff,
|
||||||
bool check_ibeacon_minor_{false};
|
bool check_ibeacon_minor_{false};
|
||||||
bool check_minimum_rssi_{false};
|
bool check_minimum_rssi_{false};
|
||||||
|
|
||||||
bool resolve_irk_(uint64_t addr64, const uint8_t *irk) {
|
|
||||||
uint8_t ecb_key[16];
|
|
||||||
uint8_t ecb_plaintext[16];
|
|
||||||
uint8_t ecb_ciphertext[16];
|
|
||||||
|
|
||||||
memcpy(&ecb_key, irk, 16);
|
|
||||||
memset(&ecb_plaintext, 0, 16);
|
|
||||||
|
|
||||||
ecb_plaintext[13] = (addr64 >> 40) & 0xff;
|
|
||||||
ecb_plaintext[14] = (addr64 >> 32) & 0xff;
|
|
||||||
ecb_plaintext[15] = (addr64 >> 24) & 0xff;
|
|
||||||
|
|
||||||
mbedtls_aes_context ctx = {0, 0, {0}};
|
|
||||||
mbedtls_aes_init(&ctx);
|
|
||||||
|
|
||||||
if (mbedtls_aes_setkey_enc(&ctx, ecb_key, 128) != 0) {
|
|
||||||
mbedtls_aes_free(&ctx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mbedtls_aes_crypt_ecb(&ctx,
|
|
||||||
#ifdef USE_ARDUINO
|
|
||||||
MBEDTLS_AES_ENCRYPT,
|
|
||||||
#elif defined(USE_ESP_IDF)
|
|
||||||
ESP_AES_ENCRYPT,
|
|
||||||
#endif
|
|
||||||
ecb_plaintext, ecb_ciphertext) != 0) {
|
|
||||||
mbedtls_aes_free(&ctx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_aes_free(&ctx);
|
|
||||||
|
|
||||||
return ecb_ciphertext[15] == (addr64 & 0xff) && ecb_ciphertext[14] == ((addr64 >> 8) & 0xff) &&
|
|
||||||
ecb_ciphertext[13] == ((addr64 >> 16) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found_{false};
|
bool found_{false};
|
||||||
uint32_t last_seen_{};
|
uint32_t last_seen_{};
|
||||||
uint32_t timeout_{};
|
uint32_t timeout_{};
|
||||||
|
|
|
@ -15,6 +15,10 @@ class BLERSSISensor : public sensor::Sensor, public esp32_ble_tracker::ESPBTDevi
|
||||||
this->match_by_ = MATCH_BY_MAC_ADDRESS;
|
this->match_by_ = MATCH_BY_MAC_ADDRESS;
|
||||||
this->address_ = address;
|
this->address_ = address;
|
||||||
}
|
}
|
||||||
|
void set_irk(uint8_t *irk) {
|
||||||
|
this->match_by_ = MATCH_BY_IRK;
|
||||||
|
this->irk_ = irk;
|
||||||
|
}
|
||||||
void set_service_uuid16(uint16_t uuid) {
|
void set_service_uuid16(uint16_t uuid) {
|
||||||
this->match_by_ = MATCH_BY_SERVICE_UUID;
|
this->match_by_ = MATCH_BY_SERVICE_UUID;
|
||||||
this->uuid_ = esp32_ble_tracker::ESPBTUUID::from_uint16(uuid);
|
this->uuid_ = esp32_ble_tracker::ESPBTUUID::from_uint16(uuid);
|
||||||
|
@ -53,6 +57,13 @@ class BLERSSISensor : public sensor::Sensor, public esp32_ble_tracker::ESPBTDevi
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MATCH_BY_IRK:
|
||||||
|
if (device.resolve_irk(this->irk_)) {
|
||||||
|
this->publish_state(device.get_rssi());
|
||||||
|
this->found_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MATCH_BY_SERVICE_UUID:
|
case MATCH_BY_SERVICE_UUID:
|
||||||
for (auto uuid : device.get_service_uuids()) {
|
for (auto uuid : device.get_service_uuids()) {
|
||||||
if (this->uuid_ == uuid) {
|
if (this->uuid_ == uuid) {
|
||||||
|
@ -91,12 +102,13 @@ class BLERSSISensor : public sensor::Sensor, public esp32_ble_tracker::ESPBTDevi
|
||||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum MatchType { MATCH_BY_MAC_ADDRESS, MATCH_BY_SERVICE_UUID, MATCH_BY_IBEACON_UUID };
|
enum MatchType { MATCH_BY_MAC_ADDRESS, MATCH_BY_IRK, MATCH_BY_SERVICE_UUID, MATCH_BY_IBEACON_UUID };
|
||||||
MatchType match_by_;
|
MatchType match_by_;
|
||||||
|
|
||||||
bool found_{false};
|
bool found_{false};
|
||||||
|
|
||||||
uint64_t address_;
|
uint64_t address_;
|
||||||
|
uint8_t *irk_;
|
||||||
|
|
||||||
esp32_ble_tracker::ESPBTUUID uuid_;
|
esp32_ble_tracker::ESPBTUUID uuid_;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ from esphome.const import (
|
||||||
UNIT_DECIBEL_MILLIWATT,
|
UNIT_DECIBEL_MILLIWATT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONF_IRK = "irk"
|
||||||
|
|
||||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||||
|
|
||||||
ble_rssi_ns = cg.esphome_ns.namespace("ble_rssi")
|
ble_rssi_ns = cg.esphome_ns.namespace("ble_rssi")
|
||||||
|
@ -39,6 +41,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
.extend(
|
.extend(
|
||||||
{
|
{
|
||||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||||
|
cv.Optional(CONF_IRK): cv.uuid,
|
||||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||||
cv.Optional(CONF_IBEACON_MAJOR): cv.uint16_t,
|
cv.Optional(CONF_IBEACON_MAJOR): cv.uint16_t,
|
||||||
cv.Optional(CONF_IBEACON_MINOR): cv.uint16_t,
|
cv.Optional(CONF_IBEACON_MINOR): cv.uint16_t,
|
||||||
|
@ -47,7 +50,9 @@ CONFIG_SCHEMA = cv.All(
|
||||||
)
|
)
|
||||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||||
.extend(cv.COMPONENT_SCHEMA),
|
.extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.has_exactly_one_key(CONF_MAC_ADDRESS, CONF_SERVICE_UUID, CONF_IBEACON_UUID),
|
cv.has_exactly_one_key(
|
||||||
|
CONF_MAC_ADDRESS, CONF_IRK, CONF_SERVICE_UUID, CONF_IBEACON_UUID
|
||||||
|
),
|
||||||
_validate,
|
_validate,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,6 +65,10 @@ async def to_code(config):
|
||||||
if mac_address := config.get(CONF_MAC_ADDRESS):
|
if mac_address := config.get(CONF_MAC_ADDRESS):
|
||||||
cg.add(var.set_address(mac_address.as_hex))
|
cg.add(var.set_address(mac_address.as_hex))
|
||||||
|
|
||||||
|
if irk := config.get(CONF_IRK):
|
||||||
|
irk = esp32_ble_tracker.as_hex_array(str(irk))
|
||||||
|
cg.add(var.set_irk(irk))
|
||||||
|
|
||||||
if service_uuid := config.get(CONF_SERVICE_UUID):
|
if service_uuid := config.get(CONF_SERVICE_UUID):
|
||||||
if len(service_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
|
if len(service_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||||
cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(service_uuid)))
|
cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(service_uuid)))
|
||||||
|
|
|
@ -14,15 +14,41 @@ CONF_HEX = "hex"
|
||||||
|
|
||||||
|
|
||||||
def hex_color(value):
|
def hex_color(value):
|
||||||
|
if isinstance(value, int):
|
||||||
|
value = str(value)
|
||||||
|
if not isinstance(value, str):
|
||||||
|
raise cv.Invalid("Invalid value for hex color")
|
||||||
if len(value) != 6:
|
if len(value) != 6:
|
||||||
raise cv.Invalid("Color must have six digits")
|
raise cv.Invalid("Hex color must have six digits")
|
||||||
try:
|
try:
|
||||||
return (int(value[0:2], 16), int(value[2:4], 16), int(value[4:6], 16))
|
return int(value[0:2], 16), int(value[2:4], 16), int(value[4:6], 16)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise cv.Invalid("Color must be hexadecimal") from exc
|
raise cv.Invalid("Color must be hexadecimal") from exc
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Any(
|
components = {
|
||||||
|
CONF_RED,
|
||||||
|
CONF_RED_INT,
|
||||||
|
CONF_GREEN,
|
||||||
|
CONF_GREEN_INT,
|
||||||
|
CONF_BLUE,
|
||||||
|
CONF_BLUE_INT,
|
||||||
|
CONF_WHITE,
|
||||||
|
CONF_WHITE_INT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_color(config):
|
||||||
|
has_components = set(config) & components
|
||||||
|
has_hex = CONF_HEX in config
|
||||||
|
if has_hex and has_components:
|
||||||
|
raise cv.Invalid("Hex color value may not be combined with component values")
|
||||||
|
if not has_hex and not has_components:
|
||||||
|
raise cv.Invalid("Must provide at least one color option")
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
||||||
|
@ -34,14 +60,10 @@ CONFIG_SCHEMA = cv.Any(
|
||||||
cv.Exclusive(CONF_BLUE_INT, "blue"): cv.uint8_t,
|
cv.Exclusive(CONF_BLUE_INT, "blue"): cv.uint8_t,
|
||||||
cv.Exclusive(CONF_WHITE, "white"): cv.percentage,
|
cv.Exclusive(CONF_WHITE, "white"): cv.percentage,
|
||||||
cv.Exclusive(CONF_WHITE_INT, "white"): cv.uint8_t,
|
cv.Exclusive(CONF_WHITE_INT, "white"): cv.uint8_t,
|
||||||
|
cv.Optional(CONF_HEX): hex_color,
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.Schema(
|
validate_color,
|
||||||
{
|
|
||||||
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
|
||||||
cv.Required(CONF_HEX): hex_color,
|
|
||||||
}
|
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ void CST816Touchscreen::continue_setup_() {
|
||||||
}
|
}
|
||||||
switch (this->chip_id_) {
|
switch (this->chip_id_) {
|
||||||
case CST820_CHIP_ID:
|
case CST820_CHIP_ID:
|
||||||
|
case CST826_CHIP_ID:
|
||||||
case CST716_CHIP_ID:
|
case CST716_CHIP_ID:
|
||||||
case CST816S_CHIP_ID:
|
case CST816S_CHIP_ID:
|
||||||
case CST816D_CHIP_ID:
|
case CST816D_CHIP_ID:
|
||||||
|
@ -90,6 +91,9 @@ void CST816Touchscreen::dump_config() {
|
||||||
case CST820_CHIP_ID:
|
case CST820_CHIP_ID:
|
||||||
name = "CST820";
|
name = "CST820";
|
||||||
break;
|
break;
|
||||||
|
case CST826_CHIP_ID:
|
||||||
|
name = "CST826";
|
||||||
|
break;
|
||||||
case CST816S_CHIP_ID:
|
case CST816S_CHIP_ID:
|
||||||
name = "CST816S";
|
name = "CST816S";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -24,6 +24,7 @@ static const uint8_t REG_SLEEP = 0xE5;
|
||||||
static const uint8_t REG_IRQ_CTL = 0xFA;
|
static const uint8_t REG_IRQ_CTL = 0xFA;
|
||||||
static const uint8_t IRQ_EN_MOTION = 0x70;
|
static const uint8_t IRQ_EN_MOTION = 0x70;
|
||||||
|
|
||||||
|
static const uint8_t CST826_CHIP_ID = 0x11;
|
||||||
static const uint8_t CST820_CHIP_ID = 0xB7;
|
static const uint8_t CST820_CHIP_ID = 0xB7;
|
||||||
static const uint8_t CST816S_CHIP_ID = 0xB4;
|
static const uint8_t CST816S_CHIP_ID = 0xB4;
|
||||||
static const uint8_t CST816D_CHIP_ID = 0xB6;
|
static const uint8_t CST816D_CHIP_ID = 0xB6;
|
||||||
|
|
|
@ -8,62 +8,16 @@
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
|
|
||||||
#include <esp_heap_caps.h>
|
|
||||||
#include <esp_system.h>
|
|
||||||
|
|
||||||
#include <esp_chip_info.h>
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
#include <esp32/rom/rtc.h>
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
|
||||||
#include <esp32c3/rom/rtc.h>
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C6)
|
|
||||||
#include <esp32c6/rom/rtc.h>
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
|
||||||
#include <esp32s2/rom/rtc.h>
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
#include <esp32s3/rom/rtc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // USE_ESP32
|
|
||||||
|
|
||||||
#ifdef USE_ARDUINO
|
|
||||||
#ifdef USE_RP2040
|
|
||||||
#include <Arduino.h>
|
|
||||||
#elif defined(USE_ESP32) || defined(USE_ESP8266)
|
|
||||||
#include <Esp.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace debug {
|
namespace debug {
|
||||||
|
|
||||||
static const char *const TAG = "debug";
|
static const char *const TAG = "debug";
|
||||||
|
|
||||||
static uint32_t get_free_heap() {
|
|
||||||
#if defined(USE_ESP8266)
|
|
||||||
return ESP.getFreeHeap(); // NOLINT(readability-static-accessed-through-instance)
|
|
||||||
#elif defined(USE_ESP32)
|
|
||||||
return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
|
||||||
#elif defined(USE_RP2040)
|
|
||||||
return rp2040.getFreeHeap();
|
|
||||||
#elif defined(USE_LIBRETINY)
|
|
||||||
return lt_heap_get_free();
|
|
||||||
#elif defined(USE_HOST)
|
|
||||||
return INT_MAX;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugComponent::dump_config() {
|
void DebugComponent::dump_config() {
|
||||||
#ifndef ESPHOME_LOG_HAS_DEBUG
|
#ifndef ESPHOME_LOG_HAS_DEBUG
|
||||||
return; // Can't log below if debug logging is disabled
|
return; // Can't log below if debug logging is disabled
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string device_info;
|
|
||||||
std::string reset_reason;
|
|
||||||
device_info.reserve(256);
|
|
||||||
|
|
||||||
ESP_LOGCONFIG(TAG, "Debug component:");
|
ESP_LOGCONFIG(TAG, "Debug component:");
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
LOG_TEXT_SENSOR(" ", "Device info", this->device_info_);
|
LOG_TEXT_SENSOR(" ", "Device info", this->device_info_);
|
||||||
|
@ -76,305 +30,15 @@ void DebugComponent::dump_config() {
|
||||||
#endif // defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
#endif // defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
||||||
#endif // USE_SENSOR
|
#endif // USE_SENSOR
|
||||||
|
|
||||||
|
std::string device_info;
|
||||||
|
device_info.reserve(256);
|
||||||
ESP_LOGD(TAG, "ESPHome version %s", ESPHOME_VERSION);
|
ESP_LOGD(TAG, "ESPHome version %s", ESPHOME_VERSION);
|
||||||
device_info += ESPHOME_VERSION;
|
device_info += ESPHOME_VERSION;
|
||||||
|
|
||||||
this->free_heap_ = get_free_heap();
|
this->free_heap_ = get_free_heap_();
|
||||||
ESP_LOGD(TAG, "Free Heap Size: %" PRIu32 " bytes", this->free_heap_);
|
ESP_LOGD(TAG, "Free Heap Size: %" PRIu32 " bytes", this->free_heap_);
|
||||||
|
|
||||||
#if defined(USE_ARDUINO) && (defined(USE_ESP32) || defined(USE_ESP8266))
|
get_device_info_(device_info);
|
||||||
const char *flash_mode;
|
|
||||||
switch (ESP.getFlashChipMode()) { // NOLINT(readability-static-accessed-through-instance)
|
|
||||||
case FM_QIO:
|
|
||||||
flash_mode = "QIO";
|
|
||||||
break;
|
|
||||||
case FM_QOUT:
|
|
||||||
flash_mode = "QOUT";
|
|
||||||
break;
|
|
||||||
case FM_DIO:
|
|
||||||
flash_mode = "DIO";
|
|
||||||
break;
|
|
||||||
case FM_DOUT:
|
|
||||||
flash_mode = "DOUT";
|
|
||||||
break;
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
case FM_FAST_READ:
|
|
||||||
flash_mode = "FAST_READ";
|
|
||||||
break;
|
|
||||||
case FM_SLOW_READ:
|
|
||||||
flash_mode = "SLOW_READ";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
flash_mode = "UNKNOWN";
|
|
||||||
}
|
|
||||||
ESP_LOGD(TAG, "Flash Chip: Size=%ukB Speed=%uMHz Mode=%s",
|
|
||||||
ESP.getFlashChipSize() / 1024, // NOLINT
|
|
||||||
ESP.getFlashChipSpeed() / 1000000, flash_mode); // NOLINT
|
|
||||||
device_info += "|Flash: " + to_string(ESP.getFlashChipSize() / 1024) + // NOLINT
|
|
||||||
"kB Speed:" + to_string(ESP.getFlashChipSpeed() / 1000000) + "MHz Mode:"; // NOLINT
|
|
||||||
device_info += flash_mode;
|
|
||||||
#endif // USE_ARDUINO && (USE_ESP32 || USE_ESP8266)
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
esp_chip_info_t info;
|
|
||||||
esp_chip_info(&info);
|
|
||||||
const char *model;
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
model = "ESP32";
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
|
||||||
model = "ESP32-C3";
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C6)
|
|
||||||
model = "ESP32-C6";
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
|
||||||
model = "ESP32-S2";
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
model = "ESP32-S3";
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32H2)
|
|
||||||
model = "ESP32-H2";
|
|
||||||
#else
|
|
||||||
model = "UNKNOWN";
|
|
||||||
#endif
|
|
||||||
std::string features;
|
|
||||||
if (info.features & CHIP_FEATURE_EMB_FLASH) {
|
|
||||||
features += "EMB_FLASH,";
|
|
||||||
info.features &= ~CHIP_FEATURE_EMB_FLASH;
|
|
||||||
}
|
|
||||||
if (info.features & CHIP_FEATURE_WIFI_BGN) {
|
|
||||||
features += "WIFI_BGN,";
|
|
||||||
info.features &= ~CHIP_FEATURE_WIFI_BGN;
|
|
||||||
}
|
|
||||||
if (info.features & CHIP_FEATURE_BLE) {
|
|
||||||
features += "BLE,";
|
|
||||||
info.features &= ~CHIP_FEATURE_BLE;
|
|
||||||
}
|
|
||||||
if (info.features & CHIP_FEATURE_BT) {
|
|
||||||
features += "BT,";
|
|
||||||
info.features &= ~CHIP_FEATURE_BT;
|
|
||||||
}
|
|
||||||
if (info.features & CHIP_FEATURE_EMB_PSRAM) {
|
|
||||||
features += "EMB_PSRAM,";
|
|
||||||
info.features &= ~CHIP_FEATURE_EMB_PSRAM;
|
|
||||||
}
|
|
||||||
if (info.features)
|
|
||||||
features += "Other:" + format_hex(info.features);
|
|
||||||
ESP_LOGD(TAG, "Chip: Model=%s, Features=%s Cores=%u, Revision=%u", model, features.c_str(), info.cores,
|
|
||||||
info.revision);
|
|
||||||
device_info += "|Chip: ";
|
|
||||||
device_info += model;
|
|
||||||
device_info += " Features:";
|
|
||||||
device_info += features;
|
|
||||||
device_info += " Cores:" + to_string(info.cores);
|
|
||||||
device_info += " Revision:" + to_string(info.revision);
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "ESP-IDF Version: %s", esp_get_idf_version());
|
|
||||||
device_info += "|ESP-IDF: ";
|
|
||||||
device_info += esp_get_idf_version();
|
|
||||||
|
|
||||||
std::string mac = get_mac_address_pretty();
|
|
||||||
ESP_LOGD(TAG, "EFuse MAC: %s", mac.c_str());
|
|
||||||
device_info += "|EFuse MAC: ";
|
|
||||||
device_info += mac;
|
|
||||||
|
|
||||||
switch (rtc_get_reset_reason(0)) {
|
|
||||||
case POWERON_RESET:
|
|
||||||
reset_reason = "Power On Reset";
|
|
||||||
break;
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
case SW_RESET:
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
case RTC_SW_SYS_RESET:
|
|
||||||
#endif
|
|
||||||
reset_reason = "Software Reset Digital Core";
|
|
||||||
break;
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
case OWDT_RESET:
|
|
||||||
reset_reason = "Watch Dog Reset Digital Core";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case DEEPSLEEP_RESET:
|
|
||||||
reset_reason = "Deep Sleep Reset Digital Core";
|
|
||||||
break;
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
case SDIO_RESET:
|
|
||||||
reset_reason = "SLC Module Reset Digital Core";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case TG0WDT_SYS_RESET:
|
|
||||||
reset_reason = "Timer Group 0 Watch Dog Reset Digital Core";
|
|
||||||
break;
|
|
||||||
case TG1WDT_SYS_RESET:
|
|
||||||
reset_reason = "Timer Group 1 Watch Dog Reset Digital Core";
|
|
||||||
break;
|
|
||||||
case RTCWDT_SYS_RESET:
|
|
||||||
reset_reason = "RTC Watch Dog Reset Digital Core";
|
|
||||||
break;
|
|
||||||
#if !defined(USE_ESP32_VARIANT_ESP32C6)
|
|
||||||
case INTRUSION_RESET:
|
|
||||||
reset_reason = "Intrusion Reset CPU";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
case TGWDT_CPU_RESET:
|
|
||||||
reset_reason = "Timer Group Reset CPU";
|
|
||||||
break;
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
case TG0WDT_CPU_RESET:
|
|
||||||
reset_reason = "Timer Group 0 Reset CPU";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
case SW_CPU_RESET:
|
|
||||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
case RTC_SW_CPU_RESET:
|
|
||||||
#endif
|
|
||||||
reset_reason = "Software Reset CPU";
|
|
||||||
break;
|
|
||||||
case RTCWDT_CPU_RESET:
|
|
||||||
reset_reason = "RTC Watch Dog Reset CPU";
|
|
||||||
break;
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
|
||||||
case EXT_CPU_RESET:
|
|
||||||
reset_reason = "External CPU Reset";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case RTCWDT_BROWN_OUT_RESET:
|
|
||||||
reset_reason = "Voltage Unstable Reset";
|
|
||||||
break;
|
|
||||||
case RTCWDT_RTC_RESET:
|
|
||||||
reset_reason = "RTC Watch Dog Reset Digital Core And RTC Module";
|
|
||||||
break;
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
case TG1WDT_CPU_RESET:
|
|
||||||
reset_reason = "Timer Group 1 Reset CPU";
|
|
||||||
break;
|
|
||||||
case SUPER_WDT_RESET:
|
|
||||||
reset_reason = "Super Watchdog Reset Digital Core And RTC Module";
|
|
||||||
break;
|
|
||||||
case GLITCH_RTC_RESET:
|
|
||||||
reset_reason = "Glitch Reset Digital Core And RTC Module";
|
|
||||||
break;
|
|
||||||
case EFUSE_RESET:
|
|
||||||
reset_reason = "eFuse Reset Digital Core";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
|
|
||||||
case USB_UART_CHIP_RESET:
|
|
||||||
reset_reason = "USB UART Reset Digital Core";
|
|
||||||
break;
|
|
||||||
case USB_JTAG_CHIP_RESET:
|
|
||||||
reset_reason = "USB JTAG Reset Digital Core";
|
|
||||||
break;
|
|
||||||
case POWER_GLITCH_RESET:
|
|
||||||
reset_reason = "Power Glitch Reset Digital Core And RTC Module";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
reset_reason = "Unknown Reset Reason";
|
|
||||||
}
|
|
||||||
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
|
||||||
device_info += "|Reset: ";
|
|
||||||
device_info += reset_reason;
|
|
||||||
|
|
||||||
const char *wakeup_reason;
|
|
||||||
switch (rtc_get_wakeup_cause()) {
|
|
||||||
case NO_SLEEP:
|
|
||||||
wakeup_reason = "No Sleep";
|
|
||||||
break;
|
|
||||||
case EXT_EVENT0_TRIG:
|
|
||||||
wakeup_reason = "External Event 0";
|
|
||||||
break;
|
|
||||||
case EXT_EVENT1_TRIG:
|
|
||||||
wakeup_reason = "External Event 1";
|
|
||||||
break;
|
|
||||||
case GPIO_TRIG:
|
|
||||||
wakeup_reason = "GPIO";
|
|
||||||
break;
|
|
||||||
case TIMER_EXPIRE:
|
|
||||||
wakeup_reason = "Wakeup Timer";
|
|
||||||
break;
|
|
||||||
case SDIO_TRIG:
|
|
||||||
wakeup_reason = "SDIO";
|
|
||||||
break;
|
|
||||||
case MAC_TRIG:
|
|
||||||
wakeup_reason = "MAC";
|
|
||||||
break;
|
|
||||||
case UART0_TRIG:
|
|
||||||
wakeup_reason = "UART0";
|
|
||||||
break;
|
|
||||||
case UART1_TRIG:
|
|
||||||
wakeup_reason = "UART1";
|
|
||||||
break;
|
|
||||||
case TOUCH_TRIG:
|
|
||||||
wakeup_reason = "Touch";
|
|
||||||
break;
|
|
||||||
case SAR_TRIG:
|
|
||||||
wakeup_reason = "SAR";
|
|
||||||
break;
|
|
||||||
case BT_TRIG:
|
|
||||||
wakeup_reason = "BT";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
wakeup_reason = "Unknown";
|
|
||||||
}
|
|
||||||
ESP_LOGD(TAG, "Wakeup Reason: %s", wakeup_reason);
|
|
||||||
device_info += "|Wakeup: ";
|
|
||||||
device_info += wakeup_reason;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_ESP8266) && !defined(CLANG_TIDY)
|
|
||||||
ESP_LOGD(TAG, "Chip ID: 0x%08X", ESP.getChipId());
|
|
||||||
ESP_LOGD(TAG, "SDK Version: %s", ESP.getSdkVersion());
|
|
||||||
ESP_LOGD(TAG, "Core Version: %s", ESP.getCoreVersion().c_str());
|
|
||||||
ESP_LOGD(TAG, "Boot Version=%u Mode=%u", ESP.getBootVersion(), ESP.getBootMode());
|
|
||||||
ESP_LOGD(TAG, "CPU Frequency: %u", ESP.getCpuFreqMHz());
|
|
||||||
ESP_LOGD(TAG, "Flash Chip ID=0x%08X", ESP.getFlashChipId());
|
|
||||||
ESP_LOGD(TAG, "Reset Reason: %s", ESP.getResetReason().c_str());
|
|
||||||
ESP_LOGD(TAG, "Reset Info: %s", ESP.getResetInfo().c_str());
|
|
||||||
|
|
||||||
device_info += "|Chip: 0x" + format_hex(ESP.getChipId());
|
|
||||||
device_info += "|SDK: ";
|
|
||||||
device_info += ESP.getSdkVersion();
|
|
||||||
device_info += "|Core: ";
|
|
||||||
device_info += ESP.getCoreVersion().c_str();
|
|
||||||
device_info += "|Boot: ";
|
|
||||||
device_info += to_string(ESP.getBootVersion());
|
|
||||||
device_info += "|Mode: " + to_string(ESP.getBootMode());
|
|
||||||
device_info += "|CPU: " + to_string(ESP.getCpuFreqMHz());
|
|
||||||
device_info += "|Flash: 0x" + format_hex(ESP.getFlashChipId());
|
|
||||||
device_info += "|Reset: ";
|
|
||||||
device_info += ESP.getResetReason().c_str();
|
|
||||||
device_info += "|";
|
|
||||||
device_info += ESP.getResetInfo().c_str();
|
|
||||||
|
|
||||||
reset_reason = ESP.getResetReason().c_str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
|
||||||
ESP_LOGD(TAG, "CPU Frequency: %u", rp2040.f_cpu());
|
|
||||||
device_info += "CPU Frequency: " + to_string(rp2040.f_cpu());
|
|
||||||
#endif // USE_RP2040
|
|
||||||
|
|
||||||
#ifdef USE_LIBRETINY
|
|
||||||
ESP_LOGD(TAG, "LibreTiny Version: %s", lt_get_version());
|
|
||||||
ESP_LOGD(TAG, "Chip: %s (%04x) @ %u MHz", lt_cpu_get_model_name(), lt_cpu_get_model(), lt_cpu_get_freq_mhz());
|
|
||||||
ESP_LOGD(TAG, "Chip ID: 0x%06X", lt_cpu_get_mac_id());
|
|
||||||
ESP_LOGD(TAG, "Board: %s", lt_get_board_code());
|
|
||||||
ESP_LOGD(TAG, "Flash: %u KiB / RAM: %u KiB", lt_flash_get_size() / 1024, lt_ram_get_size() / 1024);
|
|
||||||
ESP_LOGD(TAG, "Reset Reason: %s", lt_get_reboot_reason_name(lt_get_reboot_reason()));
|
|
||||||
|
|
||||||
device_info += "|Version: ";
|
|
||||||
device_info += LT_BANNER_STR + 10;
|
|
||||||
device_info += "|Reset Reason: ";
|
|
||||||
device_info += lt_get_reboot_reason_name(lt_get_reboot_reason());
|
|
||||||
device_info += "|Chip Name: ";
|
|
||||||
device_info += lt_cpu_get_model_name();
|
|
||||||
device_info += "|Chip ID: 0x" + format_hex(lt_cpu_get_mac_id());
|
|
||||||
device_info += "|Flash: " + to_string(lt_flash_get_size() / 1024) + " KiB";
|
|
||||||
device_info += "|RAM: " + to_string(lt_ram_get_size() / 1024) + " KiB";
|
|
||||||
|
|
||||||
reset_reason = lt_get_reboot_reason_name(lt_get_reboot_reason());
|
|
||||||
#endif // USE_LIBRETINY
|
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
if (this->device_info_ != nullptr) {
|
if (this->device_info_ != nullptr) {
|
||||||
|
@ -383,14 +47,14 @@ void DebugComponent::dump_config() {
|
||||||
this->device_info_->publish_state(device_info);
|
this->device_info_->publish_state(device_info);
|
||||||
}
|
}
|
||||||
if (this->reset_reason_ != nullptr) {
|
if (this->reset_reason_ != nullptr) {
|
||||||
this->reset_reason_->publish_state(reset_reason);
|
this->reset_reason_->publish_state(get_reset_reason_());
|
||||||
}
|
}
|
||||||
#endif // USE_TEXT_SENSOR
|
#endif // USE_TEXT_SENSOR
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugComponent::loop() {
|
void DebugComponent::loop() {
|
||||||
// log when free heap space has halved
|
// log when free heap space has halved
|
||||||
uint32_t new_free_heap = get_free_heap();
|
uint32_t new_free_heap = get_free_heap_();
|
||||||
if (new_free_heap < this->free_heap_ / 2) {
|
if (new_free_heap < this->free_heap_ / 2) {
|
||||||
this->free_heap_ = new_free_heap;
|
this->free_heap_ = new_free_heap;
|
||||||
ESP_LOGD(TAG, "Free Heap Size: %" PRIu32 " bytes", this->free_heap_);
|
ESP_LOGD(TAG, "Free Heap Size: %" PRIu32 " bytes", this->free_heap_);
|
||||||
|
@ -411,38 +75,16 @@ void DebugComponent::loop() {
|
||||||
void DebugComponent::update() {
|
void DebugComponent::update() {
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
if (this->free_sensor_ != nullptr) {
|
if (this->free_sensor_ != nullptr) {
|
||||||
this->free_sensor_->publish_state(get_free_heap());
|
this->free_sensor_->publish_state(get_free_heap_());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->block_sensor_ != nullptr) {
|
|
||||||
#if defined(USE_ESP8266)
|
|
||||||
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
|
|
||||||
this->block_sensor_->publish_state(ESP.getMaxFreeBlockSize());
|
|
||||||
#elif defined(USE_ESP32)
|
|
||||||
this->block_sensor_->publish_state(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
|
|
||||||
#elif defined(USE_LIBRETINY)
|
|
||||||
this->block_sensor_->publish_state(lt_heap_get_max_alloc());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
|
||||||
if (this->fragmentation_sensor_ != nullptr) {
|
|
||||||
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
|
|
||||||
this->fragmentation_sensor_->publish_state(ESP.getHeapFragmentation());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (this->loop_time_sensor_ != nullptr) {
|
if (this->loop_time_sensor_ != nullptr) {
|
||||||
this->loop_time_sensor_->publish_state(this->max_loop_time_);
|
this->loop_time_sensor_->publish_state(this->max_loop_time_);
|
||||||
this->max_loop_time_ = 0;
|
this->max_loop_time_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
if (this->psram_sensor_ != nullptr) {
|
|
||||||
this->psram_sensor_->publish_state(heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
|
||||||
}
|
|
||||||
#endif // USE_ESP32
|
|
||||||
#endif // USE_SENSOR
|
#endif // USE_SENSOR
|
||||||
|
update_platform_();
|
||||||
}
|
}
|
||||||
|
|
||||||
float DebugComponent::get_setup_priority() const { return setup_priority::LATE; }
|
float DebugComponent::get_setup_priority() const { return setup_priority::LATE; }
|
||||||
|
|
|
@ -59,6 +59,11 @@ class DebugComponent : public PollingComponent {
|
||||||
text_sensor::TextSensor *device_info_{nullptr};
|
text_sensor::TextSensor *device_info_{nullptr};
|
||||||
text_sensor::TextSensor *reset_reason_{nullptr};
|
text_sensor::TextSensor *reset_reason_{nullptr};
|
||||||
#endif // USE_TEXT_SENSOR
|
#endif // USE_TEXT_SENSOR
|
||||||
|
|
||||||
|
std::string get_reset_reason_();
|
||||||
|
uint32_t get_free_heap_();
|
||||||
|
void get_device_info_(std::string &device_info);
|
||||||
|
void update_platform_();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace debug
|
} // namespace debug
|
||||||
|
|
287
esphome/components/debug/debug_esp32.cpp
Normal file
287
esphome/components/debug/debug_esp32.cpp
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
#include "debug_component.h"
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#include <esp_heap_caps.h>
|
||||||
|
#include <esp_system.h>
|
||||||
|
#include <esp_chip_info.h>
|
||||||
|
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
#include <esp32/rom/rtc.h>
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||||
|
#include <esp32c3/rom/rtc.h>
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C6)
|
||||||
|
#include <esp32c6/rom/rtc.h>
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
||||||
|
#include <esp32s2/rom/rtc.h>
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
#include <esp32s3/rom/rtc.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ARDUINO
|
||||||
|
#include <Esp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
static const char *const TAG = "debug";
|
||||||
|
|
||||||
|
std::string DebugComponent::get_reset_reason_() {
|
||||||
|
std::string reset_reason;
|
||||||
|
switch (rtc_get_reset_reason(0)) {
|
||||||
|
case POWERON_RESET:
|
||||||
|
reset_reason = "Power On Reset";
|
||||||
|
break;
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
case SW_RESET:
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
case RTC_SW_SYS_RESET:
|
||||||
|
#endif
|
||||||
|
reset_reason = "Software Reset Digital Core";
|
||||||
|
break;
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
case OWDT_RESET:
|
||||||
|
reset_reason = "Watch Dog Reset Digital Core";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DEEPSLEEP_RESET:
|
||||||
|
reset_reason = "Deep Sleep Reset Digital Core";
|
||||||
|
break;
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
case SDIO_RESET:
|
||||||
|
reset_reason = "SLC Module Reset Digital Core";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case TG0WDT_SYS_RESET:
|
||||||
|
reset_reason = "Timer Group 0 Watch Dog Reset Digital Core";
|
||||||
|
break;
|
||||||
|
case TG1WDT_SYS_RESET:
|
||||||
|
reset_reason = "Timer Group 1 Watch Dog Reset Digital Core";
|
||||||
|
break;
|
||||||
|
case RTCWDT_SYS_RESET:
|
||||||
|
reset_reason = "RTC Watch Dog Reset Digital Core";
|
||||||
|
break;
|
||||||
|
#if !defined(USE_ESP32_VARIANT_ESP32C6)
|
||||||
|
case INTRUSION_RESET:
|
||||||
|
reset_reason = "Intrusion Reset CPU";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
case TGWDT_CPU_RESET:
|
||||||
|
reset_reason = "Timer Group Reset CPU";
|
||||||
|
break;
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
case TG0WDT_CPU_RESET:
|
||||||
|
reset_reason = "Timer Group 0 Reset CPU";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
case SW_CPU_RESET:
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
case RTC_SW_CPU_RESET:
|
||||||
|
#endif
|
||||||
|
reset_reason = "Software Reset CPU";
|
||||||
|
break;
|
||||||
|
case RTCWDT_CPU_RESET:
|
||||||
|
reset_reason = "RTC Watch Dog Reset CPU";
|
||||||
|
break;
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
case EXT_CPU_RESET:
|
||||||
|
reset_reason = "External CPU Reset";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case RTCWDT_BROWN_OUT_RESET:
|
||||||
|
reset_reason = "Voltage Unstable Reset";
|
||||||
|
break;
|
||||||
|
case RTCWDT_RTC_RESET:
|
||||||
|
reset_reason = "RTC Watch Dog Reset Digital Core And RTC Module";
|
||||||
|
break;
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
case TG1WDT_CPU_RESET:
|
||||||
|
reset_reason = "Timer Group 1 Reset CPU";
|
||||||
|
break;
|
||||||
|
case SUPER_WDT_RESET:
|
||||||
|
reset_reason = "Super Watchdog Reset Digital Core And RTC Module";
|
||||||
|
break;
|
||||||
|
case GLITCH_RTC_RESET:
|
||||||
|
reset_reason = "Glitch Reset Digital Core And RTC Module";
|
||||||
|
break;
|
||||||
|
case EFUSE_RESET:
|
||||||
|
reset_reason = "eFuse Reset Digital Core";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
case USB_UART_CHIP_RESET:
|
||||||
|
reset_reason = "USB UART Reset Digital Core";
|
||||||
|
break;
|
||||||
|
case USB_JTAG_CHIP_RESET:
|
||||||
|
reset_reason = "USB JTAG Reset Digital Core";
|
||||||
|
break;
|
||||||
|
case POWER_GLITCH_RESET:
|
||||||
|
reset_reason = "Power Glitch Reset Digital Core And RTC Module";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
reset_reason = "Unknown Reset Reason";
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||||
|
return reset_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DebugComponent::get_free_heap_() { return heap_caps_get_free_size(MALLOC_CAP_INTERNAL); }
|
||||||
|
|
||||||
|
void DebugComponent::get_device_info_(std::string &device_info) {
|
||||||
|
#if defined(USE_ARDUINO)
|
||||||
|
const char *flash_mode;
|
||||||
|
switch (ESP.getFlashChipMode()) { // NOLINT(readability-static-accessed-through-instance)
|
||||||
|
case FM_QIO:
|
||||||
|
flash_mode = "QIO";
|
||||||
|
break;
|
||||||
|
case FM_QOUT:
|
||||||
|
flash_mode = "QOUT";
|
||||||
|
break;
|
||||||
|
case FM_DIO:
|
||||||
|
flash_mode = "DIO";
|
||||||
|
break;
|
||||||
|
case FM_DOUT:
|
||||||
|
flash_mode = "DOUT";
|
||||||
|
break;
|
||||||
|
case FM_FAST_READ:
|
||||||
|
flash_mode = "FAST_READ";
|
||||||
|
break;
|
||||||
|
case FM_SLOW_READ:
|
||||||
|
flash_mode = "SLOW_READ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
flash_mode = "UNKNOWN";
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Flash Chip: Size=%ukB Speed=%uMHz Mode=%s",
|
||||||
|
ESP.getFlashChipSize() / 1024, // NOLINT
|
||||||
|
ESP.getFlashChipSpeed() / 1000000, flash_mode); // NOLINT
|
||||||
|
device_info += "|Flash: " + to_string(ESP.getFlashChipSize() / 1024) + // NOLINT
|
||||||
|
"kB Speed:" + to_string(ESP.getFlashChipSpeed() / 1000000) + "MHz Mode:"; // NOLINT
|
||||||
|
device_info += flash_mode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_chip_info_t info;
|
||||||
|
esp_chip_info(&info);
|
||||||
|
const char *model;
|
||||||
|
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||||
|
model = "ESP32";
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||||
|
model = "ESP32-C3";
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32C6)
|
||||||
|
model = "ESP32-C6";
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
||||||
|
model = "ESP32-S2";
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
model = "ESP32-S3";
|
||||||
|
#elif defined(USE_ESP32_VARIANT_ESP32H2)
|
||||||
|
model = "ESP32-H2";
|
||||||
|
#else
|
||||||
|
model = "UNKNOWN";
|
||||||
|
#endif
|
||||||
|
std::string features;
|
||||||
|
if (info.features & CHIP_FEATURE_EMB_FLASH) {
|
||||||
|
features += "EMB_FLASH,";
|
||||||
|
info.features &= ~CHIP_FEATURE_EMB_FLASH;
|
||||||
|
}
|
||||||
|
if (info.features & CHIP_FEATURE_WIFI_BGN) {
|
||||||
|
features += "WIFI_BGN,";
|
||||||
|
info.features &= ~CHIP_FEATURE_WIFI_BGN;
|
||||||
|
}
|
||||||
|
if (info.features & CHIP_FEATURE_BLE) {
|
||||||
|
features += "BLE,";
|
||||||
|
info.features &= ~CHIP_FEATURE_BLE;
|
||||||
|
}
|
||||||
|
if (info.features & CHIP_FEATURE_BT) {
|
||||||
|
features += "BT,";
|
||||||
|
info.features &= ~CHIP_FEATURE_BT;
|
||||||
|
}
|
||||||
|
if (info.features & CHIP_FEATURE_EMB_PSRAM) {
|
||||||
|
features += "EMB_PSRAM,";
|
||||||
|
info.features &= ~CHIP_FEATURE_EMB_PSRAM;
|
||||||
|
}
|
||||||
|
if (info.features)
|
||||||
|
features += "Other:" + format_hex(info.features);
|
||||||
|
ESP_LOGD(TAG, "Chip: Model=%s, Features=%s Cores=%u, Revision=%u", model, features.c_str(), info.cores,
|
||||||
|
info.revision);
|
||||||
|
device_info += "|Chip: ";
|
||||||
|
device_info += model;
|
||||||
|
device_info += " Features:";
|
||||||
|
device_info += features;
|
||||||
|
device_info += " Cores:" + to_string(info.cores);
|
||||||
|
device_info += " Revision:" + to_string(info.revision);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "ESP-IDF Version: %s", esp_get_idf_version());
|
||||||
|
device_info += "|ESP-IDF: ";
|
||||||
|
device_info += esp_get_idf_version();
|
||||||
|
|
||||||
|
std::string mac = get_mac_address_pretty();
|
||||||
|
ESP_LOGD(TAG, "EFuse MAC: %s", mac.c_str());
|
||||||
|
device_info += "|EFuse MAC: ";
|
||||||
|
device_info += mac;
|
||||||
|
|
||||||
|
device_info += "|Reset: ";
|
||||||
|
device_info += get_reset_reason_();
|
||||||
|
|
||||||
|
const char *wakeup_reason;
|
||||||
|
switch (rtc_get_wakeup_cause()) {
|
||||||
|
case NO_SLEEP:
|
||||||
|
wakeup_reason = "No Sleep";
|
||||||
|
break;
|
||||||
|
case EXT_EVENT0_TRIG:
|
||||||
|
wakeup_reason = "External Event 0";
|
||||||
|
break;
|
||||||
|
case EXT_EVENT1_TRIG:
|
||||||
|
wakeup_reason = "External Event 1";
|
||||||
|
break;
|
||||||
|
case GPIO_TRIG:
|
||||||
|
wakeup_reason = "GPIO";
|
||||||
|
break;
|
||||||
|
case TIMER_EXPIRE:
|
||||||
|
wakeup_reason = "Wakeup Timer";
|
||||||
|
break;
|
||||||
|
case SDIO_TRIG:
|
||||||
|
wakeup_reason = "SDIO";
|
||||||
|
break;
|
||||||
|
case MAC_TRIG:
|
||||||
|
wakeup_reason = "MAC";
|
||||||
|
break;
|
||||||
|
case UART0_TRIG:
|
||||||
|
wakeup_reason = "UART0";
|
||||||
|
break;
|
||||||
|
case UART1_TRIG:
|
||||||
|
wakeup_reason = "UART1";
|
||||||
|
break;
|
||||||
|
case TOUCH_TRIG:
|
||||||
|
wakeup_reason = "Touch";
|
||||||
|
break;
|
||||||
|
case SAR_TRIG:
|
||||||
|
wakeup_reason = "SAR";
|
||||||
|
break;
|
||||||
|
case BT_TRIG:
|
||||||
|
wakeup_reason = "BT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wakeup_reason = "Unknown";
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Wakeup Reason: %s", wakeup_reason);
|
||||||
|
device_info += "|Wakeup: ";
|
||||||
|
device_info += wakeup_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugComponent::update_platform_() {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->block_sensor_ != nullptr) {
|
||||||
|
this->block_sensor_->publish_state(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
|
||||||
|
}
|
||||||
|
if (this->psram_sensor_ != nullptr) {
|
||||||
|
this->psram_sensor_->publish_state(heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
#endif
|
94
esphome/components/debug/debug_esp8266.cpp
Normal file
94
esphome/components/debug/debug_esp8266.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#include "debug_component.h"
|
||||||
|
#ifdef USE_ESP8266
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include <Esp.h>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
static const char *const TAG = "debug";
|
||||||
|
|
||||||
|
std::string DebugComponent::get_reset_reason_() {
|
||||||
|
#if !defined(CLANG_TIDY)
|
||||||
|
return ESP.getResetReason().c_str();
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DebugComponent::get_free_heap_() {
|
||||||
|
return ESP.getFreeHeap(); // NOLINT(readability-static-accessed-through-instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugComponent::get_device_info_(std::string &device_info) {
|
||||||
|
const char *flash_mode;
|
||||||
|
switch (ESP.getFlashChipMode()) { // NOLINT(readability-static-accessed-through-instance)
|
||||||
|
case FM_QIO:
|
||||||
|
flash_mode = "QIO";
|
||||||
|
break;
|
||||||
|
case FM_QOUT:
|
||||||
|
flash_mode = "QOUT";
|
||||||
|
break;
|
||||||
|
case FM_DIO:
|
||||||
|
flash_mode = "DIO";
|
||||||
|
break;
|
||||||
|
case FM_DOUT:
|
||||||
|
flash_mode = "DOUT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
flash_mode = "UNKNOWN";
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Flash Chip: Size=%ukB Speed=%uMHz Mode=%s",
|
||||||
|
ESP.getFlashChipSize() / 1024, // NOLINT
|
||||||
|
ESP.getFlashChipSpeed() / 1000000, flash_mode); // NOLINT
|
||||||
|
device_info += "|Flash: " + to_string(ESP.getFlashChipSize() / 1024) + // NOLINT
|
||||||
|
"kB Speed:" + to_string(ESP.getFlashChipSpeed() / 1000000) + "MHz Mode:"; // NOLINT
|
||||||
|
device_info += flash_mode;
|
||||||
|
|
||||||
|
#if !defined(CLANG_TIDY)
|
||||||
|
auto reset_reason = get_reset_reason_();
|
||||||
|
ESP_LOGD(TAG, "Chip ID: 0x%08X", ESP.getChipId());
|
||||||
|
ESP_LOGD(TAG, "SDK Version: %s", ESP.getSdkVersion());
|
||||||
|
ESP_LOGD(TAG, "Core Version: %s", ESP.getCoreVersion().c_str());
|
||||||
|
ESP_LOGD(TAG, "Boot Version=%u Mode=%u", ESP.getBootVersion(), ESP.getBootMode());
|
||||||
|
ESP_LOGD(TAG, "CPU Frequency: %u", ESP.getCpuFreqMHz());
|
||||||
|
ESP_LOGD(TAG, "Flash Chip ID=0x%08X", ESP.getFlashChipId());
|
||||||
|
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||||
|
ESP_LOGD(TAG, "Reset Info: %s", ESP.getResetInfo().c_str());
|
||||||
|
|
||||||
|
device_info += "|Chip: 0x" + format_hex(ESP.getChipId());
|
||||||
|
device_info += "|SDK: ";
|
||||||
|
device_info += ESP.getSdkVersion();
|
||||||
|
device_info += "|Core: ";
|
||||||
|
device_info += ESP.getCoreVersion().c_str();
|
||||||
|
device_info += "|Boot: ";
|
||||||
|
device_info += to_string(ESP.getBootVersion());
|
||||||
|
device_info += "|Mode: " + to_string(ESP.getBootMode());
|
||||||
|
device_info += "|CPU: " + to_string(ESP.getCpuFreqMHz());
|
||||||
|
device_info += "|Flash: 0x" + format_hex(ESP.getFlashChipId());
|
||||||
|
device_info += "|Reset: ";
|
||||||
|
device_info += reset_reason;
|
||||||
|
device_info += "|";
|
||||||
|
device_info += ESP.getResetInfo().c_str();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugComponent::update_platform_() {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->block_sensor_ != nullptr) {
|
||||||
|
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
|
||||||
|
this->block_sensor_->publish_state(ESP.getMaxFreeBlockSize());
|
||||||
|
}
|
||||||
|
#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
||||||
|
if (this->fragmentation_sensor_ != nullptr) {
|
||||||
|
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
|
||||||
|
this->fragmentation_sensor_->publish_state(ESP.getHeapFragmentation());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
#endif
|
18
esphome/components/debug/debug_host.cpp
Normal file
18
esphome/components/debug/debug_host.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include "debug_component.h"
|
||||||
|
#ifdef USE_HOST
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
std::string DebugComponent::get_reset_reason_() { return ""; }
|
||||||
|
|
||||||
|
uint32_t DebugComponent::get_free_heap_() { return INT_MAX; }
|
||||||
|
|
||||||
|
void DebugComponent::get_device_info_(std::string &device_info) {}
|
||||||
|
|
||||||
|
void DebugComponent::update_platform_() {}
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
#endif
|
44
esphome/components/debug/debug_libretiny.cpp
Normal file
44
esphome/components/debug/debug_libretiny.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include "debug_component.h"
|
||||||
|
#ifdef USE_LIBRETINY
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
static const char *const TAG = "debug";
|
||||||
|
|
||||||
|
std::string DebugComponent::get_reset_reason_() { return lt_get_reboot_reason_name(lt_get_reboot_reason()); }
|
||||||
|
|
||||||
|
uint32_t DebugComponent::get_free_heap_() { return lt_heap_get_free(); }
|
||||||
|
|
||||||
|
void DebugComponent::get_device_info_(std::string &device_info) {
|
||||||
|
reset_reason = get_reset_reason_();
|
||||||
|
ESP_LOGD(TAG, "LibreTiny Version: %s", lt_get_version());
|
||||||
|
ESP_LOGD(TAG, "Chip: %s (%04x) @ %u MHz", lt_cpu_get_model_name(), lt_cpu_get_model(), lt_cpu_get_freq_mhz());
|
||||||
|
ESP_LOGD(TAG, "Chip ID: 0x%06X", lt_cpu_get_mac_id());
|
||||||
|
ESP_LOGD(TAG, "Board: %s", lt_get_board_code());
|
||||||
|
ESP_LOGD(TAG, "Flash: %u KiB / RAM: %u KiB", lt_flash_get_size() / 1024, lt_ram_get_size() / 1024);
|
||||||
|
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||||
|
|
||||||
|
device_info += "|Version: ";
|
||||||
|
device_info += LT_BANNER_STR + 10;
|
||||||
|
device_info += "|Reset Reason: ";
|
||||||
|
device_info += reset_reason;
|
||||||
|
device_info += "|Chip Name: ";
|
||||||
|
device_info += lt_cpu_get_model_name();
|
||||||
|
device_info += "|Chip ID: 0x" + format_hex(lt_cpu_get_mac_id());
|
||||||
|
device_info += "|Flash: " + to_string(lt_flash_get_size() / 1024) + " KiB";
|
||||||
|
device_info += "|RAM: " + to_string(lt_ram_get_size() / 1024) + " KiB";
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugComponent::update_platform_() {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->block_sensor_ != nullptr) {
|
||||||
|
this->block_sensor_->publish_state(lt_heap_get_max_alloc());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
#endif
|
23
esphome/components/debug/debug_rp2040.cpp
Normal file
23
esphome/components/debug/debug_rp2040.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "debug_component.h"
|
||||||
|
#ifdef USE_RP2040
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
static const char *const TAG = "debug";
|
||||||
|
|
||||||
|
std::string DebugComponent::get_reset_reason_() { return ""; }
|
||||||
|
|
||||||
|
uint32_t DebugComponent::get_free_heap_() { return rp2040.getFreeHeap(); }
|
||||||
|
|
||||||
|
void DebugComponent::get_device_info_(std::string &device_info) {
|
||||||
|
ESP_LOGD(TAG, "CPU Frequency: %u", rp2040.f_cpu());
|
||||||
|
device_info += "CPU Frequency: " + to_string(rp2040.f_cpu());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugComponent::update_platform_() {}
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
#endif
|
|
@ -227,7 +227,7 @@ ARDUINO_PLATFORM_VERSION = cv.Version(5, 4, 0)
|
||||||
# The default/recommended esp-idf framework version
|
# The default/recommended esp-idf framework version
|
||||||
# - https://github.com/espressif/esp-idf/releases
|
# - https://github.com/espressif/esp-idf/releases
|
||||||
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
|
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
|
||||||
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 4, 6)
|
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 4, 7)
|
||||||
# The platformio/espressif32 version to use for esp-idf frameworks
|
# The platformio/espressif32 version to use for esp-idf frameworks
|
||||||
# - https://github.com/platformio/platform-espressif32/releases
|
# - https://github.com/platformio/platform-espressif32/releases
|
||||||
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
|
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
#include <esp32-hal-bt.h>
|
#include <esp32-hal-bt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MBEDTLS_AES_ALT
|
||||||
|
#include <aes_alt.h>
|
||||||
|
|
||||||
// bt_trace.h
|
// bt_trace.h
|
||||||
#undef TAG
|
#undef TAG
|
||||||
|
|
||||||
|
@ -692,6 +695,39 @@ void ESP32BLETracker::print_bt_device_info(const ESPBTDevice &device) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ESPBTDevice::resolve_irk(const uint8_t *irk) const {
|
||||||
|
uint8_t ecb_key[16];
|
||||||
|
uint8_t ecb_plaintext[16];
|
||||||
|
uint8_t ecb_ciphertext[16];
|
||||||
|
|
||||||
|
uint64_t addr64 = esp32_ble::ble_addr_to_uint64(this->address_);
|
||||||
|
|
||||||
|
memcpy(&ecb_key, irk, 16);
|
||||||
|
memset(&ecb_plaintext, 0, 16);
|
||||||
|
|
||||||
|
ecb_plaintext[13] = (addr64 >> 40) & 0xff;
|
||||||
|
ecb_plaintext[14] = (addr64 >> 32) & 0xff;
|
||||||
|
ecb_plaintext[15] = (addr64 >> 24) & 0xff;
|
||||||
|
|
||||||
|
mbedtls_aes_context ctx = {0, 0, {0}};
|
||||||
|
mbedtls_aes_init(&ctx);
|
||||||
|
|
||||||
|
if (mbedtls_aes_setkey_enc(&ctx, ecb_key, 128) != 0) {
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_aes_crypt_ecb(&ctx, ESP_AES_ENCRYPT, ecb_plaintext, ecb_ciphertext) != 0) {
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
|
||||||
|
return ecb_ciphertext[15] == (addr64 & 0xff) && ecb_ciphertext[14] == ((addr64 >> 8) & 0xff) &&
|
||||||
|
ecb_ciphertext[13] == ((addr64 >> 16) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace esp32_ble_tracker
|
} // namespace esp32_ble_tracker
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ class ESPBTDevice {
|
||||||
|
|
||||||
const esp_ble_gap_cb_param_t::ble_scan_result_evt_param &get_scan_result() const { return scan_result_; }
|
const esp_ble_gap_cb_param_t::ble_scan_result_evt_param &get_scan_result() const { return scan_result_; }
|
||||||
|
|
||||||
|
bool resolve_irk(const uint8_t *irk) const;
|
||||||
|
|
||||||
optional<ESPBLEiBeacon> get_ibeacon() const {
|
optional<ESPBLEiBeacon> get_ibeacon() const {
|
||||||
for (auto &it : this->manufacturer_datas_) {
|
for (auto &it : this->manufacturer_datas_) {
|
||||||
auto res = ESPBLEiBeacon::from_manufacturer_data(it);
|
auto res = ESPBLEiBeacon::from_manufacturer_data(it);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "ethernet_component.h"
|
#include "ethernet_component.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/util.h"
|
#include "esphome/core/util.h"
|
||||||
#include "esphome/core/application.h"
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
#include <cinttypes>
|
|
||||||
#include <lwip/dns.h>
|
#include <lwip/dns.h>
|
||||||
|
#include <cinttypes>
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
|
||||||
#ifdef USE_ETHERNET_SPI
|
#ifdef USE_ETHERNET_SPI
|
||||||
|
@ -184,6 +184,10 @@ void EthernetComponent::setup() {
|
||||||
// KSZ8081RNA default is incorrect. It expects a 25MHz clock instead of the 50MHz we provide.
|
// KSZ8081RNA default is incorrect. It expects a 25MHz clock instead of the 50MHz we provide.
|
||||||
this->ksz8081_set_clock_reference_(mac);
|
this->ksz8081_set_clock_reference_(mac);
|
||||||
}
|
}
|
||||||
|
if (this->type_ == ETHERNET_TYPE_RTL8201 && this->clk_mode_ == EMAC_CLK_EXT_IN) {
|
||||||
|
// Change in default behavior of RTL8201FI may require register setting to enable external clock
|
||||||
|
this->rtl8201_set_rmii_mode_(mac);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// use ESP internal eth mac
|
// use ESP internal eth mac
|
||||||
|
@ -554,9 +558,10 @@ bool EthernetComponent::powerdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_ETHERNET_SPI
|
#ifndef USE_ETHERNET_SPI
|
||||||
void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
|
|
||||||
#define KSZ80XX_PC2R_REG_ADDR (0x1F)
|
|
||||||
|
|
||||||
|
constexpr uint8_t KSZ80XX_PC2R_REG_ADDR = 0x1F;
|
||||||
|
|
||||||
|
void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
|
|
||||||
uint32_t phy_control_2;
|
uint32_t phy_control_2;
|
||||||
|
@ -581,9 +586,47 @@ void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
|
||||||
ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed");
|
ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed");
|
||||||
ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str());
|
ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef KSZ80XX_PC2R_REG_ADDR
|
|
||||||
}
|
}
|
||||||
|
constexpr uint8_t RTL8201_RMSR_REG_ADDR = 0x10;
|
||||||
|
void EthernetComponent::rtl8201_set_rmii_mode_(esp_eth_mac_t *mac) {
|
||||||
|
esp_err_t err;
|
||||||
|
uint32_t phy_rmii_mode;
|
||||||
|
err = mac->write_phy_reg(mac, this->phy_addr_, 0x1f, 0x07);
|
||||||
|
ESPHL_ERROR_CHECK(err, "Setting Page 7 failed");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RTL8201 RMII Mode Setting Register (RMSR)
|
||||||
|
* Page 7 Register 16
|
||||||
|
*
|
||||||
|
* bit 0 Reserved 0
|
||||||
|
* bit 1 Rg_rmii_rxdsel 1 (default)
|
||||||
|
* bit 2 Rg_rmii_rxdv_sel: 0 (default)
|
||||||
|
* bit 3 RMII Mode: 1 (RMII Mode)
|
||||||
|
* bit 4~7 Rg_rmii_rx_offset: 1111 (default)
|
||||||
|
* bit 8~11 Rg_rmii_tx_offset: 1111 (default)
|
||||||
|
* bit 12 Rg_rmii_clkdir: 1 (Input)
|
||||||
|
* bit 13~15 Reserved 000
|
||||||
|
*
|
||||||
|
* Binary: 0001 1111 1111 1010
|
||||||
|
* Hex: 0x1FFA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
err = mac->read_phy_reg(mac, this->phy_addr_, RTL8201_RMSR_REG_ADDR, &(phy_rmii_mode));
|
||||||
|
ESPHL_ERROR_CHECK(err, "Read PHY RMSR Register failed");
|
||||||
|
ESP_LOGV(TAG, "Hardware default RTL8201 RMII Mode Register is: 0x%04X", phy_rmii_mode);
|
||||||
|
|
||||||
|
err = mac->write_phy_reg(mac, this->phy_addr_, RTL8201_RMSR_REG_ADDR, 0x1FFA);
|
||||||
|
ESPHL_ERROR_CHECK(err, "Setting Register 16 RMII Mode Setting failed");
|
||||||
|
|
||||||
|
err = mac->read_phy_reg(mac, this->phy_addr_, RTL8201_RMSR_REG_ADDR, &(phy_rmii_mode));
|
||||||
|
ESPHL_ERROR_CHECK(err, "Read PHY RMSR Register failed");
|
||||||
|
ESP_LOGV(TAG, "Setting RTL8201 RMII Mode Register to: 0x%04X", phy_rmii_mode);
|
||||||
|
|
||||||
|
err = mac->write_phy_reg(mac, this->phy_addr_, 0x1f, 0x0);
|
||||||
|
ESPHL_ERROR_CHECK(err, "Setting Page 0 failed");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace ethernet
|
} // namespace ethernet
|
||||||
|
|
|
@ -86,6 +86,8 @@ class EthernetComponent : public Component {
|
||||||
void dump_connect_params_();
|
void dump_connect_params_();
|
||||||
/// @brief Set `RMII Reference Clock Select` bit for KSZ8081.
|
/// @brief Set `RMII Reference Clock Select` bit for KSZ8081.
|
||||||
void ksz8081_set_clock_reference_(esp_eth_mac_t *mac);
|
void ksz8081_set_clock_reference_(esp_eth_mac_t *mac);
|
||||||
|
/// @brief Set `RMII Mode Setting Register` for RTL8201.
|
||||||
|
void rtl8201_set_rmii_mode_(esp_eth_mac_t *mac);
|
||||||
|
|
||||||
std::string use_address_;
|
std::string use_address_;
|
||||||
#ifdef USE_ETHERNET_SPI
|
#ifdef USE_ETHERNET_SPI
|
||||||
|
|
32
esphome/components/gdk101/__init__.py
Normal file
32
esphome/components/gdk101/__init__.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import i2c
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ["@Szewcson"]
|
||||||
|
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
MULTI_CONF = True
|
||||||
|
|
||||||
|
CONF_GDK101_ID = "gdk101_id"
|
||||||
|
|
||||||
|
gdk101_ns = cg.esphome_ns.namespace("gdk101")
|
||||||
|
GDK101Component = gdk101_ns.class_(
|
||||||
|
"GDK101Component", cg.PollingComponent, i2c.I2CDevice
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(GDK101Component),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
.extend(i2c.i2c_device_schema(0x18))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await i2c.register_i2c_device(var, config)
|
29
esphome/components/gdk101/binary_sensor.py
Normal file
29
esphome/components/gdk101/binary_sensor.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import binary_sensor
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_VIBRATIONS,
|
||||||
|
DEVICE_CLASS_VIBRATION,
|
||||||
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
ICON_VIBRATE,
|
||||||
|
)
|
||||||
|
from . import CONF_GDK101_ID, GDK101Component
|
||||||
|
|
||||||
|
DEPENDENCIES = ["gdk101"]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_GDK101_ID): cv.use_id(GDK101Component),
|
||||||
|
cv.Required(CONF_VIBRATIONS): binary_sensor.binary_sensor_schema(
|
||||||
|
device_class=DEVICE_CLASS_VIBRATION,
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
icon=ICON_VIBRATE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
hub = await cg.get_variable(config[CONF_GDK101_ID])
|
||||||
|
var = await binary_sensor.new_binary_sensor(config[CONF_VIBRATIONS])
|
||||||
|
cg.add(hub.set_vibration_binary_sensor(var))
|
189
esphome/components/gdk101/gdk101.cpp
Normal file
189
esphome/components/gdk101/gdk101.cpp
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
#include "gdk101.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace gdk101 {
|
||||||
|
|
||||||
|
static const char *const TAG = "gdk101";
|
||||||
|
static const uint8_t NUMBER_OF_READ_RETRIES = 5;
|
||||||
|
|
||||||
|
void GDK101Component::update() {
|
||||||
|
uint8_t data[2];
|
||||||
|
if (!this->read_dose_1m_(data)) {
|
||||||
|
this->status_set_warning("Failed to read dose 1m");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->read_dose_10m_(data)) {
|
||||||
|
this->status_set_warning("Failed to read dose 10m");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->read_status_(data)) {
|
||||||
|
this->status_set_warning("Failed to read status");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->read_measurement_duration_(data)) {
|
||||||
|
this->status_set_warning("Failed to read measurement duration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->status_clear_warning();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDK101Component::setup() {
|
||||||
|
uint8_t data[2];
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up GDK101...");
|
||||||
|
// first, reset the sensor
|
||||||
|
if (!this->reset_sensor_(data)) {
|
||||||
|
this->status_set_error("Reset failed!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// sensor should acknowledge success of the reset procedure
|
||||||
|
if (data[0] != 1) {
|
||||||
|
this->status_set_error("Reset not acknowledged!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delay(10);
|
||||||
|
// read firmware version
|
||||||
|
if (!this->read_fw_version_(data)) {
|
||||||
|
this->status_set_error("Failed to read firmware version");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDK101Component::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "GDK101:");
|
||||||
|
LOG_I2C_DEVICE(this);
|
||||||
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGE(TAG, "Communication with GDK101 failed!");
|
||||||
|
}
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
LOG_SENSOR(" ", "Firmware Version", this->fw_version_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Average Radaition Dose per 1 minute", this->rad_1m_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Average Radaition Dose per 10 minutes", this->rad_10m_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Status", this->status_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Measurement Duration", this->measurement_duration_sensor_);
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
LOG_BINARY_SENSOR(" ", "Vibration Status", this->vibration_binary_sensor_);
|
||||||
|
#endif // USE_BINARY_SENSOR
|
||||||
|
}
|
||||||
|
|
||||||
|
float GDK101Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
|
||||||
|
bool GDK101Component::read_bytes_with_retry_(uint8_t a_register, uint8_t *data, uint8_t len) {
|
||||||
|
uint8_t retry = NUMBER_OF_READ_RETRIES;
|
||||||
|
bool status = false;
|
||||||
|
while (!status && retry) {
|
||||||
|
status = this->read_bytes(a_register, data, len);
|
||||||
|
retry--;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDK101Component::reset_sensor_(uint8_t *data) {
|
||||||
|
// It looks like reset is not so well designed in that sensor
|
||||||
|
// After sending reset command it looks that sensor start performing reset and is unresponsible during read
|
||||||
|
// after a while we can send another reset command and read "0x01" as confirmation
|
||||||
|
// Documentation not going in to such details unfortunately
|
||||||
|
if (!this->read_bytes_with_retry_(GDK101_REG_RESET, data, 2)) {
|
||||||
|
ESP_LOGE(TAG, "Updating GDK101 failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDK101Component::read_dose_1m_(uint8_t *data) {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->rad_1m_sensor_ != nullptr) {
|
||||||
|
if (!this->read_bytes(GDK101_REG_READ_1MIN_AVG, data, 2)) {
|
||||||
|
ESP_LOGE(TAG, "Updating GDK101 failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float dose = data[0] + (data[1] / 100.0f);
|
||||||
|
|
||||||
|
this->rad_1m_sensor_->publish_state(dose);
|
||||||
|
}
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDK101Component::read_dose_10m_(uint8_t *data) {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->rad_10m_sensor_ != nullptr) {
|
||||||
|
if (!this->read_bytes(GDK101_REG_READ_10MIN_AVG, data, 2)) {
|
||||||
|
ESP_LOGE(TAG, "Updating GDK101 failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float dose = data[0] + (data[1] / 100.0f);
|
||||||
|
|
||||||
|
this->rad_10m_sensor_->publish_state(dose);
|
||||||
|
}
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDK101Component::read_status_(uint8_t *data) {
|
||||||
|
if (!this->read_bytes(GDK101_REG_READ_STATUS, data, 2)) {
|
||||||
|
ESP_LOGE(TAG, "Updating GDK101 failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->status_sensor_ != nullptr) {
|
||||||
|
this->status_sensor_->publish_state(data[0]);
|
||||||
|
}
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
if (this->vibration_binary_sensor_ != nullptr) {
|
||||||
|
this->vibration_binary_sensor_->publish_state(data[1]);
|
||||||
|
}
|
||||||
|
#endif // USE_BINARY_SENSOR
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDK101Component::read_fw_version_(uint8_t *data) {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->fw_version_sensor_ != nullptr) {
|
||||||
|
if (!this->read_bytes(GDK101_REG_READ_FIRMWARE, data, 2)) {
|
||||||
|
ESP_LOGE(TAG, "Updating GDK101 failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float fw_version = data[0] + (data[1] / 10.0f);
|
||||||
|
|
||||||
|
this->fw_version_sensor_->publish_state(fw_version);
|
||||||
|
}
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDK101Component::read_measurement_duration_(uint8_t *data) {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->measurement_duration_sensor_ != nullptr) {
|
||||||
|
if (!this->read_bytes(GDK101_REG_READ_MEASURING_TIME, data, 2)) {
|
||||||
|
ESP_LOGE(TAG, "Updating GDK101 failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float meas_time = (data[0] * 60) + data[1];
|
||||||
|
|
||||||
|
this->measurement_duration_sensor_->publish_state(meas_time);
|
||||||
|
}
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gdk101
|
||||||
|
} // namespace esphome
|
52
esphome/components/gdk101/gdk101.h
Normal file
52
esphome/components/gdk101/gdk101.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
|
#endif // USE_BINARY_SENSOR
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace gdk101 {
|
||||||
|
|
||||||
|
static const uint8_t GDK101_REG_READ_FIRMWARE = 0xB4; // Firmware version
|
||||||
|
static const uint8_t GDK101_REG_RESET = 0xA0; // Reset register - reading its value triggers reset
|
||||||
|
static const uint8_t GDK101_REG_READ_STATUS = 0xB0; // Status register
|
||||||
|
static const uint8_t GDK101_REG_READ_MEASURING_TIME = 0xB1; // Mesuring time
|
||||||
|
static const uint8_t GDK101_REG_READ_10MIN_AVG = 0xB2; // Average radiation dose per 10 min
|
||||||
|
static const uint8_t GDK101_REG_READ_1MIN_AVG = 0xB3; // Average radiation dose per 1 min
|
||||||
|
|
||||||
|
class GDK101Component : public PollingComponent, public i2c::I2CDevice {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
SUB_SENSOR(rad_1m)
|
||||||
|
SUB_SENSOR(rad_10m)
|
||||||
|
SUB_SENSOR(status)
|
||||||
|
SUB_SENSOR(fw_version)
|
||||||
|
SUB_SENSOR(measurement_duration)
|
||||||
|
#endif // USE_SENSOR
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
SUB_BINARY_SENSOR(vibration)
|
||||||
|
#endif // USE_BINARY_SENSOR
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool read_bytes_with_retry_(uint8_t a_register, uint8_t *data, uint8_t len);
|
||||||
|
bool reset_sensor_(uint8_t *data);
|
||||||
|
bool read_dose_1m_(uint8_t *data);
|
||||||
|
bool read_dose_10m_(uint8_t *data);
|
||||||
|
bool read_status_(uint8_t *data);
|
||||||
|
bool read_fw_version_(uint8_t *data);
|
||||||
|
bool read_measurement_duration_(uint8_t *data);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gdk101
|
||||||
|
} // namespace esphome
|
83
esphome/components/gdk101/sensor.py
Normal file
83
esphome/components/gdk101/sensor.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import sensor
|
||||||
|
from esphome.const import (
|
||||||
|
DEVICE_CLASS_DURATION,
|
||||||
|
DEVICE_CLASS_EMPTY,
|
||||||
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
CONF_MEASUREMENT_DURATION,
|
||||||
|
CONF_STATUS,
|
||||||
|
CONF_VERSION,
|
||||||
|
ICON_RADIOACTIVE,
|
||||||
|
ICON_TIMER,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
STATE_CLASS_TOTAL_INCREASING,
|
||||||
|
UNIT_MICROSILVERTS_PER_HOUR,
|
||||||
|
UNIT_SECOND,
|
||||||
|
)
|
||||||
|
from . import CONF_GDK101_ID, GDK101Component
|
||||||
|
|
||||||
|
CONF_RADIATION_DOSE_PER_1M = "radiation_dose_per_1m"
|
||||||
|
CONF_RADIATION_DOSE_PER_10M = "radiation_dose_per_10m"
|
||||||
|
|
||||||
|
DEPENDENCIES = ["gdk101"]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_GDK101_ID): cv.use_id(GDK101Component),
|
||||||
|
cv.Optional(CONF_RADIATION_DOSE_PER_1M): sensor.sensor_schema(
|
||||||
|
icon=ICON_RADIOACTIVE,
|
||||||
|
unit_of_measurement=UNIT_MICROSILVERTS_PER_HOUR,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
device_class=DEVICE_CLASS_EMPTY,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_RADIATION_DOSE_PER_10M): sensor.sensor_schema(
|
||||||
|
icon=ICON_RADIOACTIVE,
|
||||||
|
unit_of_measurement=UNIT_MICROSILVERTS_PER_HOUR,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
device_class=DEVICE_CLASS_EMPTY,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_VERSION): sensor.sensor_schema(
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
accuracy_decimals=1,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_STATUS): sensor.sensor_schema(
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
accuracy_decimals=0,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_MEASUREMENT_DURATION): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_SECOND,
|
||||||
|
icon=ICON_TIMER,
|
||||||
|
accuracy_decimals=0,
|
||||||
|
state_class=STATE_CLASS_TOTAL_INCREASING,
|
||||||
|
device_class=DEVICE_CLASS_DURATION,
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
hub = await cg.get_variable(config[CONF_GDK101_ID])
|
||||||
|
|
||||||
|
if radiation_dose_per_1m := config.get(CONF_RADIATION_DOSE_PER_1M):
|
||||||
|
sens = await sensor.new_sensor(radiation_dose_per_1m)
|
||||||
|
cg.add(hub.set_rad_1m_sensor(sens))
|
||||||
|
|
||||||
|
if radiation_dose_per_10m := config.get(CONF_RADIATION_DOSE_PER_10M):
|
||||||
|
sens = await sensor.new_sensor(radiation_dose_per_10m)
|
||||||
|
cg.add(hub.set_rad_10m_sensor(sens))
|
||||||
|
|
||||||
|
if version_config := config.get(CONF_VERSION):
|
||||||
|
sens = await sensor.new_sensor(version_config)
|
||||||
|
cg.add(hub.set_fw_version_sensor(sens))
|
||||||
|
|
||||||
|
if status_config := config.get(CONF_STATUS):
|
||||||
|
sens = await sensor.new_sensor(status_config)
|
||||||
|
cg.add(hub.set_status_sensor(sens))
|
||||||
|
|
||||||
|
if measurement_duration_config := config.get(CONF_MEASUREMENT_DURATION):
|
||||||
|
sens = await sensor.new_sensor(measurement_duration_config)
|
||||||
|
cg.add(hub.set_measurement_duration_sensor(sens))
|
|
@ -8,6 +8,9 @@ namespace ltr390 {
|
||||||
|
|
||||||
static const char *const TAG = "ltr390";
|
static const char *const TAG = "ltr390";
|
||||||
|
|
||||||
|
static const uint8_t LTR390_WAKEUP_TIME = 10;
|
||||||
|
static const uint8_t LTR390_SETTLE_TIME = 5;
|
||||||
|
|
||||||
static const uint8_t LTR390_MAIN_CTRL = 0x00;
|
static const uint8_t LTR390_MAIN_CTRL = 0x00;
|
||||||
static const uint8_t LTR390_MEAS_RATE = 0x04;
|
static const uint8_t LTR390_MEAS_RATE = 0x04;
|
||||||
static const uint8_t LTR390_GAIN = 0x05;
|
static const uint8_t LTR390_GAIN = 0x05;
|
||||||
|
@ -101,21 +104,27 @@ void LTR390Component::read_mode_(int mode_index) {
|
||||||
|
|
||||||
std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
|
std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
|
||||||
ctrl[LTR390_CTRL_MODE] = mode;
|
ctrl[LTR390_CTRL_MODE] = mode;
|
||||||
|
ctrl[LTR390_CTRL_EN] = true;
|
||||||
this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
|
this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
|
||||||
|
|
||||||
// After the sensor integration time do the following
|
// After the sensor integration time do the following
|
||||||
this->set_timeout(((uint32_t) RESOLUTIONVALUE[this->res_]) * 100, [this, mode_index]() {
|
this->set_timeout(((uint32_t) RESOLUTIONVALUE[this->res_]) * 100 + LTR390_WAKEUP_TIME + LTR390_SETTLE_TIME,
|
||||||
// Read from the sensor
|
[this, mode_index]() {
|
||||||
std::get<1>(this->mode_funcs_[mode_index])();
|
// Read from the sensor
|
||||||
|
std::get<1>(this->mode_funcs_[mode_index])();
|
||||||
|
|
||||||
// If there are more modes to read then begin the next
|
// If there are more modes to read then begin the next
|
||||||
// otherwise stop
|
// otherwise stop
|
||||||
if (mode_index + 1 < (int) this->mode_funcs_.size()) {
|
if (mode_index + 1 < (int) this->mode_funcs_.size()) {
|
||||||
this->read_mode_(mode_index + 1);
|
this->read_mode_(mode_index + 1);
|
||||||
} else {
|
} else {
|
||||||
this->reading_ = false;
|
// put sensor in standby
|
||||||
}
|
std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
|
||||||
});
|
ctrl[LTR390_CTRL_EN] = false;
|
||||||
|
this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
|
||||||
|
this->reading_ = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LTR390Component::setup() {
|
void LTR390Component::setup() {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "esphome/components/display/display_color_utils.h"
|
#include "esphome/components/display/display_color_utils.h"
|
||||||
|
|
||||||
#ifdef USE_NEXTION_TFT_UPLOAD
|
#ifdef USE_NEXTION_TFT_UPLOAD
|
||||||
#ifdef ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#endif // USE_ESP32
|
#endif // USE_ESP32
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#endif // USE_ESP8266
|
#endif // USE_ESP8266
|
||||||
#elif defined(USE_ESP_IDF)
|
#elif defined(USE_ESP_IDF)
|
||||||
#include <esp_http_client.h>
|
#include <esp_http_client.h>
|
||||||
#endif // ARDUINO vs ESP-IDF
|
#endif // ARDUINO vs USE_ESP_IDF
|
||||||
#endif // USE_NEXTION_TFT_UPLOAD
|
#endif // USE_NEXTION_TFT_UPLOAD
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -987,7 +987,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
|
||||||
|
|
||||||
#ifdef USE_NEXTION_TFT_UPLOAD
|
#ifdef USE_NEXTION_TFT_UPLOAD
|
||||||
/**
|
/**
|
||||||
* Set the tft file URL. https seems problematic with arduino..
|
* Set the tft file URL. https seems problematic with Arduino..
|
||||||
*/
|
*/
|
||||||
void set_tft_url(const std::string &tft_url) { this->tft_url_ = tft_url; }
|
void set_tft_url(const std::string &tft_url) { this->tft_url_ = tft_url; }
|
||||||
|
|
||||||
|
@ -1190,7 +1190,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
|
||||||
uint32_t original_baud_rate_ = 0;
|
uint32_t original_baud_rate_ = 0;
|
||||||
bool upload_first_chunk_sent_ = false;
|
bool upload_first_chunk_sent_ = false;
|
||||||
|
|
||||||
#ifdef ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
/**
|
/**
|
||||||
* will request chunk_size chunks from the web server
|
* will request chunk_size chunks from the web server
|
||||||
* and send each to the nextion
|
* and send each to the nextion
|
||||||
|
@ -1208,7 +1208,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
|
||||||
* @return position of last byte transferred, -1 for failure.
|
* @return position of last byte transferred, -1 for failure.
|
||||||
*/
|
*/
|
||||||
int upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &range_start);
|
int upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &range_start);
|
||||||
#endif // ARDUINO vs USE_ESP_IDF
|
#endif // USE_ARDUINO vs USE_ESP_IDF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends the upload process, restart Nextion and, if successful,
|
* Ends the upload process, restart Nextion and, if successful,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "nextion.h"
|
#include "nextion.h"
|
||||||
|
|
||||||
#ifdef USE_NEXTION_TFT_UPLOAD
|
#ifdef USE_NEXTION_TFT_UPLOAD
|
||||||
#ifdef ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/defines.h"
|
#include "esphome/core/defines.h"
|
||||||
|
@ -383,5 +383,5 @@ WiFiClient *Nextion::get_wifi_client_() {
|
||||||
} // namespace nextion
|
} // namespace nextion
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
#endif // ARDUINO
|
#endif // USE_ARDUINO
|
||||||
#endif // USE_NEXTION_TFT_UPLOAD
|
#endif // USE_NEXTION_TFT_UPLOAD
|
||||||
|
|
|
@ -58,6 +58,7 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
||||||
void decode_rmt_(rmt_item32_t *item, size_t len);
|
void decode_rmt_(rmt_item32_t *item, size_t len);
|
||||||
RingbufHandle_t ringbuf_;
|
RingbufHandle_t ringbuf_;
|
||||||
esp_err_t error_code_{ESP_OK};
|
esp_err_t error_code_{ESP_OK};
|
||||||
|
std::string error_string_{""};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
||||||
|
|
|
@ -29,6 +29,7 @@ void RemoteReceiverComponent::setup() {
|
||||||
esp_err_t error = rmt_config(&rmt);
|
esp_err_t error = rmt_config(&rmt);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_config";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -36,18 +37,25 @@ void RemoteReceiverComponent::setup() {
|
||||||
error = rmt_driver_install(this->channel_, this->buffer_size_, 0);
|
error = rmt_driver_install(this->channel_, this->buffer_size_, 0);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
if (error == ESP_ERR_INVALID_STATE) {
|
||||||
|
this->error_string_ = str_sprintf("RMT channel %i is already in use by another component", this->channel_);
|
||||||
|
} else {
|
||||||
|
this->error_string_ = "in rmt_driver_install";
|
||||||
|
}
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error = rmt_get_ringbuf_handle(this->channel_, &this->ringbuf_);
|
error = rmt_get_ringbuf_handle(this->channel_, &this->ringbuf_);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_get_ringbuf_handle";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error = rmt_rx_start(this->channel_, true);
|
error = rmt_rx_start(this->channel_, true);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_rx_start";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +75,8 @@ void RemoteReceiverComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, " Filter out pulses shorter than: %" PRIu32 " us", this->filter_us_);
|
ESP_LOGCONFIG(TAG, " Filter out pulses shorter than: %" PRIu32 " us", this->filter_us_);
|
||||||
ESP_LOGCONFIG(TAG, " Signal is done after %" PRIu32 " us of no changes", this->idle_us_);
|
ESP_LOGCONFIG(TAG, " Signal is done after %" PRIu32 " us of no changes", this->idle_us_);
|
||||||
if (this->is_failed()) {
|
if (this->is_failed()) {
|
||||||
ESP_LOGE(TAG, "Configuring RMT driver failed: %s", esp_err_to_name(this->error_code_));
|
ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_),
|
||||||
|
this->error_string_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
||||||
bool initialized_{false};
|
bool initialized_{false};
|
||||||
std::vector<rmt_item32_t> rmt_temp_;
|
std::vector<rmt_item32_t> rmt_temp_;
|
||||||
esp_err_t error_code_{ESP_OK};
|
esp_err_t error_code_{ESP_OK};
|
||||||
|
std::string error_string_{""};
|
||||||
bool inverted_{false};
|
bool inverted_{false};
|
||||||
#endif
|
#endif
|
||||||
uint8_t carrier_duty_percent_;
|
uint8_t carrier_duty_percent_;
|
||||||
|
|
|
@ -23,7 +23,8 @@ void RemoteTransmitterComponent::dump_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->is_failed()) {
|
if (this->is_failed()) {
|
||||||
ESP_LOGE(TAG, "Configuring RMT driver failed: %s", esp_err_to_name(this->error_code_));
|
ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_),
|
||||||
|
this->error_string_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ void RemoteTransmitterComponent::configure_rmt_() {
|
||||||
esp_err_t error = rmt_config(&c);
|
esp_err_t error = rmt_config(&c);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_config";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +66,11 @@ void RemoteTransmitterComponent::configure_rmt_() {
|
||||||
error = rmt_driver_install(this->channel_, 0, 0);
|
error = rmt_driver_install(this->channel_, 0, 0);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
if (error == ESP_ERR_INVALID_STATE) {
|
||||||
|
this->error_string_ = str_sprintf("RMT channel %i is already in use by another component", this->channel_);
|
||||||
|
} else {
|
||||||
|
this->error_string_ = "in rmt_driver_install";
|
||||||
|
}
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,9 @@ void TimeBasedCover::control(const CoverCall &call) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto op = pos < this->position ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING;
|
auto op = pos < this->position ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING;
|
||||||
|
if (this->manual_control_ && (pos == COVER_OPEN || pos == COVER_CLOSED)) {
|
||||||
|
this->position = pos == COVER_CLOSED ? COVER_OPEN : COVER_CLOSED;
|
||||||
|
}
|
||||||
this->target_position_ = pos;
|
this->target_position_ = pos;
|
||||||
this->start_direction_(op);
|
this->start_direction_(op);
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,10 +94,10 @@ class VoiceAssistant : public Component {
|
||||||
uint32_t get_feature_flags() const {
|
uint32_t get_feature_flags() const {
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
flags |= VoiceAssistantFeature::FEATURE_VOICE_ASSISTANT;
|
flags |= VoiceAssistantFeature::FEATURE_VOICE_ASSISTANT;
|
||||||
|
flags |= VoiceAssistantFeature::FEATURE_API_AUDIO;
|
||||||
#ifdef USE_SPEAKER
|
#ifdef USE_SPEAKER
|
||||||
if (this->speaker_ != nullptr) {
|
if (this->speaker_ != nullptr) {
|
||||||
flags |= VoiceAssistantFeature::FEATURE_SPEAKER;
|
flags |= VoiceAssistantFeature::FEATURE_SPEAKER;
|
||||||
flags |= VoiceAssistantFeature::FEATURE_API_AUDIO;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return flags;
|
return flags;
|
||||||
|
|
|
@ -148,6 +148,8 @@ class Config(OrderedDict, fv.FinalValidateConfig):
|
||||||
path = path or []
|
path = path or []
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
|
except cv.FinalExternalInvalid as e:
|
||||||
|
self.add_error(e)
|
||||||
except vol.Invalid as e:
|
except vol.Invalid as e:
|
||||||
e.prepend(path)
|
e.prepend(path)
|
||||||
self.add_error(e)
|
self.add_error(e)
|
||||||
|
|
|
@ -267,6 +267,10 @@ class Required(vol.Required):
|
||||||
super().__init__(key, msg=msg)
|
super().__init__(key, msg=msg)
|
||||||
|
|
||||||
|
|
||||||
|
class FinalExternalInvalid(Invalid):
|
||||||
|
"""Represents an invalid value in the final validation phase where the path should not be prepended."""
|
||||||
|
|
||||||
|
|
||||||
def check_not_templatable(value):
|
def check_not_templatable(value):
|
||||||
if isinstance(value, Lambda):
|
if isinstance(value, Lambda):
|
||||||
raise Invalid("This option is not templatable!")
|
raise Invalid("This option is not templatable!")
|
||||||
|
|
|
@ -884,6 +884,7 @@ CONF_VALUE_FONT = "value_font"
|
||||||
CONF_VARIABLES = "variables"
|
CONF_VARIABLES = "variables"
|
||||||
CONF_VARIANT = "variant"
|
CONF_VARIANT = "variant"
|
||||||
CONF_VERSION = "version"
|
CONF_VERSION = "version"
|
||||||
|
CONF_VIBRATIONS = "vibrations"
|
||||||
CONF_VISIBLE = "visible"
|
CONF_VISIBLE = "visible"
|
||||||
CONF_VISUAL = "visual"
|
CONF_VISUAL = "visual"
|
||||||
CONF_VOLTAGE = "voltage"
|
CONF_VOLTAGE = "voltage"
|
||||||
|
@ -983,6 +984,7 @@ ICON_SIGNAL_DISTANCE_VARIANT = "mdi:signal"
|
||||||
ICON_THERMOMETER = "mdi:thermometer"
|
ICON_THERMOMETER = "mdi:thermometer"
|
||||||
ICON_TIMELAPSE = "mdi:timelapse"
|
ICON_TIMELAPSE = "mdi:timelapse"
|
||||||
ICON_TIMER = "mdi:timer-outline"
|
ICON_TIMER = "mdi:timer-outline"
|
||||||
|
ICON_VIBRATE = "mdi:vibrate"
|
||||||
ICON_WATER = "mdi:water"
|
ICON_WATER = "mdi:water"
|
||||||
ICON_WATER_PERCENT = "mdi:water-percent"
|
ICON_WATER_PERCENT = "mdi:water-percent"
|
||||||
ICON_WEATHER_SUNSET = "mdi:weather-sunset"
|
ICON_WEATHER_SUNSET = "mdi:weather-sunset"
|
||||||
|
@ -1024,6 +1026,7 @@ UNIT_METER_PER_SECOND_SQUARED = "m/s²"
|
||||||
UNIT_MICROGRAMS_PER_CUBIC_METER = "µg/m³"
|
UNIT_MICROGRAMS_PER_CUBIC_METER = "µg/m³"
|
||||||
UNIT_MICROMETER = "µm"
|
UNIT_MICROMETER = "µm"
|
||||||
UNIT_MICROSIEMENS_PER_CENTIMETER = "µS/cm"
|
UNIT_MICROSIEMENS_PER_CENTIMETER = "µS/cm"
|
||||||
|
UNIT_MICROSILVERTS_PER_HOUR = "µSv/h"
|
||||||
UNIT_MICROTESLA = "µT"
|
UNIT_MICROTESLA = "µT"
|
||||||
UNIT_MILLIGRAMS_PER_CUBIC_METER = "mg/m³"
|
UNIT_MILLIGRAMS_PER_CUBIC_METER = "mg/m³"
|
||||||
UNIT_MILLISECOND = "ms"
|
UNIT_MILLISECOND = "ms"
|
||||||
|
|
|
@ -340,6 +340,8 @@ class ID:
|
||||||
|
|
||||||
if self.id is None:
|
if self.id is None:
|
||||||
base = str(self.type).replace("::", "_").lower()
|
base = str(self.type).replace("::", "_").lower()
|
||||||
|
if base == self.type:
|
||||||
|
base = base + "_id"
|
||||||
name = "".join(c for c in base if c.isalnum() or c == "_")
|
name = "".join(c for c in base if c.isalnum() or c == "_")
|
||||||
used = set(registered_ids) | set(RESERVED_IDS) | CORE.loaded_integrations
|
used = set(registered_ids) | set(RESERVED_IDS) | CORE.loaded_integrations
|
||||||
self.id = ensure_unique_string(name, used)
|
self.id = ensure_unique_string(name, used)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import abc
|
||||||
import inspect
|
import inspect
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
from collections.abc import Generator, Sequence
|
from collections.abc import Sequence
|
||||||
from typing import Any, Callable, Optional, Union
|
from typing import Any, Callable, Optional, Union
|
||||||
|
|
||||||
from esphome.core import (
|
from esphome.core import (
|
||||||
|
@ -477,6 +477,7 @@ def variable(
|
||||||
:param rhs: The expression to place on the right hand side of the assignment.
|
:param rhs: The expression to place on the right hand side of the assignment.
|
||||||
:param type_: Manually define a type for the variable, only use this when it's not possible
|
:param type_: Manually define a type for the variable, only use this when it's not possible
|
||||||
to do so during config validation phase (for example because of template arguments).
|
to do so during config validation phase (for example because of template arguments).
|
||||||
|
:param register: If true register the variable with the core
|
||||||
|
|
||||||
:return: The new variable as a MockObj.
|
:return: The new variable as a MockObj.
|
||||||
"""
|
"""
|
||||||
|
@ -492,9 +493,7 @@ def variable(
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def with_local_variable(
|
def with_local_variable(id_: ID, rhs: SafeExpType, callback: Callable, *args) -> None:
|
||||||
id_: ID, rhs: SafeExpType, callback: Callable[["MockObj"], None], *args
|
|
||||||
) -> None:
|
|
||||||
"""Declare a new variable, not pointer type, in the code generation, within a scoped block
|
"""Declare a new variable, not pointer type, in the code generation, within a scoped block
|
||||||
The variable is only usable within the callback
|
The variable is only usable within the callback
|
||||||
The callback cannot be async.
|
The callback cannot be async.
|
||||||
|
@ -599,6 +598,7 @@ def add_library(name: str, version: Optional[str], repository: Optional[str] = N
|
||||||
|
|
||||||
:param name: The name of the library (for example 'AsyncTCP')
|
:param name: The name of the library (for example 'AsyncTCP')
|
||||||
:param version: The version of the library, may be None.
|
:param version: The version of the library, may be None.
|
||||||
|
:param repository: The repository for the library
|
||||||
"""
|
"""
|
||||||
CORE.add_library(Library(name, version, repository))
|
CORE.add_library(Library(name, version, repository))
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ async def process_lambda(
|
||||||
parameters: list[tuple[SafeExpType, str]],
|
parameters: list[tuple[SafeExpType, str]],
|
||||||
capture: str = "=",
|
capture: str = "=",
|
||||||
return_type: SafeExpType = None,
|
return_type: SafeExpType = None,
|
||||||
) -> Generator[LambdaExpression, None, None]:
|
) -> Union[LambdaExpression, None]:
|
||||||
"""Process the given lambda value into a LambdaExpression.
|
"""Process the given lambda value into a LambdaExpression.
|
||||||
|
|
||||||
This is a coroutine because lambdas can depend on other IDs,
|
This is a coroutine because lambdas can depend on other IDs,
|
||||||
|
@ -673,7 +673,7 @@ async def process_lambda(
|
||||||
)
|
)
|
||||||
|
|
||||||
if value is None:
|
if value is None:
|
||||||
return
|
return None
|
||||||
parts = value.parts[:]
|
parts = value.parts[:]
|
||||||
for i, id in enumerate(value.requires_ids):
|
for i, id in enumerate(value.requires_ids):
|
||||||
full_id, var = await get_variable_with_full_id(id)
|
full_id, var = await get_variable_with_full_id(id)
|
||||||
|
@ -712,7 +712,7 @@ async def templatable(
|
||||||
value: Any,
|
value: Any,
|
||||||
args: list[tuple[SafeExpType, str]],
|
args: list[tuple[SafeExpType, str]],
|
||||||
output_type: Optional[SafeExpType],
|
output_type: Optional[SafeExpType],
|
||||||
to_exp: Any = None,
|
to_exp: Union[Callable, dict] = None,
|
||||||
):
|
):
|
||||||
"""Generate code for a templatable config option.
|
"""Generate code for a templatable config option.
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ extra_scripts = post:esphome/components/esp32/post_build.py.script
|
||||||
extends = common:idf
|
extends = common:idf
|
||||||
platform = platformio/espressif32@5.4.0
|
platform = platformio/espressif32@5.4.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
platformio/framework-espidf@~3.40406.0
|
platformio/framework-espidf@~3.40407.0
|
||||||
|
|
||||||
framework = espidf
|
framework = espidf
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
|
|
@ -16,3 +16,6 @@ sensor:
|
||||||
- platform: ble_rssi
|
- platform: ble_rssi
|
||||||
service_uuid: 11223344-5566-7788-99aa-bbccddeeff00
|
service_uuid: 11223344-5566-7788-99aa-bbccddeeff00
|
||||||
name: BLE Test iBeacon UUID
|
name: BLE Test iBeacon UUID
|
||||||
|
- platform: ble_rssi
|
||||||
|
irk: 1234567890abcdef1234567890abcdef
|
||||||
|
name: "BLE Tracker with Identity Resolving Key"
|
||||||
|
|
|
@ -9,3 +9,12 @@ color:
|
||||||
blue: 100%
|
blue: 100%
|
||||||
- id: kbx_green
|
- id: kbx_green
|
||||||
hex: "3DEC55"
|
hex: "3DEC55"
|
||||||
|
- id: kbx_green_1
|
||||||
|
hex: 3DEC55
|
||||||
|
- id: cps_red
|
||||||
|
hex: 800000
|
||||||
|
- id: cps_green
|
||||||
|
hex: 008000
|
||||||
|
- id: cps_blue
|
||||||
|
hex: 000080
|
||||||
|
|
||||||
|
|
28
tests/components/gdk101/common.yaml
Normal file
28
tests/components/gdk101/common.yaml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
i2c:
|
||||||
|
id: i2c_bus
|
||||||
|
sda: ${i2c_sda}
|
||||||
|
scl: ${i2c_scl}
|
||||||
|
|
||||||
|
gdk101:
|
||||||
|
id: my_gdk101
|
||||||
|
i2c_id: i2c_bus
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: gdk101
|
||||||
|
gdk101_id: my_gdk101
|
||||||
|
radiation_dose_per_1m:
|
||||||
|
name: Radiation Dose @ 1 min
|
||||||
|
radiation_dose_per_10m:
|
||||||
|
name: Radiation Dose @ 10 min
|
||||||
|
status:
|
||||||
|
name: Status
|
||||||
|
version:
|
||||||
|
name: FW Version
|
||||||
|
measurement_duration:
|
||||||
|
name: Measuring Time
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: gdk101
|
||||||
|
gdk101_id: my_gdk101
|
||||||
|
vibrations:
|
||||||
|
name: Vibrations
|
5
tests/components/gdk101/test.esp32-idf.yaml
Normal file
5
tests/components/gdk101/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
substitutions:
|
||||||
|
i2c_scl: GPIO16
|
||||||
|
i2c_sda: GPIO17
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/gdk101/test.esp32.yaml
Normal file
5
tests/components/gdk101/test.esp32.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
substitutions:
|
||||||
|
i2c_scl: GPIO16
|
||||||
|
i2c_sda: GPIO17
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/gdk101/test.esp8266.yaml
Normal file
5
tests/components/gdk101/test.esp8266.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
substitutions:
|
||||||
|
i2c_scl: GPIO5
|
||||||
|
i2c_sda: GPIO4
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/gdk101/test.rp2040.yaml
Normal file
5
tests/components/gdk101/test.rp2040.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
substitutions:
|
||||||
|
i2c_scl: GPIO5
|
||||||
|
i2c_sda: GPIO4
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
Loading…
Reference in a new issue