mirror of
https://github.com/esphome/esphome.git
synced 2024-11-30 18:54:14 +01:00
Merge branch 'dev' into nvds-status-info
This commit is contained in:
commit
97878b187c
428 changed files with 10738 additions and 116 deletions
|
@ -199,6 +199,7 @@ esphome/components/mcp9808/* @k7hpn
|
||||||
esphome/components/md5/* @esphome/core
|
esphome/components/md5/* @esphome/core
|
||||||
esphome/components/mdns/* @esphome/core
|
esphome/components/mdns/* @esphome/core
|
||||||
esphome/components/media_player/* @jesserockz
|
esphome/components/media_player/* @jesserockz
|
||||||
|
esphome/components/micro_wake_word/* @jesserockz @kahrendt
|
||||||
esphome/components/micronova/* @jorre05
|
esphome/components/micronova/* @jorre05
|
||||||
esphome/components/microphone/* @jesserockz
|
esphome/components/microphone/* @jesserockz
|
||||||
esphome/components/mics_4514/* @jesserockz
|
esphome/components/mics_4514/* @jesserockz
|
||||||
|
|
|
@ -35,7 +35,7 @@ RUN \
|
||||||
iputils-ping=3:20221126-1 \
|
iputils-ping=3:20221126-1 \
|
||||||
git=1:2.39.2-1.1 \
|
git=1:2.39.2-1.1 \
|
||||||
curl=7.88.1-10+deb12u5 \
|
curl=7.88.1-10+deb12u5 \
|
||||||
openssh-client=1:9.2p1-2+deb12u1 \
|
openssh-client=1:9.2p1-2+deb12u2 \
|
||||||
python3-cffi=1.15.1-5 \
|
python3-cffi=1.15.1-5 \
|
||||||
libcairo2=1.16.0-7 \
|
libcairo2=1.16.0-7 \
|
||||||
libmagic1=1:5.44-3 \
|
libmagic1=1:5.44-3 \
|
||||||
|
|
|
@ -11,6 +11,7 @@ MULTI_CONF = True
|
||||||
CONF_BME680_BSEC_ID = "bme680_bsec_id"
|
CONF_BME680_BSEC_ID = "bme680_bsec_id"
|
||||||
CONF_TEMPERATURE_OFFSET = "temperature_offset"
|
CONF_TEMPERATURE_OFFSET = "temperature_offset"
|
||||||
CONF_IAQ_MODE = "iaq_mode"
|
CONF_IAQ_MODE = "iaq_mode"
|
||||||
|
CONF_SUPPLY_VOLTAGE = "supply_voltage"
|
||||||
CONF_SAMPLE_RATE = "sample_rate"
|
CONF_SAMPLE_RATE = "sample_rate"
|
||||||
CONF_STATE_SAVE_INTERVAL = "state_save_interval"
|
CONF_STATE_SAVE_INTERVAL = "state_save_interval"
|
||||||
|
|
||||||
|
@ -22,6 +23,12 @@ IAQ_MODE_OPTIONS = {
|
||||||
"MOBILE": IAQMode.IAQ_MODE_MOBILE,
|
"MOBILE": IAQMode.IAQ_MODE_MOBILE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SupplyVoltage = bme680_bsec_ns.enum("SupplyVoltage")
|
||||||
|
SUPPLY_VOLTAGE_OPTIONS = {
|
||||||
|
"1.8V": SupplyVoltage.SUPPLY_VOLTAGE_1V8,
|
||||||
|
"3.3V": SupplyVoltage.SUPPLY_VOLTAGE_3V3,
|
||||||
|
}
|
||||||
|
|
||||||
SampleRate = bme680_bsec_ns.enum("SampleRate")
|
SampleRate = bme680_bsec_ns.enum("SampleRate")
|
||||||
SAMPLE_RATE_OPTIONS = {
|
SAMPLE_RATE_OPTIONS = {
|
||||||
"LP": SampleRate.SAMPLE_RATE_LP,
|
"LP": SampleRate.SAMPLE_RATE_LP,
|
||||||
|
@ -40,6 +47,9 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_IAQ_MODE, default="STATIC"): cv.enum(
|
cv.Optional(CONF_IAQ_MODE, default="STATIC"): cv.enum(
|
||||||
IAQ_MODE_OPTIONS, upper=True
|
IAQ_MODE_OPTIONS, upper=True
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_SUPPLY_VOLTAGE, default="3.3V"): cv.enum(
|
||||||
|
SUPPLY_VOLTAGE_OPTIONS, upper=True
|
||||||
|
),
|
||||||
cv.Optional(CONF_SAMPLE_RATE, default="LP"): cv.enum(
|
cv.Optional(CONF_SAMPLE_RATE, default="LP"): cv.enum(
|
||||||
SAMPLE_RATE_OPTIONS, upper=True
|
SAMPLE_RATE_OPTIONS, upper=True
|
||||||
),
|
),
|
||||||
|
@ -67,6 +77,7 @@ async def to_code(config):
|
||||||
cg.add(var.set_device_id(str(config[CONF_ID])))
|
cg.add(var.set_device_id(str(config[CONF_ID])))
|
||||||
cg.add(var.set_temperature_offset(config[CONF_TEMPERATURE_OFFSET]))
|
cg.add(var.set_temperature_offset(config[CONF_TEMPERATURE_OFFSET]))
|
||||||
cg.add(var.set_iaq_mode(config[CONF_IAQ_MODE]))
|
cg.add(var.set_iaq_mode(config[CONF_IAQ_MODE]))
|
||||||
|
cg.add(var.set_supply_voltage(config[CONF_SUPPLY_VOLTAGE]))
|
||||||
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
||||||
cg.add(
|
cg.add(
|
||||||
var.set_state_save_interval(config[CONF_STATE_SAVE_INTERVAL].total_milliseconds)
|
var.set_state_save_interval(config[CONF_STATE_SAVE_INTERVAL].total_milliseconds)
|
||||||
|
|
|
@ -52,17 +52,33 @@ void BME680BSECComponent::setup() {
|
||||||
|
|
||||||
void BME680BSECComponent::set_config_() {
|
void BME680BSECComponent::set_config_() {
|
||||||
if (this->sample_rate_ == SAMPLE_RATE_ULP) {
|
if (this->sample_rate_ == SAMPLE_RATE_ULP) {
|
||||||
|
if (this->supply_voltage_ == SUPPLY_VOLTAGE_3V3) {
|
||||||
const uint8_t config[] = {
|
const uint8_t config[] = {
|
||||||
#include "config/generic_33v_300s_28d/bsec_iaq.txt"
|
#include "config/generic_33v_300s_28d/bsec_iaq.txt"
|
||||||
};
|
};
|
||||||
this->bsec_status_ =
|
this->bsec_status_ =
|
||||||
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
} else {
|
} else { // SUPPLY_VOLTAGE_1V8
|
||||||
|
const uint8_t config[] = {
|
||||||
|
#include "config/generic_18v_300s_28d/bsec_iaq.txt"
|
||||||
|
};
|
||||||
|
this->bsec_status_ =
|
||||||
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
|
}
|
||||||
|
} else { // SAMPLE_RATE_LP
|
||||||
|
if (this->supply_voltage_ == SUPPLY_VOLTAGE_3V3) {
|
||||||
const uint8_t config[] = {
|
const uint8_t config[] = {
|
||||||
#include "config/generic_33v_3s_28d/bsec_iaq.txt"
|
#include "config/generic_33v_3s_28d/bsec_iaq.txt"
|
||||||
};
|
};
|
||||||
this->bsec_status_ =
|
this->bsec_status_ =
|
||||||
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
|
} else { // SUPPLY_VOLTAGE_1V8
|
||||||
|
const uint8_t config[] = {
|
||||||
|
#include "config/generic_18v_3s_28d/bsec_iaq.txt"
|
||||||
|
};
|
||||||
|
this->bsec_status_ =
|
||||||
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +161,7 @@ void BME680BSECComponent::dump_config() {
|
||||||
|
|
||||||
ESP_LOGCONFIG(TAG, " Temperature Offset: %.2f", this->temperature_offset_);
|
ESP_LOGCONFIG(TAG, " Temperature Offset: %.2f", this->temperature_offset_);
|
||||||
ESP_LOGCONFIG(TAG, " IAQ Mode: %s", this->iaq_mode_ == IAQ_MODE_STATIC ? "Static" : "Mobile");
|
ESP_LOGCONFIG(TAG, " IAQ Mode: %s", this->iaq_mode_ == IAQ_MODE_STATIC ? "Static" : "Mobile");
|
||||||
|
ESP_LOGCONFIG(TAG, " Supply Voltage: %sV", this->supply_voltage_ == SUPPLY_VOLTAGE_3V3 ? "3.3" : "1.8");
|
||||||
ESP_LOGCONFIG(TAG, " Sample Rate: %s", BME680_BSEC_SAMPLE_RATE_LOG(this->sample_rate_));
|
ESP_LOGCONFIG(TAG, " Sample Rate: %s", BME680_BSEC_SAMPLE_RATE_LOG(this->sample_rate_));
|
||||||
ESP_LOGCONFIG(TAG, " State Save Interval: %ims", this->state_save_interval_ms_);
|
ESP_LOGCONFIG(TAG, " State Save Interval: %ims", this->state_save_interval_ms_);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,11 @@ enum IAQMode {
|
||||||
IAQ_MODE_MOBILE = 1,
|
IAQ_MODE_MOBILE = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SupplyVoltage {
|
||||||
|
SUPPLY_VOLTAGE_3V3 = 0,
|
||||||
|
SUPPLY_VOLTAGE_1V8 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
enum SampleRate {
|
enum SampleRate {
|
||||||
SAMPLE_RATE_LP = 0,
|
SAMPLE_RATE_LP = 0,
|
||||||
SAMPLE_RATE_ULP = 1,
|
SAMPLE_RATE_ULP = 1,
|
||||||
|
@ -35,6 +40,7 @@ class BME680BSECComponent : public Component, public i2c::I2CDevice {
|
||||||
void set_temperature_offset(float offset) { this->temperature_offset_ = offset; }
|
void set_temperature_offset(float offset) { this->temperature_offset_ = offset; }
|
||||||
void set_iaq_mode(IAQMode iaq_mode) { this->iaq_mode_ = iaq_mode; }
|
void set_iaq_mode(IAQMode iaq_mode) { this->iaq_mode_ = iaq_mode; }
|
||||||
void set_state_save_interval(uint32_t interval) { this->state_save_interval_ms_ = interval; }
|
void set_state_save_interval(uint32_t interval) { this->state_save_interval_ms_ = interval; }
|
||||||
|
void set_supply_voltage(SupplyVoltage supply_voltage) { this->supply_voltage_ = supply_voltage; }
|
||||||
|
|
||||||
void set_sample_rate(SampleRate sample_rate) { this->sample_rate_ = sample_rate; }
|
void set_sample_rate(SampleRate sample_rate) { this->sample_rate_ = sample_rate; }
|
||||||
void set_temperature_sample_rate(SampleRate sample_rate) { this->temperature_sample_rate_ = sample_rate; }
|
void set_temperature_sample_rate(SampleRate sample_rate) { this->temperature_sample_rate_ = sample_rate; }
|
||||||
|
@ -109,6 +115,7 @@ class BME680BSECComponent : public Component, public i2c::I2CDevice {
|
||||||
std::string device_id_;
|
std::string device_id_;
|
||||||
float temperature_offset_{0};
|
float temperature_offset_{0};
|
||||||
IAQMode iaq_mode_{IAQ_MODE_STATIC};
|
IAQMode iaq_mode_{IAQ_MODE_STATIC};
|
||||||
|
SupplyVoltage supply_voltage_;
|
||||||
|
|
||||||
SampleRate sample_rate_{SAMPLE_RATE_LP}; // Core/gas sample rate
|
SampleRate sample_rate_{SAMPLE_RATE_LP}; // Core/gas sample rate
|
||||||
SampleRate temperature_sample_rate_{SAMPLE_RATE_DEFAULT};
|
SampleRate temperature_sample_rate_{SAMPLE_RATE_DEFAULT};
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "cse7766.h"
|
#include "cse7766.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace cse7766 {
|
namespace cse7766 {
|
||||||
|
@ -68,20 +70,26 @@ bool CSE7766Component::check_byte_() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void CSE7766Component::parse_data_() {
|
void CSE7766Component::parse_data_() {
|
||||||
ESP_LOGVV(TAG, "CSE7766 Data: ");
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Raw data:" << std::hex << std::uppercase << std::setfill('0');
|
||||||
for (uint8_t i = 0; i < 23; i++) {
|
for (uint8_t i = 0; i < 23; i++) {
|
||||||
ESP_LOGVV(TAG, " %u: 0b" BYTE_TO_BINARY_PATTERN " (0x%02X)", i + 1, BYTE_TO_BINARY(this->raw_data_[i]),
|
ss << ' ' << std::setw(2) << static_cast<unsigned>(this->raw_data_[i]);
|
||||||
this->raw_data_[i]);
|
|
||||||
}
|
}
|
||||||
|
ESP_LOGVV(TAG, "%s", ss.str().c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Parse header
|
||||||
uint8_t header1 = this->raw_data_[0];
|
uint8_t header1 = this->raw_data_[0];
|
||||||
|
|
||||||
if (header1 == 0xAA) {
|
if (header1 == 0xAA) {
|
||||||
ESP_LOGE(TAG, "CSE7766 not calibrated!");
|
ESP_LOGE(TAG, "CSE7766 not calibrated!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool power_cycle_exceeds_range = false;
|
bool power_cycle_exceeds_range = false;
|
||||||
|
|
||||||
if ((header1 & 0xF0) == 0xF0) {
|
if ((header1 & 0xF0) == 0xF0) {
|
||||||
if (header1 & 0xD) {
|
if (header1 & 0xD) {
|
||||||
ESP_LOGE(TAG, "CSE7766 reports abnormal external circuit or chip damage: (0x%02X)", header1);
|
ESP_LOGE(TAG, "CSE7766 reports abnormal external circuit or chip damage: (0x%02X)", header1);
|
||||||
|
@ -94,76 +102,108 @@ void CSE7766Component::parse_data_() {
|
||||||
if (header1 & (1 << 0)) {
|
if (header1 & (1 << 0)) {
|
||||||
ESP_LOGE(TAG, " Coefficient storage area is abnormal.");
|
ESP_LOGE(TAG, " Coefficient storage area is abnormal.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Datasheet: voltage or current cycle exceeding range means invalid values
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
power_cycle_exceeds_range = header1 & (1 << 1);
|
power_cycle_exceeds_range = header1 & (1 << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t voltage_calib = this->get_24_bit_uint_(2);
|
// Parse data frame
|
||||||
|
uint32_t voltage_coeff = this->get_24_bit_uint_(2);
|
||||||
uint32_t voltage_cycle = this->get_24_bit_uint_(5);
|
uint32_t voltage_cycle = this->get_24_bit_uint_(5);
|
||||||
uint32_t current_calib = this->get_24_bit_uint_(8);
|
uint32_t current_coeff = this->get_24_bit_uint_(8);
|
||||||
uint32_t current_cycle = this->get_24_bit_uint_(11);
|
uint32_t current_cycle = this->get_24_bit_uint_(11);
|
||||||
uint32_t power_calib = this->get_24_bit_uint_(14);
|
uint32_t power_coeff = this->get_24_bit_uint_(14);
|
||||||
uint32_t power_cycle = this->get_24_bit_uint_(17);
|
uint32_t power_cycle = this->get_24_bit_uint_(17);
|
||||||
|
|
||||||
uint8_t adj = this->raw_data_[20];
|
uint8_t adj = this->raw_data_[20];
|
||||||
uint32_t cf_pulses = (this->raw_data_[21] << 8) + this->raw_data_[22];
|
uint32_t cf_pulses = (this->raw_data_[21] << 8) + this->raw_data_[22];
|
||||||
|
|
||||||
|
bool have_power = adj & 0x10;
|
||||||
|
bool have_current = adj & 0x20;
|
||||||
bool have_voltage = adj & 0x40;
|
bool have_voltage = adj & 0x40;
|
||||||
|
|
||||||
|
float voltage = 0.0f;
|
||||||
if (have_voltage) {
|
if (have_voltage) {
|
||||||
// voltage cycle of serial port outputted is a complete cycle;
|
voltage = voltage_coeff / float(voltage_cycle);
|
||||||
float voltage = voltage_calib / float(voltage_cycle);
|
if (this->voltage_sensor_ != nullptr) {
|
||||||
if (this->voltage_sensor_ != nullptr)
|
|
||||||
this->voltage_sensor_->publish_state(voltage);
|
this->voltage_sensor_->publish_state(voltage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool have_power = adj & 0x10;
|
|
||||||
float power = 0.0f;
|
|
||||||
|
|
||||||
if (have_power) {
|
|
||||||
// power cycle of serial port outputted is a complete cycle;
|
|
||||||
// According to the user manual, power cycle exceeding range means the measured power is 0
|
|
||||||
if (!power_cycle_exceeds_range) {
|
|
||||||
power = power_calib / float(power_cycle);
|
|
||||||
}
|
}
|
||||||
if (this->power_sensor_ != nullptr)
|
|
||||||
this->power_sensor_->publish_state(power);
|
|
||||||
|
|
||||||
uint32_t difference;
|
float power = 0.0f;
|
||||||
|
float energy = 0.0f;
|
||||||
|
if (power_cycle_exceeds_range) {
|
||||||
|
// Datasheet: power cycle exceeding range means active power is 0
|
||||||
|
if (this->power_sensor_ != nullptr) {
|
||||||
|
this->power_sensor_->publish_state(0.0f);
|
||||||
|
}
|
||||||
|
} else if (have_power) {
|
||||||
|
power = power_coeff / float(power_cycle);
|
||||||
|
if (this->power_sensor_ != nullptr) {
|
||||||
|
this->power_sensor_->publish_state(power);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add CF pulses to the total energy only if we have Power coefficient to multiply by
|
||||||
|
|
||||||
if (this->cf_pulses_last_ == 0) {
|
if (this->cf_pulses_last_ == 0) {
|
||||||
this->cf_pulses_last_ = cf_pulses;
|
this->cf_pulses_last_ = cf_pulses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t cf_diff;
|
||||||
if (cf_pulses < this->cf_pulses_last_) {
|
if (cf_pulses < this->cf_pulses_last_) {
|
||||||
difference = cf_pulses + (0x10000 - this->cf_pulses_last_);
|
cf_diff = cf_pulses + (0x10000 - this->cf_pulses_last_);
|
||||||
} else {
|
} else {
|
||||||
difference = cf_pulses - this->cf_pulses_last_;
|
cf_diff = cf_pulses - this->cf_pulses_last_;
|
||||||
}
|
}
|
||||||
this->cf_pulses_last_ = cf_pulses;
|
this->cf_pulses_last_ = cf_pulses;
|
||||||
this->energy_total_ += difference * float(power_calib) / 1000000.0f / 3600.0f;
|
|
||||||
|
energy = cf_diff * float(power_coeff) / 1000000.0f / 3600.0f;
|
||||||
|
this->energy_total_ += energy;
|
||||||
if (this->energy_sensor_ != nullptr)
|
if (this->energy_sensor_ != nullptr)
|
||||||
this->energy_sensor_->publish_state(this->energy_total_);
|
this->energy_sensor_->publish_state(this->energy_total_);
|
||||||
} else if ((this->energy_sensor_ != nullptr) && !this->energy_sensor_->has_state()) {
|
} else if ((this->energy_sensor_ != nullptr) && !this->energy_sensor_->has_state()) {
|
||||||
this->energy_sensor_->publish_state(0);
|
this->energy_sensor_->publish_state(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adj & 0x20) {
|
|
||||||
// indicates current cycle of serial port outputted is a complete cycle;
|
|
||||||
float current = 0.0f;
|
float current = 0.0f;
|
||||||
if (have_voltage && !have_power) {
|
float calculated_current = 0.0f;
|
||||||
// Testing has shown that when we have voltage and current but not power, that means the power is 0.
|
if (have_current) {
|
||||||
// We report a power of 0, which in turn means we should report a current of 0.
|
// Assumption: if we don't have power measurement, then current is likely below 50mA
|
||||||
if (this->power_sensor_ != nullptr)
|
if (have_power && voltage > 1.0f) {
|
||||||
this->power_sensor_->publish_state(0);
|
calculated_current = power / voltage;
|
||||||
} else if (power != 0.0f) {
|
|
||||||
current = current_calib / float(current_cycle);
|
|
||||||
}
|
}
|
||||||
if (this->current_sensor_ != nullptr)
|
// Datasheet: minimum measured current is 50mA
|
||||||
|
if (calculated_current > 0.05f) {
|
||||||
|
current = current_coeff / float(current_cycle);
|
||||||
|
}
|
||||||
|
if (this->current_sensor_ != nullptr) {
|
||||||
this->current_sensor_->publish_state(current);
|
this->current_sensor_->publish_state(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Parsed:";
|
||||||
|
if (have_voltage) {
|
||||||
|
ss << " V=" << voltage << "V";
|
||||||
|
}
|
||||||
|
if (have_current) {
|
||||||
|
ss << " I=" << current * 1000.0f << "mA (~" << calculated_current * 1000.0f << "mA)";
|
||||||
|
}
|
||||||
|
if (have_power) {
|
||||||
|
ss << " P=" << power << "W";
|
||||||
|
}
|
||||||
|
if (energy != 0.0f) {
|
||||||
|
ss << " E=" << energy << "kWh (" << cf_pulses << ")";
|
||||||
|
}
|
||||||
|
ESP_LOGVV(TAG, "%s", ss.str().c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t CSE7766Component::get_24_bit_uint_(uint8_t start_index) {
|
uint32_t CSE7766Component::get_24_bit_uint_(uint8_t start_index) {
|
||||||
return (uint32_t(this->raw_data_[start_index]) << 16) | (uint32_t(this->raw_data_[start_index + 1]) << 8) |
|
return (uint32_t(this->raw_data_[start_index]) << 16) | (uint32_t(this->raw_data_[start_index + 1]) << 8) |
|
||||||
uint32_t(this->raw_data_[start_index + 2]);
|
uint32_t(this->raw_data_[start_index + 2]);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
from esphome import core
|
|
||||||
from esphome.automation import maybe_simple_id
|
from esphome.automation import maybe_simple_id
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_ID
|
||||||
from esphome.components import uart
|
from esphome.components import uart
|
||||||
|
@ -101,7 +100,7 @@ def range_segment_list(input):
|
||||||
|
|
||||||
largest_distance = -1
|
largest_distance = -1
|
||||||
for distance in input:
|
for distance in input:
|
||||||
if isinstance(distance, core.Lambda):
|
if isinstance(distance, cv.Lambda):
|
||||||
continue
|
continue
|
||||||
m = cv.distance(distance)
|
m = cv.distance(distance)
|
||||||
if m > 9:
|
if m > 9:
|
||||||
|
@ -128,14 +127,14 @@ MMWAVE_SETTINGS_SCHEMA = cv.Schema(
|
||||||
cv.Optional(CONF_OUTPUT_LATENCY): {
|
cv.Optional(CONF_OUTPUT_LATENCY): {
|
||||||
cv.Required(CONF_DELAY_AFTER_DETECT): cv.templatable(
|
cv.Required(CONF_DELAY_AFTER_DETECT): cv.templatable(
|
||||||
cv.All(
|
cv.All(
|
||||||
cv.positive_time_period,
|
cv.positive_time_period_milliseconds,
|
||||||
cv.Range(max=core.TimePeriod(seconds=1638.375)),
|
cv.Range(max=cv.TimePeriod(seconds=1638.375)),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
cv.Required(CONF_DELAY_AFTER_DISAPPEAR): cv.templatable(
|
cv.Required(CONF_DELAY_AFTER_DISAPPEAR): cv.templatable(
|
||||||
cv.All(
|
cv.All(
|
||||||
cv.positive_time_period,
|
cv.positive_time_period_milliseconds,
|
||||||
cv.Range(max=core.TimePeriod(seconds=1638.375)),
|
cv.Range(max=cv.TimePeriod(seconds=1638.375)),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -50,7 +50,7 @@ class DfrobotSen0395SettingsAction : public Action<Ts...>, public Parented<Dfrob
|
||||||
float detect = this->delay_after_detect_.value(x...);
|
float detect = this->delay_after_detect_.value(x...);
|
||||||
float disappear = this->delay_after_disappear_.value(x...);
|
float disappear = this->delay_after_disappear_.value(x...);
|
||||||
if (detect >= 0 && disappear >= 0) {
|
if (detect >= 0 && disappear >= 0) {
|
||||||
this->parent_->enqueue(make_unique<OutputLatencyCommand>(detect, disappear));
|
this->parent_->enqueue(make_unique<SetLatencyCommand>(detect, disappear));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->start_after_power_on_.has_value()) {
|
if (this->start_after_power_on_.has_value()) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#include "dfrobot_sen0395.h"
|
#include "dfrobot_sen0395.h"
|
||||||
|
@ -194,32 +196,22 @@ uint8_t DetRangeCfgCommand::on_message(std::string &message) {
|
||||||
return 0; // Command not done yet.
|
return 0; // Command not done yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputLatencyCommand::OutputLatencyCommand(float delay_after_detection, float delay_after_disappear) {
|
SetLatencyCommand::SetLatencyCommand(float delay_after_detection, float delay_after_disappear) {
|
||||||
delay_after_detection = round(delay_after_detection / 0.025) * 0.025;
|
delay_after_detection = std::round(delay_after_detection / 0.025f) * 0.025f;
|
||||||
delay_after_disappear = round(delay_after_disappear / 0.025) * 0.025;
|
delay_after_disappear = std::round(delay_after_disappear / 0.025f) * 0.025f;
|
||||||
if (delay_after_detection < 0)
|
this->delay_after_detection_ = clamp(delay_after_detection, 0.0f, 1638.375f);
|
||||||
delay_after_detection = 0;
|
this->delay_after_disappear_ = clamp(delay_after_disappear, 0.0f, 1638.375f);
|
||||||
if (delay_after_detection > 1638.375)
|
this->cmd_ = str_sprintf("setLatency %.03f %.03f", this->delay_after_detection_, this->delay_after_disappear_);
|
||||||
delay_after_detection = 1638.375;
|
|
||||||
if (delay_after_disappear < 0)
|
|
||||||
delay_after_disappear = 0;
|
|
||||||
if (delay_after_disappear > 1638.375)
|
|
||||||
delay_after_disappear = 1638.375;
|
|
||||||
|
|
||||||
this->delay_after_detection_ = delay_after_detection;
|
|
||||||
this->delay_after_disappear_ = delay_after_disappear;
|
|
||||||
|
|
||||||
this->cmd_ = str_sprintf("outputLatency -1 %.0f %.0f", delay_after_detection / 0.025, delay_after_disappear / 0.025);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t OutputLatencyCommand::on_message(std::string &message) {
|
uint8_t SetLatencyCommand::on_message(std::string &message) {
|
||||||
if (message == "sensor is not stopped") {
|
if (message == "sensor is not stopped") {
|
||||||
ESP_LOGE(TAG, "Cannot configure output latency. Sensor is not stopped!");
|
ESP_LOGE(TAG, "Cannot configure output latency. Sensor is not stopped!");
|
||||||
return 1; // Command done
|
return 1; // Command done
|
||||||
} else if (message == "Done") {
|
} else if (message == "Done") {
|
||||||
ESP_LOGI(TAG, "Updated output latency config:");
|
ESP_LOGI(TAG, "Updated output latency config:");
|
||||||
ESP_LOGI(TAG, "Signal that someone was detected is delayed by %.02fs.", this->delay_after_detection_);
|
ESP_LOGI(TAG, "Signal that someone was detected is delayed by %.03f s.", this->delay_after_detection_);
|
||||||
ESP_LOGI(TAG, "Signal that nobody is detected anymore is delayed by %.02fs.", this->delay_after_disappear_);
|
ESP_LOGI(TAG, "Signal that nobody is detected anymore is delayed by %.03f s.", this->delay_after_disappear_);
|
||||||
ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
|
ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
|
||||||
return 1; // Command done
|
return 1; // Command done
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,9 @@ class DetRangeCfgCommand : public Command {
|
||||||
// TODO: Set min max values in component, so they can be published as sensor.
|
// TODO: Set min max values in component, so they can be published as sensor.
|
||||||
};
|
};
|
||||||
|
|
||||||
class OutputLatencyCommand : public Command {
|
class SetLatencyCommand : public Command {
|
||||||
public:
|
public:
|
||||||
OutputLatencyCommand(float delay_after_detection, float delay_after_disappear);
|
SetLatencyCommand(float delay_after_detection, float delay_after_disappear);
|
||||||
uint8_t on_message(std::string &message) override;
|
uint8_t on_message(std::string &message) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -160,11 +160,13 @@ light::ESPColorView ESP32RMTLEDStripLightOutput::get_view_internal(int32_t index
|
||||||
b = 0;
|
b = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint8_t multiplier = this->is_rgbw_ ? 4 : 3;
|
uint8_t multiplier = this->is_rgbw_ || this->is_wrgb_ ? 4 : 3;
|
||||||
return {this->buf_ + (index * multiplier) + r,
|
uint8_t white = this->is_wrgb_ ? 0 : 3;
|
||||||
this->buf_ + (index * multiplier) + g,
|
|
||||||
this->buf_ + (index * multiplier) + b,
|
return {this->buf_ + (index * multiplier) + r + this->is_wrgb_,
|
||||||
this->is_rgbw_ ? this->buf_ + (index * multiplier) + 3 : nullptr,
|
this->buf_ + (index * multiplier) + g + this->is_wrgb_,
|
||||||
|
this->buf_ + (index * multiplier) + b + this->is_wrgb_,
|
||||||
|
this->is_rgbw_ || this->is_wrgb_ ? this->buf_ + (index * multiplier) + white : nullptr,
|
||||||
&this->effect_data_[index],
|
&this->effect_data_[index],
|
||||||
&this->correction_};
|
&this->correction_};
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
|
||||||
int32_t size() const override { return this->num_leds_; }
|
int32_t size() const override { return this->num_leds_; }
|
||||||
light::LightTraits get_traits() override {
|
light::LightTraits get_traits() override {
|
||||||
auto traits = light::LightTraits();
|
auto traits = light::LightTraits();
|
||||||
if (this->is_rgbw_) {
|
if (this->is_rgbw_ || this->is_wrgb_) {
|
||||||
traits.set_supported_color_modes({light::ColorMode::RGB_WHITE, light::ColorMode::WHITE});
|
traits.set_supported_color_modes({light::ColorMode::RGB_WHITE, light::ColorMode::WHITE});
|
||||||
} else {
|
} else {
|
||||||
traits.set_supported_color_modes({light::ColorMode::RGB});
|
traits.set_supported_color_modes({light::ColorMode::RGB});
|
||||||
|
@ -44,6 +44,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
|
||||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||||
void set_num_leds(uint16_t num_leds) { this->num_leds_ = num_leds; }
|
void set_num_leds(uint16_t num_leds) { this->num_leds_ = num_leds; }
|
||||||
void set_is_rgbw(bool is_rgbw) { this->is_rgbw_ = is_rgbw; }
|
void set_is_rgbw(bool is_rgbw) { this->is_rgbw_ = is_rgbw; }
|
||||||
|
void set_is_wrgb(bool is_wrgb) { this->is_wrgb_ = is_wrgb; }
|
||||||
|
|
||||||
/// Set a maximum refresh rate in µs as some lights do not like being updated too often.
|
/// Set a maximum refresh rate in µs as some lights do not like being updated too often.
|
||||||
void set_max_refresh_rate(uint32_t interval_us) { this->max_refresh_rate_ = interval_us; }
|
void set_max_refresh_rate(uint32_t interval_us) { this->max_refresh_rate_ = interval_us; }
|
||||||
|
@ -72,6 +73,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
|
||||||
uint8_t pin_;
|
uint8_t pin_;
|
||||||
uint16_t num_leds_;
|
uint16_t num_leds_;
|
||||||
bool is_rgbw_;
|
bool is_rgbw_;
|
||||||
|
bool is_wrgb_;
|
||||||
|
|
||||||
rmt_item32_t bit0_, bit1_;
|
rmt_item32_t bit0_, bit1_;
|
||||||
RGBOrder rgb_order_;
|
RGBOrder rgb_order_;
|
||||||
|
|
|
@ -52,6 +52,7 @@ CHIPSETS = {
|
||||||
|
|
||||||
|
|
||||||
CONF_IS_RGBW = "is_rgbw"
|
CONF_IS_RGBW = "is_rgbw"
|
||||||
|
CONF_IS_WRGB = "is_wrgb"
|
||||||
CONF_BIT0_HIGH = "bit0_high"
|
CONF_BIT0_HIGH = "bit0_high"
|
||||||
CONF_BIT0_LOW = "bit0_low"
|
CONF_BIT0_LOW = "bit0_low"
|
||||||
CONF_BIT1_HIGH = "bit1_high"
|
CONF_BIT1_HIGH = "bit1_high"
|
||||||
|
@ -90,6 +91,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||||
cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
||||||
cv.Optional(CONF_IS_RGBW, default=False): cv.boolean,
|
cv.Optional(CONF_IS_RGBW, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_IS_WRGB, default=False): cv.boolean,
|
||||||
cv.Inclusive(
|
cv.Inclusive(
|
||||||
CONF_BIT0_HIGH,
|
CONF_BIT0_HIGH,
|
||||||
"custom",
|
"custom",
|
||||||
|
@ -145,6 +147,7 @@ async def to_code(config):
|
||||||
|
|
||||||
cg.add(var.set_rgb_order(config[CONF_RGB_ORDER]))
|
cg.add(var.set_rgb_order(config[CONF_RGB_ORDER]))
|
||||||
cg.add(var.set_is_rgbw(config[CONF_IS_RGBW]))
|
cg.add(var.set_is_rgbw(config[CONF_IS_RGBW]))
|
||||||
|
cg.add(var.set_is_wrgb(config[CONF_IS_WRGB]))
|
||||||
|
|
||||||
cg.add(
|
cg.add(
|
||||||
var.set_rmt_channel(
|
var.set_rmt_channel(
|
||||||
|
|
|
@ -119,4 +119,4 @@ def to_code(config):
|
||||||
cg.add_library("tonia/HeatpumpIR", "1.0.23")
|
cg.add_library("tonia/HeatpumpIR", "1.0.23")
|
||||||
|
|
||||||
if CORE.is_esp8266 or CORE.is_esp32:
|
if CORE.is_esp8266 or CORE.is_esp32:
|
||||||
cg.add_library("crankyoldgit/IRremoteESP8266", "2.7.12")
|
cg.add_library("crankyoldgit/IRremoteESP8266", "2.8.4")
|
||||||
|
|
|
@ -4,6 +4,7 @@ from esphome.const import (
|
||||||
KEY_TARGET_FRAMEWORK,
|
KEY_TARGET_FRAMEWORK,
|
||||||
KEY_TARGET_PLATFORM,
|
KEY_TARGET_PLATFORM,
|
||||||
PLATFORM_HOST,
|
PLATFORM_HOST,
|
||||||
|
CONF_MAC_ADDRESS,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
from esphome.helpers import IS_MACOS
|
from esphome.helpers import IS_MACOS
|
||||||
|
@ -28,13 +29,18 @@ def set_core_data(config):
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema({}),
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_MAC_ADDRESS, default="98:35:69:ab:f6:79"): cv.mac_address,
|
||||||
|
}
|
||||||
|
),
|
||||||
set_core_data,
|
set_core_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
cg.add_build_flag("-DUSE_HOST")
|
cg.add_build_flag("-DUSE_HOST")
|
||||||
|
cg.add_define("USE_ESPHOME_HOST_MAC_ADDRESS", config[CONF_MAC_ADDRESS].parts)
|
||||||
cg.add_build_flag("-std=c++17")
|
cg.add_build_flag("-std=c++17")
|
||||||
cg.add_build_flag("-lsodium")
|
cg.add_build_flag("-lsodium")
|
||||||
if IS_MACOS:
|
if IS_MACOS:
|
||||||
|
|
|
@ -120,6 +120,7 @@ void LightState::loop() {
|
||||||
// Apply transformer (if any)
|
// Apply transformer (if any)
|
||||||
if (this->transformer_ != nullptr) {
|
if (this->transformer_ != nullptr) {
|
||||||
auto values = this->transformer_->apply();
|
auto values = this->transformer_->apply();
|
||||||
|
this->is_transformer_active_ = true;
|
||||||
if (values.has_value()) {
|
if (values.has_value()) {
|
||||||
this->current_values = *values;
|
this->current_values = *values;
|
||||||
this->output_->update_state(this);
|
this->output_->update_state(this);
|
||||||
|
@ -131,6 +132,7 @@ void LightState::loop() {
|
||||||
this->current_values = this->transformer_->get_target_values();
|
this->current_values = this->transformer_->get_target_values();
|
||||||
|
|
||||||
this->transformer_->stop();
|
this->transformer_->stop();
|
||||||
|
this->is_transformer_active_ = false;
|
||||||
this->transformer_ = nullptr;
|
this->transformer_ = nullptr;
|
||||||
this->target_state_reached_callback_.call();
|
this->target_state_reached_callback_.call();
|
||||||
}
|
}
|
||||||
|
@ -214,6 +216,8 @@ void LightState::current_values_as_ct(float *color_temperature, float *white_bri
|
||||||
this->gamma_correct_);
|
this->gamma_correct_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LightState::is_transformer_active() { return this->is_transformer_active_; }
|
||||||
|
|
||||||
void LightState::start_effect_(uint32_t effect_index) {
|
void LightState::start_effect_(uint32_t effect_index) {
|
||||||
this->stop_effect_();
|
this->stop_effect_();
|
||||||
if (effect_index == 0)
|
if (effect_index == 0)
|
||||||
|
@ -263,6 +267,7 @@ void LightState::start_flash_(const LightColorValues &target, uint32_t length, b
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightState::set_immediately_(const LightColorValues &target, bool set_remote_values) {
|
void LightState::set_immediately_(const LightColorValues &target, bool set_remote_values) {
|
||||||
|
this->is_transformer_active_ = false;
|
||||||
this->transformer_ = nullptr;
|
this->transformer_ = nullptr;
|
||||||
this->current_values = target;
|
this->current_values = target;
|
||||||
if (set_remote_values) {
|
if (set_remote_values) {
|
||||||
|
|
|
@ -144,6 +144,17 @@ class LightState : public EntityBase, public Component {
|
||||||
|
|
||||||
void current_values_as_ct(float *color_temperature, float *white_brightness);
|
void current_values_as_ct(float *color_temperature, float *white_brightness);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicator if a transformer (e.g. transition) is active. This is useful
|
||||||
|
* for effects e.g. at the start of the apply() method, add a check like:
|
||||||
|
*
|
||||||
|
* if (this->state_->is_transformer_active()) {
|
||||||
|
* // Something is already running.
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
bool is_transformer_active();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend LightOutput;
|
friend LightOutput;
|
||||||
friend LightCall;
|
friend LightCall;
|
||||||
|
@ -203,6 +214,9 @@ class LightState : public EntityBase, public Component {
|
||||||
LightRestoreMode restore_mode_;
|
LightRestoreMode restore_mode_;
|
||||||
/// List of effects for this light.
|
/// List of effects for this light.
|
||||||
std::vector<LightEffect *> effects_;
|
std::vector<LightEffect *> effects_;
|
||||||
|
|
||||||
|
// for effects, true if a transformer (transition) is active.
|
||||||
|
bool is_transformer_active_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace light
|
} // namespace light
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace lightwaverf {
|
namespace lightwaverf {
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,14 @@ void HOT Logger::log_message_(int level, const char *tag, int offset) {
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_HOST
|
#ifdef USE_HOST
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm *timeinfo;
|
||||||
|
char buffer[80];
|
||||||
|
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
strftime(buffer, sizeof buffer, "[%H:%M:%S]", timeinfo);
|
||||||
|
fputs(buffer, stdout);
|
||||||
puts(msg);
|
puts(msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
367
esphome/components/micro_wake_word/__init__.py
Normal file
367
esphome/components/micro_wake_word/__init__.py
Normal file
|
@ -0,0 +1,367 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
from pathlib import Path
|
||||||
|
import requests
|
||||||
|
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
from esphome.core import CORE, HexInt, EsphomeError
|
||||||
|
|
||||||
|
from esphome.components import esp32, microphone
|
||||||
|
from esphome import automation, git, external_files
|
||||||
|
from esphome.automation import register_action, register_condition
|
||||||
|
|
||||||
|
|
||||||
|
from esphome.const import (
|
||||||
|
__version__,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_MICROPHONE,
|
||||||
|
CONF_MODEL,
|
||||||
|
CONF_URL,
|
||||||
|
CONF_FILE,
|
||||||
|
CONF_PATH,
|
||||||
|
CONF_REF,
|
||||||
|
CONF_REFRESH,
|
||||||
|
CONF_TYPE,
|
||||||
|
CONF_USERNAME,
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_RAW_DATA_ID,
|
||||||
|
TYPE_GIT,
|
||||||
|
TYPE_LOCAL,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CODEOWNERS = ["@kahrendt", "@jesserockz"]
|
||||||
|
DEPENDENCIES = ["microphone"]
|
||||||
|
DOMAIN = "micro_wake_word"
|
||||||
|
|
||||||
|
CONF_PROBABILITY_CUTOFF = "probability_cutoff"
|
||||||
|
CONF_SLIDING_WINDOW_AVERAGE_SIZE = "sliding_window_average_size"
|
||||||
|
CONF_ON_WAKE_WORD_DETECTED = "on_wake_word_detected"
|
||||||
|
|
||||||
|
TYPE_HTTP = "http"
|
||||||
|
|
||||||
|
micro_wake_word_ns = cg.esphome_ns.namespace("micro_wake_word")
|
||||||
|
|
||||||
|
MicroWakeWord = micro_wake_word_ns.class_("MicroWakeWord", cg.Component)
|
||||||
|
|
||||||
|
StartAction = micro_wake_word_ns.class_("StartAction", automation.Action)
|
||||||
|
StopAction = micro_wake_word_ns.class_("StopAction", automation.Action)
|
||||||
|
|
||||||
|
IsRunningCondition = micro_wake_word_ns.class_(
|
||||||
|
"IsRunningCondition", automation.Condition
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_json_filename(value):
|
||||||
|
value = cv.string(value)
|
||||||
|
if not value.endswith(".json"):
|
||||||
|
raise cv.Invalid("Manifest filename must end with .json")
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _process_git_source(config):
|
||||||
|
repo_dir, _ = git.clone_or_update(
|
||||||
|
url=config[CONF_URL],
|
||||||
|
ref=config.get(CONF_REF),
|
||||||
|
refresh=config[CONF_REFRESH],
|
||||||
|
domain=DOMAIN,
|
||||||
|
username=config.get(CONF_USERNAME),
|
||||||
|
password=config.get(CONF_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
if not (repo_dir / config[CONF_FILE]).exists():
|
||||||
|
raise cv.Invalid("File does not exist in repository")
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
CV_GIT_SCHEMA = cv.GIT_SCHEMA
|
||||||
|
if isinstance(CV_GIT_SCHEMA, dict):
|
||||||
|
CV_GIT_SCHEMA = cv.Schema(CV_GIT_SCHEMA)
|
||||||
|
|
||||||
|
GIT_SCHEMA = cv.All(
|
||||||
|
CV_GIT_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_FILE): _validate_json_filename,
|
||||||
|
cv.Optional(CONF_REFRESH, default="1d"): cv.All(
|
||||||
|
cv.string, cv.source_refresh
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
_process_git_source,
|
||||||
|
)
|
||||||
|
|
||||||
|
KEY_WAKE_WORD = "wake_word"
|
||||||
|
KEY_AUTHOR = "author"
|
||||||
|
KEY_WEBSITE = "website"
|
||||||
|
KEY_VERSION = "version"
|
||||||
|
KEY_MICRO = "micro"
|
||||||
|
KEY_MINIMUM_ESPHOME_VERSION = "minimum_esphome_version"
|
||||||
|
|
||||||
|
MANIFEST_SCHEMA_V1 = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_TYPE): "micro",
|
||||||
|
cv.Required(KEY_WAKE_WORD): cv.string,
|
||||||
|
cv.Required(KEY_AUTHOR): cv.string,
|
||||||
|
cv.Required(KEY_WEBSITE): cv.url,
|
||||||
|
cv.Required(KEY_VERSION): cv.All(cv.int_, 1),
|
||||||
|
cv.Required(CONF_MODEL): cv.string,
|
||||||
|
cv.Required(KEY_MICRO): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_PROBABILITY_CUTOFF): cv.float_,
|
||||||
|
cv.Required(CONF_SLIDING_WINDOW_AVERAGE_SIZE): cv.positive_int,
|
||||||
|
cv.Optional(KEY_MINIMUM_ESPHOME_VERSION): cv.All(
|
||||||
|
cv.version_number, cv.validate_esphome_version
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _compute_local_file_path(config: dict) -> Path:
|
||||||
|
url = config[CONF_URL]
|
||||||
|
h = hashlib.new("sha256")
|
||||||
|
h.update(url.encode())
|
||||||
|
key = h.hexdigest()[:8]
|
||||||
|
base_dir = external_files.compute_local_file_dir(DOMAIN)
|
||||||
|
return base_dir / key
|
||||||
|
|
||||||
|
|
||||||
|
def _download_file(url: str, path: Path) -> bytes:
|
||||||
|
if not external_files.has_remote_file_changed(url, path):
|
||||||
|
_LOGGER.debug("Remote file has not changed, skipping download")
|
||||||
|
return path.read_bytes()
|
||||||
|
|
||||||
|
try:
|
||||||
|
req = requests.get(
|
||||||
|
url,
|
||||||
|
timeout=external_files.NETWORK_TIMEOUT,
|
||||||
|
headers={"User-agent": f"ESPHome/{__version__} (https://esphome.io)"},
|
||||||
|
)
|
||||||
|
req.raise_for_status()
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
raise cv.Invalid(f"Could not download file from {url}: {e}") from e
|
||||||
|
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_bytes(req.content)
|
||||||
|
return req.content
|
||||||
|
|
||||||
|
|
||||||
|
def _process_http_source(config):
|
||||||
|
url = config[CONF_URL]
|
||||||
|
path = _compute_local_file_path(config)
|
||||||
|
|
||||||
|
json_path = path / "manifest.json"
|
||||||
|
|
||||||
|
json_contents = _download_file(url, json_path)
|
||||||
|
|
||||||
|
manifest_data = json.loads(json_contents)
|
||||||
|
if not isinstance(manifest_data, dict):
|
||||||
|
raise cv.Invalid("Manifest file must contain a JSON object")
|
||||||
|
|
||||||
|
try:
|
||||||
|
MANIFEST_SCHEMA_V1(manifest_data)
|
||||||
|
except cv.Invalid as e:
|
||||||
|
raise cv.Invalid(f"Invalid manifest file: {e}") from e
|
||||||
|
|
||||||
|
model = manifest_data[CONF_MODEL]
|
||||||
|
model_url = urljoin(url, model)
|
||||||
|
|
||||||
|
model_path = path / model
|
||||||
|
|
||||||
|
_download_file(str(model_url), model_path)
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
HTTP_SCHEMA = cv.All(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_URL): cv.url,
|
||||||
|
},
|
||||||
|
_process_http_source,
|
||||||
|
)
|
||||||
|
|
||||||
|
LOCAL_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_PATH): cv.All(_validate_json_filename, cv.file_),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_source_model_name(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
raise cv.Invalid("Model name must be a string")
|
||||||
|
|
||||||
|
if value.endswith(".json"):
|
||||||
|
raise cv.Invalid("Model name must not end with .json")
|
||||||
|
|
||||||
|
return MODEL_SOURCE_SCHEMA(
|
||||||
|
{
|
||||||
|
CONF_TYPE: TYPE_HTTP,
|
||||||
|
CONF_URL: f"https://github.com/esphome/micro-wake-word-models/raw/main/models/{value}.json",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_source_shorthand(value):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
raise cv.Invalid("Shorthand only for strings")
|
||||||
|
|
||||||
|
try: # Test for model name
|
||||||
|
return _validate_source_model_name(value)
|
||||||
|
except cv.Invalid:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try: # Test for local path
|
||||||
|
return MODEL_SOURCE_SCHEMA({CONF_TYPE: TYPE_LOCAL, CONF_PATH: value})
|
||||||
|
except cv.Invalid:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try: # Test for http url
|
||||||
|
return MODEL_SOURCE_SCHEMA({CONF_TYPE: TYPE_HTTP, CONF_URL: value})
|
||||||
|
except cv.Invalid:
|
||||||
|
pass
|
||||||
|
|
||||||
|
git_file = git.GitFile.from_shorthand(value)
|
||||||
|
|
||||||
|
conf = {
|
||||||
|
CONF_TYPE: TYPE_GIT,
|
||||||
|
CONF_URL: git_file.git_url,
|
||||||
|
CONF_FILE: git_file.filename,
|
||||||
|
}
|
||||||
|
if git_file.ref:
|
||||||
|
conf[CONF_REF] = git_file.ref
|
||||||
|
|
||||||
|
try:
|
||||||
|
return MODEL_SOURCE_SCHEMA(conf)
|
||||||
|
except cv.Invalid as e:
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"Could not find file '{git_file.filename}' in the repository. Please make sure it exists."
|
||||||
|
) from e
|
||||||
|
|
||||||
|
|
||||||
|
MODEL_SOURCE_SCHEMA = cv.Any(
|
||||||
|
_validate_source_shorthand,
|
||||||
|
cv.typed_schema(
|
||||||
|
{
|
||||||
|
TYPE_GIT: GIT_SCHEMA,
|
||||||
|
TYPE_LOCAL: LOCAL_SCHEMA,
|
||||||
|
TYPE_HTTP: HTTP_SCHEMA,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
msg="Not a valid model name, local path, http(s) url, or github shorthand",
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(MicroWakeWord),
|
||||||
|
cv.GenerateID(CONF_MICROPHONE): cv.use_id(microphone.Microphone),
|
||||||
|
cv.Optional(CONF_PROBABILITY_CUTOFF): cv.percentage,
|
||||||
|
cv.Optional(CONF_SLIDING_WINDOW_AVERAGE_SIZE): cv.positive_int,
|
||||||
|
cv.Optional(CONF_ON_WAKE_WORD_DETECTED): automation.validate_automation(
|
||||||
|
single=True
|
||||||
|
),
|
||||||
|
cv.Required(CONF_MODEL): MODEL_SOURCE_SCHEMA,
|
||||||
|
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
|
cv.only_with_esp_idf,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _load_model_data(manifest_path: Path):
|
||||||
|
with open(manifest_path, encoding="utf-8") as f:
|
||||||
|
manifest = json.load(f)
|
||||||
|
|
||||||
|
try:
|
||||||
|
MANIFEST_SCHEMA_V1(manifest)
|
||||||
|
except cv.Invalid as e:
|
||||||
|
raise EsphomeError(f"Invalid manifest file: {e}") from e
|
||||||
|
|
||||||
|
model_path = urljoin(str(manifest_path), manifest[CONF_MODEL])
|
||||||
|
|
||||||
|
with open(model_path, "rb") as f:
|
||||||
|
model = f.read()
|
||||||
|
|
||||||
|
return manifest, model
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
|
||||||
|
mic = await cg.get_variable(config[CONF_MICROPHONE])
|
||||||
|
cg.add(var.set_microphone(mic))
|
||||||
|
|
||||||
|
if on_wake_word_detection_config := config.get(CONF_ON_WAKE_WORD_DETECTED):
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_wake_word_detected_trigger(),
|
||||||
|
[(cg.std_string, "wake_word")],
|
||||||
|
on_wake_word_detection_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
esp32.add_idf_component(
|
||||||
|
name="esp-tflite-micro",
|
||||||
|
repo="https://github.com/espressif/esp-tflite-micro",
|
||||||
|
)
|
||||||
|
|
||||||
|
cg.add_build_flag("-DTF_LITE_STATIC_MEMORY")
|
||||||
|
cg.add_build_flag("-DTF_LITE_DISABLE_X86_NEON")
|
||||||
|
cg.add_build_flag("-DESP_NN")
|
||||||
|
|
||||||
|
model_config = config.get(CONF_MODEL)
|
||||||
|
data = []
|
||||||
|
if model_config[CONF_TYPE] == TYPE_GIT:
|
||||||
|
# compute path to model file
|
||||||
|
key = f"{model_config[CONF_URL]}@{model_config.get(CONF_REF)}"
|
||||||
|
base_dir = Path(CORE.data_dir) / DOMAIN
|
||||||
|
h = hashlib.new("sha256")
|
||||||
|
h.update(key.encode())
|
||||||
|
file: Path = base_dir / h.hexdigest()[:8] / model_config[CONF_FILE]
|
||||||
|
|
||||||
|
elif model_config[CONF_TYPE] == TYPE_LOCAL:
|
||||||
|
file = model_config[CONF_PATH]
|
||||||
|
|
||||||
|
elif model_config[CONF_TYPE] == TYPE_HTTP:
|
||||||
|
file = _compute_local_file_path(model_config) / "manifest.json"
|
||||||
|
|
||||||
|
manifest, data = _load_model_data(file)
|
||||||
|
|
||||||
|
rhs = [HexInt(x) for x in data]
|
||||||
|
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
|
||||||
|
cg.add(var.set_model_start(prog_arr))
|
||||||
|
|
||||||
|
probability_cutoff = config.get(
|
||||||
|
CONF_PROBABILITY_CUTOFF, manifest[KEY_MICRO][CONF_PROBABILITY_CUTOFF]
|
||||||
|
)
|
||||||
|
cg.add(var.set_probability_cutoff(probability_cutoff))
|
||||||
|
sliding_window_average_size = config.get(
|
||||||
|
CONF_SLIDING_WINDOW_AVERAGE_SIZE,
|
||||||
|
manifest[KEY_MICRO][CONF_SLIDING_WINDOW_AVERAGE_SIZE],
|
||||||
|
)
|
||||||
|
cg.add(var.set_sliding_window_average_size(sliding_window_average_size))
|
||||||
|
|
||||||
|
cg.add(var.set_wake_word(manifest[KEY_WAKE_WORD]))
|
||||||
|
|
||||||
|
|
||||||
|
MICRO_WAKE_WORD_ACTION_SCHEMA = cv.Schema({cv.GenerateID(): cv.use_id(MicroWakeWord)})
|
||||||
|
|
||||||
|
|
||||||
|
@register_action("micro_wake_word.start", StartAction, MICRO_WAKE_WORD_ACTION_SCHEMA)
|
||||||
|
@register_action("micro_wake_word.stop", StopAction, MICRO_WAKE_WORD_ACTION_SCHEMA)
|
||||||
|
@register_condition(
|
||||||
|
"micro_wake_word.is_running", IsRunningCondition, MICRO_WAKE_WORD_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
async def micro_wake_word_action_to_code(config, action_id, template_arg, args):
|
||||||
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
|
await cg.register_parented(var, config[CONF_ID])
|
||||||
|
return var
|
|
@ -0,0 +1,493 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_ESP_IDF
|
||||||
|
|
||||||
|
// Converted audio_preprocessor_int8.tflite
|
||||||
|
// From https://github.com/tensorflow/tflite-micro/tree/main/tensorflow/lite/micro/examples/micro_speech/models accessed
|
||||||
|
// January 2024
|
||||||
|
//
|
||||||
|
// Copyright 2023 The TensorFlow Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace micro_wake_word {
|
||||||
|
|
||||||
|
const unsigned char G_AUDIO_PREPROCESSOR_INT8_TFLITE[] = {
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x14, 0x00, 0x20, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x14, 0x00, 0x10,
|
||||||
|
0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x88, 0x00,
|
||||||
|
0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x00, 0x00, 0x90, 0x0e, 0x00, 0x00, 0xcc, 0x1f, 0x00, 0x00, 0x03,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe2, 0xeb, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67,
|
||||||
|
0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x94, 0xff,
|
||||||
|
0xff, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x70, 0x75,
|
||||||
|
0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc2, 0xf5, 0xff, 0xff,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
|
||||||
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xdc, 0xff, 0xff, 0xff, 0x2d, 0x00,
|
||||||
|
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f,
|
||||||
|
0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e,
|
||||||
|
0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x2e, 0x00,
|
||||||
|
0x00, 0x00, 0x9c, 0x0d, 0x00, 0x00, 0x94, 0x0d, 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00, 0x48,
|
||||||
|
0x09, 0x00, 0x00, 0x34, 0x09, 0x00, 0x00, 0x20, 0x09, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0xf8, 0x08, 0x00, 0x00,
|
||||||
|
0xec, 0x07, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x24, 0x07, 0x00, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x38, 0x04, 0x00,
|
||||||
|
0x00, 0xb0, 0x01, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x60, 0x01,
|
||||||
|
0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x2c,
|
||||||
|
0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00,
|
||||||
|
0x04, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00,
|
||||||
|
0x00, 0xdc, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0xbc, 0x00,
|
||||||
|
0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x94,
|
||||||
|
0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0xf6, 0xff, 0xff,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04,
|
||||||
|
0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x08, 0x00,
|
||||||
|
0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0a, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x2e, 0x31, 0x32, 0x2e, 0x30, 0x00,
|
||||||
|
0x00, 0x56, 0xf7, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x2e, 0x38, 0x2e, 0x30, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xe1, 0xff, 0xff, 0xd8, 0xe1, 0xff, 0xff, 0xdc,
|
||||||
|
0xe1, 0xff, 0xff, 0xe0, 0xe1, 0xff, 0xff, 0xe4, 0xe1, 0xff, 0xff, 0xe8, 0xe1, 0xff, 0xff, 0xec, 0xe1, 0xff, 0xff,
|
||||||
|
0xf0, 0xe1, 0xff, 0xff, 0xf4, 0xe1, 0xff, 0xff, 0xf8, 0xe1, 0xff, 0xff, 0xfc, 0xe1, 0xff, 0xff, 0x00, 0xe2, 0xff,
|
||||||
|
0xff, 0x04, 0xe2, 0xff, 0xff, 0x08, 0xe2, 0xff, 0xff, 0x0c, 0xe2, 0xff, 0xff, 0x10, 0xe2, 0xff, 0xff, 0x14, 0xe2,
|
||||||
|
0xff, 0xff, 0x18, 0xe2, 0xff, 0xff, 0x1c, 0xe2, 0xff, 0xff, 0x20, 0xe2, 0xff, 0xff, 0x24, 0xe2, 0xff, 0xff, 0x28,
|
||||||
|
0xe2, 0xff, 0xff, 0x2c, 0xe2, 0xff, 0xff, 0x30, 0xe2, 0xff, 0xff, 0xd2, 0xf7, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x9a, 0x02, 0x00, 0x00, 0xe2, 0xf7, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x00, 0x00, 0xf2, 0xf7, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0xff,
|
||||||
|
0xff, 0xff, 0x02, 0xf8, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x12,
|
||||||
|
0xf8, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x22, 0xf8, 0xff, 0xff,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x61, 0x05, 0x00, 0x00, 0x00, 0x00, 0x23, 0x0b, 0x41,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x0e, 0x80, 0x05,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xd1, 0x0c, 0x63, 0x04, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0c, 0x3f, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x81, 0x0c, 0xf7, 0x04, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x0d, 0x77, 0x06, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x0f,
|
||||||
|
0xa9, 0x08, 0x01, 0x02, 0x7f, 0x0b, 0x22, 0x05, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x0e, 0xd1, 0x08, 0xdb, 0x02, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x03, 0x0d, 0x4a, 0x07, 0xad, 0x01, 0x2c, 0x0c, 0xc6, 0x06, 0x79, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x45, 0x0c, 0x29, 0x07, 0x23, 0x02, 0x34, 0x0d, 0x5b, 0x08, 0x96, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x0e, 0x48,
|
||||||
|
0x0a, 0xbd, 0x05, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x0c, 0x88, 0x08, 0x43, 0x04,
|
||||||
|
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x0b, 0xd3, 0x07, 0xcb, 0x03, 0xd2, 0x0f, 0xe7,
|
||||||
|
0x0b, 0x09, 0x08, 0x39, 0x04, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x0c, 0x14, 0x09,
|
||||||
|
0x75, 0x05, 0xe2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x0e, 0xdd, 0x0a, 0x6b, 0x07, 0x03,
|
||||||
|
0x04, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x0d, 0x09, 0x0a, 0xc9, 0x06, 0x93, 0x03, 0x65, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0d, 0x25, 0x0a, 0x12, 0x07, 0x07, 0x04, 0x05, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0a, 0x0e, 0x17, 0x0b, 0x2c, 0x08, 0x49, 0x05, 0x6d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x98, 0x0f, 0xcb, 0x0c, 0x04, 0x0a, 0x44, 0x07, 0x8b, 0x04, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x0f, 0x87,
|
||||||
|
0x0c, 0xe7, 0x09, 0x4e, 0x07, 0xba, 0x04, 0x2d, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x0f, 0x23, 0x0d, 0xa7, 0x0a,
|
||||||
|
0x30, 0x08, 0xbe, 0x05, 0x52, 0x03, 0xeb, 0x00, 0x89, 0x0e, 0x2c, 0x0c, 0xd4, 0x09, 0x81, 0x07, 0x33, 0x05, 0xe9,
|
||||||
|
0x02, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0e, 0x29, 0x0c, 0xf1, 0x09, 0xbe, 0x07, 0x90, 0x05, 0x65, 0x03,
|
||||||
|
0x3f, 0x01, 0x1d, 0x0f, 0xff, 0x0c, 0xe5, 0x0a, 0xcf, 0x08, 0xbc, 0x06, 0xae, 0x04, 0xa3, 0x02, 0x9c, 0x00, 0x99,
|
||||||
|
0x0e, 0x99, 0x0c, 0x9d, 0x0a, 0xa4, 0x08, 0xaf, 0x06, 0xbd, 0x04, 0xcf, 0x02, 0xe4, 0x00, 0xfc, 0x0e, 0x17, 0x0d,
|
||||||
|
0x36, 0x0b, 0x57, 0x09, 0x7c, 0x07, 0xa4, 0x05, 0xcf, 0x03, 0xfd, 0x01, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x62, 0x0e, 0x98, 0x0c, 0xd2, 0x0a, 0x0e, 0x09, 0x4d, 0x07, 0x8f, 0x05, 0xd4, 0x03, 0x1b, 0x02,
|
||||||
|
0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x0d, 0x52, 0x0b, 0xa6, 0x09, 0xfd, 0x07, 0x56, 0x06, 0xb1,
|
||||||
|
0x04, 0x0f, 0x03, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x0f, 0x37, 0x0e, 0x9e, 0x0c,
|
||||||
|
0x08, 0x0b, 0x73, 0x09, 0xe1, 0x07, 0x52, 0x06, 0xc4, 0x04, 0x38, 0x03, 0xaf, 0x01, 0x28, 0x00, 0xa3, 0x0e, 0x1f,
|
||||||
|
0x0d, 0x9e, 0x0b, 0x1f, 0x0a, 0xa2, 0x08, 0x27, 0x07, 0xae, 0x05, 0x37, 0x04, 0xc2, 0x02, 0x4e, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xdd, 0x0f, 0x6d, 0x0e, 0xff, 0x0c, 0x93, 0x0b, 0x29, 0x0a, 0xc1, 0x08, 0x5a, 0x07, 0xf5, 0x05, 0x92,
|
||||||
|
0x04, 0x30, 0x03, 0xd1, 0x01, 0x73, 0x00, 0x16, 0x0f, 0xbc, 0x0d, 0x62, 0x0c, 0x0b, 0x0b, 0xb5, 0x09, 0x61, 0x08,
|
||||||
|
0x0e, 0x07, 0xbd, 0x05, 0x6d, 0x04, 0x1f, 0x03, 0xd3, 0x01, 0x88, 0x00, 0x3e, 0x0f, 0xf6, 0x0d, 0xaf, 0x0c, 0x6a,
|
||||||
|
0x0b, 0x27, 0x0a, 0xe4, 0x08, 0xa3, 0x07, 0x64, 0x06, 0x26, 0x05, 0xe9, 0x03, 0xae, 0x02, 0x74, 0x01, 0x3b, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0f, 0xce, 0x0d, 0x99, 0x0c, 0x66, 0x0b, 0x34, 0x0a, 0x03,
|
||||||
|
0x09, 0xd3, 0x07, 0xa5, 0x06, 0x78, 0x05, 0x4c, 0x04, 0x22, 0x03, 0xf8, 0x01, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xa9, 0x0f, 0x83, 0x0e, 0x5f, 0x0d, 0x3b, 0x0c, 0x19, 0x0b, 0xf8, 0x09, 0xd8, 0x08, 0xb9, 0x07, 0x9b, 0x06, 0x7e,
|
||||||
|
0x05, 0x63, 0x04, 0x48, 0x03, 0x2f, 0x02, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xfa, 0xff, 0xff, 0x04, 0x00,
|
||||||
|
0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x04, 0xbe, 0x0e, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x01, 0x7f, 0x0a, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x2e, 0x03, 0x9c, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x03, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x7e,
|
||||||
|
0x03, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x88, 0x09, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x56, 0x07,
|
||||||
|
0xfe, 0x0d, 0x80, 0x04, 0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x16, 0x01, 0x2e, 0x07, 0x24, 0x0d, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xfc, 0x02, 0xb5, 0x08, 0x52, 0x0e, 0xd3, 0x03, 0x39, 0x09, 0x86, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xba, 0x03,
|
||||||
|
0xd6, 0x08, 0xdc, 0x0d, 0xcb, 0x02, 0xa4, 0x07, 0x69, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x01, 0xb7, 0x05, 0x42,
|
||||||
|
0x0a, 0xba, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x03, 0x77, 0x07, 0xbc, 0x0b, 0xf1, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x04, 0x2c, 0x08, 0x34, 0x0c, 0x2d, 0x00, 0x18, 0x04, 0xf6,
|
||||||
|
0x07, 0xc6, 0x0b, 0x89, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0xeb, 0x06, 0x8a, 0x0a,
|
||||||
|
0x1d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x01, 0x22, 0x05, 0x94, 0x08, 0xfc, 0x0b, 0x59,
|
||||||
|
0x0f, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0xf6, 0x05, 0x36, 0x09, 0x6c, 0x0c, 0x9a, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xbe, 0x02, 0xda, 0x05, 0xed, 0x08, 0xf8, 0x0b, 0xfa, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xf5,
|
||||||
|
0x01, 0xe8, 0x04, 0xd3, 0x07, 0xb6, 0x0a, 0x92, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00,
|
||||||
|
0x34, 0x03, 0xfb, 0x05, 0xbb, 0x08, 0x74, 0x0b, 0x27, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x78, 0x03, 0x18,
|
||||||
|
0x06, 0xb1, 0x08, 0x45, 0x0b, 0xd2, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0xdc, 0x02, 0x58, 0x05, 0xcf, 0x07,
|
||||||
|
0x41, 0x0a, 0xad, 0x0c, 0x14, 0x0f, 0x76, 0x01, 0xd3, 0x03, 0x2b, 0x06, 0x7e, 0x08, 0xcc, 0x0a, 0x16, 0x0d, 0x5a,
|
||||||
|
0x0f, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x01, 0xd6, 0x03, 0x0e, 0x06, 0x41, 0x08, 0x6f, 0x0a, 0x9a, 0x0c, 0xc0, 0x0e,
|
||||||
|
0xe2, 0x00, 0x00, 0x03, 0x1a, 0x05, 0x30, 0x07, 0x43, 0x09, 0x51, 0x0b, 0x5c, 0x0d, 0x63, 0x0f, 0x66, 0x01, 0x66,
|
||||||
|
0x03, 0x62, 0x05, 0x5b, 0x07, 0x50, 0x09, 0x42, 0x0b, 0x30, 0x0d, 0x1b, 0x0f, 0x03, 0x01, 0xe8, 0x02, 0xc9, 0x04,
|
||||||
|
0xa8, 0x06, 0x83, 0x08, 0x5b, 0x0a, 0x30, 0x0c, 0x02, 0x0e, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x9d, 0x01, 0x67, 0x03, 0x2d, 0x05, 0xf1, 0x06, 0xb2, 0x08, 0x70, 0x0a, 0x2b, 0x0c, 0xe4, 0x0d, 0x9a, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0xff, 0x02, 0xad, 0x04, 0x59, 0x06, 0x02, 0x08, 0xa9, 0x09, 0x4e, 0x0b, 0xf0,
|
||||||
|
0x0c, 0x90, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0xc8, 0x01, 0x61, 0x03, 0xf7, 0x04,
|
||||||
|
0x8c, 0x06, 0x1e, 0x08, 0xad, 0x09, 0x3b, 0x0b, 0xc7, 0x0c, 0x50, 0x0e, 0xd7, 0x0f, 0x5c, 0x01, 0xe0, 0x02, 0x61,
|
||||||
|
0x04, 0xe0, 0x05, 0x5d, 0x07, 0xd8, 0x08, 0x51, 0x0a, 0xc8, 0x0b, 0x3d, 0x0d, 0xb1, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x22, 0x00, 0x92, 0x01, 0x00, 0x03, 0x6c, 0x04, 0xd6, 0x05, 0x3e, 0x07, 0xa5, 0x08, 0x0a, 0x0a, 0x6d, 0x0b, 0xcf,
|
||||||
|
0x0c, 0x2e, 0x0e, 0x8c, 0x0f, 0xe9, 0x00, 0x43, 0x02, 0x9d, 0x03, 0xf4, 0x04, 0x4a, 0x06, 0x9e, 0x07, 0xf1, 0x08,
|
||||||
|
0x42, 0x0a, 0x92, 0x0b, 0xe0, 0x0c, 0x2c, 0x0e, 0x77, 0x0f, 0xc1, 0x00, 0x09, 0x02, 0x50, 0x03, 0x95, 0x04, 0xd8,
|
||||||
|
0x05, 0x1b, 0x07, 0x5c, 0x08, 0x9b, 0x09, 0xd9, 0x0a, 0x16, 0x0c, 0x51, 0x0d, 0x8b, 0x0e, 0xc4, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x31, 0x02, 0x66, 0x03, 0x99, 0x04, 0xcb, 0x05, 0xfc, 0x06, 0x2c,
|
||||||
|
0x08, 0x5a, 0x09, 0x87, 0x0a, 0xb3, 0x0b, 0xdd, 0x0c, 0x07, 0x0e, 0x2f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00,
|
||||||
|
0x7c, 0x01, 0xa0, 0x02, 0xc4, 0x03, 0xe6, 0x04, 0x07, 0x06, 0x27, 0x07, 0x46, 0x08, 0x64, 0x09, 0x81, 0x0a, 0x9c,
|
||||||
|
0x0b, 0xb7, 0x0c, 0xd0, 0x0d, 0xe8, 0x0e, 0x00, 0x10, 0x00, 0x00, 0x2a, 0xfd, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x52, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x10,
|
||||||
|
0x00, 0x12, 0x00, 0x16, 0x00, 0x18, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x24, 0x00, 0x26, 0x00, 0x2a, 0x00,
|
||||||
|
0x2e, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3a, 0x00, 0x40, 0x00, 0x44, 0x00, 0x4a, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x5a,
|
||||||
|
0x00, 0x62, 0x00, 0x68, 0x00, 0x70, 0x00, 0x78, 0x00, 0x80, 0x00, 0x88, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa6, 0x00,
|
||||||
|
0xb0, 0x00, 0xbc, 0x00, 0xc8, 0x00, 0xd4, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x8a, 0xfd, 0xff, 0xff, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x18, 0x00,
|
||||||
|
0x1c, 0x00, 0x20, 0x00, 0x24, 0x00, 0x28, 0x00, 0x2c, 0x00, 0x30, 0x00, 0x34, 0x00, 0x38, 0x00, 0x3c, 0x00, 0x44,
|
||||||
|
0x00, 0x4c, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x68, 0x00, 0x70, 0x00, 0x78, 0x00, 0x80, 0x00, 0x88, 0x00,
|
||||||
|
0x90, 0x00, 0x98, 0x00, 0xa0, 0x00, 0xa8, 0x00, 0xb0, 0x00, 0xb8, 0x00, 0xc4, 0x00, 0xd0, 0x00, 0xdc, 0x00, 0xe8,
|
||||||
|
0x00, 0xf4, 0x00, 0x00, 0x01, 0x0c, 0x01, 0x1c, 0x01, 0x2c, 0x01, 0x00, 0x00, 0xea, 0xfd, 0xff, 0xff, 0x04, 0x00,
|
||||||
|
0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04,
|
||||||
|
0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00,
|
||||||
|
0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
|
||||||
|
0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00,
|
||||||
|
0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x4a, 0xfe, 0xff, 0xff, 0x04,
|
||||||
|
0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x7c, 0x7f, 0x79, 0x7f, 0x76, 0x7f, 0xfa, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x70, 0x7f, 0xf4, 0xff, 0x00, 0x00, 0x00, 0x00, 0x64, 0x7f, 0xe9, 0xff, 0xfe, 0xff, 0x00, 0x00, 0x4b, 0x7f, 0xd0,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x7f, 0xa0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x7e, 0x42, 0xff, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfd, 0x7d, 0x86, 0xfe, 0x04, 0x00, 0x00, 0x00, 0x87, 0x7c, 0x1d, 0xfd, 0x12, 0x00, 0x00, 0x00, 0xb6,
|
||||||
|
0x79, 0x7f, 0xfa, 0x3e, 0x00, 0x00, 0x00, 0x73, 0x74, 0xf9, 0xf5, 0xca, 0x00, 0x00, 0x00, 0x36, 0x6b, 0x33, 0xef,
|
||||||
|
0x32, 0x02, 0x00, 0x00, 0x9b, 0x5c, 0x87, 0xe7, 0xce, 0x04, 0x00, 0x00, 0xf0, 0x48, 0xde, 0xe2, 0xa0, 0x07, 0x00,
|
||||||
|
0x00, 0x6e, 0x33, 0x8a, 0xe4, 0xa4, 0x08, 0x00, 0x00, 0x9c, 0x20, 0x22, 0xeb, 0x4c, 0x07, 0x00, 0x00, 0x0a, 0x13,
|
||||||
|
0x7d, 0xf2, 0x02, 0x05, 0x00, 0x00, 0x89, 0x0a, 0x17, 0xf8, 0x06, 0x03, 0x00, 0x00, 0xa6, 0x05, 0xa0, 0xfb, 0xb4,
|
||||||
|
0x01, 0x00, 0x00, 0xfa, 0x02, 0xac, 0xfd, 0xe8, 0x00, 0x00, 0x00, 0x8e, 0x01, 0xc7, 0xfe, 0x7a, 0x00, 0x00, 0x00,
|
||||||
|
0xcf, 0x00, 0x5c, 0xff, 0x40, 0x00, 0x00, 0x00, 0x6b, 0x00, 0xab, 0xff, 0x22, 0x00, 0x00, 0x00, 0x38, 0x00, 0xd3,
|
||||||
|
0xff, 0x12, 0x00, 0x00, 0x00, 0x1d, 0x00, 0xea, 0xff, 0x08, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xf3, 0xff, 0x06, 0x00,
|
||||||
|
0x00, 0x00, 0x08, 0x00, 0xf8, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||||
|
0x00, 0xfd, 0xff, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfd, 0xff,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||||
|
0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x72, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x82, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4d, 0x01, 0x00, 0x00,
|
||||||
|
0x92, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xff, 0xff, 0xff, 0x04, 0x00,
|
||||||
|
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00,
|
||||||
|
0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x02, 0x00, 0x04, 0x00, 0x05, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x13, 0x00, 0x17, 0x00,
|
||||||
|
0x1b, 0x00, 0x20, 0x00, 0x25, 0x00, 0x2a, 0x00, 0x30, 0x00, 0x35, 0x00, 0x3c, 0x00, 0x42, 0x00, 0x49, 0x00, 0x51,
|
||||||
|
0x00, 0x58, 0x00, 0x60, 0x00, 0x68, 0x00, 0x71, 0x00, 0x7a, 0x00, 0x83, 0x00, 0x8d, 0x00, 0x97, 0x00, 0xa1, 0x00,
|
||||||
|
0xac, 0x00, 0xb7, 0x00, 0xc2, 0x00, 0xcd, 0x00, 0xd9, 0x00, 0xe5, 0x00, 0xf2, 0x00, 0xff, 0x00, 0x0c, 0x01, 0x19,
|
||||||
|
0x01, 0x27, 0x01, 0x35, 0x01, 0x43, 0x01, 0x52, 0x01, 0x61, 0x01, 0x70, 0x01, 0x7f, 0x01, 0x8f, 0x01, 0x9f, 0x01,
|
||||||
|
0xaf, 0x01, 0xc0, 0x01, 0xd1, 0x01, 0xe2, 0x01, 0xf3, 0x01, 0x05, 0x02, 0x17, 0x02, 0x29, 0x02, 0x3c, 0x02, 0x4e,
|
||||||
|
0x02, 0x61, 0x02, 0x75, 0x02, 0x88, 0x02, 0x9c, 0x02, 0xb0, 0x02, 0xc4, 0x02, 0xd8, 0x02, 0xed, 0x02, 0x02, 0x03,
|
||||||
|
0x17, 0x03, 0x2c, 0x03, 0x41, 0x03, 0x57, 0x03, 0x6d, 0x03, 0x83, 0x03, 0x99, 0x03, 0xb0, 0x03, 0xc7, 0x03, 0xdd,
|
||||||
|
0x03, 0xf4, 0x03, 0x0c, 0x04, 0x23, 0x04, 0x3b, 0x04, 0x52, 0x04, 0x6a, 0x04, 0x82, 0x04, 0x9a, 0x04, 0xb3, 0x04,
|
||||||
|
0xcb, 0x04, 0xe4, 0x04, 0xfd, 0x04, 0x16, 0x05, 0x2f, 0x05, 0x48, 0x05, 0x61, 0x05, 0x7a, 0x05, 0x94, 0x05, 0xad,
|
||||||
|
0x05, 0xc7, 0x05, 0xe1, 0x05, 0xfb, 0x05, 0x15, 0x06, 0x2f, 0x06, 0x49, 0x06, 0x63, 0x06, 0x7e, 0x06, 0x98, 0x06,
|
||||||
|
0xb2, 0x06, 0xcd, 0x06, 0xe7, 0x06, 0x02, 0x07, 0x1d, 0x07, 0x37, 0x07, 0x52, 0x07, 0x6d, 0x07, 0x87, 0x07, 0xa2,
|
||||||
|
0x07, 0xbd, 0x07, 0xd8, 0x07, 0xf3, 0x07, 0x0d, 0x08, 0x28, 0x08, 0x43, 0x08, 0x5e, 0x08, 0x79, 0x08, 0x93, 0x08,
|
||||||
|
0xae, 0x08, 0xc9, 0x08, 0xe3, 0x08, 0xfe, 0x08, 0x19, 0x09, 0x33, 0x09, 0x4e, 0x09, 0x68, 0x09, 0x82, 0x09, 0x9d,
|
||||||
|
0x09, 0xb7, 0x09, 0xd1, 0x09, 0xeb, 0x09, 0x05, 0x0a, 0x1f, 0x0a, 0x39, 0x0a, 0x53, 0x0a, 0x6c, 0x0a, 0x86, 0x0a,
|
||||||
|
0x9f, 0x0a, 0xb8, 0x0a, 0xd1, 0x0a, 0xea, 0x0a, 0x03, 0x0b, 0x1c, 0x0b, 0x35, 0x0b, 0x4d, 0x0b, 0x66, 0x0b, 0x7e,
|
||||||
|
0x0b, 0x96, 0x0b, 0xae, 0x0b, 0xc5, 0x0b, 0xdd, 0x0b, 0xf4, 0x0b, 0x0c, 0x0c, 0x23, 0x0c, 0x39, 0x0c, 0x50, 0x0c,
|
||||||
|
0x67, 0x0c, 0x7d, 0x0c, 0x93, 0x0c, 0xa9, 0x0c, 0xbf, 0x0c, 0xd4, 0x0c, 0xe9, 0x0c, 0xfe, 0x0c, 0x13, 0x0d, 0x28,
|
||||||
|
0x0d, 0x3c, 0x0d, 0x50, 0x0d, 0x64, 0x0d, 0x78, 0x0d, 0x8b, 0x0d, 0x9f, 0x0d, 0xb2, 0x0d, 0xc4, 0x0d, 0xd7, 0x0d,
|
||||||
|
0xe9, 0x0d, 0xfb, 0x0d, 0x0d, 0x0e, 0x1e, 0x0e, 0x2f, 0x0e, 0x40, 0x0e, 0x51, 0x0e, 0x61, 0x0e, 0x71, 0x0e, 0x81,
|
||||||
|
0x0e, 0x90, 0x0e, 0x9f, 0x0e, 0xae, 0x0e, 0xbd, 0x0e, 0xcb, 0x0e, 0xd9, 0x0e, 0xe7, 0x0e, 0xf4, 0x0e, 0x01, 0x0f,
|
||||||
|
0x0e, 0x0f, 0x1b, 0x0f, 0x27, 0x0f, 0x33, 0x0f, 0x3e, 0x0f, 0x49, 0x0f, 0x54, 0x0f, 0x5f, 0x0f, 0x69, 0x0f, 0x73,
|
||||||
|
0x0f, 0x7d, 0x0f, 0x86, 0x0f, 0x8f, 0x0f, 0x98, 0x0f, 0xa0, 0x0f, 0xa8, 0x0f, 0xaf, 0x0f, 0xb7, 0x0f, 0xbe, 0x0f,
|
||||||
|
0xc4, 0x0f, 0xcb, 0x0f, 0xd0, 0x0f, 0xd6, 0x0f, 0xdb, 0x0f, 0xe0, 0x0f, 0xe5, 0x0f, 0xe9, 0x0f, 0xed, 0x0f, 0xf0,
|
||||||
|
0x0f, 0xf3, 0x0f, 0xf6, 0x0f, 0xf9, 0x0f, 0xfb, 0x0f, 0xfc, 0x0f, 0xfe, 0x0f, 0xff, 0x0f, 0x00, 0x10, 0x00, 0x10,
|
||||||
|
0x00, 0x10, 0x00, 0x10, 0xff, 0x0f, 0xfe, 0x0f, 0xfc, 0x0f, 0xfb, 0x0f, 0xf9, 0x0f, 0xf6, 0x0f, 0xf3, 0x0f, 0xf0,
|
||||||
|
0x0f, 0xed, 0x0f, 0xe9, 0x0f, 0xe5, 0x0f, 0xe0, 0x0f, 0xdb, 0x0f, 0xd6, 0x0f, 0xd0, 0x0f, 0xcb, 0x0f, 0xc4, 0x0f,
|
||||||
|
0xbe, 0x0f, 0xb7, 0x0f, 0xaf, 0x0f, 0xa8, 0x0f, 0xa0, 0x0f, 0x98, 0x0f, 0x8f, 0x0f, 0x86, 0x0f, 0x7d, 0x0f, 0x73,
|
||||||
|
0x0f, 0x69, 0x0f, 0x5f, 0x0f, 0x54, 0x0f, 0x49, 0x0f, 0x3e, 0x0f, 0x33, 0x0f, 0x27, 0x0f, 0x1b, 0x0f, 0x0e, 0x0f,
|
||||||
|
0x01, 0x0f, 0xf4, 0x0e, 0xe7, 0x0e, 0xd9, 0x0e, 0xcb, 0x0e, 0xbd, 0x0e, 0xae, 0x0e, 0x9f, 0x0e, 0x90, 0x0e, 0x81,
|
||||||
|
0x0e, 0x71, 0x0e, 0x61, 0x0e, 0x51, 0x0e, 0x40, 0x0e, 0x2f, 0x0e, 0x1e, 0x0e, 0x0d, 0x0e, 0xfb, 0x0d, 0xe9, 0x0d,
|
||||||
|
0xd7, 0x0d, 0xc4, 0x0d, 0xb2, 0x0d, 0x9f, 0x0d, 0x8b, 0x0d, 0x78, 0x0d, 0x64, 0x0d, 0x50, 0x0d, 0x3c, 0x0d, 0x28,
|
||||||
|
0x0d, 0x13, 0x0d, 0xfe, 0x0c, 0xe9, 0x0c, 0xd4, 0x0c, 0xbf, 0x0c, 0xa9, 0x0c, 0x93, 0x0c, 0x7d, 0x0c, 0x67, 0x0c,
|
||||||
|
0x50, 0x0c, 0x39, 0x0c, 0x23, 0x0c, 0x0c, 0x0c, 0xf4, 0x0b, 0xdd, 0x0b, 0xc5, 0x0b, 0xae, 0x0b, 0x96, 0x0b, 0x7e,
|
||||||
|
0x0b, 0x66, 0x0b, 0x4d, 0x0b, 0x35, 0x0b, 0x1c, 0x0b, 0x03, 0x0b, 0xea, 0x0a, 0xd1, 0x0a, 0xb8, 0x0a, 0x9f, 0x0a,
|
||||||
|
0x86, 0x0a, 0x6c, 0x0a, 0x53, 0x0a, 0x39, 0x0a, 0x1f, 0x0a, 0x05, 0x0a, 0xeb, 0x09, 0xd1, 0x09, 0xb7, 0x09, 0x9d,
|
||||||
|
0x09, 0x82, 0x09, 0x68, 0x09, 0x4e, 0x09, 0x33, 0x09, 0x19, 0x09, 0xfe, 0x08, 0xe3, 0x08, 0xc9, 0x08, 0xae, 0x08,
|
||||||
|
0x93, 0x08, 0x79, 0x08, 0x5e, 0x08, 0x43, 0x08, 0x28, 0x08, 0x0d, 0x08, 0xf3, 0x07, 0xd8, 0x07, 0xbd, 0x07, 0xa2,
|
||||||
|
0x07, 0x87, 0x07, 0x6d, 0x07, 0x52, 0x07, 0x37, 0x07, 0x1d, 0x07, 0x02, 0x07, 0xe7, 0x06, 0xcd, 0x06, 0xb2, 0x06,
|
||||||
|
0x98, 0x06, 0x7e, 0x06, 0x63, 0x06, 0x49, 0x06, 0x2f, 0x06, 0x15, 0x06, 0xfb, 0x05, 0xe1, 0x05, 0xc7, 0x05, 0xad,
|
||||||
|
0x05, 0x94, 0x05, 0x7a, 0x05, 0x61, 0x05, 0x48, 0x05, 0x2f, 0x05, 0x16, 0x05, 0xfd, 0x04, 0xe4, 0x04, 0xcb, 0x04,
|
||||||
|
0xb3, 0x04, 0x9a, 0x04, 0x82, 0x04, 0x6a, 0x04, 0x52, 0x04, 0x3b, 0x04, 0x23, 0x04, 0x0c, 0x04, 0xf4, 0x03, 0xdd,
|
||||||
|
0x03, 0xc7, 0x03, 0xb0, 0x03, 0x99, 0x03, 0x83, 0x03, 0x6d, 0x03, 0x57, 0x03, 0x41, 0x03, 0x2c, 0x03, 0x17, 0x03,
|
||||||
|
0x02, 0x03, 0xed, 0x02, 0xd8, 0x02, 0xc4, 0x02, 0xb0, 0x02, 0x9c, 0x02, 0x88, 0x02, 0x75, 0x02, 0x61, 0x02, 0x4e,
|
||||||
|
0x02, 0x3c, 0x02, 0x29, 0x02, 0x17, 0x02, 0x05, 0x02, 0xf3, 0x01, 0xe2, 0x01, 0xd1, 0x01, 0xc0, 0x01, 0xaf, 0x01,
|
||||||
|
0x9f, 0x01, 0x8f, 0x01, 0x7f, 0x01, 0x70, 0x01, 0x61, 0x01, 0x52, 0x01, 0x43, 0x01, 0x35, 0x01, 0x27, 0x01, 0x19,
|
||||||
|
0x01, 0x0c, 0x01, 0xff, 0x00, 0xf2, 0x00, 0xe5, 0x00, 0xd9, 0x00, 0xcd, 0x00, 0xc2, 0x00, 0xb7, 0x00, 0xac, 0x00,
|
||||||
|
0xa1, 0x00, 0x97, 0x00, 0x8d, 0x00, 0x83, 0x00, 0x7a, 0x00, 0x71, 0x00, 0x68, 0x00, 0x60, 0x00, 0x58, 0x00, 0x51,
|
||||||
|
0x00, 0x49, 0x00, 0x42, 0x00, 0x3c, 0x00, 0x35, 0x00, 0x30, 0x00, 0x2a, 0x00, 0x25, 0x00, 0x20, 0x00, 0x1b, 0x00,
|
||||||
|
0x17, 0x00, 0x13, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x05, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xee, 0xff, 0xff, 0x38, 0xee, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x4d, 0x4c,
|
||||||
|
0x49, 0x52, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00,
|
||||||
|
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xf4, 0x05, 0x00, 0x00, 0xf8, 0x05, 0x00,
|
||||||
|
0x00, 0xfc, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
|
||||||
|
0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x68, 0x05, 0x00, 0x00, 0x24, 0x05, 0x00, 0x00, 0xc8, 0x04, 0x00, 0x00, 0x70,
|
||||||
|
0x04, 0x00, 0x00, 0x4c, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00,
|
||||||
|
0x4c, 0x03, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x6c, 0x01, 0x00,
|
||||||
|
0x00, 0x48, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x78, 0x00,
|
||||||
|
0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf6, 0xfa, 0xff, 0xff, 0x0c,
|
||||||
|
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x16, 0xfb, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3a, 0xfb, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||||
|
0x0e, 0x00, 0x00, 0x00, 0xa6, 0xfc, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x14, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x68, 0xef, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x27, 0x00,
|
||||||
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xd6, 0xfc, 0xff, 0xff, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
|
||||||
|
0x98, 0xef, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00,
|
||||||
|
0x00, 0x12, 0x00, 0x00, 0x00, 0x06, 0xfd, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x10, 0x00,
|
||||||
|
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xc8, 0xef, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x25,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x36, 0xfd, 0xff, 0xff,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
|
||||||
|
0x00, 0xf8, 0xef, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00,
|
||||||
|
0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
0x84, 0xfc, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69,
|
||||||
|
0x6f, 0x6e, 0x5f, 0x62, 0x69, 0x74, 0x73, 0x00, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x73, 0x63, 0x61, 0x6c,
|
||||||
|
0x65, 0x00, 0x02, 0x24, 0x0f, 0x02, 0x01, 0x02, 0x03, 0x40, 0x04, 0x04, 0x04, 0x24, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xdc, 0xfc, 0xff, 0xff, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x24, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x73, 0x6e,
|
||||||
|
0x72, 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, 0x00, 0x01, 0x0b, 0x01, 0x01, 0x01, 0x06, 0x04, 0x02, 0x24, 0x01, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x20, 0xfd, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00,
|
||||||
|
0x00, 0x0a, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x5f,
|
||||||
|
0x6f, 0x6e, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x75, 0x73, 0x5f, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67,
|
||||||
|
0x00, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x69, 0x6e,
|
||||||
|
0x67, 0x00, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x69, 0x6e, 0x67, 0x00, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e,
|
||||||
|
0x61, 0x6c, 0x5f, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x68,
|
||||||
|
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x00, 0x6f, 0x6e, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x75, 0x73, 0x5f, 0x73, 0x6d,
|
||||||
|
0x6f, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x00, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x00, 0x73,
|
||||||
|
0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x69, 0x74, 0x73, 0x00, 0x73, 0x70, 0x65, 0x63, 0x74,
|
||||||
|
0x72, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x69, 0x74,
|
||||||
|
0x73, 0x00, 0x09, 0xa5, 0x88, 0x75, 0x6d, 0x59, 0x4d, 0x3a, 0x31, 0x23, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x29,
|
||||||
|
0x3c, 0xd7, 0x03, 0x00, 0x00, 0x33, 0x03, 0x28, 0x00, 0x67, 0x3e, 0x99, 0x01, 0x0a, 0x00, 0x0e, 0x00, 0x05, 0x05,
|
||||||
|
0x69, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1b, 0x25, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0xfe, 0xff, 0xff, 0x10, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x1d, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x54, 0xfe, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
|
||||||
|
0x00, 0x2c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x68,
|
||||||
|
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x00, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x28, 0x04, 0x02, 0x24, 0x01, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x62, 0xfe, 0xff,
|
||||||
|
0xff, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xca, 0xff, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8c, 0xf2, 0xff, 0xff,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
|
||||||
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x00,
|
||||||
|
0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd0, 0xf2, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
|
||||||
|
0x00, 0xfe, 0xfe, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x64, 0xff, 0xff, 0xff, 0x10,
|
||||||
|
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
|
||||||
|
0x65, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x00, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x64,
|
||||||
|
0x65, 0x78, 0x00, 0x02, 0x17, 0x0e, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0xf1, 0x00, 0x05, 0x00, 0x05, 0x05,
|
||||||
|
0x06, 0x25, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17,
|
||||||
|
0x00, 0x00, 0x00, 0xb8, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x54, 0x00, 0x66, 0x66, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74,
|
||||||
|
0x68, 0x00, 0x02, 0x0e, 0x0d, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x02, 0x05, 0x05, 0x06, 0x25,
|
||||||
|
0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x10,
|
||||||
|
0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08,
|
||||||
|
0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00,
|
||||||
|
0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x73,
|
||||||
|
0x68, 0x69, 0x66, 0x74, 0x00, 0x01, 0x07, 0x01, 0x01, 0x01, 0x0c, 0x04, 0x02, 0x24, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xc4, 0x0a,
|
||||||
|
0x00, 0x00, 0x74, 0x0a, 0x00, 0x00, 0x3c, 0x0a, 0x00, 0x00, 0x04, 0x0a, 0x00, 0x00, 0xd0, 0x09, 0x00, 0x00, 0x88,
|
||||||
|
0x09, 0x00, 0x00, 0x40, 0x09, 0x00, 0x00, 0xfc, 0x08, 0x00, 0x00, 0xb8, 0x08, 0x00, 0x00, 0x6c, 0x08, 0x00, 0x00,
|
||||||
|
0x20, 0x08, 0x00, 0x00, 0xd4, 0x07, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x3c, 0x07, 0x00, 0x00, 0xf8, 0x06, 0x00,
|
||||||
|
0x00, 0xb8, 0x06, 0x00, 0x00, 0x84, 0x06, 0x00, 0x00, 0x50, 0x06, 0x00, 0x00, 0x1c, 0x06, 0x00, 0x00, 0xd8, 0x05,
|
||||||
|
0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x58, 0x05, 0x00, 0x00, 0x14, 0x05, 0x00, 0x00, 0xd8, 0x04, 0x00, 0x00, 0x98,
|
||||||
|
0x04, 0x00, 0x00, 0x60, 0x04, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00,
|
||||||
|
0x6c, 0x03, 0x00, 0x00, 0x1c, 0x03, 0x00, 0x00, 0xc4, 0x02, 0x00, 0x00, 0x68, 0x02, 0x00, 0x00, 0x2c, 0x02, 0x00,
|
||||||
|
0x00, 0xe4, 0x01, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x08, 0x01,
|
||||||
|
0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xfe,
|
||||||
|
0xf5, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x00, 0x44, 0xf5, 0xff, 0xff, 0x11, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72,
|
||||||
|
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x3a, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3e, 0xf6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x84, 0xf5, 0xff, 0xff,
|
||||||
|
0x0d, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x62, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x7a, 0xf6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00,
|
||||||
|
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x00, 0xc0,
|
||||||
|
0xf5, 0xff, 0xff, 0x15, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x62, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75,
|
||||||
|
0x65, 0x2f, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
|
||||||
|
0x00, 0xbe, 0xf6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x04, 0xf6, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x61,
|
||||||
|
0x64, 0x64, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf2, 0xf6, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x18, 0x00, 0x00, 0x00, 0x38, 0xf6, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61,
|
||||||
|
0x74, 0x65, 0x44, 0x69, 0x76, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2a, 0xf7, 0xff, 0xff, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x70, 0xf6, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x28, 0x00, 0x00, 0x00, 0x5a, 0xf7, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00,
|
||||||
|
0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0xa0, 0xf6, 0xff, 0xff, 0x03,
|
||||||
|
0x00, 0x00, 0x00, 0x6d, 0x75, 0x6c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x8a, 0xf7, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x14, 0x00, 0x00, 0x00, 0xd0, 0xf6, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x43, 0x61, 0x73, 0x74, 0x5f, 0x32,
|
||||||
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xbe, 0xf7, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x24, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0xf7, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74,
|
||||||
|
0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||||
|
0x00, 0x00, 0x02, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x22,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x18, 0x00, 0x00, 0x00, 0x48, 0xf7, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00,
|
||||||
|
0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x63, 0x61, 0x6e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
|
||||||
|
0x00, 0x3a, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x00, 0x00, 0x00, 0x80, 0xf7, 0xff, 0xff, 0x28, 0x00, 0x00, 0x00, 0x73,
|
||||||
|
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x5f, 0x73,
|
||||||
|
0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
|
0x31, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x92, 0xf8, 0xff, 0xff, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x34,
|
||||||
|
0x00, 0x00, 0x00, 0xd8, 0xf7, 0xff, 0xff, 0x27, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66,
|
||||||
|
0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x72, 0x61, 0x6c,
|
||||||
|
0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||||
|
0x00, 0x00, 0xe6, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x2c, 0x00, 0x00, 0x00, 0x2c, 0xf8, 0xff, 0xff, 0x1e, 0x00, 0x00, 0x00,
|
||||||
|
0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x5f,
|
||||||
|
0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||||
|
0x00, 0x00, 0x32, 0xf9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1e,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x78, 0xf8, 0xff, 0xff, 0x12, 0x00, 0x00, 0x00,
|
||||||
|
0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x72, 0xf9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00,
|
||||||
|
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x14, 0x00, 0x00, 0x00, 0xb8,
|
||||||
|
0xf8, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x43, 0x61, 0x73, 0x74, 0x5f, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x01, 0x00, 0x00, 0xa6, 0xf9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0xec, 0xf8, 0xff, 0xff, 0x06, 0x00,
|
||||||
|
0x00, 0x00, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xda,
|
||||||
|
0xf9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x20, 0xf9, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72,
|
||||||
|
0x69, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xec, 0x00,
|
||||||
|
0x00, 0x00, 0x16, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1a,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x5c, 0xf9, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x43, 0x61, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x4a, 0xfa, 0xff,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0f, 0x1c, 0x00, 0x00, 0x00, 0x90, 0xf9, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
||||||
|
0x6c, 0x5f, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
|
||||||
|
0x86, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xf9, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x73, 0x69,
|
||||||
|
0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x66, 0x66, 0x74, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0xbe,
|
||||||
|
0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x00, 0x04, 0xfa, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67,
|
||||||
|
0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x66, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x31,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x24, 0x00, 0x00, 0x00, 0x44, 0xfa, 0xff, 0xff,
|
||||||
|
0x15, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x66, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x6f,
|
||||||
|
0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x42, 0xfb,
|
||||||
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x00, 0x88, 0xfa, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68,
|
||||||
|
0x61, 0x70, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x76, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x00,
|
||||||
|
0x00, 0x00, 0xbc, 0xfa, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x77, 0x69,
|
||||||
|
0x6e, 0x64, 0x6f, 0x77, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
|
||||||
|
0xb6, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0xfc, 0xfa, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x43, 0x6f,
|
||||||
|
0x6e, 0x73, 0x74, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14,
|
||||||
|
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00,
|
||||||
|
0x2c, 0xfb, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x16, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x5c, 0xfb, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x43,
|
||||||
|
0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00,
|
||||||
|
0x00, 0x8c, 0xfb, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x2f, 0x73, 0x68,
|
||||||
|
0x61, 0x70, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x82, 0xfc, 0xff, 0xff, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||||
|
0x24, 0x00, 0x00, 0x00, 0xc8, 0xfb, 0xff, 0xff, 0x17, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x62, 0x79,
|
||||||
|
0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2f, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x2f, 0x79, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc2, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0e,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x28, 0x00, 0x00, 0x00, 0x08, 0xfc, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x2f,
|
||||||
|
0x43, 0x6f, 0x6e, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x0a, 0xfd,
|
||||||
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x07, 0x28, 0x00, 0x00, 0x00, 0x50, 0xfc, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e,
|
||||||
|
0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x2f, 0x43, 0x6f, 0x6e, 0x73,
|
||||||
|
0x74, 0x5f, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x52, 0xfd, 0xff, 0xff, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x28,
|
||||||
|
0x00, 0x00, 0x00, 0x98, 0xfc, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66,
|
||||||
|
0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x32, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x9a, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00,
|
||||||
|
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x28, 0x00, 0x00, 0x00, 0xe0,
|
||||||
|
0xfc, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65,
|
||||||
|
0x72, 0x5f, 0x62, 0x61, 0x6e, 0x6b, 0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x33, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x29, 0x00, 0x00, 0x00, 0xe2, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00,
|
||||||
|
0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x28, 0x00, 0x00, 0x00, 0x28, 0xfd, 0xff, 0xff, 0x1a,
|
||||||
|
0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x62, 0x61,
|
||||||
|
0x6e, 0x6b, 0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x34, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00,
|
||||||
|
0x00, 0x2a, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x09, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, 0x00, 0x00, 0x00, 0x70, 0xfd, 0xff, 0xff, 0x11, 0x00, 0x00, 0x00, 0x73,
|
||||||
|
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x63, 0x61, 0x6e, 0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x6a, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00,
|
||||||
|
0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0xb0, 0xfd,
|
||||||
|
0xff, 0xff, 0x13, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65,
|
||||||
|
0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xaa, 0xfe, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x24, 0x00, 0x00, 0x00, 0xf0, 0xfd, 0xff, 0xff, 0x15, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x64, 0x65,
|
||||||
|
0x64, 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xee, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x00, 0x34, 0xfe, 0xff,
|
||||||
|
0xff, 0x15, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x2f,
|
||||||
|
0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32,
|
||||||
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x78, 0xfe, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x43, 0x61, 0x73,
|
||||||
|
0x74, 0x5f, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00,
|
||||||
|
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0xa8,
|
||||||
|
0xfe, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x7a, 0x65, 0x72, 0x6f, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x05, 0x00, 0x00, 0x00, 0x96, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00,
|
||||||
|
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0xdc, 0xfe, 0xff, 0xff, 0x07, 0x00,
|
||||||
|
0x00, 0x00, 0x7a, 0x65, 0x72, 0x6f, 0x73, 0x5f, 0x31, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xca,
|
||||||
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e,
|
||||||
|
0x73, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x1c, 0x00,
|
||||||
|
0x18, 0x00, 0x17, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x16,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x2c, 0x00, 0x00, 0x00, 0x5c, 0xff, 0xff, 0xff, 0x1d, 0x00, 0x00, 0x00, 0x73, 0x65, 0x72,
|
||||||
|
0x76, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x5f,
|
||||||
|
0x66, 0x72, 0x61, 0x6d, 0x65, 0x3a, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0,
|
||||||
|
0x01, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00,
|
||||||
|
0xa4, 0x01, 0x00, 0x00, 0x7c, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x3c, 0x01, 0x00,
|
||||||
|
0x00, 0x10, 0x01, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x50, 0x00,
|
||||||
|
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04,
|
||||||
|
0x00, 0x00, 0x00, 0x50, 0xfe, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x5c, 0xfe, 0xff, 0xff,
|
||||||
|
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x68, 0xfe, 0xff, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x2a, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7c, 0xfe, 0xff, 0xff, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x12, 0x70, 0xfe, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x13,
|
||||||
|
0x00, 0x00, 0x00, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6e, 0x6b,
|
||||||
|
0x4c, 0x6f, 0x67, 0x00, 0x98, 0xfe, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x0a, 0x00, 0x00, 0x00, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x50, 0x43, 0x41, 0x4e, 0x00, 0x00, 0xb8, 0xfe,
|
||||||
|
0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x23, 0x00, 0x00, 0x00, 0x53,
|
||||||
|
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63,
|
||||||
|
0x74, 0x72, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0xf0, 0xfe, 0xff,
|
||||||
|
0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x1a, 0x00, 0x00, 0x00, 0x53, 0x69,
|
||||||
|
0x67, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6e, 0x6b, 0x53, 0x71, 0x75, 0x61, 0x72,
|
||||||
|
0x65, 0x52, 0x6f, 0x6f, 0x74, 0x00, 0x00, 0x20, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65,
|
||||||
|
0x72, 0x42, 0x61, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x02, 0x6c, 0xff, 0xff, 0xff, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x0c, 0x00, 0x10, 0x00, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x35, 0x7c, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x0c, 0x00, 0x00, 0x00, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xa0, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0a,
|
||||||
|
0x00, 0x00, 0x00, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x66, 0x66, 0x74, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x53, 0x69, 0x67,
|
||||||
|
0x6e, 0x61, 0x6c, 0x46, 0x66, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0x00, 0x0c, 0x00,
|
||||||
|
0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x16, 0x0c, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0c, 0x00, 0x00, 0x00, 0x53, 0x69, 0x67,
|
||||||
|
0x6e, 0x61, 0x6c, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
} // namespace micro_wake_word
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_ESP_IDF
|
521
esphome/components/micro_wake_word/micro_wake_word.cpp
Normal file
521
esphome/components/micro_wake_word/micro_wake_word.cpp
Normal file
|
@ -0,0 +1,521 @@
|
||||||
|
#include "micro_wake_word.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a workaround until we can figure out a way to get
|
||||||
|
* the tflite-micro idf component code available in CI
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
//
|
||||||
|
#ifndef CLANG_TIDY
|
||||||
|
|
||||||
|
#ifdef USE_ESP_IDF
|
||||||
|
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#include "audio_preprocessor_int8_model_data.h"
|
||||||
|
|
||||||
|
#include <tensorflow/lite/core/c/common.h>
|
||||||
|
#include <tensorflow/lite/micro/micro_interpreter.h>
|
||||||
|
#include <tensorflow/lite/micro/micro_mutable_op_resolver.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace micro_wake_word {
|
||||||
|
|
||||||
|
static const char *const TAG = "micro_wake_word";
|
||||||
|
|
||||||
|
static const size_t SAMPLE_RATE_HZ = 16000; // 16 kHz
|
||||||
|
static const size_t BUFFER_LENGTH = 500; // 0.5 seconds
|
||||||
|
static const size_t BUFFER_SIZE = SAMPLE_RATE_HZ / 1000 * BUFFER_LENGTH;
|
||||||
|
static const size_t INPUT_BUFFER_SIZE = 32 * SAMPLE_RATE_HZ / 1000; // 32ms * 16kHz / 1000ms
|
||||||
|
|
||||||
|
float MicroWakeWord::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; }
|
||||||
|
|
||||||
|
static const LogString *micro_wake_word_state_to_string(State state) {
|
||||||
|
switch (state) {
|
||||||
|
case State::IDLE:
|
||||||
|
return LOG_STR("IDLE");
|
||||||
|
case State::START_MICROPHONE:
|
||||||
|
return LOG_STR("START_MICROPHONE");
|
||||||
|
case State::STARTING_MICROPHONE:
|
||||||
|
return LOG_STR("STARTING_MICROPHONE");
|
||||||
|
case State::DETECTING_WAKE_WORD:
|
||||||
|
return LOG_STR("DETECTING_WAKE_WORD");
|
||||||
|
case State::STOP_MICROPHONE:
|
||||||
|
return LOG_STR("STOP_MICROPHONE");
|
||||||
|
case State::STOPPING_MICROPHONE:
|
||||||
|
return LOG_STR("STOPPING_MICROPHONE");
|
||||||
|
default:
|
||||||
|
return LOG_STR("UNKNOWN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "microWakeWord:");
|
||||||
|
ESP_LOGCONFIG(TAG, " Wake Word: %s", this->get_wake_word().c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " Probability cutoff: %.3f", this->probability_cutoff_);
|
||||||
|
ESP_LOGCONFIG(TAG, " Sliding window size: %d", this->sliding_window_average_size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up microWakeWord...");
|
||||||
|
|
||||||
|
if (!this->initialize_models()) {
|
||||||
|
ESP_LOGE(TAG, "Failed to initialize models");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalRAMAllocator<int16_t> allocator(ExternalRAMAllocator<int16_t>::ALLOW_FAILURE);
|
||||||
|
this->input_buffer_ = allocator.allocate(INPUT_BUFFER_SIZE * sizeof(int16_t));
|
||||||
|
if (this->input_buffer_ == nullptr) {
|
||||||
|
ESP_LOGW(TAG, "Could not allocate input buffer");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->ring_buffer_ = RingBuffer::create(BUFFER_SIZE * sizeof(int16_t));
|
||||||
|
if (this->ring_buffer_ == nullptr) {
|
||||||
|
ESP_LOGW(TAG, "Could not allocate ring buffer");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG, "Micro Wake Word initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
int MicroWakeWord::read_microphone_() {
|
||||||
|
size_t bytes_read = this->microphone_->read(this->input_buffer_, INPUT_BUFFER_SIZE * sizeof(int16_t));
|
||||||
|
if (bytes_read == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_written = this->ring_buffer_->write((void *) this->input_buffer_, bytes_read);
|
||||||
|
if (bytes_written != bytes_read) {
|
||||||
|
ESP_LOGW(TAG, "Failed to write some data to ring buffer (written=%d, expected=%d)", bytes_written, bytes_read);
|
||||||
|
}
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::loop() {
|
||||||
|
switch (this->state_) {
|
||||||
|
case State::IDLE:
|
||||||
|
break;
|
||||||
|
case State::START_MICROPHONE:
|
||||||
|
ESP_LOGD(TAG, "Starting Microphone");
|
||||||
|
this->microphone_->start();
|
||||||
|
this->set_state_(State::STARTING_MICROPHONE);
|
||||||
|
this->high_freq_.start();
|
||||||
|
break;
|
||||||
|
case State::STARTING_MICROPHONE:
|
||||||
|
if (this->microphone_->is_running()) {
|
||||||
|
this->set_state_(State::DETECTING_WAKE_WORD);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case State::DETECTING_WAKE_WORD:
|
||||||
|
this->read_microphone_();
|
||||||
|
if (this->detect_wake_word_()) {
|
||||||
|
ESP_LOGD(TAG, "Wake Word Detected");
|
||||||
|
this->detected_ = true;
|
||||||
|
this->set_state_(State::STOP_MICROPHONE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case State::STOP_MICROPHONE:
|
||||||
|
ESP_LOGD(TAG, "Stopping Microphone");
|
||||||
|
this->microphone_->stop();
|
||||||
|
this->set_state_(State::STOPPING_MICROPHONE);
|
||||||
|
this->high_freq_.stop();
|
||||||
|
break;
|
||||||
|
case State::STOPPING_MICROPHONE:
|
||||||
|
if (this->microphone_->is_stopped()) {
|
||||||
|
this->set_state_(State::IDLE);
|
||||||
|
if (this->detected_) {
|
||||||
|
this->detected_ = false;
|
||||||
|
this->wake_word_detected_trigger_->trigger("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::start() {
|
||||||
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGW(TAG, "Wake word component is marked as failed. Please check setup logs");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->state_ != State::IDLE) {
|
||||||
|
ESP_LOGW(TAG, "Wake word is already running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->set_state_(State::START_MICROPHONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::stop() {
|
||||||
|
if (this->state_ == State::IDLE) {
|
||||||
|
ESP_LOGW(TAG, "Wake word is already stopped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->state_ == State::STOPPING_MICROPHONE) {
|
||||||
|
ESP_LOGW(TAG, "Wake word is already stopping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->set_state_(State::STOP_MICROPHONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::set_state_(State state) {
|
||||||
|
ESP_LOGD(TAG, "State changed from %s to %s", LOG_STR_ARG(micro_wake_word_state_to_string(this->state_)),
|
||||||
|
LOG_STR_ARG(micro_wake_word_state_to_string(state)));
|
||||||
|
this->state_ = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::initialize_models() {
|
||||||
|
ExternalRAMAllocator<uint8_t> arena_allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
|
||||||
|
ExternalRAMAllocator<int8_t> features_allocator(ExternalRAMAllocator<int8_t>::ALLOW_FAILURE);
|
||||||
|
ExternalRAMAllocator<int16_t> audio_samples_allocator(ExternalRAMAllocator<int16_t>::ALLOW_FAILURE);
|
||||||
|
|
||||||
|
this->streaming_tensor_arena_ = arena_allocator.allocate(STREAMING_MODEL_ARENA_SIZE);
|
||||||
|
if (this->streaming_tensor_arena_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate the streaming model's tensor arena.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->streaming_var_arena_ = arena_allocator.allocate(STREAMING_MODEL_VARIABLE_ARENA_SIZE);
|
||||||
|
if (this->streaming_var_arena_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate the streaming model variable's tensor arena.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->preprocessor_tensor_arena_ = arena_allocator.allocate(PREPROCESSOR_ARENA_SIZE);
|
||||||
|
if (this->preprocessor_tensor_arena_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate the audio preprocessor model's tensor arena.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->new_features_data_ = features_allocator.allocate(PREPROCESSOR_FEATURE_SIZE);
|
||||||
|
if (this->new_features_data_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate the audio features buffer.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->preprocessor_audio_buffer_ = audio_samples_allocator.allocate(SAMPLE_DURATION_COUNT);
|
||||||
|
if (this->preprocessor_audio_buffer_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate the audio preprocessor's buffer.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->preprocessor_stride_buffer_ = audio_samples_allocator.allocate(HISTORY_SAMPLES_TO_KEEP);
|
||||||
|
if (this->preprocessor_stride_buffer_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate the audio preprocessor's stride buffer.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->preprocessor_model_ = tflite::GetModel(G_AUDIO_PREPROCESSOR_INT8_TFLITE);
|
||||||
|
if (this->preprocessor_model_->version() != TFLITE_SCHEMA_VERSION) {
|
||||||
|
ESP_LOGE(TAG, "Wake word's audio preprocessor model's schema is not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->streaming_model_ = tflite::GetModel(this->model_start_);
|
||||||
|
if (this->streaming_model_->version() != TFLITE_SCHEMA_VERSION) {
|
||||||
|
ESP_LOGE(TAG, "Wake word's streaming model's schema is not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tflite::MicroMutableOpResolver<18> preprocessor_op_resolver;
|
||||||
|
static tflite::MicroMutableOpResolver<14> streaming_op_resolver;
|
||||||
|
|
||||||
|
if (!this->register_preprocessor_ops_(preprocessor_op_resolver))
|
||||||
|
return false;
|
||||||
|
if (!this->register_streaming_ops_(streaming_op_resolver))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tflite::MicroAllocator *ma =
|
||||||
|
tflite::MicroAllocator::Create(this->streaming_var_arena_, STREAMING_MODEL_VARIABLE_ARENA_SIZE);
|
||||||
|
this->mrv_ = tflite::MicroResourceVariables::Create(ma, 15);
|
||||||
|
|
||||||
|
static tflite::MicroInterpreter static_preprocessor_interpreter(
|
||||||
|
this->preprocessor_model_, preprocessor_op_resolver, this->preprocessor_tensor_arena_, PREPROCESSOR_ARENA_SIZE);
|
||||||
|
|
||||||
|
static tflite::MicroInterpreter static_streaming_interpreter(this->streaming_model_, streaming_op_resolver,
|
||||||
|
this->streaming_tensor_arena_,
|
||||||
|
STREAMING_MODEL_ARENA_SIZE, this->mrv_);
|
||||||
|
|
||||||
|
this->preprocessor_interperter_ = &static_preprocessor_interpreter;
|
||||||
|
this->streaming_interpreter_ = &static_streaming_interpreter;
|
||||||
|
|
||||||
|
// Allocate tensors for each models.
|
||||||
|
if (this->preprocessor_interperter_->AllocateTensors() != kTfLiteOk) {
|
||||||
|
ESP_LOGE(TAG, "Failed to allocate tensors for the audio preprocessor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this->streaming_interpreter_->AllocateTensors() != kTfLiteOk) {
|
||||||
|
ESP_LOGE(TAG, "Failed to allocate tensors for the streaming model");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify input tensor matches expected values
|
||||||
|
TfLiteTensor *input = this->streaming_interpreter_->input(0);
|
||||||
|
if ((input->dims->size != 3) || (input->dims->data[0] != 1) || (input->dims->data[0] != 1) ||
|
||||||
|
(input->dims->data[1] != 1) || (input->dims->data[2] != PREPROCESSOR_FEATURE_SIZE)) {
|
||||||
|
ESP_LOGE(TAG, "Wake word detection model tensor input dimensions is not 1x1x%u", input->dims->data[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input->type != kTfLiteInt8) {
|
||||||
|
ESP_LOGE(TAG, "Wake word detection model tensor input is not int8.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify output tensor matches expected values
|
||||||
|
TfLiteTensor *output = this->streaming_interpreter_->output(0);
|
||||||
|
if ((output->dims->size != 2) || (output->dims->data[0] != 1) || (output->dims->data[1] != 1)) {
|
||||||
|
ESP_LOGE(TAG, "Wake word detection model tensor output dimensions is not 1x1.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output->type != kTfLiteUInt8) {
|
||||||
|
ESP_LOGE(TAG, "Wake word detection model tensor input is not uint8.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->recent_streaming_probabilities_.resize(this->sliding_window_average_size_, 0.0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::update_features_() {
|
||||||
|
// Retrieve strided audio samples
|
||||||
|
int16_t *audio_samples = nullptr;
|
||||||
|
if (!this->stride_audio_samples_(&audio_samples)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the features for the newest audio samples
|
||||||
|
if (!this->generate_single_feature_(audio_samples, SAMPLE_DURATION_COUNT, this->new_features_data_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MicroWakeWord::perform_streaming_inference_() {
|
||||||
|
TfLiteTensor *input = this->streaming_interpreter_->input(0);
|
||||||
|
|
||||||
|
size_t bytes_to_copy = input->bytes;
|
||||||
|
|
||||||
|
memcpy((void *) (tflite::GetTensorData<int8_t>(input)), (const void *) (this->new_features_data_), bytes_to_copy);
|
||||||
|
|
||||||
|
uint32_t prior_invoke = millis();
|
||||||
|
|
||||||
|
TfLiteStatus invoke_status = this->streaming_interpreter_->Invoke();
|
||||||
|
if (invoke_status != kTfLiteOk) {
|
||||||
|
ESP_LOGW(TAG, "Streaming Interpreter Invoke failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "Streaming Inference Latency=%u ms", (millis() - prior_invoke));
|
||||||
|
|
||||||
|
TfLiteTensor *output = this->streaming_interpreter_->output(0);
|
||||||
|
|
||||||
|
return static_cast<float>(output->data.uint8[0]) / 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::detect_wake_word_() {
|
||||||
|
// Preprocess the newest audio samples into features
|
||||||
|
if (!this->update_features_()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform inference
|
||||||
|
uint32_t streaming_size = micros();
|
||||||
|
float streaming_prob = this->perform_streaming_inference_();
|
||||||
|
|
||||||
|
// Add the most recent probability to the sliding window
|
||||||
|
this->recent_streaming_probabilities_[this->last_n_index_] = streaming_prob;
|
||||||
|
++this->last_n_index_;
|
||||||
|
if (this->last_n_index_ == this->sliding_window_average_size_)
|
||||||
|
this->last_n_index_ = 0;
|
||||||
|
|
||||||
|
float sum = 0.0;
|
||||||
|
for (auto &prob : this->recent_streaming_probabilities_) {
|
||||||
|
sum += prob;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sliding_window_average = sum / static_cast<float>(this->sliding_window_average_size_);
|
||||||
|
|
||||||
|
// Ensure we have enough samples since the last positive detection
|
||||||
|
this->ignore_windows_ = std::min(this->ignore_windows_ + 1, 0);
|
||||||
|
if (this->ignore_windows_ < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect the wake word if the sliding window average is above the cutoff
|
||||||
|
if (sliding_window_average > this->probability_cutoff_) {
|
||||||
|
this->ignore_windows_ = -MIN_SLICES_BEFORE_DETECTION;
|
||||||
|
for (auto &prob : this->recent_streaming_probabilities_) {
|
||||||
|
prob = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroWakeWord::set_sliding_window_average_size(size_t size) {
|
||||||
|
this->sliding_window_average_size_ = size;
|
||||||
|
this->recent_streaming_probabilities_.resize(this->sliding_window_average_size_, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::slice_available_() {
|
||||||
|
size_t available = this->ring_buffer_->available();
|
||||||
|
|
||||||
|
size_t free = this->ring_buffer_->free();
|
||||||
|
|
||||||
|
if (free < NEW_SAMPLES_TO_GET * sizeof(int16_t)) {
|
||||||
|
// If the ring buffer is within one audio slice of being full, then wake word detection will have issues.
|
||||||
|
// If this is constantly occuring, then some possibilities why are
|
||||||
|
// 1) there are too many other slow components configured
|
||||||
|
// 2) the ESP32 isn't fast enough; e.g., an ESP32 is much slower than an ESP32-S3 at inferences.
|
||||||
|
// 3) the model is too large
|
||||||
|
// 4) the model uses operations that are not optimized
|
||||||
|
ESP_LOGW(TAG,
|
||||||
|
"Audio buffer is nearly full. Wake word detection may be less accurate and have slower reponse times. "
|
||||||
|
#if !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
|
"microWakeWord is designed for the ESP32-S3. The current platform is too slow for this model."
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return available > (NEW_SAMPLES_TO_GET * sizeof(int16_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::stride_audio_samples_(int16_t **audio_samples) {
|
||||||
|
if (!this->slice_available_()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy 320 bytes (160 samples over 10 ms) into preprocessor_audio_buffer_ from history in
|
||||||
|
// preprocessor_stride_buffer_
|
||||||
|
memcpy((void *) (this->preprocessor_audio_buffer_), (void *) (this->preprocessor_stride_buffer_),
|
||||||
|
HISTORY_SAMPLES_TO_KEEP * sizeof(int16_t));
|
||||||
|
|
||||||
|
// Copy 640 bytes (320 samples over 20 ms) from the ring buffer
|
||||||
|
// The first 320 bytes (160 samples over 10 ms) will be from history
|
||||||
|
size_t bytes_read = this->ring_buffer_->read((void *) (this->preprocessor_audio_buffer_ + HISTORY_SAMPLES_TO_KEEP),
|
||||||
|
NEW_SAMPLES_TO_GET * sizeof(int16_t), pdMS_TO_TICKS(200));
|
||||||
|
|
||||||
|
if (bytes_read == 0) {
|
||||||
|
ESP_LOGE(TAG, "Could not read data from Ring Buffer");
|
||||||
|
} else if (bytes_read < NEW_SAMPLES_TO_GET * sizeof(int16_t)) {
|
||||||
|
ESP_LOGD(TAG, "Partial Read of Data by Model");
|
||||||
|
ESP_LOGD(TAG, "Could only read %d bytes when required %d bytes ", bytes_read,
|
||||||
|
(int) (NEW_SAMPLES_TO_GET * sizeof(int16_t)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the last 320 bytes (160 samples over 10 ms) from the audio buffer into history stride buffer for the next
|
||||||
|
// iteration
|
||||||
|
memcpy((void *) (this->preprocessor_stride_buffer_), (void *) (this->preprocessor_audio_buffer_ + NEW_SAMPLES_TO_GET),
|
||||||
|
HISTORY_SAMPLES_TO_KEEP * sizeof(int16_t));
|
||||||
|
|
||||||
|
*audio_samples = this->preprocessor_audio_buffer_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::generate_single_feature_(const int16_t *audio_data, const int audio_data_size,
|
||||||
|
int8_t feature_output[PREPROCESSOR_FEATURE_SIZE]) {
|
||||||
|
TfLiteTensor *input = this->preprocessor_interperter_->input(0);
|
||||||
|
TfLiteTensor *output = this->preprocessor_interperter_->output(0);
|
||||||
|
std::copy_n(audio_data, audio_data_size, tflite::GetTensorData<int16_t>(input));
|
||||||
|
|
||||||
|
if (this->preprocessor_interperter_->Invoke() != kTfLiteOk) {
|
||||||
|
ESP_LOGE(TAG, "Failed to preprocess audio for local wake word.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::memcpy(feature_output, tflite::GetTensorData<int8_t>(output), PREPROCESSOR_FEATURE_SIZE * sizeof(int8_t));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::register_preprocessor_ops_(tflite::MicroMutableOpResolver<18> &op_resolver) {
|
||||||
|
if (op_resolver.AddReshape() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddCast() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddStridedSlice() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddConcatenation() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddMul() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddAdd() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddDiv() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddMinimum() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddMaximum() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddWindow() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddFftAutoScale() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddRfft() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddEnergy() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddFilterBank() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddFilterBankSquareRoot() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddFilterBankSpectralSubtraction() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddPCAN() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddFilterBankLog() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MicroWakeWord::register_streaming_ops_(tflite::MicroMutableOpResolver<14> &op_resolver) {
|
||||||
|
if (op_resolver.AddCallOnce() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddVarHandle() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddReshape() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddReadVariable() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddStridedSlice() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddConcatenation() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddAssignVariable() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddConv2D() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddMul() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddAdd() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddMean() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddFullyConnected() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddLogistic() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
if (op_resolver.AddQuantize() != kTfLiteOk)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace micro_wake_word
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_ESP_IDF
|
||||||
|
|
||||||
|
#endif // CLANG_TIDY
|
207
esphome/components/micro_wake_word/micro_wake_word.h
Normal file
207
esphome/components/micro_wake_word/micro_wake_word.h
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a workaround until we can figure out a way to get
|
||||||
|
* the tflite-micro idf component code available in CI
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
//
|
||||||
|
#ifndef CLANG_TIDY
|
||||||
|
|
||||||
|
#ifdef USE_ESP_IDF
|
||||||
|
|
||||||
|
#include "esphome/core/automation.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/ring_buffer.h"
|
||||||
|
|
||||||
|
#include "esphome/components/microphone/microphone.h"
|
||||||
|
|
||||||
|
#include <tensorflow/lite/core/c/common.h>
|
||||||
|
#include <tensorflow/lite/micro/micro_interpreter.h>
|
||||||
|
#include <tensorflow/lite/micro/micro_mutable_op_resolver.h>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace micro_wake_word {
|
||||||
|
|
||||||
|
// The following are dictated by the preprocessor model
|
||||||
|
//
|
||||||
|
// The number of features the audio preprocessor generates per slice
|
||||||
|
static const uint8_t PREPROCESSOR_FEATURE_SIZE = 40;
|
||||||
|
// How frequently the preprocessor generates a new set of features
|
||||||
|
static const uint8_t FEATURE_STRIDE_MS = 20;
|
||||||
|
// Duration of each slice used as input into the preprocessor
|
||||||
|
static const uint8_t FEATURE_DURATION_MS = 30;
|
||||||
|
// Audio sample frequency in hertz
|
||||||
|
static const uint16_t AUDIO_SAMPLE_FREQUENCY = 16000;
|
||||||
|
// The number of old audio samples that are saved to be part of the next feature window
|
||||||
|
static const uint16_t HISTORY_SAMPLES_TO_KEEP =
|
||||||
|
((FEATURE_DURATION_MS - FEATURE_STRIDE_MS) * (AUDIO_SAMPLE_FREQUENCY / 1000));
|
||||||
|
// The number of new audio samples to receive to be included with the next feature window
|
||||||
|
static const uint16_t NEW_SAMPLES_TO_GET = (FEATURE_STRIDE_MS * (AUDIO_SAMPLE_FREQUENCY / 1000));
|
||||||
|
// The total number of audio samples included in the feature window
|
||||||
|
static const uint16_t SAMPLE_DURATION_COUNT = FEATURE_DURATION_MS * AUDIO_SAMPLE_FREQUENCY / 1000;
|
||||||
|
// Number of bytes in memory needed for the preprocessor arena
|
||||||
|
static const uint32_t PREPROCESSOR_ARENA_SIZE = 9528;
|
||||||
|
|
||||||
|
// The following configure the streaming wake word model
|
||||||
|
//
|
||||||
|
// The number of audio slices to process before accepting a positive detection
|
||||||
|
static const uint8_t MIN_SLICES_BEFORE_DETECTION = 74;
|
||||||
|
|
||||||
|
// Number of bytes in memory needed for the streaming wake word model
|
||||||
|
static const uint32_t STREAMING_MODEL_ARENA_SIZE = 64000;
|
||||||
|
static const uint32_t STREAMING_MODEL_VARIABLE_ARENA_SIZE = 1024;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
IDLE,
|
||||||
|
START_MICROPHONE,
|
||||||
|
STARTING_MICROPHONE,
|
||||||
|
DETECTING_WAKE_WORD,
|
||||||
|
STOP_MICROPHONE,
|
||||||
|
STOPPING_MICROPHONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MicroWakeWord : public Component {
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void loop() override;
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
bool is_running() const { return this->state_ != State::IDLE; }
|
||||||
|
|
||||||
|
bool initialize_models();
|
||||||
|
|
||||||
|
std::string get_wake_word() { return this->wake_word_; }
|
||||||
|
|
||||||
|
// Increasing either of these will reduce the rate of false acceptances while increasing the false rejection rate
|
||||||
|
void set_probability_cutoff(float probability_cutoff) { this->probability_cutoff_ = probability_cutoff; }
|
||||||
|
void set_sliding_window_average_size(size_t size);
|
||||||
|
|
||||||
|
void set_microphone(microphone::Microphone *microphone) { this->microphone_ = microphone; }
|
||||||
|
|
||||||
|
Trigger<std::string> *get_wake_word_detected_trigger() const { return this->wake_word_detected_trigger_; }
|
||||||
|
|
||||||
|
void set_model_start(const uint8_t *model_start) { this->model_start_ = model_start; }
|
||||||
|
void set_wake_word(const std::string &wake_word) { this->wake_word_ = wake_word; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void set_state_(State state);
|
||||||
|
int read_microphone_();
|
||||||
|
|
||||||
|
const uint8_t *model_start_;
|
||||||
|
std::string wake_word_;
|
||||||
|
|
||||||
|
microphone::Microphone *microphone_{nullptr};
|
||||||
|
Trigger<std::string> *wake_word_detected_trigger_ = new Trigger<std::string>();
|
||||||
|
State state_{State::IDLE};
|
||||||
|
HighFrequencyLoopRequester high_freq_;
|
||||||
|
|
||||||
|
std::unique_ptr<RingBuffer> ring_buffer_;
|
||||||
|
|
||||||
|
int16_t *input_buffer_;
|
||||||
|
|
||||||
|
const tflite::Model *preprocessor_model_{nullptr};
|
||||||
|
const tflite::Model *streaming_model_{nullptr};
|
||||||
|
tflite::MicroInterpreter *streaming_interpreter_{nullptr};
|
||||||
|
tflite::MicroInterpreter *preprocessor_interperter_{nullptr};
|
||||||
|
|
||||||
|
std::vector<float> recent_streaming_probabilities_;
|
||||||
|
size_t last_n_index_{0};
|
||||||
|
|
||||||
|
float probability_cutoff_{0.5};
|
||||||
|
size_t sliding_window_average_size_{10};
|
||||||
|
|
||||||
|
// When the wake word detection first starts or after the word has been detected once, we ignore this many audio
|
||||||
|
// feature slices before accepting a positive detection again
|
||||||
|
int16_t ignore_windows_{-MIN_SLICES_BEFORE_DETECTION};
|
||||||
|
|
||||||
|
uint8_t *streaming_var_arena_{nullptr};
|
||||||
|
uint8_t *streaming_tensor_arena_{nullptr};
|
||||||
|
uint8_t *preprocessor_tensor_arena_{nullptr};
|
||||||
|
int8_t *new_features_data_{nullptr};
|
||||||
|
|
||||||
|
tflite::MicroResourceVariables *mrv_{nullptr};
|
||||||
|
|
||||||
|
// Stores audio fed into feature generator preprocessor
|
||||||
|
int16_t *preprocessor_audio_buffer_;
|
||||||
|
int16_t *preprocessor_stride_buffer_;
|
||||||
|
|
||||||
|
bool detected_{false};
|
||||||
|
|
||||||
|
/** Detects if wake word has been said
|
||||||
|
*
|
||||||
|
* If enough audio samples are available, it will generate one slice of new features.
|
||||||
|
* If the streaming model predicts the wake word, then the nonstreaming model confirms it.
|
||||||
|
* @param ring_Buffer Ring buffer containing raw audio samples
|
||||||
|
* @return True if the wake word is detected, false otherwise
|
||||||
|
*/
|
||||||
|
bool detect_wake_word_();
|
||||||
|
|
||||||
|
/// @brief Returns true if there are enough audio samples in the buffer to generate another slice of features
|
||||||
|
bool slice_available_();
|
||||||
|
|
||||||
|
/** Shifts previous feature slices over by one and generates a new slice of features
|
||||||
|
*
|
||||||
|
* @param ring_buffer ring buffer containing raw audio samples
|
||||||
|
* @return True if a new slice of features was generated, false otherwise
|
||||||
|
*/
|
||||||
|
bool update_features_();
|
||||||
|
|
||||||
|
/** Generates features from audio samples
|
||||||
|
*
|
||||||
|
* Adapted from TFLite micro speech example
|
||||||
|
* @param audio_data Pointer to array with the audio samples
|
||||||
|
* @param audio_data_size The number of samples to use as input to the preprocessor model
|
||||||
|
* @param feature_output Array that will store the features
|
||||||
|
* @return True if successful, false otherwise.
|
||||||
|
*/
|
||||||
|
bool generate_single_feature_(const int16_t *audio_data, int audio_data_size,
|
||||||
|
int8_t feature_output[PREPROCESSOR_FEATURE_SIZE]);
|
||||||
|
|
||||||
|
/** Performs inference over the most recent feature slice with the streaming model
|
||||||
|
*
|
||||||
|
* @return Probability of the wake word between 0.0 and 1.0
|
||||||
|
*/
|
||||||
|
float perform_streaming_inference_();
|
||||||
|
|
||||||
|
/** Strides the audio samples by keeping the last 10 ms of the previous slice
|
||||||
|
*
|
||||||
|
* Adapted from the TFLite micro speech example
|
||||||
|
* @param ring_buffer Ring buffer containing raw audio samples
|
||||||
|
* @param audio_samples Pointer to an array that will store the strided audio samples
|
||||||
|
* @return True if successful, false otherwise
|
||||||
|
*/
|
||||||
|
bool stride_audio_samples_(int16_t **audio_samples);
|
||||||
|
|
||||||
|
/// @brief Returns true if successfully registered the preprocessor's TensorFlow operations
|
||||||
|
bool register_preprocessor_ops_(tflite::MicroMutableOpResolver<18> &op_resolver);
|
||||||
|
|
||||||
|
/// @brief Returns true if successfully registered the streaming model's TensorFlow operations
|
||||||
|
bool register_streaming_ops_(tflite::MicroMutableOpResolver<14> &op_resolver);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class StartAction : public Action<Ts...>, public Parented<MicroWakeWord> {
|
||||||
|
public:
|
||||||
|
void play(Ts... x) override { this->parent_->start(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class StopAction : public Action<Ts...>, public Parented<MicroWakeWord> {
|
||||||
|
public:
|
||||||
|
void play(Ts... x) override { this->parent_->stop(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class IsRunningCondition : public Condition<Ts...>, public Parented<MicroWakeWord> {
|
||||||
|
public:
|
||||||
|
bool check(Ts... x) override { return this->parent_->is_running(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace micro_wake_word
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_ESP_IDF
|
||||||
|
|
||||||
|
#endif // CLANG_TIDY
|
|
@ -62,6 +62,7 @@ from esphome.const import (
|
||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_FLOW_RATE,
|
||||||
DEVICE_CLASS_VOLUME_STORAGE,
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
|
@ -117,6 +118,7 @@ DEVICE_CLASSES = [
|
||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_FLOW_RATE,
|
||||||
DEVICE_CLASS_VOLUME_STORAGE,
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
|
|
|
@ -14,7 +14,7 @@ static const uint8_t NBITS_ADDRESS = 16;
|
||||||
static const uint8_t NBITS_CHANNEL = 5;
|
static const uint8_t NBITS_CHANNEL = 5;
|
||||||
static const uint8_t NBITS_COMMAND = 7;
|
static const uint8_t NBITS_COMMAND = 7;
|
||||||
static const uint8_t NDATABITS = NBITS_ADDRESS + NBITS_CHANNEL + NBITS_COMMAND;
|
static const uint8_t NDATABITS = NBITS_ADDRESS + NBITS_CHANNEL + NBITS_COMMAND;
|
||||||
static const uint8_t MIN_RX_SRC = (NDATABITS * 2 + NBITS_SYNC / 2);
|
static const uint8_t MIN_RX_SRC = (NDATABITS + NBITS_SYNC / 2);
|
||||||
|
|
||||||
static const uint8_t CMD_ON = 0x41;
|
static const uint8_t CMD_ON = 0x41;
|
||||||
static const uint8_t CMD_OFF = 0x02;
|
static const uint8_t CMD_OFF = 0x02;
|
||||||
|
@ -135,7 +135,7 @@ optional<DraytonData> DraytonProtocol::decode(RemoteReceiveData src) {
|
||||||
.command = 0,
|
.command = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
while (src.size() - src.get_index() > MIN_RX_SRC) {
|
while (src.size() - src.get_index() >= MIN_RX_SRC) {
|
||||||
ESP_LOGVV(TAG,
|
ESP_LOGVV(TAG,
|
||||||
"Decode Drayton: %" PRId32 ", %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
"Decode Drayton: %" PRId32 ", %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
||||||
" %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
" %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
||||||
|
@ -150,7 +150,7 @@ optional<DraytonData> DraytonProtocol::decode(RemoteReceiveData src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for sync pulse, after. If sucessful index points to space of sync symbol
|
// Look for sync pulse, after. If sucessful index points to space of sync symbol
|
||||||
while (src.size() - src.get_index() >= NDATABITS) {
|
while (src.size() - src.get_index() >= MIN_RX_SRC) {
|
||||||
ESP_LOGVV(TAG, "Decode Drayton: sync search %d, %" PRId32 " %" PRId32, src.size() - src.get_index(), src.peek(),
|
ESP_LOGVV(TAG, "Decode Drayton: sync search %d, %" PRId32 " %" PRId32, src.size() - src.get_index(), src.peek(),
|
||||||
src.peek(1));
|
src.peek(1));
|
||||||
if (src.peek_mark(2 * BIT_TIME_US) &&
|
if (src.peek_mark(2 * BIT_TIME_US) &&
|
||||||
|
|
|
@ -82,6 +82,7 @@ from esphome.const import (
|
||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_FLOW_RATE,
|
||||||
DEVICE_CLASS_VOLUME_STORAGE,
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
|
@ -141,6 +142,7 @@ DEVICE_CLASSES = [
|
||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_FLOW_RATE,
|
||||||
DEVICE_CLASS_VOLUME_STORAGE,
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
|
|
|
@ -29,7 +29,8 @@ from esphome.const import (
|
||||||
from esphome.core import HexInt, CORE
|
from esphome.core import HexInt, CORE
|
||||||
|
|
||||||
DOMAIN = "shelly_dimmer"
|
DOMAIN = "shelly_dimmer"
|
||||||
DEPENDENCIES = ["sensor", "uart", "esp8266"]
|
AUTO_LOAD = ["sensor"]
|
||||||
|
DEPENDENCIES = ["uart", "esp8266"]
|
||||||
|
|
||||||
shelly_dimmer_ns = cg.esphome_ns.namespace("shelly_dimmer")
|
shelly_dimmer_ns = cg.esphome_ns.namespace("shelly_dimmer")
|
||||||
ShellyDimmer = shelly_dimmer_ns.class_(
|
ShellyDimmer = shelly_dimmer_ns.class_(
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace sntp {
|
||||||
static const char *const TAG = "sntp";
|
static const char *const TAG = "sntp";
|
||||||
|
|
||||||
void SNTPComponent::setup() {
|
void SNTPComponent::setup() {
|
||||||
|
#ifndef USE_HOST
|
||||||
ESP_LOGCONFIG(TAG, "Setting up SNTP...");
|
ESP_LOGCONFIG(TAG, "Setting up SNTP...");
|
||||||
#if defined(USE_ESP32) || defined(USE_LIBRETINY)
|
#if defined(USE_ESP32) || defined(USE_LIBRETINY)
|
||||||
if (sntp_enabled()) {
|
if (sntp_enabled()) {
|
||||||
|
@ -48,6 +49,7 @@ void SNTPComponent::setup() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sntp_init();
|
sntp_init();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void SNTPComponent::dump_config() {
|
void SNTPComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "SNTP Time:");
|
ESP_LOGCONFIG(TAG, "SNTP Time:");
|
||||||
|
@ -57,7 +59,7 @@ void SNTPComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, " Timezone: '%s'", this->timezone_.c_str());
|
ESP_LOGCONFIG(TAG, " Timezone: '%s'", this->timezone_.c_str());
|
||||||
}
|
}
|
||||||
void SNTPComponent::update() {
|
void SNTPComponent::update() {
|
||||||
#ifndef USE_ESP_IDF
|
#if !defined(USE_ESP_IDF) && !defined(USE_HOST)
|
||||||
// force resync
|
// force resync
|
||||||
if (sntp_enabled()) {
|
if (sntp_enabled()) {
|
||||||
sntp_stop();
|
sntp_stop();
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Filter {
|
||||||
* @param value The new value.
|
* @param value The new value.
|
||||||
* @return An optional string, the new value that should be pushed out.
|
* @return An optional string, the new value that should be pushed out.
|
||||||
*/
|
*/
|
||||||
virtual optional<std::string> new_value(std::string value);
|
virtual optional<std::string> new_value(std::string value) = 0;
|
||||||
|
|
||||||
/// Initialize this filter, please note this can be called more than once.
|
/// Initialize this filter, please note this can be called more than once.
|
||||||
virtual void initialize(TextSensor *parent, Filter *next);
|
virtual void initialize(TextSensor *parent, Filter *next);
|
||||||
|
|
|
@ -8,6 +8,8 @@ wled_ns = cg.esphome_ns.namespace("wled")
|
||||||
WLEDLightEffect = wled_ns.class_("WLEDLightEffect", AddressableLightEffect)
|
WLEDLightEffect = wled_ns.class_("WLEDLightEffect", AddressableLightEffect)
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(cv.Schema({}), cv.only_with_arduino)
|
CONFIG_SCHEMA = cv.All(cv.Schema({}), cv.only_with_arduino)
|
||||||
|
CONF_SYNC_GROUP_MASK = "sync_group_mask"
|
||||||
|
CONF_BLANK_ON_START = "blank_on_start"
|
||||||
|
|
||||||
|
|
||||||
@register_addressable_effect(
|
@register_addressable_effect(
|
||||||
|
@ -16,10 +18,13 @@ CONFIG_SCHEMA = cv.All(cv.Schema({}), cv.only_with_arduino)
|
||||||
"WLED",
|
"WLED",
|
||||||
{
|
{
|
||||||
cv.Optional(CONF_PORT, default=21324): cv.port,
|
cv.Optional(CONF_PORT, default=21324): cv.port,
|
||||||
|
cv.Optional(CONF_SYNC_GROUP_MASK, default=0): cv.int_range(min=0, max=255),
|
||||||
|
cv.Optional(CONF_BLANK_ON_START, default=True): cv.boolean,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
async def wled_light_effect_to_code(config, effect_id):
|
async def wled_light_effect_to_code(config, effect_id):
|
||||||
effect = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
effect = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||||
cg.add(effect.set_port(config[CONF_PORT]))
|
cg.add(effect.set_port(config[CONF_PORT]))
|
||||||
|
cg.add(effect.set_sync_group_mask(config[CONF_SYNC_GROUP_MASK]))
|
||||||
|
cg.add(effect.set_blank_on_start(config[CONF_BLANK_ON_START]))
|
||||||
return effect
|
return effect
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
#include <WiFiUdp.h>
|
#include <WiFiUdp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BK72XX
|
||||||
|
#include <WiFiUdp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace wled {
|
namespace wled {
|
||||||
|
|
||||||
|
@ -29,7 +33,11 @@ WLEDLightEffect::WLEDLightEffect(const std::string &name) : AddressableLightEffe
|
||||||
void WLEDLightEffect::start() {
|
void WLEDLightEffect::start() {
|
||||||
AddressableLightEffect::start();
|
AddressableLightEffect::start();
|
||||||
|
|
||||||
blank_at_ = 0;
|
if (this->blank_on_start_) {
|
||||||
|
this->blank_at_ = 0;
|
||||||
|
} else {
|
||||||
|
this->blank_at_ = UINT32_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WLEDLightEffect::stop() {
|
void WLEDLightEffect::stop() {
|
||||||
|
@ -101,8 +109,11 @@ bool WLEDLightEffect::parse_frame_(light::AddressableLight &it, const uint8_t *p
|
||||||
if (!parse_drgb_frame_(it, payload, size))
|
if (!parse_drgb_frame_(it, payload, size))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (!parse_notifier_frame_(it, payload, size))
|
if (!parse_notifier_frame_(it, payload, size)) {
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
timeout = UINT8_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -143,8 +154,32 @@ bool WLEDLightEffect::parse_frame_(light::AddressableLight &it, const uint8_t *p
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WLEDLightEffect::parse_notifier_frame_(light::AddressableLight &it, const uint8_t *payload, uint16_t size) {
|
bool WLEDLightEffect::parse_notifier_frame_(light::AddressableLight &it, const uint8_t *payload, uint16_t size) {
|
||||||
// Packet needs to be empty
|
// Receive at least RGBW and Brightness for all LEDs from WLED Sync Notification
|
||||||
return size == 0;
|
// https://kno.wled.ge/interfaces/udp-notifier/
|
||||||
|
// https://github.com/Aircoookie/WLED/blob/main/wled00/udp.cpp
|
||||||
|
|
||||||
|
if (size < 34) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t payload_sync_group_mask = payload[34];
|
||||||
|
|
||||||
|
if (this->sync_group_mask_ && !(payload_sync_group_mask & this->sync_group_mask_)) {
|
||||||
|
ESP_LOGD(TAG, "sync group mask does not match");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bri = payload[0];
|
||||||
|
uint8_t r = esp_scale8(payload[1], bri);
|
||||||
|
uint8_t g = esp_scale8(payload[2], bri);
|
||||||
|
uint8_t b = esp_scale8(payload[3], bri);
|
||||||
|
uint8_t w = esp_scale8(payload[8], bri);
|
||||||
|
|
||||||
|
for (auto &&led : it) {
|
||||||
|
led.set(Color(r, g, b, w));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WLEDLightEffect::parse_warls_frame_(light::AddressableLight &it, const uint8_t *payload, uint16_t size) {
|
bool WLEDLightEffect::parse_warls_frame_(light::AddressableLight &it, const uint8_t *payload, uint16_t size) {
|
||||||
|
|
|
@ -21,6 +21,8 @@ class WLEDLightEffect : public light::AddressableLightEffect {
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void apply(light::AddressableLight &it, const Color ¤t_color) override;
|
void apply(light::AddressableLight &it, const Color ¤t_color) override;
|
||||||
void set_port(uint16_t port) { this->port_ = port; }
|
void set_port(uint16_t port) { this->port_ = port; }
|
||||||
|
void set_sync_group_mask(uint8_t mask) { this->sync_group_mask_ = mask; }
|
||||||
|
void set_blank_on_start(bool blank) { this->blank_on_start_ = blank; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void blank_all_leds_(light::AddressableLight &it);
|
void blank_all_leds_(light::AddressableLight &it);
|
||||||
|
@ -35,6 +37,8 @@ class WLEDLightEffect : public light::AddressableLightEffect {
|
||||||
std::unique_ptr<UDP> udp_;
|
std::unique_ptr<UDP> udp_;
|
||||||
uint32_t blank_at_{0};
|
uint32_t blank_at_{0};
|
||||||
uint32_t dropped_{0};
|
uint32_t dropped_{0};
|
||||||
|
uint8_t sync_group_mask_{0};
|
||||||
|
bool blank_on_start_{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wled
|
} // namespace wled
|
||||||
|
|
|
@ -57,6 +57,7 @@ from esphome.const import (
|
||||||
TYPE_GIT,
|
TYPE_GIT,
|
||||||
TYPE_LOCAL,
|
TYPE_LOCAL,
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS,
|
VALID_SUBSTITUTIONS_CHARACTERS,
|
||||||
|
__version__ as ESPHOME_VERSION,
|
||||||
)
|
)
|
||||||
from esphome.core import (
|
from esphome.core import (
|
||||||
CORE,
|
CORE,
|
||||||
|
@ -1895,6 +1896,16 @@ def version_number(value):
|
||||||
raise Invalid("Not a valid version number") from e
|
raise Invalid("Not a valid version number") from e
|
||||||
|
|
||||||
|
|
||||||
|
def validate_esphome_version(value: str):
|
||||||
|
min_version = Version.parse(value)
|
||||||
|
current_version = Version.parse(ESPHOME_VERSION)
|
||||||
|
if current_version < min_version:
|
||||||
|
raise Invalid(
|
||||||
|
f"Your ESPHome version is too old. Please update to at least {min_version}"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def platformio_version_constraint(value):
|
def platformio_version_constraint(value):
|
||||||
# for documentation on valid version constraints:
|
# for documentation on valid version constraints:
|
||||||
# https://docs.platformio.org/en/latest/core/userguide/platforms/cmd_install.html#cmd-platform-install
|
# https://docs.platformio.org/en/latest/core/userguide/platforms/cmd_install.html#cmd-platform-install
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2024.1.0-dev"
|
__version__ = "2024.3.0-dev"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||||
|
@ -1082,6 +1082,7 @@ DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
|
||||||
DEVICE_CLASS_VOLTAGE = "voltage"
|
DEVICE_CLASS_VOLTAGE = "voltage"
|
||||||
DEVICE_CLASS_VOLUME = "volume"
|
DEVICE_CLASS_VOLUME = "volume"
|
||||||
|
DEVICE_CLASS_VOLUME_FLOW_RATE = "volume_flow_rate"
|
||||||
DEVICE_CLASS_VOLUME_STORAGE = "volume_storage"
|
DEVICE_CLASS_VOLUME_STORAGE = "volume_storage"
|
||||||
DEVICE_CLASS_WATER = "water"
|
DEVICE_CLASS_WATER = "water"
|
||||||
DEVICE_CLASS_WEIGHT = "weight"
|
DEVICE_CLASS_WEIGHT = "weight"
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "esphome/core/optional.h"
|
#include "esphome/core/optional.h"
|
||||||
|
|
||||||
|
|
|
@ -102,16 +102,6 @@ def valid_project_name(value: str):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def validate_version(value: str):
|
|
||||||
min_version = cv.Version.parse(value)
|
|
||||||
current_version = cv.Version.parse(ESPHOME_VERSION)
|
|
||||||
if current_version < min_version:
|
|
||||||
raise cv.Invalid(
|
|
||||||
f"Your ESPHome version is too old. Please update to at least {min_version}"
|
|
||||||
)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
|
if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
|
||||||
_compile_process_limit_default = min(
|
_compile_process_limit_default = min(
|
||||||
int(os.environ["ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT"]),
|
int(os.environ["ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT"]),
|
||||||
|
@ -164,7 +154,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
|
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
|
||||||
cv.version_number, validate_version
|
cv.version_number, cv.validate_esphome_version
|
||||||
),
|
),
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default
|
CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#ifdef USE_HOST
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
#if defined(USE_ESP8266)
|
#if defined(USE_ESP8266)
|
||||||
#include <osapi.h>
|
#include <osapi.h>
|
||||||
#include <user_interface.h>
|
#include <user_interface.h>
|
||||||
|
@ -415,7 +421,7 @@ std::string value_accuracy_to_string(float value, int8_t accuracy_decimals) {
|
||||||
int8_t step_to_accuracy_decimals(float step) {
|
int8_t step_to_accuracy_decimals(float step) {
|
||||||
// use printf %g to find number of digits based on temperature step
|
// use printf %g to find number of digits based on temperature step
|
||||||
char buf[32];
|
char buf[32];
|
||||||
sprintf(buf, "%.5g", step);
|
snprintf(buf, sizeof buf, "%.5g", step);
|
||||||
|
|
||||||
std::string str{buf};
|
std::string str{buf};
|
||||||
size_t dot_pos = str.find('.');
|
size_t dot_pos = str.find('.');
|
||||||
|
@ -551,7 +557,10 @@ void HighFrequencyLoopRequester::stop() {
|
||||||
bool HighFrequencyLoopRequester::is_high_frequency() { return num_requests > 0; }
|
bool HighFrequencyLoopRequester::is_high_frequency() { return num_requests > 0; }
|
||||||
|
|
||||||
void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
|
void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
|
||||||
#if defined(USE_ESP32)
|
#if defined(USE_HOST)
|
||||||
|
static const uint8_t esphome_host_mac_address[6] = USE_ESPHOME_HOST_MAC_ADDRESS;
|
||||||
|
memcpy(mac, esphome_host_mac_address, sizeof(esphome_host_mac_address));
|
||||||
|
#elif defined(USE_ESP32)
|
||||||
#if defined(CONFIG_SOC_IEEE802154_SUPPORTED) || defined(USE_ESP32_IGNORE_EFUSE_MAC_CRC)
|
#if defined(CONFIG_SOC_IEEE802154_SUPPORTED) || defined(USE_ESP32_IGNORE_EFUSE_MAC_CRC)
|
||||||
// When CONFIG_SOC_IEEE802154_SUPPORTED is defined, esp_efuse_mac_get_default
|
// When CONFIG_SOC_IEEE802154_SUPPORTED is defined, esp_efuse_mac_get_default
|
||||||
// returns the 802.15.4 EUI-64 address. Read directly from eFuse instead.
|
// returns the 802.15.4 EUI-64 address. Read directly from eFuse instead.
|
||||||
|
@ -569,6 +578,8 @@ void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parame
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
#elif defined(USE_LIBRETINY)
|
#elif defined(USE_LIBRETINY)
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
|
#else
|
||||||
|
// this should be an error, but that messes with CI checks. #error No mac address method defined
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
std::string get_mac_address() {
|
std::string get_mac_address() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -478,7 +478,7 @@ def variable(
|
||||||
: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).
|
||||||
|
|
||||||
:returns The new variable as a MockObj.
|
:return: The new variable as a MockObj.
|
||||||
"""
|
"""
|
||||||
assert isinstance(id_, ID)
|
assert isinstance(id_, ID)
|
||||||
rhs = safe_exp(rhs)
|
rhs = safe_exp(rhs)
|
||||||
|
@ -526,7 +526,7 @@ def new_variable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj
|
||||||
: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).
|
||||||
|
|
||||||
:returns The new variable as a MockObj.
|
:return: The new variable as a MockObj.
|
||||||
"""
|
"""
|
||||||
assert isinstance(id_, ID)
|
assert isinstance(id_, ID)
|
||||||
rhs = safe_exp(rhs)
|
rhs = safe_exp(rhs)
|
||||||
|
@ -549,7 +549,7 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
||||||
: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).
|
||||||
|
|
||||||
:returns The new variable as a MockObj.
|
:return: The new variable as a MockObj.
|
||||||
"""
|
"""
|
||||||
rhs = safe_exp(rhs)
|
rhs = safe_exp(rhs)
|
||||||
obj = MockObj(id_, "->")
|
obj = MockObj(id_, "->")
|
||||||
|
@ -570,7 +570,7 @@ def new_Pvariable(id_: ID, *args: SafeExpType) -> Pvariable:
|
||||||
:param id_: The ID used to declare the variable (also specifies the type).
|
:param id_: The ID used to declare the variable (also specifies the type).
|
||||||
:param args: The values to pass to the constructor.
|
:param args: The values to pass to the constructor.
|
||||||
|
|
||||||
:returns The new variable as a MockObj.
|
:return: The new variable as a MockObj.
|
||||||
"""
|
"""
|
||||||
if args and isinstance(args[0], TemplateArguments):
|
if args and isinstance(args[0], TemplateArguments):
|
||||||
id_ = id_.copy()
|
id_ = id_.copy()
|
||||||
|
|
|
@ -93,7 +93,7 @@ lib_deps =
|
||||||
ESP8266HTTPClient ; http_request (Arduino built-in)
|
ESP8266HTTPClient ; http_request (Arduino built-in)
|
||||||
ESP8266mDNS ; mdns (Arduino built-in)
|
ESP8266mDNS ; mdns (Arduino built-in)
|
||||||
DNSServer ; captive_portal (Arduino built-in)
|
DNSServer ; captive_portal (Arduino built-in)
|
||||||
crankyoldgit/IRremoteESP8266@2.7.12 ; heatpumpir
|
crankyoldgit/IRremoteESP8266@~2.8.4 ; heatpumpir
|
||||||
build_flags =
|
build_flags =
|
||||||
${common:arduino.build_flags}
|
${common:arduino.build_flags}
|
||||||
-Wno-nonnull-compare
|
-Wno-nonnull-compare
|
||||||
|
@ -122,7 +122,7 @@ lib_deps =
|
||||||
ESPmDNS ; mdns (Arduino built-in)
|
ESPmDNS ; mdns (Arduino built-in)
|
||||||
DNSServer ; captive_portal (Arduino built-in)
|
DNSServer ; captive_portal (Arduino built-in)
|
||||||
esphome/ESP32-audioI2S@2.0.7 ; i2s_audio
|
esphome/ESP32-audioI2S@2.0.7 ; i2s_audio
|
||||||
crankyoldgit/IRremoteESP8266@2.7.12 ; heatpumpir
|
crankyoldgit/IRremoteESP8266@~2.8.4 ; heatpumpir
|
||||||
droscy/esp_wireguard@0.3.2 ; wireguard
|
droscy/esp_wireguard@0.3.2 ; wireguard
|
||||||
build_flags =
|
build_flags =
|
||||||
${common:arduino.build_flags}
|
${common:arduino.build_flags}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
async_timeout==4.0.3; python_version <= "3.10"
|
async_timeout==4.0.3; python_version <= "3.10"
|
||||||
|
cryptography==42.0.2
|
||||||
voluptuous==0.14.1
|
voluptuous==0.14.1
|
||||||
PyYAML==6.0.1
|
PyYAML==6.0.1
|
||||||
paho-mqtt==1.6.1
|
paho-mqtt==1.6.1
|
||||||
|
@ -12,7 +13,7 @@ platformio==6.1.13 # When updating platformio, also update Dockerfile
|
||||||
esptool==4.7.0
|
esptool==4.7.0
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
esphome-dashboard==20231107.0
|
esphome-dashboard==20231107.0
|
||||||
aioesphomeapi==21.0.1
|
aioesphomeapi==21.0.2
|
||||||
zeroconf==0.131.0
|
zeroconf==0.131.0
|
||||||
python-magic==0.4.27
|
python-magic==0.4.27
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
pillow==10.2.0
|
pillow==10.2.0
|
||||||
cairosvg==2.7.1
|
cairosvg==2.7.1
|
||||||
cryptography==41.0.4
|
|
||||||
|
|
13
tests/components/a01nyub/test.esp32-c3-idf.yaml
Normal file
13
tests/components/a01nyub/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a01nyub
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a01nyub
|
||||||
|
id: a01nyub_sensor
|
||||||
|
name: a01nyub Distance
|
||||||
|
uart_id: uart_a01nyub
|
13
tests/components/a01nyub/test.esp32-c3.yaml
Normal file
13
tests/components/a01nyub/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a01nyub
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a01nyub
|
||||||
|
id: a01nyub_sensor
|
||||||
|
name: a01nyub Distance
|
||||||
|
uart_id: uart_a01nyub
|
13
tests/components/a01nyub/test.esp32-idf.yaml
Normal file
13
tests/components/a01nyub/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a01nyub
|
||||||
|
tx_pin:
|
||||||
|
number: 17
|
||||||
|
rx_pin:
|
||||||
|
number: 16
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a01nyub
|
||||||
|
id: a01nyub_sensor
|
||||||
|
name: a01nyub Distance
|
||||||
|
uart_id: uart_a01nyub
|
13
tests/components/a01nyub/test.esp32.yaml
Normal file
13
tests/components/a01nyub/test.esp32.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a01nyub
|
||||||
|
tx_pin:
|
||||||
|
number: 17
|
||||||
|
rx_pin:
|
||||||
|
number: 16
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a01nyub
|
||||||
|
id: a01nyub_sensor
|
||||||
|
name: a01nyub Distance
|
||||||
|
uart_id: uart_a01nyub
|
13
tests/components/a01nyub/test.esp8266.yaml
Normal file
13
tests/components/a01nyub/test.esp8266.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a01nyub
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a01nyub
|
||||||
|
id: a01nyub_sensor
|
||||||
|
name: a01nyub Distance
|
||||||
|
uart_id: uart_a01nyub
|
13
tests/components/a01nyub/test.rp2040.yaml
Normal file
13
tests/components/a01nyub/test.rp2040.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a01nyub
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a01nyub
|
||||||
|
id: a01nyub_sensor
|
||||||
|
name: a01nyub Distance
|
||||||
|
uart_id: uart_a01nyub
|
13
tests/components/a02yyuw/test.esp32-c3-idf.yaml
Normal file
13
tests/components/a02yyuw/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a02yyuw
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a02yyuw
|
||||||
|
id: a02yyuw_sensor
|
||||||
|
name: a02yyuw Distance
|
||||||
|
uart_id: uart_a02yyuw
|
13
tests/components/a02yyuw/test.esp32-c3.yaml
Normal file
13
tests/components/a02yyuw/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a02yyuw
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a02yyuw
|
||||||
|
id: a02yyuw_sensor
|
||||||
|
name: a02yyuw Distance
|
||||||
|
uart_id: uart_a02yyuw
|
13
tests/components/a02yyuw/test.esp32-idf.yaml
Normal file
13
tests/components/a02yyuw/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a02yyuw
|
||||||
|
tx_pin:
|
||||||
|
number: 17
|
||||||
|
rx_pin:
|
||||||
|
number: 16
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a02yyuw
|
||||||
|
id: a02yyuw_sensor
|
||||||
|
name: a02yyuw Distance
|
||||||
|
uart_id: uart_a02yyuw
|
13
tests/components/a02yyuw/test.esp32.yaml
Normal file
13
tests/components/a02yyuw/test.esp32.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a02yyuw
|
||||||
|
tx_pin:
|
||||||
|
number: 17
|
||||||
|
rx_pin:
|
||||||
|
number: 16
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a02yyuw
|
||||||
|
id: a02yyuw_sensor
|
||||||
|
name: a02yyuw Distance
|
||||||
|
uart_id: uart_a02yyuw
|
13
tests/components/a02yyuw/test.esp8266.yaml
Normal file
13
tests/components/a02yyuw/test.esp8266.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a02yyuw
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a02yyuw
|
||||||
|
id: a02yyuw_sensor
|
||||||
|
name: a02yyuw Distance
|
||||||
|
uart_id: uart_a02yyuw
|
13
tests/components/a02yyuw/test.rp2040.yaml
Normal file
13
tests/components/a02yyuw/test.rp2040.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
uart:
|
||||||
|
- id: uart_a02yyuw
|
||||||
|
tx_pin:
|
||||||
|
number: 4
|
||||||
|
rx_pin:
|
||||||
|
number: 5
|
||||||
|
baud_rate: 9600
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: a02yyuw
|
||||||
|
id: a02yyuw_sensor
|
||||||
|
name: a02yyuw Distance
|
||||||
|
uart_id: uart_a02yyuw
|
12
tests/components/a4988/test.esp32-c3-idf.yaml
Normal file
12
tests/components/a4988/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
stepper:
|
||||||
|
- platform: a4988
|
||||||
|
id: a4988_stepper
|
||||||
|
step_pin:
|
||||||
|
number: 2
|
||||||
|
dir_pin:
|
||||||
|
number: 3
|
||||||
|
sleep_pin:
|
||||||
|
number: 5
|
||||||
|
max_speed: 250 steps/s
|
||||||
|
acceleration: 100 steps/s^2
|
||||||
|
deceleration: 200 steps/s^2
|
12
tests/components/a4988/test.esp32-c3.yaml
Normal file
12
tests/components/a4988/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
stepper:
|
||||||
|
- platform: a4988
|
||||||
|
id: a4988_stepper
|
||||||
|
step_pin:
|
||||||
|
number: 2
|
||||||
|
dir_pin:
|
||||||
|
number: 3
|
||||||
|
sleep_pin:
|
||||||
|
number: 5
|
||||||
|
max_speed: 250 steps/s
|
||||||
|
acceleration: 100 steps/s^2
|
||||||
|
deceleration: 200 steps/s^2
|
12
tests/components/a4988/test.esp32-idf.yaml
Normal file
12
tests/components/a4988/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
stepper:
|
||||||
|
- platform: a4988
|
||||||
|
id: a4988_stepper
|
||||||
|
step_pin:
|
||||||
|
number: 22
|
||||||
|
dir_pin:
|
||||||
|
number: 23
|
||||||
|
sleep_pin:
|
||||||
|
number: 25
|
||||||
|
max_speed: 250 steps/s
|
||||||
|
acceleration: 100 steps/s^2
|
||||||
|
deceleration: 200 steps/s^2
|
12
tests/components/a4988/test.esp32.yaml
Normal file
12
tests/components/a4988/test.esp32.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
stepper:
|
||||||
|
- platform: a4988
|
||||||
|
id: a4988_stepper
|
||||||
|
step_pin:
|
||||||
|
number: 22
|
||||||
|
dir_pin:
|
||||||
|
number: 23
|
||||||
|
sleep_pin:
|
||||||
|
number: 25
|
||||||
|
max_speed: 250 steps/s
|
||||||
|
acceleration: 100 steps/s^2
|
||||||
|
deceleration: 200 steps/s^2
|
12
tests/components/a4988/test.esp8266.yaml
Normal file
12
tests/components/a4988/test.esp8266.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
stepper:
|
||||||
|
- platform: a4988
|
||||||
|
id: a4988_stepper
|
||||||
|
step_pin:
|
||||||
|
number: 1
|
||||||
|
dir_pin:
|
||||||
|
number: 2
|
||||||
|
sleep_pin:
|
||||||
|
number: 5
|
||||||
|
max_speed: 250 steps/s
|
||||||
|
acceleration: 100 steps/s^2
|
||||||
|
deceleration: 200 steps/s^2
|
12
tests/components/a4988/test.rp2040.yaml
Normal file
12
tests/components/a4988/test.rp2040.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
stepper:
|
||||||
|
- platform: a4988
|
||||||
|
id: a4988_stepper
|
||||||
|
step_pin:
|
||||||
|
number: 2
|
||||||
|
dir_pin:
|
||||||
|
number: 3
|
||||||
|
sleep_pin:
|
||||||
|
number: 5
|
||||||
|
max_speed: 250 steps/s
|
||||||
|
acceleration: 100 steps/s^2
|
||||||
|
deceleration: 200 steps/s^2
|
21
tests/components/absolute_humidity/test.esp32-c3-idf.yaml
Normal file
21
tests/components/absolute_humidity/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sensor:
|
||||||
|
- platform: absolute_humidity
|
||||||
|
name: Absolute Humidity
|
||||||
|
temperature: template_temperature
|
||||||
|
humidity: template_humidity
|
||||||
|
- platform: template
|
||||||
|
id: template_humidity
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 0.6;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
- platform: template
|
||||||
|
id: template_temperature
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 42.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
21
tests/components/absolute_humidity/test.esp32-c3.yaml
Normal file
21
tests/components/absolute_humidity/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sensor:
|
||||||
|
- platform: absolute_humidity
|
||||||
|
name: Absolute Humidity
|
||||||
|
temperature: template_temperature
|
||||||
|
humidity: template_humidity
|
||||||
|
- platform: template
|
||||||
|
id: template_humidity
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 0.6;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
- platform: template
|
||||||
|
id: template_temperature
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 42.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
21
tests/components/absolute_humidity/test.esp32-idf.yaml
Normal file
21
tests/components/absolute_humidity/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sensor:
|
||||||
|
- platform: absolute_humidity
|
||||||
|
name: Absolute Humidity
|
||||||
|
temperature: template_temperature
|
||||||
|
humidity: template_humidity
|
||||||
|
- platform: template
|
||||||
|
id: template_humidity
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 0.6;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
- platform: template
|
||||||
|
id: template_temperature
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 42.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
21
tests/components/absolute_humidity/test.esp32.yaml
Normal file
21
tests/components/absolute_humidity/test.esp32.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sensor:
|
||||||
|
- platform: absolute_humidity
|
||||||
|
name: Absolute Humidity
|
||||||
|
temperature: template_temperature
|
||||||
|
humidity: template_humidity
|
||||||
|
- platform: template
|
||||||
|
id: template_humidity
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 0.6;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
- platform: template
|
||||||
|
id: template_temperature
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 42.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
21
tests/components/absolute_humidity/test.esp8266.yaml
Normal file
21
tests/components/absolute_humidity/test.esp8266.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sensor:
|
||||||
|
- platform: absolute_humidity
|
||||||
|
name: Absolute Humidity
|
||||||
|
temperature: template_temperature
|
||||||
|
humidity: template_humidity
|
||||||
|
- platform: template
|
||||||
|
id: template_humidity
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 0.6;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
- platform: template
|
||||||
|
id: template_temperature
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 42.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
21
tests/components/absolute_humidity/test.rp2040.yaml
Normal file
21
tests/components/absolute_humidity/test.rp2040.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sensor:
|
||||||
|
- platform: absolute_humidity
|
||||||
|
name: Absolute Humidity
|
||||||
|
temperature: template_temperature
|
||||||
|
humidity: template_humidity
|
||||||
|
- platform: template
|
||||||
|
id: template_humidity
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 0.6;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
- platform: template
|
||||||
|
id: template_temperature
|
||||||
|
lambda: |-
|
||||||
|
if (millis() > 10000) {
|
||||||
|
return 42.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
7
tests/components/ac_dimmer/test.esp32-c3.yaml
Normal file
7
tests/components/ac_dimmer/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
output:
|
||||||
|
- platform: ac_dimmer
|
||||||
|
id: ac_dimmer_1
|
||||||
|
gate_pin:
|
||||||
|
number: 5
|
||||||
|
zero_cross_pin:
|
||||||
|
number: 6
|
7
tests/components/ac_dimmer/test.esp32.yaml
Normal file
7
tests/components/ac_dimmer/test.esp32.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
output:
|
||||||
|
- platform: ac_dimmer
|
||||||
|
id: ac_dimmer_1
|
||||||
|
gate_pin:
|
||||||
|
number: 12
|
||||||
|
zero_cross_pin:
|
||||||
|
number: 13
|
7
tests/components/ac_dimmer/test.esp8266.yaml
Normal file
7
tests/components/ac_dimmer/test.esp8266.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
output:
|
||||||
|
- platform: ac_dimmer
|
||||||
|
id: ac_dimmer_1
|
||||||
|
gate_pin:
|
||||||
|
number: 5
|
||||||
|
zero_cross_pin:
|
||||||
|
number: 4
|
7
tests/components/ac_dimmer/test.rp2040.yaml
Normal file
7
tests/components/ac_dimmer/test.rp2040.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
output:
|
||||||
|
- platform: ac_dimmer
|
||||||
|
id: ac_dimmer_1
|
||||||
|
gate_pin:
|
||||||
|
number: 5
|
||||||
|
zero_cross_pin:
|
||||||
|
number: 6
|
14
tests/components/adc128s102/test.esp32-c3-idf.yaml
Normal file
14
tests/components/adc128s102/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_adc128s102
|
||||||
|
clk_pin: 6
|
||||||
|
mosi_pin: 7
|
||||||
|
miso_pin: 5
|
||||||
|
|
||||||
|
adc128s102:
|
||||||
|
cs_pin: 8
|
||||||
|
id: adc128s102_adc
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: adc128s102
|
||||||
|
id: adc128s102_channel_0
|
||||||
|
channel: 0
|
14
tests/components/adc128s102/test.esp32-c3.yaml
Normal file
14
tests/components/adc128s102/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_adc128s102
|
||||||
|
clk_pin: 6
|
||||||
|
mosi_pin: 7
|
||||||
|
miso_pin: 5
|
||||||
|
|
||||||
|
adc128s102:
|
||||||
|
cs_pin: 8
|
||||||
|
id: adc128s102_adc
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: adc128s102
|
||||||
|
id: adc128s102_channel_0
|
||||||
|
channel: 0
|
14
tests/components/adc128s102/test.esp32-idf.yaml
Normal file
14
tests/components/adc128s102/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_adc128s102
|
||||||
|
clk_pin: 16
|
||||||
|
mosi_pin: 17
|
||||||
|
miso_pin: 15
|
||||||
|
|
||||||
|
adc128s102:
|
||||||
|
cs_pin: 12
|
||||||
|
id: adc128s102_adc
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: adc128s102
|
||||||
|
id: adc128s102_channel_0
|
||||||
|
channel: 0
|
14
tests/components/adc128s102/test.esp32.yaml
Normal file
14
tests/components/adc128s102/test.esp32.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_adc128s102
|
||||||
|
clk_pin: 16
|
||||||
|
mosi_pin: 17
|
||||||
|
miso_pin: 15
|
||||||
|
|
||||||
|
adc128s102:
|
||||||
|
cs_pin: 12
|
||||||
|
id: adc128s102_adc
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: adc128s102
|
||||||
|
id: adc128s102_channel_0
|
||||||
|
channel: 0
|
14
tests/components/adc128s102/test.esp8266.yaml
Normal file
14
tests/components/adc128s102/test.esp8266.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_adc128s102
|
||||||
|
clk_pin: 14
|
||||||
|
mosi_pin: 13
|
||||||
|
miso_pin: 12
|
||||||
|
|
||||||
|
adc128s102:
|
||||||
|
cs_pin: 15
|
||||||
|
id: adc128s102_adc
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: adc128s102
|
||||||
|
id: adc128s102_channel_0
|
||||||
|
channel: 0
|
14
tests/components/adc128s102/test.rp2040.yaml
Normal file
14
tests/components/adc128s102/test.rp2040.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_adc128s102
|
||||||
|
clk_pin: 2
|
||||||
|
mosi_pin: 3
|
||||||
|
miso_pin: 4
|
||||||
|
|
||||||
|
adc128s102:
|
||||||
|
cs_pin: 5
|
||||||
|
id: adc128s102_adc
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: adc128s102
|
||||||
|
id: adc128s102_channel_0
|
||||||
|
channel: 0
|
31
tests/components/addressable_light/test.esp32-c3-idf.yaml
Normal file
31
tests/components/addressable_light/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
light:
|
||||||
|
- platform: esp32_rmt_led_strip
|
||||||
|
id: led_matrix_32x8
|
||||||
|
default_transition_length: 500ms
|
||||||
|
chipset: ws2812
|
||||||
|
rgb_order: GRB
|
||||||
|
num_leds: 256
|
||||||
|
pin: 2
|
||||||
|
rmt_channel: 0
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: addressable_light
|
||||||
|
id: led_matrix_32x8_display
|
||||||
|
addressable_light_id: led_matrix_32x8
|
||||||
|
width: 32
|
||||||
|
height: 8
|
||||||
|
pixel_mapper: |-
|
||||||
|
if (x % 2 == 0) {
|
||||||
|
return (x * 8) + y;
|
||||||
|
}
|
||||||
|
return (x * 8) + (7 - y);
|
||||||
|
lambda: |-
|
||||||
|
Color red = Color(0xFF0000);
|
||||||
|
Color green = Color(0x00FF00);
|
||||||
|
Color blue = Color(0x0000FF);
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height(), red);
|
||||||
|
it.rectangle(1, 1, it.get_width()-2, it.get_height()-2, green);
|
||||||
|
it.rectangle(2, 2, it.get_width()-4, it.get_height()-4, blue);
|
||||||
|
it.rectangle(3, 3, it.get_width()-6, it.get_height()-6, red);
|
||||||
|
rotation: 0°
|
||||||
|
update_interval: 16ms
|
31
tests/components/addressable_light/test.esp32-c3.yaml
Normal file
31
tests/components/addressable_light/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
light:
|
||||||
|
- platform: esp32_rmt_led_strip
|
||||||
|
id: led_matrix_32x8
|
||||||
|
default_transition_length: 500ms
|
||||||
|
chipset: ws2812
|
||||||
|
rgb_order: GRB
|
||||||
|
num_leds: 256
|
||||||
|
pin: 2
|
||||||
|
rmt_channel: 0
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: addressable_light
|
||||||
|
id: led_matrix_32x8_display
|
||||||
|
addressable_light_id: led_matrix_32x8
|
||||||
|
width: 32
|
||||||
|
height: 8
|
||||||
|
pixel_mapper: |-
|
||||||
|
if (x % 2 == 0) {
|
||||||
|
return (x * 8) + y;
|
||||||
|
}
|
||||||
|
return (x * 8) + (7 - y);
|
||||||
|
lambda: |-
|
||||||
|
Color red = Color(0xFF0000);
|
||||||
|
Color green = Color(0x00FF00);
|
||||||
|
Color blue = Color(0x0000FF);
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height(), red);
|
||||||
|
it.rectangle(1, 1, it.get_width()-2, it.get_height()-2, green);
|
||||||
|
it.rectangle(2, 2, it.get_width()-4, it.get_height()-4, blue);
|
||||||
|
it.rectangle(3, 3, it.get_width()-6, it.get_height()-6, red);
|
||||||
|
rotation: 0°
|
||||||
|
update_interval: 16ms
|
31
tests/components/addressable_light/test.esp32-idf.yaml
Normal file
31
tests/components/addressable_light/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
light:
|
||||||
|
- platform: esp32_rmt_led_strip
|
||||||
|
id: led_matrix_32x8
|
||||||
|
default_transition_length: 500ms
|
||||||
|
chipset: ws2812
|
||||||
|
rgb_order: GRB
|
||||||
|
num_leds: 256
|
||||||
|
pin: 2
|
||||||
|
rmt_channel: 0
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: addressable_light
|
||||||
|
id: led_matrix_32x8_display
|
||||||
|
addressable_light_id: led_matrix_32x8
|
||||||
|
width: 32
|
||||||
|
height: 8
|
||||||
|
pixel_mapper: |-
|
||||||
|
if (x % 2 == 0) {
|
||||||
|
return (x * 8) + y;
|
||||||
|
}
|
||||||
|
return (x * 8) + (7 - y);
|
||||||
|
lambda: |-
|
||||||
|
Color red = Color(0xFF0000);
|
||||||
|
Color green = Color(0x00FF00);
|
||||||
|
Color blue = Color(0x0000FF);
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height(), red);
|
||||||
|
it.rectangle(1, 1, it.get_width()-2, it.get_height()-2, green);
|
||||||
|
it.rectangle(2, 2, it.get_width()-4, it.get_height()-4, blue);
|
||||||
|
it.rectangle(3, 3, it.get_width()-6, it.get_height()-6, red);
|
||||||
|
rotation: 0°
|
||||||
|
update_interval: 16ms
|
32
tests/components/addressable_light/test.esp32.yaml
Normal file
32
tests/components/addressable_light/test.esp32.yaml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
light:
|
||||||
|
- platform: fastled_clockless
|
||||||
|
id: led_matrix_32x8
|
||||||
|
name: led_matrix_32x8
|
||||||
|
chipset: WS2812B
|
||||||
|
pin: 2
|
||||||
|
num_leds: 256
|
||||||
|
rgb_order: GRB
|
||||||
|
default_transition_length: 0s
|
||||||
|
color_correct: [50%, 50%, 50%]
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: addressable_light
|
||||||
|
id: led_matrix_32x8_display
|
||||||
|
addressable_light_id: led_matrix_32x8
|
||||||
|
width: 32
|
||||||
|
height: 8
|
||||||
|
pixel_mapper: |-
|
||||||
|
if (x % 2 == 0) {
|
||||||
|
return (x * 8) + y;
|
||||||
|
}
|
||||||
|
return (x * 8) + (7 - y);
|
||||||
|
lambda: |-
|
||||||
|
Color red = Color(0xFF0000);
|
||||||
|
Color green = Color(0x00FF00);
|
||||||
|
Color blue = Color(0x0000FF);
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height(), red);
|
||||||
|
it.rectangle(1, 1, it.get_width()-2, it.get_height()-2, green);
|
||||||
|
it.rectangle(2, 2, it.get_width()-4, it.get_height()-4, blue);
|
||||||
|
it.rectangle(3, 3, it.get_width()-6, it.get_height()-6, red);
|
||||||
|
rotation: 0°
|
||||||
|
update_interval: 16ms
|
34
tests/components/ade7953_i2c/test.esp32-c3-idf.yaml
Normal file
34
tests/components/ade7953_i2c/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ade7953
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_i2c
|
||||||
|
irq_pin: 6
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
34
tests/components/ade7953_i2c/test.esp32-c3.yaml
Normal file
34
tests/components/ade7953_i2c/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ade7953
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_i2c
|
||||||
|
irq_pin: 6
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
34
tests/components/ade7953_i2c/test.esp32-idf.yaml
Normal file
34
tests/components/ade7953_i2c/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ade7953
|
||||||
|
scl: 16
|
||||||
|
sda: 17
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_i2c
|
||||||
|
irq_pin: 15
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
34
tests/components/ade7953_i2c/test.esp32.yaml
Normal file
34
tests/components/ade7953_i2c/test.esp32.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ade7953
|
||||||
|
scl: 16
|
||||||
|
sda: 17
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_i2c
|
||||||
|
irq_pin: 15
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
34
tests/components/ade7953_i2c/test.esp8266.yaml
Normal file
34
tests/components/ade7953_i2c/test.esp8266.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ade7953
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_i2c
|
||||||
|
irq_pin: 15
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
34
tests/components/ade7953_i2c/test.rp2040.yaml
Normal file
34
tests/components/ade7953_i2c/test.rp2040.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ade7953
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_i2c
|
||||||
|
irq_pin: 6
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
36
tests/components/ade7953_spi/test.esp32-c3-idf.yaml
Normal file
36
tests/components/ade7953_spi/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_ade7953
|
||||||
|
clk_pin: 6
|
||||||
|
mosi_pin: 7
|
||||||
|
miso_pin: 5
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_spi
|
||||||
|
cs_pin: 8
|
||||||
|
irq_pin: 9
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
36
tests/components/ade7953_spi/test.esp32-c3.yaml
Normal file
36
tests/components/ade7953_spi/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_ade7953
|
||||||
|
clk_pin: 6
|
||||||
|
mosi_pin: 7
|
||||||
|
miso_pin: 5
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_spi
|
||||||
|
cs_pin: 8
|
||||||
|
irq_pin: 9
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
36
tests/components/ade7953_spi/test.esp32-idf.yaml
Normal file
36
tests/components/ade7953_spi/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_ade7953
|
||||||
|
clk_pin: 16
|
||||||
|
mosi_pin: 17
|
||||||
|
miso_pin: 15
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_spi
|
||||||
|
cs_pin: 5
|
||||||
|
irq_pin: 13
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
36
tests/components/ade7953_spi/test.esp32.yaml
Normal file
36
tests/components/ade7953_spi/test.esp32.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_ade7953
|
||||||
|
clk_pin: 16
|
||||||
|
mosi_pin: 17
|
||||||
|
miso_pin: 15
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_spi
|
||||||
|
cs_pin: 5
|
||||||
|
irq_pin: 13
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
36
tests/components/ade7953_spi/test.esp8266.yaml
Normal file
36
tests/components/ade7953_spi/test.esp8266.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_ade7953
|
||||||
|
clk_pin: 14
|
||||||
|
mosi_pin: 13
|
||||||
|
miso_pin: 12
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_spi
|
||||||
|
cs_pin: 15
|
||||||
|
irq_pin: 5
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
36
tests/components/ade7953_spi/test.rp2040.yaml
Normal file
36
tests/components/ade7953_spi/test.rp2040.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
spi:
|
||||||
|
- id: spi_ade7953
|
||||||
|
clk_pin: 2
|
||||||
|
mosi_pin: 3
|
||||||
|
miso_pin: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ade7953_spi
|
||||||
|
cs_pin: 5
|
||||||
|
irq_pin: 6
|
||||||
|
voltage:
|
||||||
|
name: ADE7953 Voltage
|
||||||
|
id: ade7953_voltage
|
||||||
|
current_a:
|
||||||
|
name: ADE7953 Current A
|
||||||
|
id: ade7953_current_a
|
||||||
|
current_b:
|
||||||
|
name: ADE7953 Current B
|
||||||
|
id: ade7953_current_b
|
||||||
|
power_factor_a:
|
||||||
|
name: ADE7953 Power Factor A
|
||||||
|
power_factor_b:
|
||||||
|
name: ADE7953 Power Factor B
|
||||||
|
apparent_power_a:
|
||||||
|
name: ADE7953 Apparent Power A
|
||||||
|
apparent_power_b:
|
||||||
|
name: ADE7953 Apparent Power B
|
||||||
|
active_power_a:
|
||||||
|
name: ADE7953 Active Power A
|
||||||
|
active_power_b:
|
||||||
|
name: ADE7953 Active Power B
|
||||||
|
reactive_power_a:
|
||||||
|
name: ADE7953 Reactive Power A
|
||||||
|
reactive_power_b:
|
||||||
|
name: ADE7953 Reactive Power B
|
||||||
|
update_interval: 1s
|
13
tests/components/ads1115/test.esp32-c3-idf.yaml
Normal file
13
tests/components/ads1115/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ads1115
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
ads1115:
|
||||||
|
address: 0x48
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ads1115
|
||||||
|
multiplexer: A0_A1
|
||||||
|
gain: 1.024
|
||||||
|
id: ads1115_sensor
|
13
tests/components/ads1115/test.esp32-c3.yaml
Normal file
13
tests/components/ads1115/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ads1115
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
ads1115:
|
||||||
|
address: 0x48
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ads1115
|
||||||
|
multiplexer: A0_A1
|
||||||
|
gain: 1.024
|
||||||
|
id: ads1115_sensor
|
13
tests/components/ads1115/test.esp32-idf.yaml
Normal file
13
tests/components/ads1115/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ads1115
|
||||||
|
scl: 16
|
||||||
|
sda: 17
|
||||||
|
|
||||||
|
ads1115:
|
||||||
|
address: 0x48
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ads1115
|
||||||
|
multiplexer: A0_A1
|
||||||
|
gain: 1.024
|
||||||
|
id: ads1115_sensor
|
13
tests/components/ads1115/test.esp32.yaml
Normal file
13
tests/components/ads1115/test.esp32.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ads1115
|
||||||
|
scl: 16
|
||||||
|
sda: 17
|
||||||
|
|
||||||
|
ads1115:
|
||||||
|
address: 0x48
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ads1115
|
||||||
|
multiplexer: A0_A1
|
||||||
|
gain: 1.024
|
||||||
|
id: ads1115_sensor
|
13
tests/components/ads1115/test.esp8266.yaml
Normal file
13
tests/components/ads1115/test.esp8266.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ads1115
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
ads1115:
|
||||||
|
address: 0x48
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ads1115
|
||||||
|
multiplexer: A0_A1
|
||||||
|
gain: 1.024
|
||||||
|
id: ads1115_sensor
|
13
tests/components/ads1115/test.rp2040.yaml
Normal file
13
tests/components/ads1115/test.rp2040.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_ads1115
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
ads1115:
|
||||||
|
address: 0x48
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: ads1115
|
||||||
|
multiplexer: A0_A1
|
||||||
|
gain: 1.024
|
||||||
|
id: ads1115_sensor
|
11
tests/components/aht10/test.esp32-c3-idf.yaml
Normal file
11
tests/components/aht10/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_aht10
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: aht10
|
||||||
|
temperature:
|
||||||
|
name: Temperature
|
||||||
|
humidity:
|
||||||
|
name: Humidity
|
11
tests/components/aht10/test.esp32-c3.yaml
Normal file
11
tests/components/aht10/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
i2c:
|
||||||
|
- id: i2c_aht10
|
||||||
|
scl: 5
|
||||||
|
sda: 4
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: aht10
|
||||||
|
temperature:
|
||||||
|
name: Temperature
|
||||||
|
humidity:
|
||||||
|
name: Humidity
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue