Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
Daniël Koek 2024-04-08 17:58:40 +01:00
commit fb79b0a845
387 changed files with 12365 additions and 16 deletions

View file

@ -1,6 +1,5 @@
name: API Proto CI
# yamllint disable-line rule:truthy
on:
pull_request:
paths:

View file

@ -2,7 +2,7 @@
name: CI for docker images
# Only run when docker paths change
# yamllint disable-line rule:truthy
on:
push:
branches: [dev, beta, release]

View file

@ -1,7 +1,6 @@
---
name: CI
# yamllint disable-line rule:truthy
on:
push:
branches: [dev, beta, release]

View file

@ -1,7 +1,6 @@
---
name: Lock
# yamllint disable-line rule:truthy
on:
schedule:
- cron: "30 0 * * *"

View file

@ -1,6 +1,5 @@
name: Needs Docs
# yamllint disable-line rule:truthy
on:
pull_request:
types: [labeled, unlabeled]

View file

@ -1,7 +1,6 @@
---
name: Publish Release
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
release:

View file

@ -1,7 +1,6 @@
---
name: Stale
# yamllint disable-line rule:truthy
on:
schedule:
- cron: "30 0 * * *"

View file

@ -1,7 +1,6 @@
---
name: Synchronise Device Classes from Home Assistant
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
schedule:

View file

@ -1,7 +1,6 @@
---
name: YAML lint
# yamllint disable-line rule:truthy
on:
push:
branches: [dev, beta, release]

View file

@ -16,3 +16,4 @@ rules:
indent-sequences: true
check-multi-line-strings: false
line-length: disable
truthy: disable

View file

@ -42,6 +42,7 @@ esphome/components/as5600/* @ammmze
esphome/components/as5600/sensor/* @ammmze
esphome/components/as7341/* @mrgnr
esphome/components/async_tcp/* @OttoWinter
esphome/components/at581x/* @X-Ryl669
esphome/components/atc_mithermometer/* @ahpohl
esphome/components/atm90e26/* @danieltwagner
esphome/components/b_parasite/* @rbaron
@ -86,6 +87,7 @@ esphome/components/cst816/* @clydebarrow
esphome/components/ct_clamp/* @jesserockz
esphome/components/current_based/* @djwmarcx
esphome/components/dac7678/* @NickB1
esphome/components/daikin_arc/* @MagicBear
esphome/components/daikin_brc/* @hagak
esphome/components/daly_bms/* @s1lvi0
esphome/components/dashboard_import/* @esphome/core
@ -173,6 +175,7 @@ esphome/components/inkplate6/* @jesserockz
esphome/components/integration/* @OttoWinter
esphome/components/internal_temperature/* @Mat931
esphome/components/interval/* @esphome/core
esphome/components/jsn_sr04t/* @Mafus1
esphome/components/json/* @OttoWinter
esphome/components/kamstrup_kmp/* @cfeenstra1024
esphome/components/key_collector/* @ssieb
@ -307,6 +310,7 @@ esphome/components/sfa30/* @ghsensdev
esphome/components/sgp40/* @SenexCrenshaw
esphome/components/sgp4x/* @SenexCrenshaw @martgras
esphome/components/shelly_dimmer/* @edge90 @rnauber
esphome/components/sht3xd/* @mrtoy-me
esphome/components/sht4x/* @sjtrny
esphome/components/shutdown/* @esphome/core @jsuanet
esphome/components/sigma_delta_output/* @Cat-Ion

View file

@ -0,0 +1,224 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation, core
from esphome.components import i2c
from esphome.automation import maybe_simple_id
from esphome.const import (
CONF_ID,
CONF_FREQUENCY,
)
CODEOWNERS = ["@X-Ryl669"]
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
at581x_ns = cg.esphome_ns.namespace("at581x")
AT581XComponent = at581x_ns.class_("AT581XComponent", cg.Component, i2c.I2CDevice)
CONF_AT581X_ID = "at581x_id"
CONF_SENSING_DISTANCE = "sensing_distance"
CONF_SENSITIVITY = "sensitivity"
CONF_POWERON_SELFCHECK_TIME = "poweron_selfcheck_time"
CONF_PROTECT_TIME = "protect_time"
CONF_TRIGGER_BASE = "trigger_base"
CONF_TRIGGER_KEEP = "trigger_keep"
CONF_STAGE_GAIN = "stage_gain"
CONF_POWER_CONSUMPTION = "power_consumption"
CONF_HW_FRONTEND_RESET = "hw_frontend_reset"
RADAR_ALLOWED_FREQ = [
5696e6,
5715e6,
5730e6,
5748e6,
5765e6,
5784e6,
5800e6,
5819e6,
5836e6,
5851e6,
5869e6,
5888e6,
]
RADAR_ALLOWED_CUR_CONSUMPTION = [
48e-6,
56e-6,
63e-6,
70e-6,
77e-6,
91e-6,
105e-6,
115e-6,
40e-6,
44e-6,
47e-6,
51e-6,
54e-6,
61e-6,
68e-6,
78e-6,
]
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(AT581XComponent),
}
)
CONFIG_SCHEMA = cv.All(
CONFIG_SCHEMA.extend(i2c.i2c_device_schema(0x28)).extend(cv.COMPONENT_SCHEMA)
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
# Actions
AT581XResetAction = at581x_ns.class_("AT581XResetAction", automation.Action)
AT581XSettingsAction = at581x_ns.class_("AT581XSettingsAction", automation.Action)
@automation.register_action(
"at581x.reset",
AT581XResetAction,
maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(AT581XComponent),
}
),
)
async def at581x_reset_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
RADAR_SETTINGS_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.use_id(AT581XComponent),
cv.Optional(CONF_HW_FRONTEND_RESET): cv.templatable(cv.boolean),
cv.Optional(CONF_FREQUENCY, default="5800MHz"): cv.templatable(
cv.All(cv.frequency, cv.one_of(*RADAR_ALLOWED_FREQ))
),
cv.Optional(CONF_SENSING_DISTANCE, default=823): cv.templatable(
cv.int_range(min=0, max=1023)
),
cv.Optional(CONF_POWERON_SELFCHECK_TIME, default="2000ms"): cv.templatable(
cv.All(
cv.positive_time_period_milliseconds,
cv.Range(max=core.TimePeriod(milliseconds=65535)),
)
),
cv.Optional(CONF_POWER_CONSUMPTION, default="70uA"): cv.templatable(
cv.All(cv.current, cv.one_of(*RADAR_ALLOWED_CUR_CONSUMPTION))
),
cv.Optional(CONF_PROTECT_TIME, default="1000ms"): cv.templatable(
cv.All(
cv.positive_time_period_milliseconds,
cv.Range(
min=core.TimePeriod(milliseconds=1),
max=core.TimePeriod(milliseconds=65535),
),
)
),
cv.Optional(CONF_TRIGGER_BASE, default="500ms"): cv.templatable(
cv.All(
cv.positive_time_period_milliseconds,
cv.Range(
min=core.TimePeriod(milliseconds=1),
max=core.TimePeriod(milliseconds=65535),
),
)
),
cv.Optional(CONF_TRIGGER_KEEP, default="1500ms"): cv.templatable(
cv.All(
cv.positive_time_period_milliseconds,
cv.Range(
min=core.TimePeriod(milliseconds=1),
max=core.TimePeriod(milliseconds=65535),
),
)
),
cv.Optional(CONF_STAGE_GAIN, default=3): cv.templatable(
cv.int_range(min=0, max=12)
),
}
).add_extra(
cv.has_at_least_one_key(
CONF_HW_FRONTEND_RESET,
CONF_FREQUENCY,
CONF_SENSING_DISTANCE,
)
)
@automation.register_action(
"at581x.settings",
AT581XSettingsAction,
RADAR_SETTINGS_SCHEMA,
)
async def at581x_settings_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
# Radar configuration
if frontend_reset := config.get(CONF_HW_FRONTEND_RESET):
template_ = await cg.templatable(frontend_reset, args, int)
cg.add(var.set_hw_frontend_reset(template_))
if freq := config.get(CONF_FREQUENCY):
template_ = await cg.templatable(freq, args, float)
template_ = int(template_ / 1000000)
cg.add(var.set_frequency(template_))
if sens_dist := config.get(CONF_SENSING_DISTANCE):
template_ = await cg.templatable(sens_dist, args, int)
cg.add(var.set_sensing_distance(template_))
if selfcheck := config.get(CONF_POWERON_SELFCHECK_TIME):
template_ = await cg.templatable(selfcheck, args, float)
if isinstance(template_, cv.TimePeriod):
template_ = template_.total_milliseconds
template_ = int(template_)
cg.add(var.set_poweron_selfcheck_time(template_))
if protect := config.get(CONF_PROTECT_TIME):
template_ = await cg.templatable(protect, args, float)
if isinstance(template_, cv.TimePeriod):
template_ = template_.total_milliseconds
template_ = int(template_)
cg.add(var.set_protect_time(template_))
if trig_base := config.get(CONF_TRIGGER_BASE):
template_ = await cg.templatable(trig_base, args, float)
if isinstance(template_, cv.TimePeriod):
template_ = template_.total_milliseconds
template_ = int(template_)
cg.add(var.set_trigger_base(template_))
if trig_keep := config.get(CONF_TRIGGER_KEEP):
template_ = await cg.templatable(trig_keep, args, float)
if isinstance(template_, cv.TimePeriod):
template_ = template_.total_milliseconds
template_ = int(template_)
cg.add(var.set_trigger_keep(template_))
if stage_gain := config.get(CONF_STAGE_GAIN):
template_ = await cg.templatable(stage_gain, args, int)
cg.add(var.set_stage_gain(template_))
if power := config.get(CONF_POWER_CONSUMPTION):
template_ = await cg.templatable(power, args, float)
template_ = int(template_ * 1000000)
cg.add(var.set_power_consumption(template_))
return var

View file

@ -0,0 +1,195 @@
#include "at581x.h"
#include "esphome/core/log.h"
/* Select gain for AT581X (3dB per step for level1, 6dB per step for level 2), high value = small gain. (p12) */
const uint8_t GAIN_ADDR_TABLE[] = {0x5c, 0x63};
const uint8_t GAIN5C_TABLE[] = {0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, 0xb8, 0xc8};
const uint8_t GAIN63_TABLE[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
const uint8_t GAIN61_VALUE = 0xCA; // 0xC0 | 0x02 (freq present) | 0x08 (gain present)
/*!< Power consumption configuration table (p12). */
const uint8_t POWER_TABLE[] = {48, 56, 63, 70, 77, 91, 105, 115, 40, 44, 47, 51, 54, 61, 68, 78};
const uint8_t POWER67_TABLE[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
const uint8_t POWER68_TABLE[] = {0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
24, 24, 24, 24, 24, 24, 24, 24}; // See Page 12, shift by 3 bits
/*!< Frequency Configuration table (p14/15 of datasheet). */
const uint8_t FREQ_ADDR = 0x61;
const uint16_t FREQ_TABLE[] = {5696, 5715, 5730, 5748, 5765, 5784, 5800, 5819, 5836, 5851, 5869, 5888};
const uint8_t FREQ5F_TABLE[] = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x40, 0x41, 0x42, 0x43};
const uint8_t FREQ60_TABLE[] = {0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e};
/*!< Value for RF and analog modules switch (p10). */
const uint8_t RF_OFF_TABLE[] = {0x46, 0xaa, 0x50};
const uint8_t RF_ON_TABLE[] = {0x45, 0x55, 0xA0};
const uint8_t RF_REG_ADDR[] = {0x5d, 0x62, 0x51};
/*!< Registers of Lighting delay time. Unit: ms, min 2s (p8) */
const uint8_t HIGH_LEVEL_DELAY_CONTROL_ADDR = 0x41; /*!< Time_flag_out_ctrl 0x01 */
const uint8_t HIGH_LEVEL_DELAY_VALUE_ADDR = 0x42; /*!< Time_flag_out_1 Bit<7:0> */
const uint8_t RESET_ADDR = 0x00;
/*!< Sensing distance address */
const uint8_t SIGNAL_DETECTION_THRESHOLD_ADDR_LO = 0x10;
const uint8_t SIGNAL_DETECTION_THRESHOLD_ADDR_HI = 0x11;
/*!< Bit field value for power registers */
const uint8_t POWER_THRESHOLD_ADDR_HI = 0x68;
const uint8_t POWER_THRESHOLD_ADDR_LO = 0x67;
const uint8_t PWR_WORK_TIME_EN = 8; // Reg 0x67
const uint8_t PWR_BURST_TIME_EN = 32; // Reg 0x68
const uint8_t PWR_THRESH_EN = 64; // Reg 0x68
const uint8_t PWR_THRESH_VAL_EN = 128; // Reg 0x67
/*!< Times */
const uint8_t TRIGGER_BASE_TIME_ADDR = 0x3D; // 4 bytes, so up to 0x40
const uint8_t PROTECT_TIME_ADDR = 0x4E; // 2 bytes, up to 0x4F
const uint8_t TRIGGER_KEEP_TIME_ADDR = 0x42; // 4 bytes, so up to 0x45
const uint8_t TIME41_VALUE = 1;
const uint8_t SELF_CHECK_TIME_ADDR = 0x38; // 2 bytes, up to 0x39
namespace esphome {
namespace at581x {
static const char *const TAG = "at581x";
bool AT581XComponent::i2c_write_reg(uint8_t addr, uint8_t data) {
return this->write_register(addr, &data, 1) == esphome::i2c::NO_ERROR;
}
bool AT581XComponent::i2c_write_reg(uint8_t addr, uint32_t data) {
return this->i2c_write_reg(addr + 0, uint8_t(data & 0xFF)) &&
this->i2c_write_reg(addr + 1, uint8_t((data >> 8) & 0xFF)) &&
this->i2c_write_reg(addr + 2, uint8_t((data >> 16) & 0xFF)) &&
this->i2c_write_reg(addr + 3, uint8_t((data >> 24) & 0xFF));
}
bool AT581XComponent::i2c_write_reg(uint8_t addr, uint16_t data) {
return this->i2c_write_reg(addr, uint8_t(data & 0xFF)) && this->i2c_write_reg(addr + 1, uint8_t((data >> 8) & 0xFF));
}
bool AT581XComponent::i2c_read_reg(uint8_t addr, uint8_t &data) {
return this->read_register(addr, &data, 1) == esphome::i2c::NO_ERROR;
}
void AT581XComponent::setup() { ESP_LOGCONFIG(TAG, "Setting up AT581X..."); }
void AT581XComponent::dump_config() { LOG_I2C_DEVICE(this); }
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
bool AT581XComponent::i2c_write_config() {
ESP_LOGCONFIG(TAG, "Writing new config for AT581X...");
ESP_LOGCONFIG(TAG, "Frequency: %dMHz", this->freq_);
ESP_LOGCONFIG(TAG, "Sensing distance: %d", this->delta_);
ESP_LOGCONFIG(TAG, "Power: %dµA", this->power_);
ESP_LOGCONFIG(TAG, "Gain: %d", this->gain_);
ESP_LOGCONFIG(TAG, "Trigger base time: %dms", this->trigger_base_time_ms_);
ESP_LOGCONFIG(TAG, "Trigger keep time: %dms", this->trigger_keep_time_ms_);
ESP_LOGCONFIG(TAG, "Protect time: %dms", this->protect_time_ms_);
ESP_LOGCONFIG(TAG, "Self check time: %dms", this->self_check_time_ms_);
// Set frequency point
if (!this->i2c_write_reg(FREQ_ADDR, GAIN61_VALUE)) {
ESP_LOGE(TAG, "Failed to write AT581X Freq mode");
return false;
}
// Find the current frequency from the table to know what value to write
for (size_t i = 0; i < ARRAY_SIZE(FREQ_TABLE) + 1; i++) {
if (i == ARRAY_SIZE(FREQ_TABLE)) {
ESP_LOGE(TAG, "Set frequency not found");
return false;
}
if (FREQ_TABLE[i] == this->freq_) {
if (!this->i2c_write_reg(0x5F, FREQ5F_TABLE[i]) || !this->i2c_write_reg(0x60, FREQ60_TABLE[i])) {
ESP_LOGE(TAG, "Failed to write AT581X Freq value");
return false;
}
break;
}
}
// Set distance
if (!this->i2c_write_reg(SIGNAL_DETECTION_THRESHOLD_ADDR_LO, (uint8_t) (this->delta_ & 0xFF)) ||
!this->i2c_write_reg(SIGNAL_DETECTION_THRESHOLD_ADDR_HI, (uint8_t) (this->delta_ >> 8))) {
ESP_LOGE(TAG, "Failed to write AT581X sensing distance low");
return false;
}
// Set power setting
uint8_t pwr67 = PWR_THRESH_VAL_EN | PWR_WORK_TIME_EN, pwr68 = PWR_BURST_TIME_EN | PWR_THRESH_EN;
for (size_t i = 0; i < ARRAY_SIZE(POWER_TABLE) + 1; i++) {
if (i == ARRAY_SIZE(POWER_TABLE)) {
ESP_LOGE(TAG, "Set power not found");
return false;
}
if (POWER_TABLE[i] == this->power_) {
pwr67 |= POWER67_TABLE[i];
pwr68 |= POWER68_TABLE[i]; // See Page 12
break;
}
}
if (!this->i2c_write_reg(POWER_THRESHOLD_ADDR_LO, pwr67) || !this->i2c_write_reg(POWER_THRESHOLD_ADDR_HI, pwr68)) {
ESP_LOGE(TAG, "Failed to write AT581X power registers");
return false;
}
// Set gain
if (!this->i2c_write_reg(GAIN_ADDR_TABLE[0], GAIN5C_TABLE[this->gain_]) ||
!this->i2c_write_reg(GAIN_ADDR_TABLE[1], GAIN63_TABLE[this->gain_ >> 1])) {
ESP_LOGE(TAG, "Failed to write AT581X gain registers");
return false;
}
// Set times
if (!this->i2c_write_reg(TRIGGER_BASE_TIME_ADDR, (uint32_t) this->trigger_base_time_ms_)) {
ESP_LOGE(TAG, "Failed to write AT581X trigger base time registers");
return false;
}
if (!this->i2c_write_reg(TRIGGER_KEEP_TIME_ADDR, (uint32_t) this->trigger_keep_time_ms_)) {
ESP_LOGE(TAG, "Failed to write AT581X trigger keep time registers");
return false;
}
if (!this->i2c_write_reg(PROTECT_TIME_ADDR, (uint16_t) this->protect_time_ms_)) {
ESP_LOGE(TAG, "Failed to write AT581X protect time registers");
return false;
}
if (!this->i2c_write_reg(SELF_CHECK_TIME_ADDR, (uint16_t) this->self_check_time_ms_)) {
ESP_LOGE(TAG, "Failed to write AT581X self check time registers");
return false;
}
if (!this->i2c_write_reg(0x41, TIME41_VALUE)) {
ESP_LOGE(TAG, "Failed to enable AT581X time registers");
return false;
}
// Don't know why it's required in other code, it's not in datasheet
if (!this->i2c_write_reg(0x55, (uint8_t) 0x04)) {
ESP_LOGE(TAG, "Failed to enable AT581X");
return false;
}
// Ok, config is written, let's reset the chip so it's using the new config
return this->reset_hardware_frontend();
}
// float AT581XComponent::get_setup_priority() const { return 0; }
bool AT581XComponent::reset_hardware_frontend() {
if (!this->i2c_write_reg(RESET_ADDR, (uint8_t) 0) || !this->i2c_write_reg(RESET_ADDR, (uint8_t) 1)) {
ESP_LOGE(TAG, "Failed to reset AT581X hardware frontend");
return false;
}
return true;
}
void AT581XComponent::set_rf_mode(bool enable) {
const uint8_t *p = enable ? &RF_ON_TABLE[0] : &RF_OFF_TABLE[0];
for (size_t i = 0; i < ARRAY_SIZE(RF_REG_ADDR); i++) {
if (!this->i2c_write_reg(RF_REG_ADDR[i], p[i])) {
ESP_LOGE(TAG, "Failed to write AT581X RF mode");
return;
}
}
}
} // namespace at581x
} // namespace esphome

View file

@ -0,0 +1,62 @@
#pragma once
#include <utility>
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/core/defines.h"
#ifdef USE_SWITCH
#include "esphome/components/switch/switch.h"
#endif
#include "esphome/components/i2c/i2c.h"
namespace esphome {
namespace at581x {
class AT581XComponent : public Component, public i2c::I2CDevice {
#ifdef USE_SWITCH
protected:
switch_::Switch *rf_power_switch_{nullptr};
public:
void set_rf_power_switch(switch_::Switch *s) {
this->rf_power_switch_ = s;
s->turn_on();
}
#endif
void setup() override;
void dump_config() override;
// float get_setup_priority() const override;
void set_sensing_distance(int distance) { this->delta_ = 1023 - distance; }
void set_rf_mode(bool enabled);
void set_frequency(int frequency) { this->freq_ = frequency; }
void set_poweron_selfcheck_time(int value) { this->self_check_time_ms_ = value; }
void set_protect_time(int value) { this->protect_time_ms_ = value; }
void set_trigger_base(int value) { this->trigger_base_time_ms_ = value; }
void set_trigger_keep(int value) { this->trigger_keep_time_ms_ = value; }
void set_stage_gain(int value) { this->gain_ = value; }
void set_power_consumption(int value) { this->power_ = value; }
bool i2c_write_config();
bool reset_hardware_frontend();
bool i2c_write_reg(uint8_t addr, uint8_t data);
bool i2c_write_reg(uint8_t addr, uint32_t data);
bool i2c_write_reg(uint8_t addr, uint16_t data);
bool i2c_read_reg(uint8_t addr, uint8_t &data);
protected:
int freq_;
int self_check_time_ms_; /*!< Power-on self-test time, range: 0 ~ 65536 ms */
int protect_time_ms_; /*!< Protection time, recommended 1000 ms */
int trigger_base_time_ms_; /*!< Default: 500 ms */
int trigger_keep_time_ms_; /*!< Total trig time = TRIGGER_BASE_TIME + DEF_TRIGGER_KEEP_TIME, minimum: 1 */
int delta_; /*!< Delta value: 0 ~ 1023, the larger the value, the shorter the distance */
int gain_; /*!< Default: 9dB */
int power_; /*!< In µA */
};
} // namespace at581x
} // namespace esphome

View file

@ -0,0 +1,71 @@
#pragma once
#include "esphome/core/automation.h"
#include "esphome/core/helpers.h"
#include "at581x.h"
namespace esphome {
namespace at581x {
template<typename... Ts> class AT581XResetAction : public Action<Ts...>, public Parented<AT581XComponent> {
public:
void play(Ts... x) { this->parent_->reset_hardware_frontend(); }
};
template<typename... Ts> class AT581XSettingsAction : public Action<Ts...>, public Parented<AT581XComponent> {
public:
TEMPLATABLE_VALUE(int8_t, hw_frontend_reset)
TEMPLATABLE_VALUE(int, frequency)
TEMPLATABLE_VALUE(int, sensing_distance)
TEMPLATABLE_VALUE(int, poweron_selfcheck_time)
TEMPLATABLE_VALUE(int, power_consumption)
TEMPLATABLE_VALUE(int, protect_time)
TEMPLATABLE_VALUE(int, trigger_base)
TEMPLATABLE_VALUE(int, trigger_keep)
TEMPLATABLE_VALUE(int, stage_gain)
void play(Ts... x) {
if (this->frequency_.has_value()) {
int v = this->frequency_.value(x...);
this->parent_->set_frequency(v);
}
if (this->sensing_distance_.has_value()) {
int v = this->sensing_distance_.value(x...);
this->parent_->set_sensing_distance(v);
}
if (this->poweron_selfcheck_time_.has_value()) {
int v = this->poweron_selfcheck_time_.value(x...);
this->parent_->set_poweron_selfcheck_time(v);
}
if (this->power_consumption_.has_value()) {
int v = this->power_consumption_.value(x...);
this->parent_->set_power_consumption(v);
}
if (this->protect_time_.has_value()) {
int v = this->protect_time_.value(x...);
this->parent_->set_protect_time(v);
}
if (this->trigger_base_.has_value()) {
int v = this->trigger_base_.value(x...);
this->parent_->set_trigger_base(v);
}
if (this->trigger_keep_.has_value()) {
int v = this->trigger_keep_.value(x...);
this->parent_->set_trigger_keep(v);
}
if (this->stage_gain_.has_value()) {
int v = this->stage_gain_.value(x...);
this->parent_->set_stage_gain(v);
}
// This actually perform all the modification on the system
this->parent_->i2c_write_config();
if (this->hw_frontend_reset_.has_value() && this->hw_frontend_reset_.value(x...) == true) {
this->parent_->reset_hardware_frontend();
}
}
};
} // namespace at581x
} // namespace esphome

View file

@ -0,0 +1,31 @@
import esphome.codegen as cg
from esphome.components import switch
import esphome.config_validation as cv
from esphome.const import (
DEVICE_CLASS_SWITCH,
ICON_WIFI,
)
from .. import CONF_AT581X_ID, AT581XComponent, at581x_ns
DEPENDENCIES = ["at581x"]
RFSwitch = at581x_ns.class_("RFSwitch", switch.Switch)
CONFIG_SCHEMA = switch.switch_schema(
RFSwitch,
device_class=DEVICE_CLASS_SWITCH,
icon=ICON_WIFI,
).extend(
cv.Schema(
{
cv.GenerateID(CONF_AT581X_ID): cv.use_id(AT581XComponent),
}
)
)
async def to_code(config):
at581x_component = await cg.get_variable(config[CONF_AT581X_ID])
s = await switch.new_switch(config)
await cg.register_parented(s, config[CONF_AT581X_ID])
cg.add(at581x_component.set_rf_power_switch(s))

View file

@ -0,0 +1,12 @@
#include "rf_switch.h"
namespace esphome {
namespace at581x {
void RFSwitch::write_state(bool state) {
this->publish_state(state);
this->parent_->set_rf_mode(state);
}
} // namespace at581x
} // namespace esphome

View file

@ -0,0 +1,15 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../at581x.h"
namespace esphome {
namespace at581x {
class RFSwitch : public switch_::Switch, public Parented<AT581XComponent> {
protected:
void write_state(bool state) override;
};
} // namespace at581x
} // namespace esphome

View file

@ -0,0 +1 @@
CODEOWNERS = ["@MagicBear"]

View file

@ -0,0 +1,18 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate_ir
from esphome.const import CONF_ID
AUTO_LOAD = ["climate_ir"]
daikin_arc_ns = cg.esphome_ns.namespace("daikin_arc")
DaikinArcClimate = daikin_arc_ns.class_("DaikinArcClimate", climate_ir.ClimateIR)
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
{cv.GenerateID(): cv.declare_id(DaikinArcClimate)}
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await climate_ir.register_climate_ir(var, config)

View file

@ -0,0 +1,487 @@
#include "daikin_arc.h"
#include <cmath>
#include "esphome/components/remote_base/remote_base.h"
#include "esphome/core/log.h"
namespace esphome {
namespace daikin_arc {
static const char *const TAG = "daikin.climate";
void DaikinArcClimate::setup() {
climate_ir::ClimateIR::setup();
// Never send nan to HA
if (std::isnan(this->target_humidity))
this->target_humidity = 0;
if (std::isnan(this->current_temperature))
this->current_temperature = 0;
if (std::isnan(this->current_humidity))
this->current_humidity = 0;
}
void DaikinArcClimate::transmit_query_() {
uint8_t remote_header[8] = {0x11, 0xDA, 0x27, 0x00, 0x84, 0x87, 0x20, 0x00};
// Calculate checksum
for (int i = 0; i < sizeof(remote_header) - 1; i++) {
remote_header[sizeof(remote_header) - 1] += remote_header[i];
}
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
data->set_carrier_frequency(DAIKIN_IR_FREQUENCY);
data->mark(DAIKIN_ARC_PRE_MARK);
data->space(DAIKIN_ARC_PRE_SPACE);
data->mark(DAIKIN_HEADER_MARK);
data->space(DAIKIN_HEADER_SPACE);
for (uint8_t i : remote_header) {
for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
data->mark(DAIKIN_BIT_MARK);
bool bit = i & mask;
data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
}
}
data->mark(DAIKIN_BIT_MARK);
data->space(0);
transmit.perform();
}
void DaikinArcClimate::transmit_state() {
// 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00,
// 0x42, 0x49, 0x05, 0xA2,
uint8_t remote_header[20] = {0x11, 0xDA, 0x27, 0x00, 0x02, 0xd0, 0x02, 0x03, 0x80, 0x03, 0x82, 0x30, 0x41, 0x1f, 0x82,
0xf4,
/* とつど */
/* 0x13 */
0x00, 0x24, 0x00, 0x00};
// 05 0 [1:3]MODE 1 [OFF TMR] [ON TMR] Power
// 06-07 TEMP
// 08 [0:3] SPEED [4:7] Swing
// 09 00
// 10 00
// 11, 12: timer
// 13 [0:6] 0000000 [7] POWERMODE
// 14 0a
// 15 c4
// 16 [0:3] 8 00 [6:7] SENSOR WIND = 11 / NORMAL = 00
// 17 24
uint8_t remote_state[19] = {
0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0a, 0xC4,
/* MODE TEMP HUMD FANH FANL
*/
/* ON
0x01 0x0a */
/* OF
0x00 0x02 */
0x80, 0x24, 0x00
/* センサー風 */
/* ON 0x83 */
/* OF 0x80 */
};
remote_state[5] = this->operation_mode_() | 0x08;
remote_state[6] = this->temperature_();
remote_state[7] = this->humidity_();
static uint8_t last_humidity = 0x66;
if (remote_state[7] != last_humidity && this->mode != climate::CLIMATE_MODE_OFF) {
ESP_LOGD(TAG, "Set Humditiy: %d, %d\n", (int) this->target_humidity, (int) remote_state[7]);
remote_header[9] |= 0x10;
last_humidity = remote_state[7];
}
uint16_t fan_speed = this->fan_speed_();
remote_state[8] = fan_speed >> 8;
remote_state[9] = fan_speed & 0xff;
// Calculate checksum
for (int i = 0; i < sizeof(remote_header) - 1; i++) {
remote_header[sizeof(remote_header) - 1] += remote_header[i];
}
// Calculate checksum
for (int i = 0; i < DAIKIN_STATE_FRAME_SIZE - 1; i++) {
remote_state[DAIKIN_STATE_FRAME_SIZE - 1] += remote_state[i];
}
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
data->set_carrier_frequency(DAIKIN_IR_FREQUENCY);
data->mark(DAIKIN_ARC_PRE_MARK);
data->space(DAIKIN_ARC_PRE_SPACE);
data->mark(DAIKIN_HEADER_MARK);
data->space(DAIKIN_HEADER_SPACE);
for (uint8_t i : remote_header) {
for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
data->mark(DAIKIN_BIT_MARK);
bool bit = i & mask;
data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
}
}
data->mark(DAIKIN_BIT_MARK);
data->space(DAIKIN_MESSAGE_SPACE);
data->mark(DAIKIN_HEADER_MARK);
data->space(DAIKIN_HEADER_SPACE);
for (uint8_t i : remote_state) {
for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
data->mark(DAIKIN_BIT_MARK);
bool bit = i & mask;
data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
}
}
data->mark(DAIKIN_BIT_MARK);
data->space(0);
transmit.perform();
}
uint8_t DaikinArcClimate::operation_mode_() {
uint8_t operating_mode = DAIKIN_MODE_ON;
switch (this->mode) {
case climate::CLIMATE_MODE_COOL:
operating_mode |= DAIKIN_MODE_COOL;
break;
case climate::CLIMATE_MODE_DRY:
operating_mode |= DAIKIN_MODE_DRY;
break;
case climate::CLIMATE_MODE_HEAT:
operating_mode |= DAIKIN_MODE_HEAT;
break;
case climate::CLIMATE_MODE_HEAT_COOL:
operating_mode |= DAIKIN_MODE_AUTO;
break;
case climate::CLIMATE_MODE_FAN_ONLY:
operating_mode |= DAIKIN_MODE_FAN;
break;
case climate::CLIMATE_MODE_OFF:
default:
operating_mode = DAIKIN_MODE_OFF;
break;
}
return operating_mode;
}
uint16_t DaikinArcClimate::fan_speed_() {
uint16_t fan_speed;
switch (this->fan_mode.value()) {
case climate::CLIMATE_FAN_LOW:
fan_speed = DAIKIN_FAN_1 << 8;
break;
case climate::CLIMATE_FAN_MEDIUM:
fan_speed = DAIKIN_FAN_3 << 8;
break;
case climate::CLIMATE_FAN_HIGH:
fan_speed = DAIKIN_FAN_5 << 8;
break;
case climate::CLIMATE_FAN_AUTO:
default:
fan_speed = DAIKIN_FAN_AUTO << 8;
}
// If swing is enabled switch first 4 bits to 1111
switch (this->swing_mode) {
case climate::CLIMATE_SWING_VERTICAL:
fan_speed |= 0x0F00;
break;
case climate::CLIMATE_SWING_HORIZONTAL:
fan_speed |= 0x000F;
break;
case climate::CLIMATE_SWING_BOTH:
fan_speed |= 0x0F0F;
break;
default:
break;
}
return fan_speed;
}
uint8_t DaikinArcClimate::temperature_() {
// Force special temperatures depending on the mode
switch (this->mode) {
case climate::CLIMATE_MODE_FAN_ONLY:
return 0x32;
case climate::CLIMATE_MODE_HEAT_COOL:
case climate::CLIMATE_MODE_DRY:
return 0xc0;
default:
float new_temp = clamp<float>(this->target_temperature, DAIKIN_TEMP_MIN, DAIKIN_TEMP_MAX);
uint8_t temperature = (uint8_t) floor(new_temp);
return temperature << 1 | (new_temp - temperature > 0 ? 0x01 : 0);
}
}
uint8_t DaikinArcClimate::humidity_() {
if (this->target_humidity == 39) {
return 0;
} else if (this->target_humidity <= 40 || this->target_humidity == 44) {
return 40;
} else if (this->target_humidity <= 45 || this->target_humidity == 49) // 41 - 45
{
return 45;
} else if (this->target_humidity <= 50 || this->target_humidity == 52) // 45 - 50
{
return 50;
} else {
return 0xff;
}
}
climate::ClimateTraits DaikinArcClimate::traits() {
climate::ClimateTraits traits = climate_ir::ClimateIR::traits();
traits.set_supports_current_temperature(true);
traits.set_supports_current_humidity(false);
traits.set_supports_target_humidity(true);
traits.set_visual_min_humidity(38);
traits.set_visual_max_humidity(52);
return traits;
}
bool DaikinArcClimate::parse_state_frame_(const uint8_t frame[]) {
uint8_t checksum = 0;
for (int i = 0; i < (DAIKIN_STATE_FRAME_SIZE - 1); i++) {
checksum += frame[i];
}
if (frame[DAIKIN_STATE_FRAME_SIZE - 1] != checksum) {
ESP_LOGI(TAG, "checksum error");
return false;
}
char buf[DAIKIN_STATE_FRAME_SIZE * 3 + 1] = {0};
for (size_t i = 0; i < DAIKIN_STATE_FRAME_SIZE; i++) {
sprintf(buf, "%s%02x ", buf, frame[i]);
}
ESP_LOGD(TAG, "FRAME %s", buf);
uint8_t mode = frame[5];
if (mode & DAIKIN_MODE_ON) {
switch (mode & 0xF0) {
case DAIKIN_MODE_COOL:
this->mode = climate::CLIMATE_MODE_COOL;
break;
case DAIKIN_MODE_DRY:
this->mode = climate::CLIMATE_MODE_DRY;
break;
case DAIKIN_MODE_HEAT:
this->mode = climate::CLIMATE_MODE_HEAT;
break;
case DAIKIN_MODE_AUTO:
this->mode = climate::CLIMATE_MODE_HEAT_COOL;
break;
case DAIKIN_MODE_FAN:
this->mode = climate::CLIMATE_MODE_FAN_ONLY;
break;
}
} else {
this->mode = climate::CLIMATE_MODE_OFF;
}
uint8_t temperature = frame[6];
if (!(temperature & 0xC0)) {
this->target_temperature = temperature >> 1;
this->target_temperature += (temperature & 0x1) ? 0.5 : 0;
}
this->target_humidity = frame[7]; // 0, 40, 45, 50, 0xff
uint8_t fan_mode = frame[8];
uint8_t swing_mode = frame[9];
if (fan_mode & 0xF && swing_mode & 0xF) {
this->swing_mode = climate::CLIMATE_SWING_BOTH;
} else if (fan_mode & 0xF) {
this->swing_mode = climate::CLIMATE_SWING_VERTICAL;
} else if (swing_mode & 0xF) {
this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
} else {
this->swing_mode = climate::CLIMATE_SWING_OFF;
}
switch (fan_mode & 0xF0) {
case DAIKIN_FAN_1:
case DAIKIN_FAN_2:
case DAIKIN_FAN_SILENT:
this->fan_mode = climate::CLIMATE_FAN_LOW;
break;
case DAIKIN_FAN_3:
this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
break;
case DAIKIN_FAN_4:
case DAIKIN_FAN_5:
this->fan_mode = climate::CLIMATE_FAN_HIGH;
break;
case DAIKIN_FAN_AUTO:
this->fan_mode = climate::CLIMATE_FAN_AUTO;
break;
}
/*
05 0 [1:3]MODE 1 [OFF TMR] [ON TMR] Power
06-07 TEMP
08 [0:3] SPEED [4:7] Swing
09 00
10 00
11, 12: timer
13 [0:6] 0000000 [7] POWERMODE
14 0a
15 c4
16 [0:3] 8 00 [6:7] SENSOR WIND = 11 / NORMAL = 00
17 24
05 06 07 08 09 10 11 12 13 14 15 16 17 18
None FRAME 11 da 27 00 00 49 2e 00 b0 00 00 06 60 00 0a c4 80 24 11
1H FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 c6 30 00 2a c4 80 24 c5
1H30 FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 a6 32 00 2a c4 80 24 a7
2H FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 86 34 00 2a c4 80 24 89
*/
this->publish_state();
return true;
}
bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
uint8_t state_frame[DAIKIN_STATE_FRAME_SIZE] = {};
bool valid_daikin_frame = false;
if (data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
valid_daikin_frame = true;
int bytes_count = data.size() / 2 / 8;
std::unique_ptr<char[]> buf(new char[bytes_count * 3 + 1]);
buf[0] = '\0';
for (size_t i = 0; i < bytes_count; i++) {
uint8_t byte = 0;
for (int8_t bit = 0; bit < 8; bit++) {
if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) {
byte |= 1 << bit;
} else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
valid_daikin_frame = false;
break;
}
}
sprintf(buf.get(), "%s%02x ", buf.get(), byte);
}
ESP_LOGD(TAG, "WHOLE FRAME %s size: %d", buf.get(), data.size());
}
if (!valid_daikin_frame) {
char sbuf[16 * 10 + 1];
sbuf[0] = '\0';
for (size_t j = 0; j < data.size(); j++) {
if ((j - 2) % 16 == 0) {
if (j > 0) {
ESP_LOGD(TAG, "DATA %04x: %s", (j - 16 > 0xffff ? 0 : j - 16), sbuf);
}
sbuf[0] = '\0';
}
char type_ch = ' ';
// debug_tolerance = 25%
if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK))
type_ch = 'P';
if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE))
type_ch = 'a';
if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK))
type_ch = 'H';
if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE))
type_ch = 'h';
if (DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK))
type_ch = 'B';
if (DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE))
type_ch = '1';
if (DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE))
type_ch = '0';
if (abs(data[j]) > 100000) {
sprintf(sbuf, "%s%-5d[%c] ", sbuf, data[j] > 0 ? 99999 : -99999, type_ch);
} else {
sprintf(sbuf, "%s%-5d[%c] ", sbuf, (int) (round(data[j] / 10.) * 10), type_ch);
}
if (j == data.size() - 1) {
ESP_LOGD(TAG, "DATA %04x: %s", (j - 8 > 0xffff ? 0 : j - 8), sbuf);
}
}
}
data.reset();
if (!data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
ESP_LOGI(TAG, "non daikin_arc expect item");
return false;
}
for (uint8_t pos = 0; pos < DAIKIN_STATE_FRAME_SIZE; pos++) {
uint8_t byte = 0;
for (int8_t bit = 0; bit < 8; bit++) {
if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) {
byte |= 1 << bit;
} else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
ESP_LOGI(TAG, "non daikin_arc expect item pos: %d", pos);
return false;
}
}
state_frame[pos] = byte;
if (pos == 0) {
// frame header
if (byte != 0x11) {
ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
return false;
}
} else if (pos == 1) {
// frame header
if (byte != 0xDA) {
ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
return false;
}
} else if (pos == 2) {
// frame header
if (byte != 0x27) {
ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
return false;
}
} else if (pos == 3) { // NOLINT(bugprone-branch-clone)
// frame header
if (byte != 0x00) {
ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
return false;
}
} else if (pos == 4) {
// frame type
if (byte != 0x00) {
ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
return false;
}
} else if (pos == 5) {
if (data.size() == 385) {
/*
11 da 27 00 00 1a 0c 04 2c 21 61 07 00 07 0c 00 18 00 0e 3c 00 6c 1b 61
Inside Temp
Outside Temp
Humdidity
*/
this->current_temperature = state_frame[5]; // Inside temperature
// this->current_temperature = state_frame[6]; // Outside temperature
this->publish_state();
return true;
} else if ((byte & 0x40) != 0x40) {
ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
return false;
}
}
}
return this->parse_state_frame_(state_frame);
}
void DaikinArcClimate::control(const climate::ClimateCall &call) {
if (call.get_target_humidity().has_value()) {
this->target_humidity = *call.get_target_humidity();
}
climate_ir::ClimateIR::control(call);
}
} // namespace daikin_arc
} // namespace esphome

View file

@ -0,0 +1,76 @@
#pragma once
#include "esphome/components/climate_ir/climate_ir.h"
namespace esphome {
namespace daikin_arc {
// Values for Daikin ARC43XXX IR Controllers
// Temperature
const uint8_t DAIKIN_TEMP_MIN = 10; // Celsius
const uint8_t DAIKIN_TEMP_MAX = 30; // Celsius
// Modes
const uint8_t DAIKIN_MODE_AUTO = 0x00;
const uint8_t DAIKIN_MODE_COOL = 0x30;
const uint8_t DAIKIN_MODE_HEAT = 0x40;
const uint8_t DAIKIN_MODE_DRY = 0x20;
const uint8_t DAIKIN_MODE_FAN = 0x60;
const uint8_t DAIKIN_MODE_OFF = 0x00;
const uint8_t DAIKIN_MODE_ON = 0x01;
// Fan Speed
const uint8_t DAIKIN_FAN_AUTO = 0xA0;
const uint8_t DAIKIN_FAN_SILENT = 0xB0;
const uint8_t DAIKIN_FAN_1 = 0x30;
const uint8_t DAIKIN_FAN_2 = 0x40;
const uint8_t DAIKIN_FAN_3 = 0x50;
const uint8_t DAIKIN_FAN_4 = 0x60;
const uint8_t DAIKIN_FAN_5 = 0x70;
// IR Transmission
const uint32_t DAIKIN_IR_FREQUENCY = 38000;
const uint32_t DAIKIN_ARC_PRE_MARK = 9950;
const uint32_t DAIKIN_ARC_PRE_SPACE = 25100;
const uint32_t DAIKIN_HEADER_MARK = 3450;
const uint32_t DAIKIN_HEADER_SPACE = 1760;
const uint32_t DAIKIN_BIT_MARK = 400;
const uint32_t DAIKIN_ONE_SPACE = 1300;
const uint32_t DAIKIN_ZERO_SPACE = 480;
const uint32_t DAIKIN_MESSAGE_SPACE = 35000;
const uint8_t DAIKIN_DBG_TOLERANCE = 25;
#define DAIKIN_DBG_LOWER(x) ((100 - DAIKIN_DBG_TOLERANCE) * (x) / 100U)
#define DAIKIN_DBG_UPPER(x) ((100 + DAIKIN_DBG_TOLERANCE) * (x) / 100U)
// State Frame size
const uint8_t DAIKIN_STATE_FRAME_SIZE = 19;
class DaikinArcClimate : public climate_ir::ClimateIR {
public:
DaikinArcClimate()
: climate_ir::ClimateIR(DAIKIN_TEMP_MIN, DAIKIN_TEMP_MAX, 0.5f, true, true,
{climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM,
climate::CLIMATE_FAN_HIGH},
{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL,
climate::CLIMATE_SWING_HORIZONTAL, climate::CLIMATE_SWING_BOTH}) {}
void setup() override;
protected:
void control(const climate::ClimateCall &call) override;
// Transmit via IR the state of this climate controller.
void transmit_query_();
void transmit_state() override;
climate::ClimateTraits traits() override;
uint8_t operation_mode_();
uint16_t fan_speed_();
uint8_t temperature_();
uint8_t humidity_();
// Handle received IR Buffer
bool on_receive(remote_base::RemoteReceiveData data) override;
bool parse_state_frame_(const uint8_t frame[]);
};
} // namespace daikin_arc
} // namespace esphome

View file

@ -155,6 +155,8 @@ CONFIG_SCHEMA = cv.All(
"DP83848": RMII_SCHEMA,
"IP101": RMII_SCHEMA,
"JL1101": RMII_SCHEMA,
"KSZ8081": RMII_SCHEMA,
"KSZ8081RNA": RMII_SCHEMA,
"W5500": SPI_SCHEMA,
},
upper=True,

View file

@ -0,0 +1 @@
CODEOWNERS = ["@Mafus1"]

View file

@ -0,0 +1,58 @@
#include "jsn_sr04t.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include <cinttypes>
// Very basic support for JSN_SR04T V3.0 distance sensor in mode 2
namespace esphome {
namespace jsn_sr04t {
static const char *const TAG = "jsn_sr04t.sensor";
void Jsnsr04tComponent::update() {
this->write_byte(0x55);
ESP_LOGV(TAG, "Request read out from sensor");
}
void Jsnsr04tComponent::loop() {
while (this->available() > 0) {
uint8_t data;
this->read_byte(&data);
ESP_LOGV(TAG, "Read byte from sensor: %x", data);
if (this->buffer_.empty() && data != 0xFF)
continue;
this->buffer_.push_back(data);
if (this->buffer_.size() == 4)
this->check_buffer_();
}
}
void Jsnsr04tComponent::check_buffer_() {
uint8_t checksum = this->buffer_[0] + this->buffer_[1] + this->buffer_[2];
if (this->buffer_[3] == checksum) {
uint16_t distance = encode_uint16(this->buffer_[1], this->buffer_[2]);
if (distance > 250) {
float meters = distance / 1000.0f;
ESP_LOGV(TAG, "Distance from sensor: %" PRIu32 "mm, %.3fm", distance, meters);
this->publish_state(meters);
} else {
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
}
} else {
ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]);
}
this->buffer_.clear();
}
void Jsnsr04tComponent::dump_config() {
LOG_SENSOR("", "JST_SR04T Sensor", this);
LOG_UPDATE_INTERVAL(this);
}
} // namespace jsn_sr04t
} // namespace esphome

View file

@ -0,0 +1,28 @@
#pragma once
#include <vector>
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace jsn_sr04t {
class Jsnsr04tComponent : public sensor::Sensor, public PollingComponent, public uart::UARTDevice {
public:
// Nothing really public.
// ========== INTERNAL METHODS ==========
void update() override;
void loop() override;
void dump_config() override;
protected:
void check_buffer_();
std::vector<uint8_t> buffer_;
};
} // namespace jsn_sr04t
} // namespace esphome

View file

@ -0,0 +1,44 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, uart
from esphome.const import (
STATE_CLASS_MEASUREMENT,
UNIT_METER,
ICON_ARROW_EXPAND_VERTICAL,
)
CODEOWNERS = ["@Mafus1"]
DEPENDENCIES = ["uart"]
jsn_sr04t_ns = cg.esphome_ns.namespace("jsn_sr04t")
Jsnsr04tComponent = jsn_sr04t_ns.class_(
"Jsnsr04tComponent", sensor.Sensor, cg.PollingComponent, uart.UARTDevice
)
CONFIG_SCHEMA = (
sensor.sensor_schema(
Jsnsr04tComponent,
unit_of_measurement=UNIT_METER,
icon=ICON_ARROW_EXPAND_VERTICAL,
accuracy_decimals=3,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(cv.polling_component_schema("60s"))
.extend(uart.UART_DEVICE_SCHEMA)
)
FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
"jsn_sr04t",
baud_rate=9600,
require_tx=True,
require_rx=True,
data_bits=8,
parity=None,
stop_bits=1,
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
await uart.register_uart_device(var, config)

View file

@ -51,5 +51,17 @@ void QrCode::draw(display::Display *buff, uint16_t x_offset, uint16_t y_offset,
}
}
}
uint8_t QrCode::get_size() {
if (this->needs_update_) {
this->generate_qr_code();
this->needs_update_ = false;
}
uint8_t size = qrcodegen_getSize(this->qr_);
return size;
}
} // namespace qr_code
} // namespace esphome

View file

@ -24,6 +24,8 @@ class QrCode : public Component {
void generate_qr_code();
uint8_t get_size();
protected:
std::string value_;
qrcodegen_Ecc ecc_;

View file

@ -14,6 +14,8 @@ from esphome.const import (
CONF_HEATER_ENABLED = "heater_enabled"
CODEOWNERS = ["@mrtoy-me"]
DEPENDENCIES = ["i2c"]
AUTO_LOAD = ["sensirion_common"]
@ -26,13 +28,13 @@ CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(SHT3XDComponent),
cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
accuracy_decimals=1,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Required(CONF_HUMIDITY): sensor.sensor_schema(
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
accuracy_decimals=1,
device_class=DEVICE_CLASS_HUMIDITY,

View file

@ -6,7 +6,11 @@ namespace sht3xd {
static const char *const TAG = "sht3xd";
static const uint16_t SHT3XD_COMMAND_READ_SERIAL_NUMBER = 0x3780;
// use read serial number register with clock stretching disabled as per other SHT3XD_COMMAND registers
// which provides support for SHT85 sensor
// SHT85 does not support clock stretching and uses same registers as SHT3xd with clock stretching disabled
static const uint16_t SHT3XD_COMMAND_READ_SERIAL_NUMBER = 0x3682;
static const uint16_t SHT3XD_COMMAND_READ_STATUS = 0xF32D;
static const uint16_t SHT3XD_COMMAND_CLEAR_STATUS = 0x3041;
static const uint16_t SHT3XD_COMMAND_HEATER_ENABLE = 0x306D;
@ -22,25 +26,32 @@ void SHT3XDComponent::setup() {
this->mark_failed();
return;
}
this->serial_number_ = (uint32_t(raw_serial_number[0]) << 16) | uint32_t(raw_serial_number[1]);
if (!this->write_command(heater_enabled_ ? SHT3XD_COMMAND_HEATER_ENABLE : SHT3XD_COMMAND_HEATER_DISABLE)) {
this->mark_failed();
return;
}
uint32_t serial_number = (uint32_t(raw_serial_number[0]) << 16) | uint32_t(raw_serial_number[1]);
ESP_LOGV(TAG, " Serial Number: 0x%08" PRIX32, serial_number);
}
void SHT3XDComponent::dump_config() {
ESP_LOGCONFIG(TAG, "SHT3xD:");
LOG_I2C_DEVICE(this);
if (this->is_failed()) {
ESP_LOGE(TAG, " Communication with SHT3xD failed!");
return;
}
ESP_LOGD(TAG, " Serial Number: 0x%08" PRIX32, this->serial_number_);
ESP_LOGD(TAG, " Heater Enabled: %s", this->heater_enabled_ ? "true" : "false");
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
}
float SHT3XDComponent::get_setup_priority() const { return setup_priority::DATA; }
void SHT3XDComponent::update() {
if (this->status_has_warning()) {
ESP_LOGD(TAG, "Retrying to reconnect the sensor.");

View file

@ -25,6 +25,7 @@ class SHT3XDComponent : public PollingComponent, public sensirion_common::Sensir
sensor::Sensor *temperature_sensor_{nullptr};
sensor::Sensor *humidity_sensor_{nullptr};
bool heater_enabled_{true};
uint32_t serial_number_{0};
};
} // namespace sht3xd

View file

@ -236,6 +236,7 @@ void SSD1306::set_invert(bool invert) {
// Inverse display mode (0xA6, 0xA7)
this->command(SSD1306_COMMAND_NORMAL_DISPLAY | this->invert_);
}
float SSD1306::get_contrast() { return this->contrast_; };
void SSD1306::set_contrast(float contrast) {
// validation
this->contrast_ = clamp(contrast, 0.0F, 1.0F);
@ -243,6 +244,7 @@ void SSD1306::set_contrast(float contrast) {
this->command(SSD1306_COMMAND_SET_CONTRAST);
this->command(int(SSD1306_MAX_CONTRAST * (this->contrast_)));
}
float SSD1306::get_brightness() { return this->brightness_; };
void SSD1306::set_brightness(float brightness) {
// validation
if (!this->is_ssd1305_())

View file

@ -36,7 +36,9 @@ class SSD1306 : public display::DisplayBuffer {
void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; }
void set_external_vcc(bool external_vcc) { this->external_vcc_ = external_vcc; }
void init_contrast(float contrast) { this->contrast_ = contrast; }
float get_contrast();
void set_contrast(float contrast);
float get_brightness();
void init_brightness(float brightness) { this->brightness_ = brightness; }
void set_brightness(float brightness);
void init_flip_x(bool flip_x) { this->flip_x_ = flip_x; }

View file

@ -0,0 +1,38 @@
esphome:
on_boot:
then:
- at581x.settings:
id: "Waveradar"
hw_frontend_reset: false
frequency: 5800MHz
sensing_distance: 200
poweron_selfcheck_time: 2s
protect_time: 1s
trigger_base: 500ms
trigger_keep: 10s
stage_gain: 3
power_consumption: 70uA
- at581x.reset:
id: "Waveradar"
at581x:
id: "Waveradar"
i2c_id: i2c_bus
i2c:
sda: 8
scl: 9
scan: true
frequency: 100kHz
setup_priority: -100
id: i2c_bus
binary_sensor:
- platform: gpio
pin: GPIO21
name: "Radar motion"
switch:
- platform: at581x
at581x_id: "Waveradar"
name: "Enable Radar"

View file

@ -0,0 +1,38 @@
esphome:
on_boot:
then:
- at581x.settings:
id: "Waveradar"
hw_frontend_reset: false
frequency: 5800MHz
sensing_distance: 200
poweron_selfcheck_time: 2s
protect_time: 1s
trigger_base: 500ms
trigger_keep: 10s
stage_gain: 3
power_consumption: 70uA
- at581x.reset:
id: "Waveradar"
at581x:
id: "Waveradar"
i2c_id: i2c_bus
i2c:
sda: 8
scl: 9
scan: true
frequency: 100kHz
setup_priority: -100
id: i2c_bus
binary_sensor:
- platform: gpio
pin: GPIO21
name: "Radar motion"
switch:
- platform: at581x
at581x_id: "Waveradar"
name: "Enable Radar"

View file

@ -0,0 +1,38 @@
esphome:
on_boot:
then:
- at581x.settings:
id: "Waveradar"
hw_frontend_reset: false
frequency: 5800MHz
sensing_distance: 200
poweron_selfcheck_time: 2s
protect_time: 1s
trigger_base: 500ms
trigger_keep: 10s
stage_gain: 3
power_consumption: 70uA
- at581x.reset:
id: "Waveradar"
at581x:
id: "Waveradar"
i2c_id: i2c_bus
i2c:
sda: 14
scl: 15
scan: true
frequency: 100kHz
setup_priority: -100
id: i2c_bus
binary_sensor:
- platform: gpio
pin: GPIO21
name: "Radar motion"
switch:
- platform: at581x
at581x_id: "Waveradar"
name: "Enable Radar"

View file

@ -0,0 +1,38 @@
esphome:
on_boot:
then:
- at581x.settings:
id: "Waveradar"
hw_frontend_reset: false
frequency: 5800MHz
sensing_distance: 200
poweron_selfcheck_time: 2s
protect_time: 1s
trigger_base: 500ms
trigger_keep: 10s
stage_gain: 3
power_consumption: 70uA
- at581x.reset:
id: "Waveradar"
at581x:
id: "Waveradar"
i2c_id: i2c_bus
i2c:
sda: 14
scl: 15
scan: true
frequency: 100kHz
setup_priority: -100
id: i2c_bus
binary_sensor:
- platform: gpio
pin: GPIO21
name: "Radar motion"
switch:
- platform: at581x
at581x_id: "Waveradar"
name: "Enable Radar"

View file

@ -0,0 +1,38 @@
esphome:
on_boot:
then:
- at581x.settings:
id: "Waveradar"
hw_frontend_reset: false
frequency: 5800MHz
sensing_distance: 200
poweron_selfcheck_time: 2s
protect_time: 1s
trigger_base: 500ms
trigger_keep: 10s
stage_gain: 3
power_consumption: 70uA
- at581x.reset:
id: "Waveradar"
at581x:
id: "Waveradar"
i2c_id: i2c_bus
i2c:
sda: 14
scl: 15
scan: true
frequency: 100kHz
setup_priority: -100
id: i2c_bus
binary_sensor:
- platform: gpio
pin: GPIO4
name: "Radar motion"
switch:
- platform: at581x
at581x_id: "Waveradar"
name: "Enable Radar"

View file

@ -0,0 +1,38 @@
esphome:
on_boot:
then:
- at581x.settings:
id: "Waveradar"
hw_frontend_reset: false
frequency: 5800MHz
sensing_distance: 200
poweron_selfcheck_time: 2s
protect_time: 1s
trigger_base: 500ms
trigger_keep: 10s
stage_gain: 3
power_consumption: 70uA
- at581x.reset:
id: "Waveradar"
at581x:
id: "Waveradar"
i2c_id: i2c_bus
i2c:
sda: 8
scl: 9
scan: true
frequency: 100kHz
setup_priority: -100
id: i2c_bus
binary_sensor:
- platform: gpio
pin: GPIO21
name: "Radar motion"
switch:
- platform: at581x
at581x_id: "Waveradar"
name: "Enable Radar"

View file

@ -0,0 +1,19 @@
remote_transmitter:
pin: 2
carrier_duty_percent: 50%
id: tsvr
remote_receiver:
id: rcvr
pin:
number: 27
inverted: true
mode:
input: true
pullup: true
tolerance: 40%
climate:
- platform: daikin_arc
name: "AC"
receiver_id: rcvr

View file

@ -0,0 +1,19 @@
remote_transmitter:
pin: 5
carrier_duty_percent: 50%
id: tsvr
remote_receiver:
id: rcvr
pin:
number: 2
inverted: true
mode:
input: true
pullup: true
tolerance: 40%
climate:
- platform: daikin_arc
name: "AC"
receiver_id: rcvr

View file

@ -0,0 +1,3 @@
button:
- platform: factory_reset
name: Reset to Factory Default Settings

View file

@ -0,0 +1,3 @@
button:
- platform: factory_reset
name: Reset to Factory Default Settings

View file

@ -0,0 +1,3 @@
button:
- platform: factory_reset
name: Reset to Factory Default Settings

View file

@ -0,0 +1,3 @@
button:
- platform: factory_reset
name: Reset to Factory Default Settings

View file

@ -0,0 +1,3 @@
button:
- platform: factory_reset
name: Reset to Factory Default Settings

View file

@ -0,0 +1,3 @@
button:
- platform: factory_reset
name: Reset to Factory Default Settings

View file

@ -0,0 +1,71 @@
light:
- platform: fastled_clockless
id: addr1
chipset: WS2811
pin: 13
num_leds: 100
rgb_order: BRG
max_refresh_rate: 20ms
color_correct: [75%, 100%, 50%]
name: FastLED WS2811 Light
effects:
- addressable_color_wipe:
- addressable_color_wipe:
name: Color Wipe Effect With Custom Values
colors:
- red: 100%
green: 100%
blue: 100%
num_leds: 1
- red: 0%
green: 0%
blue: 0%
num_leds: 1
add_led_interval: 100ms
reverse: false
- addressable_scan:
- addressable_scan:
name: Scan Effect With Custom Values
move_interval: 100ms
- addressable_twinkle:
- addressable_twinkle:
name: Twinkle Effect With Custom Values
twinkle_probability: 5%
progress_interval: 4ms
- addressable_random_twinkle:
- addressable_random_twinkle:
name: Random Twinkle Effect With Custom Values
twinkle_probability: 5%
progress_interval: 32ms
- addressable_fireworks:
- addressable_fireworks:
name: Fireworks Effect With Custom Values
update_interval: 32ms
spark_probability: 10%
use_random_color: false
fade_out_rate: 120
- addressable_flicker:
- addressable_flicker:
name: Flicker Effect With Custom Values
update_interval: 16ms
intensity: 5%
- addressable_lambda:
name: Test For Custom Lambda Effect
lambda: |-
if (initial_run) {
it[0] = current_color;
}
- automation:
name: Custom Effect
sequence:
- light.addressable_set:
id: addr1
red: 100%
green: 100%
blue: 0%
- delay: 100ms
- light.addressable_set:
id: addr1
red: 0%
green: 100%
blue: 0%

View file

@ -0,0 +1,71 @@
light:
- platform: fastled_spi
id: addr1
chipset: WS2801
clock_pin: 22
data_pin: 23
data_rate: 2MHz
num_leds: 60
rgb_order: BRG
name: FastLED SPI Light
effects:
- addressable_color_wipe:
- addressable_color_wipe:
name: Color Wipe Effect With Custom Values
colors:
- red: 100%
green: 100%
blue: 100%
num_leds: 1
- red: 0%
green: 0%
blue: 0%
num_leds: 1
add_led_interval: 100ms
reverse: false
- addressable_scan:
- addressable_scan:
name: Scan Effect With Custom Values
move_interval: 100ms
- addressable_twinkle:
- addressable_twinkle:
name: Twinkle Effect With Custom Values
twinkle_probability: 5%
progress_interval: 4ms
- addressable_random_twinkle:
- addressable_random_twinkle:
name: Random Twinkle Effect With Custom Values
twinkle_probability: 5%
progress_interval: 32ms
- addressable_fireworks:
- addressable_fireworks:
name: Fireworks Effect With Custom Values
update_interval: 32ms
spark_probability: 10%
use_random_color: false
fade_out_rate: 120
- addressable_flicker:
- addressable_flicker:
name: Flicker Effect With Custom Values
update_interval: 16ms
intensity: 5%
- addressable_lambda:
name: Test For Custom Lambda Effect
lambda: |-
if (initial_run) {
it[0] = current_color;
}
- automation:
name: Custom Effect
sequence:
- light.addressable_set:
id: addr1
red: 100%
green: 100%
blue: 0%
- delay: 100ms
- light.addressable_set:
id: addr1
red: 0%
green: 100%
blue: 0%

View file

@ -0,0 +1,39 @@
binary_sensor:
- platform: template
id: open_endstop_sensor
- platform: template
id: open_sensor
- platform: template
id: open_obstacle_sensor
- platform: template
id: close_endstop_sensor
- platform: template
id: close_sensor
- platform: template
id: close_obstacle_sensor
cover:
- platform: feedback
name: Feedback Cover
id: gate
device_class: gate
infer_endstop_from_movement: false
has_built_in_endstop: false
max_duration: 30s
direction_change_wait_time: 300ms
acceleration_wait_time: 150ms
obstacle_rollback: 10%
open_duration: 22.1s
open_endstop: open_endstop_sensor
open_sensor: open_sensor
open_obstacle_sensor: open_obstacle_sensor
close_duration: 22.4s
close_endstop: close_endstop_sensor
close_sensor: close_sensor
close_obstacle_sensor: close_obstacle_sensor
open_action:
- logger.log: Open Action
close_action:
- logger.log: Close Action
stop_action:
- logger.log: Stop Action

View file

@ -0,0 +1,39 @@
binary_sensor:
- platform: template
id: open_endstop_sensor
- platform: template
id: open_sensor
- platform: template
id: open_obstacle_sensor
- platform: template
id: close_endstop_sensor
- platform: template
id: close_sensor
- platform: template
id: close_obstacle_sensor
cover:
- platform: feedback
name: Feedback Cover
id: gate
device_class: gate
infer_endstop_from_movement: false
has_built_in_endstop: false
max_duration: 30s
direction_change_wait_time: 300ms
acceleration_wait_time: 150ms
obstacle_rollback: 10%
open_duration: 22.1s
open_endstop: open_endstop_sensor
open_sensor: open_sensor
open_obstacle_sensor: open_obstacle_sensor
close_duration: 22.4s
close_endstop: close_endstop_sensor
close_sensor: close_sensor
close_obstacle_sensor: close_obstacle_sensor
open_action:
- logger.log: Open Action
close_action:
- logger.log: Close Action
stop_action:
- logger.log: Stop Action

View file

@ -0,0 +1,39 @@
binary_sensor:
- platform: template
id: open_endstop_sensor
- platform: template
id: open_sensor
- platform: template
id: open_obstacle_sensor
- platform: template
id: close_endstop_sensor
- platform: template
id: close_sensor
- platform: template
id: close_obstacle_sensor
cover:
- platform: feedback
name: Feedback Cover
id: gate
device_class: gate
infer_endstop_from_movement: false
has_built_in_endstop: false
max_duration: 30s
direction_change_wait_time: 300ms
acceleration_wait_time: 150ms
obstacle_rollback: 10%
open_duration: 22.1s
open_endstop: open_endstop_sensor
open_sensor: open_sensor
open_obstacle_sensor: open_obstacle_sensor
close_duration: 22.4s
close_endstop: close_endstop_sensor
close_sensor: close_sensor
close_obstacle_sensor: close_obstacle_sensor
open_action:
- logger.log: Open Action
close_action:
- logger.log: Close Action
stop_action:
- logger.log: Stop Action

View file

@ -0,0 +1,39 @@
binary_sensor:
- platform: template
id: open_endstop_sensor
- platform: template
id: open_sensor
- platform: template
id: open_obstacle_sensor
- platform: template
id: close_endstop_sensor
- platform: template
id: close_sensor
- platform: template
id: close_obstacle_sensor
cover:
- platform: feedback
name: Feedback Cover
id: gate
device_class: gate
infer_endstop_from_movement: false
has_built_in_endstop: false
max_duration: 30s
direction_change_wait_time: 300ms
acceleration_wait_time: 150ms
obstacle_rollback: 10%
open_duration: 22.1s
open_endstop: open_endstop_sensor
open_sensor: open_sensor
open_obstacle_sensor: open_obstacle_sensor
close_duration: 22.4s
close_endstop: close_endstop_sensor
close_sensor: close_sensor
close_obstacle_sensor: close_obstacle_sensor
open_action:
- logger.log: Open Action
close_action:
- logger.log: Close Action
stop_action:
- logger.log: Stop Action

View file

@ -0,0 +1,39 @@
binary_sensor:
- platform: template
id: open_endstop_sensor
- platform: template
id: open_sensor
- platform: template
id: open_obstacle_sensor
- platform: template
id: close_endstop_sensor
- platform: template
id: close_sensor
- platform: template
id: close_obstacle_sensor
cover:
- platform: feedback
name: Feedback Cover
id: gate
device_class: gate
infer_endstop_from_movement: false
has_built_in_endstop: false
max_duration: 30s
direction_change_wait_time: 300ms
acceleration_wait_time: 150ms
obstacle_rollback: 10%
open_duration: 22.1s
open_endstop: open_endstop_sensor
open_sensor: open_sensor
open_obstacle_sensor: open_obstacle_sensor
close_duration: 22.4s
close_endstop: close_endstop_sensor
close_sensor: close_sensor
close_obstacle_sensor: close_obstacle_sensor
open_action:
- logger.log: Open Action
close_action:
- logger.log: Close Action
stop_action:
- logger.log: Stop Action

View file

@ -0,0 +1,39 @@
binary_sensor:
- platform: template
id: open_endstop_sensor
- platform: template
id: open_sensor
- platform: template
id: open_obstacle_sensor
- platform: template
id: close_endstop_sensor
- platform: template
id: close_sensor
- platform: template
id: close_obstacle_sensor
cover:
- platform: feedback
name: Feedback Cover
id: gate
device_class: gate
infer_endstop_from_movement: false
has_built_in_endstop: false
max_duration: 30s
direction_change_wait_time: 300ms
acceleration_wait_time: 150ms
obstacle_rollback: 10%
open_duration: 22.1s
open_endstop: open_endstop_sensor
open_sensor: open_sensor
open_obstacle_sensor: open_obstacle_sensor
close_duration: 22.4s
close_endstop: close_endstop_sensor
close_sensor: close_sensor
close_obstacle_sensor: close_obstacle_sensor
open_action:
- logger.log: Open Action
close_action:
- logger.log: Close Action
stop_action:
- logger.log: Stop Action

View file

@ -0,0 +1,56 @@
esphome:
on_boot:
then:
- fingerprint_grow.enroll:
finger_id: 2
num_scans: 2
- fingerprint_grow.cancel_enroll:
- fingerprint_grow.delete:
finger_id: 2
- fingerprint_grow.delete_all:
uart:
- id: uart_fingerprint_grow
tx_pin: 4
rx_pin: 5
baud_rate: 57600
fingerprint_grow:
sensing_pin: 6
password: 0x12FE37DC
new_password: 0xA65B9840
on_finger_scan_start:
- logger.log: test_fingerprint_grow_finger_scan_start
on_finger_scan_invalid:
- logger.log: test_fingerprint_grow_finger_scan_invalid
on_finger_scan_matched:
- logger.log: test_fingerprint_grow_finger_scan_matched
on_finger_scan_unmatched:
- logger.log: test_fingerprint_grow_finger_scan_unmatched
on_finger_scan_misplaced:
- logger.log: test_fingerprint_grow_finger_scan_misplaced
on_enrollment_scan:
- logger.log: test_fingerprint_grow_enrollment_scan
on_enrollment_done:
- logger.log: test_fingerprint_grow_node_enrollment_done
on_enrollment_failed:
- logger.log: test_fingerprint_grow_enrollment_failed
binary_sensor:
- platform: fingerprint_grow
name: Fingerprint Enrolling
sensor:
- platform: fingerprint_grow
fingerprint_count:
name: Fingerprint Count
status:
name: Fingerprint Status
capacity:
name: Fingerprint Capacity
security_level:
name: Fingerprint Security Level
last_finger_id:
name: Fingerprint Last Finger ID
last_confidence:
name: Fingerprint Last Confidence

View file

@ -0,0 +1,56 @@
esphome:
on_boot:
then:
- fingerprint_grow.enroll:
finger_id: 2
num_scans: 2
- fingerprint_grow.cancel_enroll:
- fingerprint_grow.delete:
finger_id: 2
- fingerprint_grow.delete_all:
uart:
- id: uart_fingerprint_grow
tx_pin: 4
rx_pin: 5
baud_rate: 57600
fingerprint_grow:
sensing_pin: 6
password: 0x12FE37DC
new_password: 0xA65B9840
on_finger_scan_start:
- logger.log: test_fingerprint_grow_finger_scan_start
on_finger_scan_invalid:
- logger.log: test_fingerprint_grow_finger_scan_invalid
on_finger_scan_matched:
- logger.log: test_fingerprint_grow_finger_scan_matched
on_finger_scan_unmatched:
- logger.log: test_fingerprint_grow_finger_scan_unmatched
on_finger_scan_misplaced:
- logger.log: test_fingerprint_grow_finger_scan_misplaced
on_enrollment_scan:
- logger.log: test_fingerprint_grow_enrollment_scan
on_enrollment_done:
- logger.log: test_fingerprint_grow_node_enrollment_done
on_enrollment_failed:
- logger.log: test_fingerprint_grow_enrollment_failed
binary_sensor:
- platform: fingerprint_grow
name: Fingerprint Enrolling
sensor:
- platform: fingerprint_grow
fingerprint_count:
name: Fingerprint Count
status:
name: Fingerprint Status
capacity:
name: Fingerprint Capacity
security_level:
name: Fingerprint Security Level
last_finger_id:
name: Fingerprint Last Finger ID
last_confidence:
name: Fingerprint Last Confidence

View file

@ -0,0 +1,56 @@
esphome:
on_boot:
then:
- fingerprint_grow.enroll:
finger_id: 2
num_scans: 2
- fingerprint_grow.cancel_enroll:
- fingerprint_grow.delete:
finger_id: 2
- fingerprint_grow.delete_all:
uart:
- id: uart_fingerprint_grow
tx_pin: 17
rx_pin: 16
baud_rate: 57600
fingerprint_grow:
sensing_pin: 18
password: 0x12FE37DC
new_password: 0xA65B9840
on_finger_scan_start:
- logger.log: test_fingerprint_grow_finger_scan_start
on_finger_scan_invalid:
- logger.log: test_fingerprint_grow_finger_scan_invalid
on_finger_scan_matched:
- logger.log: test_fingerprint_grow_finger_scan_matched
on_finger_scan_unmatched:
- logger.log: test_fingerprint_grow_finger_scan_unmatched
on_finger_scan_misplaced:
- logger.log: test_fingerprint_grow_finger_scan_misplaced
on_enrollment_scan:
- logger.log: test_fingerprint_grow_enrollment_scan
on_enrollment_done:
- logger.log: test_fingerprint_grow_node_enrollment_done
on_enrollment_failed:
- logger.log: test_fingerprint_grow_enrollment_failed
binary_sensor:
- platform: fingerprint_grow
name: Fingerprint Enrolling
sensor:
- platform: fingerprint_grow
fingerprint_count:
name: Fingerprint Count
status:
name: Fingerprint Status
capacity:
name: Fingerprint Capacity
security_level:
name: Fingerprint Security Level
last_finger_id:
name: Fingerprint Last Finger ID
last_confidence:
name: Fingerprint Last Confidence

View file

@ -0,0 +1,56 @@
esphome:
on_boot:
then:
- fingerprint_grow.enroll:
finger_id: 2
num_scans: 2
- fingerprint_grow.cancel_enroll:
- fingerprint_grow.delete:
finger_id: 2
- fingerprint_grow.delete_all:
uart:
- id: uart_fingerprint_grow
tx_pin: 17
rx_pin: 16
baud_rate: 57600
fingerprint_grow:
sensing_pin: 18
password: 0x12FE37DC
new_password: 0xA65B9840
on_finger_scan_start:
- logger.log: test_fingerprint_grow_finger_scan_start
on_finger_scan_invalid:
- logger.log: test_fingerprint_grow_finger_scan_invalid
on_finger_scan_matched:
- logger.log: test_fingerprint_grow_finger_scan_matched
on_finger_scan_unmatched:
- logger.log: test_fingerprint_grow_finger_scan_unmatched
on_finger_scan_misplaced:
- logger.log: test_fingerprint_grow_finger_scan_misplaced
on_enrollment_scan:
- logger.log: test_fingerprint_grow_enrollment_scan
on_enrollment_done:
- logger.log: test_fingerprint_grow_node_enrollment_done
on_enrollment_failed:
- logger.log: test_fingerprint_grow_enrollment_failed
binary_sensor:
- platform: fingerprint_grow
name: Fingerprint Enrolling
sensor:
- platform: fingerprint_grow
fingerprint_count:
name: Fingerprint Count
status:
name: Fingerprint Status
capacity:
name: Fingerprint Capacity
security_level:
name: Fingerprint Security Level
last_finger_id:
name: Fingerprint Last Finger ID
last_confidence:
name: Fingerprint Last Confidence

View file

@ -0,0 +1,56 @@
esphome:
on_boot:
then:
- fingerprint_grow.enroll:
finger_id: 2
num_scans: 2
- fingerprint_grow.cancel_enroll:
- fingerprint_grow.delete:
finger_id: 2
- fingerprint_grow.delete_all:
uart:
- id: uart_fingerprint_grow
tx_pin: 4
rx_pin: 5
baud_rate: 57600
fingerprint_grow:
sensing_pin: 16
password: 0x12FE37DC
new_password: 0xA65B9840
on_finger_scan_start:
- logger.log: test_fingerprint_grow_finger_scan_start
on_finger_scan_invalid:
- logger.log: test_fingerprint_grow_finger_scan_invalid
on_finger_scan_matched:
- logger.log: test_fingerprint_grow_finger_scan_matched
on_finger_scan_unmatched:
- logger.log: test_fingerprint_grow_finger_scan_unmatched
on_finger_scan_misplaced:
- logger.log: test_fingerprint_grow_finger_scan_misplaced
on_enrollment_scan:
- logger.log: test_fingerprint_grow_enrollment_scan
on_enrollment_done:
- logger.log: test_fingerprint_grow_node_enrollment_done
on_enrollment_failed:
- logger.log: test_fingerprint_grow_enrollment_failed
binary_sensor:
- platform: fingerprint_grow
name: Fingerprint Enrolling
sensor:
- platform: fingerprint_grow
fingerprint_count:
name: Fingerprint Count
status:
name: Fingerprint Status
capacity:
name: Fingerprint Capacity
security_level:
name: Fingerprint Security Level
last_finger_id:
name: Fingerprint Last Finger ID
last_confidence:
name: Fingerprint Last Confidence

View file

@ -0,0 +1,56 @@
esphome:
on_boot:
then:
- fingerprint_grow.enroll:
finger_id: 2
num_scans: 2
- fingerprint_grow.cancel_enroll:
- fingerprint_grow.delete:
finger_id: 2
- fingerprint_grow.delete_all:
uart:
- id: uart_fingerprint_grow
tx_pin: 4
rx_pin: 5
baud_rate: 57600
fingerprint_grow:
sensing_pin: 6
password: 0x12FE37DC
new_password: 0xA65B9840
on_finger_scan_start:
- logger.log: test_fingerprint_grow_finger_scan_start
on_finger_scan_invalid:
- logger.log: test_fingerprint_grow_finger_scan_invalid
on_finger_scan_matched:
- logger.log: test_fingerprint_grow_finger_scan_matched
on_finger_scan_unmatched:
- logger.log: test_fingerprint_grow_finger_scan_unmatched
on_finger_scan_misplaced:
- logger.log: test_fingerprint_grow_finger_scan_misplaced
on_enrollment_scan:
- logger.log: test_fingerprint_grow_enrollment_scan
on_enrollment_done:
- logger.log: test_fingerprint_grow_node_enrollment_done
on_enrollment_failed:
- logger.log: test_fingerprint_grow_enrollment_failed
binary_sensor:
- platform: fingerprint_grow
name: Fingerprint Enrolling
sensor:
- platform: fingerprint_grow
fingerprint_count:
name: Fingerprint Count
status:
name: Fingerprint Status
capacity:
name: Fingerprint Capacity
security_level:
name: Fingerprint Security Level
last_finger_id:
name: Fingerprint Last Finger ID
last_confidence:
name: Fingerprint Last Confidence

View file

@ -0,0 +1,19 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20

View file

@ -0,0 +1,19 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20

View file

@ -0,0 +1,19 @@
i2c:
- id: i2c_font
scl: 16
sda: 17
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 13
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20

View file

@ -0,0 +1,19 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20

View file

@ -0,0 +1,19 @@
i2c:
- id: i2c_font
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
font:
- file: "gfonts://Roboto"
id: roboto
size: 20

View file

@ -0,0 +1,10 @@
i2c:
- id: i2c_fs3000
scl: 5
sda: 4
sensor:
- platform: fs3000
name: Air Velocity
model: 1005
update_interval: 60s

View file

@ -0,0 +1,10 @@
i2c:
- id: i2c_fs3000
scl: 5
sda: 4
sensor:
- platform: fs3000
name: Air Velocity
model: 1005
update_interval: 60s

View file

@ -0,0 +1,10 @@
i2c:
- id: i2c_fs3000
scl: 16
sda: 17
sensor:
- platform: fs3000
name: Air Velocity
model: 1005
update_interval: 60s

View file

@ -0,0 +1,10 @@
i2c:
- id: i2c_fs3000
scl: 16
sda: 17
sensor:
- platform: fs3000
name: Air Velocity
model: 1005
update_interval: 60s

View file

@ -0,0 +1,10 @@
i2c:
- id: i2c_fs3000
scl: 5
sda: 4
sensor:
- platform: fs3000
name: Air Velocity
model: 1005
update_interval: 60s

View file

@ -0,0 +1,10 @@
i2c:
- id: i2c_fs3000
scl: 5
sda: 4
sensor:
- platform: fs3000
name: Air Velocity
model: 1005
update_interval: 60s

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft5x06
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft5x06
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft5x06
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft5x06
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft5x06
scl: 16
sda: 17
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 18
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft5x06
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft5x06
scl: 16
sda: 17
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 18
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft5x06
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft5x06
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft5x06
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft5x06
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft5x06
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft63x6
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft63x6
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft63x6
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft63x6
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft63x6
scl: 16
sda: 17
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 18
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft63x6
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft63x6
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft63x6
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,21 @@
i2c:
- id: i2c_ft63x6
scl: 5
sda: 4
display:
- platform: ssd1306_i2c
id: ssd1306_display
model: SSD1306_128X64
reset_pin: 3
pages:
- id: page1
lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height());
touchscreen:
- platform: ft63x6
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

View file

@ -0,0 +1,7 @@
remote_transmitter:
pin: 2
carrier_duty_percent: 50%
climate:
- platform: fujitsu_general
name: Fujitsu General Climate

View file

@ -0,0 +1,7 @@
remote_transmitter:
pin: 2
carrier_duty_percent: 50%
climate:
- platform: fujitsu_general
name: Fujitsu General Climate

View file

@ -0,0 +1,7 @@
remote_transmitter:
pin: 2
carrier_duty_percent: 50%
climate:
- platform: fujitsu_general
name: Fujitsu General Climate

View file

@ -0,0 +1,7 @@
remote_transmitter:
pin: 2
carrier_duty_percent: 50%
climate:
- platform: fujitsu_general
name: Fujitsu General Climate

View file

@ -0,0 +1,7 @@
remote_transmitter:
pin: 5
carrier_duty_percent: 50%
climate:
- platform: fujitsu_general
name: Fujitsu General Climate

View file

@ -0,0 +1,25 @@
uart:
- id: uart_gcja5
tx_pin: 4
rx_pin: 5
baud_rate: 9600
parity: EVEN
sensor:
- platform: gcja5
pm_1_0:
name: "Particulate Matter <1.0µm Concentration"
pm_2_5:
name: "Particulate Matter <2.5µm Concentration"
pm_10_0:
name: "Particulate Matter <10.0µm Concentration"
pmc_0_5:
name: "PMC 0.5"
pmc_1_0:
name: "PMC 1.0"
pmc_2_5:
name: "PMC 2.5"
pmc_5_0:
name: "PMC 5.0"
pmc_10_0:
name: "PMC 10.0"

View file

@ -0,0 +1,25 @@
uart:
- id: uart_gcja5
tx_pin: 4
rx_pin: 5
baud_rate: 9600
parity: EVEN
sensor:
- platform: gcja5
pm_1_0:
name: "Particulate Matter <1.0µm Concentration"
pm_2_5:
name: "Particulate Matter <2.5µm Concentration"
pm_10_0:
name: "Particulate Matter <10.0µm Concentration"
pmc_0_5:
name: "PMC 0.5"
pmc_1_0:
name: "PMC 1.0"
pmc_2_5:
name: "PMC 2.5"
pmc_5_0:
name: "PMC 5.0"
pmc_10_0:
name: "PMC 10.0"

View file

@ -0,0 +1,25 @@
uart:
- id: uart_gcja5
tx_pin: 17
rx_pin: 16
baud_rate: 9600
parity: EVEN
sensor:
- platform: gcja5
pm_1_0:
name: "Particulate Matter <1.0µm Concentration"
pm_2_5:
name: "Particulate Matter <2.5µm Concentration"
pm_10_0:
name: "Particulate Matter <10.0µm Concentration"
pmc_0_5:
name: "PMC 0.5"
pmc_1_0:
name: "PMC 1.0"
pmc_2_5:
name: "PMC 2.5"
pmc_5_0:
name: "PMC 5.0"
pmc_10_0:
name: "PMC 10.0"

View file

@ -0,0 +1,25 @@
uart:
- id: uart_gcja5
tx_pin: 17
rx_pin: 16
baud_rate: 9600
parity: EVEN
sensor:
- platform: gcja5
pm_1_0:
name: "Particulate Matter <1.0µm Concentration"
pm_2_5:
name: "Particulate Matter <2.5µm Concentration"
pm_10_0:
name: "Particulate Matter <10.0µm Concentration"
pmc_0_5:
name: "PMC 0.5"
pmc_1_0:
name: "PMC 1.0"
pmc_2_5:
name: "PMC 2.5"
pmc_5_0:
name: "PMC 5.0"
pmc_10_0:
name: "PMC 10.0"

View file

@ -0,0 +1,25 @@
uart:
- id: uart_gcja5
tx_pin: 4
rx_pin: 5
baud_rate: 9600
parity: EVEN
sensor:
- platform: gcja5
pm_1_0:
name: "Particulate Matter <1.0µm Concentration"
pm_2_5:
name: "Particulate Matter <2.5µm Concentration"
pm_10_0:
name: "Particulate Matter <10.0µm Concentration"
pmc_0_5:
name: "PMC 0.5"
pmc_1_0:
name: "PMC 1.0"
pmc_2_5:
name: "PMC 2.5"
pmc_5_0:
name: "PMC 5.0"
pmc_10_0:
name: "PMC 10.0"

View file

@ -0,0 +1,25 @@
uart:
- id: uart_gcja5
tx_pin: 4
rx_pin: 5
baud_rate: 9600
parity: EVEN
sensor:
- platform: gcja5
pm_1_0:
name: "Particulate Matter <1.0µm Concentration"
pm_2_5:
name: "Particulate Matter <2.5µm Concentration"
pm_10_0:
name: "Particulate Matter <10.0µm Concentration"
pmc_0_5:
name: "PMC 0.5"
pmc_1_0:
name: "PMC 1.0"
pmc_2_5:
name: "PMC 2.5"
pmc_5_0:
name: "PMC 5.0"
pmc_10_0:
name: "PMC 10.0"

View file

@ -0,0 +1,28 @@
esphome:
on_boot:
then:
- globals.set:
id: glob_int
value: "10"
globals:
- id: glob_int
type: int
restore_value: true
initial_value: "0"
- id: glob_float
type: float
restore_value: true
initial_value: "0.0f"
- id: glob_bool
type: bool
restore_value: false
initial_value: "true"
- id: glob_string
type: std::string
restore_value: false
# initial_value: ""
- id: glob_bool_processed
type: bool
restore_value: false
initial_value: "false"

View file

@ -0,0 +1,28 @@
esphome:
on_boot:
then:
- globals.set:
id: glob_int
value: "10"
globals:
- id: glob_int
type: int
restore_value: true
initial_value: "0"
- id: glob_float
type: float
restore_value: true
initial_value: "0.0f"
- id: glob_bool
type: bool
restore_value: false
initial_value: "true"
- id: glob_string
type: std::string
restore_value: false
# initial_value: ""
- id: glob_bool_processed
type: bool
restore_value: false
initial_value: "false"

View file

@ -0,0 +1,28 @@
esphome:
on_boot:
then:
- globals.set:
id: glob_int
value: "10"
globals:
- id: glob_int
type: int
restore_value: true
initial_value: "0"
- id: glob_float
type: float
restore_value: true
initial_value: "0.0f"
- id: glob_bool
type: bool
restore_value: false
initial_value: "true"
- id: glob_string
type: std::string
restore_value: false
# initial_value: ""
- id: glob_bool_processed
type: bool
restore_value: false
initial_value: "false"

View file

@ -0,0 +1,28 @@
esphome:
on_boot:
then:
- globals.set:
id: glob_int
value: "10"
globals:
- id: glob_int
type: int
restore_value: true
initial_value: "0"
- id: glob_float
type: float
restore_value: true
initial_value: "0.0f"
- id: glob_bool
type: bool
restore_value: false
initial_value: "true"
- id: glob_string
type: std::string
restore_value: false
# initial_value: ""
- id: glob_bool_processed
type: bool
restore_value: false
initial_value: "false"

View file

@ -0,0 +1,28 @@
esphome:
on_boot:
then:
- globals.set:
id: glob_int
value: "10"
globals:
- id: glob_int
type: int
restore_value: true
initial_value: "0"
- id: glob_float
type: float
restore_value: true
initial_value: "0.0f"
- id: glob_bool
type: bool
restore_value: false
initial_value: "true"
- id: glob_string
type: std::string
restore_value: false
# initial_value: ""
- id: glob_bool_processed
type: bool
restore_value: false
initial_value: "false"

Some files were not shown because too many files have changed in this diff Show more