Merge branch 'dev' into add-graphical-layout-system

This commit is contained in:
Michael Davidson 2024-04-03 22:42:18 +11:00 committed by GitHub
commit 12de837e9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
388 changed files with 11650 additions and 67 deletions

View File

@ -17,7 +17,7 @@ runs:
steps: steps:
- name: Set up Python ${{ inputs.python-version }} - name: Set up Python ${{ inputs.python-version }}
id: python id: python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: ${{ inputs.python-version }} python-version: ${{ inputs.python-version }}
- name: Restore Python virtual environment - name: Restore Python virtual environment

View File

@ -1,6 +1,5 @@
name: API Proto CI name: API Proto CI
# yamllint disable-line rule:truthy
on: on:
pull_request: pull_request:
paths: paths:
@ -24,7 +23,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.1 uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: "3.11" python-version: "3.11"

View File

@ -2,7 +2,7 @@
name: CI for docker images name: CI for docker images
# Only run when docker paths change # Only run when docker paths change
# yamllint disable-line rule:truthy
on: on:
push: push:
branches: [dev, beta, release] branches: [dev, beta, release]
@ -42,7 +42,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: "3.9" python-version: "3.9"
- name: Set up Docker Buildx - name: Set up Docker Buildx

View File

@ -1,7 +1,6 @@
--- ---
name: CI name: CI
# yamllint disable-line rule:truthy
on: on:
push: push:
branches: [dev, beta, release] branches: [dev, beta, release]
@ -42,7 +41,7 @@ jobs:
run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python id: python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment - name: Restore Python virtual environment

View File

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

View File

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

View File

@ -1,7 +1,6 @@
--- ---
name: Publish Release name: Publish Release
# yamllint disable-line rule:truthy
on: on:
workflow_dispatch: workflow_dispatch:
release: release:
@ -45,7 +44,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: "3.x" python-version: "3.x"
- name: Set up python environment - name: Set up python environment
@ -80,7 +79,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: "3.9" python-version: "3.9"

View File

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

View File

@ -1,7 +1,6 @@
--- ---
name: Synchronise Device Classes from Home Assistant name: Synchronise Device Classes from Home Assistant
# yamllint disable-line rule:truthy
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
@ -23,7 +22,7 @@ jobs:
path: lib/home-assistant path: lib/home-assistant
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v5.0.0 uses: actions/setup-python@v5.1.0
with: with:
python-version: 3.11 python-version: 3.11

View File

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

View File

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

View File

@ -87,6 +87,7 @@ esphome/components/cst816/* @clydebarrow
esphome/components/ct_clamp/* @jesserockz esphome/components/ct_clamp/* @jesserockz
esphome/components/current_based/* @djwmarcx esphome/components/current_based/* @djwmarcx
esphome/components/dac7678/* @NickB1 esphome/components/dac7678/* @NickB1
esphome/components/daikin_arc/* @MagicBear
esphome/components/daikin_brc/* @hagak esphome/components/daikin_brc/* @hagak
esphome/components/daly_bms/* @s1lvi0 esphome/components/daly_bms/* @s1lvi0
esphome/components/dashboard_import/* @esphome/core esphome/components/dashboard_import/* @esphome/core
@ -174,6 +175,7 @@ esphome/components/inkplate6/* @jesserockz
esphome/components/integration/* @OttoWinter esphome/components/integration/* @OttoWinter
esphome/components/internal_temperature/* @Mat931 esphome/components/internal_temperature/* @Mat931
esphome/components/interval/* @esphome/core esphome/components/interval/* @esphome/core
esphome/components/jsn_sr04t/* @Mafus1
esphome/components/json/* @OttoWinter esphome/components/json/* @OttoWinter
esphome/components/kamstrup_kmp/* @cfeenstra1024 esphome/components/kamstrup_kmp/* @cfeenstra1024
esphome/components/key_collector/* @ssieb esphome/components/key_collector/* @ssieb
@ -308,6 +310,7 @@ esphome/components/sfa30/* @ghsensdev
esphome/components/sgp40/* @SenexCrenshaw esphome/components/sgp40/* @SenexCrenshaw
esphome/components/sgp4x/* @SenexCrenshaw @martgras esphome/components/sgp4x/* @SenexCrenshaw @martgras
esphome/components/shelly_dimmer/* @edge90 @rnauber esphome/components/shelly_dimmer/* @edge90 @rnauber
esphome/components/sht3xd/* @mrtoy-me
esphome/components/sht4x/* @sjtrny esphome/components/sht4x/* @sjtrny
esphome/components/shutdown/* @esphome/core @jsuanet esphome/components/shutdown/* @esphome/core @jsuanet
esphome/components/sigma_delta_output/* @Cat-Ion esphome/components/sigma_delta_output/* @Cat-Ion

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

@ -60,6 +60,8 @@ void DisplayMenuComponent::left() {
if (this->editing_) { if (this->editing_) {
this->finish_editing_(); this->finish_editing_();
changed = true; changed = true;
} else {
changed = this->leave_menu_();
} }
break; break;
case MENU_MODE_JOYSTICK: case MENU_MODE_JOYSTICK:

View File

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

View File

@ -12,12 +12,12 @@ static const char *const TAG = "audio";
void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) { void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
if (call.get_media_url().has_value()) { if (call.get_media_url().has_value()) {
this->current_url_ = call.get_media_url(); this->current_url_ = call.get_media_url();
if (this->i2s_state_ != I2S_STATE_STOPPED && this->audio_ != nullptr) {
if (this->state == media_player::MEDIA_PLAYER_STATE_PLAYING && this->audio_ != nullptr) {
if (this->audio_->isRunning()) { if (this->audio_->isRunning()) {
this->audio_->stopSong(); this->audio_->stopSong();
} }
this->audio_->connecttohost(this->current_url_.value().c_str()); this->audio_->connecttohost(this->current_url_.value().c_str());
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
} else { } else {
this->start(); this->start();
} }

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

@ -4,6 +4,7 @@
#include <cstdio> #include <cstdio>
#include <array> #include <array>
#include "esphome/core/macros.h" #include "esphome/core/macros.h"
#include "esphome/core/helpers.h"
#if defined(USE_ESP_IDF) || defined(USE_LIBRETINY) || USE_ARDUINO_VERSION_CODE > VERSION_CODE(3, 0, 0) #if defined(USE_ESP_IDF) || defined(USE_LIBRETINY) || USE_ARDUINO_VERSION_CODE > VERSION_CODE(3, 0, 0)
#include <lwip/ip_addr.h> #include <lwip/ip_addr.h>
@ -116,7 +117,7 @@ struct IPAddress {
bool is_set() { return !ip_addr_isany(&ip_addr_); } bool is_set() { return !ip_addr_isany(&ip_addr_); }
bool is_ip4() { return IP_IS_V4(&ip_addr_); } bool is_ip4() { return IP_IS_V4(&ip_addr_); }
bool is_ip6() { return IP_IS_V6(&ip_addr_); } bool is_ip6() { return IP_IS_V6(&ip_addr_); }
std::string str() const { return ipaddr_ntoa(&ip_addr_); } std::string str() const { return str_lower_case(ipaddr_ntoa(&ip_addr_)); }
bool operator==(const IPAddress &other) const { return ip_addr_cmp(&ip_addr_, &other.ip_addr_); } bool operator==(const IPAddress &other) const { return ip_addr_cmp(&ip_addr_, &other.ip_addr_); }
bool operator!=(const IPAddress &other) const { return !ip_addr_cmp(&ip_addr_, &other.ip_addr_); } bool operator!=(const IPAddress &other) const { return !ip_addr_cmp(&ip_addr_, &other.ip_addr_); }
IPAddress &operator+=(uint8_t increase) { IPAddress &operator+=(uint8_t increase) {

View File

@ -1,16 +1,17 @@
#pragma once #pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h" #include "esphome/components/uart/uart.h"
#include "esphome/core/component.h"
namespace esphome { namespace esphome {
namespace pmsx003 { namespace pmsx003 {
// known command bytes // known command bytes
#define PMS_CMD_AUTO_MANUAL 0xE1 // data=0: perform measurement manually, data=1: perform measurement automatically static const uint8_t PMS_CMD_AUTO_MANUAL =
#define PMS_CMD_TRIG_MANUAL 0xE2 // trigger a manual measurement 0xE1; // data=0: perform measurement manually, data=1: perform measurement automatically
#define PMS_CMD_ON_STANDBY 0xE4 // data=0: go to standby mode, data=1: go to normal mode static const uint8_t PMS_CMD_TRIG_MANUAL = 0xE2; // trigger a manual measurement
static const uint8_t PMS_CMD_ON_STANDBY = 0xE4; // data=0: go to standby mode, data=1: go to normal mode
static const uint16_t PMS_STABILISING_MS = 30000; // time taken for the sensor to become stable after power on static const uint16_t PMS_STABILISING_MS = 30000; // time taken for the sensor to become stable after power on

View File

@ -72,19 +72,13 @@ void QMC5883LComponent::dump_config() {
LOG_SENSOR(" ", "Y Axis", this->y_sensor_); LOG_SENSOR(" ", "Y Axis", this->y_sensor_);
LOG_SENSOR(" ", "Z Axis", this->z_sensor_); LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
LOG_SENSOR(" ", "Heading", this->heading_sensor_); LOG_SENSOR(" ", "Heading", this->heading_sensor_);
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
} }
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; } float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
void QMC5883LComponent::update() { void QMC5883LComponent::update() {
uint8_t status = false; uint8_t status = false;
this->read_byte(QMC5883L_REGISTER_STATUS, &status); if (ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG)
this->read_byte(QMC5883L_REGISTER_STATUS, &status);
uint16_t raw_x, raw_y, raw_z;
if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_X_LSB, &raw_x) ||
!this->read_byte_16_(QMC5883L_REGISTER_DATA_Y_LSB, &raw_y) ||
!this->read_byte_16_(QMC5883L_REGISTER_DATA_Z_LSB, &raw_z)) {
this->status_set_warning();
return;
}
float mg_per_bit; float mg_per_bit;
switch (this->range_) { switch (this->range_) {
@ -99,12 +93,49 @@ void QMC5883LComponent::update() {
} }
// in µT // in µT
const float x = int16_t(raw_x) * mg_per_bit * 0.1f; float x = NAN, y = NAN, z = NAN;
const float y = int16_t(raw_y) * mg_per_bit * 0.1f; if (this->x_sensor_ != nullptr || this->heading_sensor_ != nullptr) {
const float z = int16_t(raw_z) * mg_per_bit * 0.1f; uint16_t raw_x;
if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_X_LSB, &raw_x)) {
this->status_set_warning();
return;
}
x = int16_t(raw_x) * mg_per_bit * 0.1f;
}
if (this->y_sensor_ != nullptr || this->heading_sensor_ != nullptr) {
uint16_t raw_y;
if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_Y_LSB, &raw_y)) {
this->status_set_warning();
return;
}
y = int16_t(raw_y) * mg_per_bit * 0.1f;
}
if (this->z_sensor_ != nullptr) {
uint16_t raw_z;
if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_Z_LSB, &raw_z)) {
this->status_set_warning();
return;
}
z = int16_t(raw_z) * mg_per_bit * 0.1f;
}
float heading = atan2f(0.0f - x, y) * 180.0f / M_PI; float heading = NAN;
ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f° status=%u", x, y, z, heading, status); if (this->heading_sensor_ != nullptr) {
heading = atan2f(0.0f - x, y) * 180.0f / M_PI;
}
float temp = NAN;
if (this->temperature_sensor_ != nullptr) {
uint16_t raw_temp;
if (!this->read_byte_16_(QMC5883L_REGISTER_TEMPERATURE_LSB, &raw_temp)) {
this->status_set_warning();
return;
}
temp = int16_t(raw_temp) * 0.01f;
}
ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f° temperature=%0.01f°C status=%u", x, y, z, heading,
temp, status);
if (this->x_sensor_ != nullptr) if (this->x_sensor_ != nullptr)
this->x_sensor_->publish_state(x); this->x_sensor_->publish_state(x);
@ -114,6 +145,8 @@ void QMC5883LComponent::update() {
this->z_sensor_->publish_state(z); this->z_sensor_->publish_state(z);
if (this->heading_sensor_ != nullptr) if (this->heading_sensor_ != nullptr)
this->heading_sensor_->publish_state(heading); this->heading_sensor_->publish_state(heading);
if (this->temperature_sensor_ != nullptr)
this->temperature_sensor_->publish_state(temp);
} }
bool QMC5883LComponent::read_byte_16_(uint8_t a_register, uint16_t *data) { bool QMC5883LComponent::read_byte_16_(uint8_t a_register, uint16_t *data) {

View File

@ -40,6 +40,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
void set_y_sensor(sensor::Sensor *y_sensor) { y_sensor_ = y_sensor; } void set_y_sensor(sensor::Sensor *y_sensor) { y_sensor_ = y_sensor; }
void set_z_sensor(sensor::Sensor *z_sensor) { z_sensor_ = z_sensor; } void set_z_sensor(sensor::Sensor *z_sensor) { z_sensor_ = z_sensor; }
void set_heading_sensor(sensor::Sensor *heading_sensor) { heading_sensor_ = heading_sensor; } void set_heading_sensor(sensor::Sensor *heading_sensor) { heading_sensor_ = heading_sensor; }
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; }
protected: protected:
QMC5883LDatarate datarate_{QMC5883L_DATARATE_10_HZ}; QMC5883LDatarate datarate_{QMC5883L_DATARATE_10_HZ};
@ -49,6 +50,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
sensor::Sensor *y_sensor_{nullptr}; sensor::Sensor *y_sensor_{nullptr};
sensor::Sensor *z_sensor_{nullptr}; sensor::Sensor *z_sensor_{nullptr};
sensor::Sensor *heading_sensor_{nullptr}; sensor::Sensor *heading_sensor_{nullptr};
sensor::Sensor *temperature_sensor_{nullptr};
enum ErrorCode { enum ErrorCode {
NONE = 0, NONE = 0,
COMMUNICATION_FAILED, COMMUNICATION_FAILED,

View File

@ -6,12 +6,15 @@ from esphome.const import (
CONF_FIELD_STRENGTH_X, CONF_FIELD_STRENGTH_X,
CONF_FIELD_STRENGTH_Y, CONF_FIELD_STRENGTH_Y,
CONF_FIELD_STRENGTH_Z, CONF_FIELD_STRENGTH_Z,
CONF_TEMPERATURE,
CONF_ID, CONF_ID,
CONF_OVERSAMPLING, CONF_OVERSAMPLING,
CONF_RANGE, CONF_RANGE,
DEVICE_CLASS_TEMPERATURE,
ICON_MAGNET, ICON_MAGNET,
STATE_CLASS_MEASUREMENT, STATE_CLASS_MEASUREMENT,
UNIT_MICROTESLA, UNIT_MICROTESLA,
UNIT_CELSIUS,
UNIT_DEGREES, UNIT_DEGREES,
ICON_SCREEN_ROTATION, ICON_SCREEN_ROTATION,
CONF_UPDATE_INTERVAL, CONF_UPDATE_INTERVAL,
@ -79,6 +82,12 @@ heading_schema = sensor.sensor_schema(
icon=ICON_SCREEN_ROTATION, icon=ICON_SCREEN_ROTATION,
accuracy_decimals=1, accuracy_decimals=1,
) )
temperature_schema = sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
accuracy_decimals=1,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
)
CONFIG_SCHEMA = ( CONFIG_SCHEMA = (
cv.Schema( cv.Schema(
@ -95,6 +104,7 @@ CONFIG_SCHEMA = (
cv.Optional(CONF_FIELD_STRENGTH_Y): field_strength_schema, cv.Optional(CONF_FIELD_STRENGTH_Y): field_strength_schema,
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema, cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
cv.Optional(CONF_HEADING): heading_schema, cv.Optional(CONF_HEADING): heading_schema,
cv.Optional(CONF_TEMPERATURE): temperature_schema,
} }
) )
.extend(cv.polling_component_schema("60s")) .extend(cv.polling_component_schema("60s"))
@ -131,3 +141,6 @@ async def to_code(config):
if CONF_HEADING in config: if CONF_HEADING in config:
sens = await sensor.new_sensor(config[CONF_HEADING]) sens = await sensor.new_sensor(config[CONF_HEADING])
cg.add(var.set_heading_sensor(sens)) cg.add(var.set_heading_sensor(sens))
if CONF_TEMPERATURE in config:
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
cg.add(var.set_temperature_sensor(sens))

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 qr_code
} // namespace esphome } // namespace esphome

View File

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

View File

@ -74,12 +74,12 @@ def _format_framework_arduino_version(ver: cv.Version) -> str:
# The default/recommended arduino framework version # The default/recommended arduino framework version
# - https://github.com/earlephilhower/arduino-pico/releases # - https://github.com/earlephilhower/arduino-pico/releases
# - https://api.registry.platformio.org/v3/packages/earlephilhower/tool/framework-arduinopico # - https://api.registry.platformio.org/v3/packages/earlephilhower/tool/framework-arduinopico
RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 6, 0) RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 7, 2)
# The platformio/raspberrypi version to use for arduino frameworks # The platformio/raspberrypi version to use for arduino frameworks
# - https://github.com/platformio/platform-raspberrypi/releases # - https://github.com/platformio/platform-raspberrypi/releases
# - https://api.registry.platformio.org/v3/packages/platformio/platform/raspberrypi # - https://api.registry.platformio.org/v3/packages/platformio/platform/raspberrypi
ARDUINO_PLATFORM_VERSION = cv.Version(1, 10, 0) ARDUINO_PLATFORM_VERSION = cv.Version(1, 12, 0)
def _arduino_check_versions(value): def _arduino_check_versions(value):

View File

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

View File

@ -6,7 +6,11 @@ namespace sht3xd {
static const char *const TAG = "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_READ_STATUS = 0xF32D;
static const uint16_t SHT3XD_COMMAND_CLEAR_STATUS = 0x3041; static const uint16_t SHT3XD_COMMAND_CLEAR_STATUS = 0x3041;
static const uint16_t SHT3XD_COMMAND_HEATER_ENABLE = 0x306D; static const uint16_t SHT3XD_COMMAND_HEATER_ENABLE = 0x306D;
@ -22,25 +26,32 @@ void SHT3XDComponent::setup() {
this->mark_failed(); this->mark_failed();
return; 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)) { if (!this->write_command(heater_enabled_ ? SHT3XD_COMMAND_HEATER_ENABLE : SHT3XD_COMMAND_HEATER_DISABLE)) {
this->mark_failed(); this->mark_failed();
return; 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() { void SHT3XDComponent::dump_config() {
ESP_LOGCONFIG(TAG, "SHT3xD:"); ESP_LOGCONFIG(TAG, "SHT3xD:");
LOG_I2C_DEVICE(this);
if (this->is_failed()) { if (this->is_failed()) {
ESP_LOGE(TAG, "Communication with SHT3xD 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_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_); LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
} }
float SHT3XDComponent::get_setup_priority() const { return setup_priority::DATA; } float SHT3XDComponent::get_setup_priority() const { return setup_priority::DATA; }
void SHT3XDComponent::update() { void SHT3XDComponent::update() {
if (this->status_has_warning()) { if (this->status_has_warning()) {
ESP_LOGD(TAG, "Retrying to reconnect the sensor."); 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 *temperature_sensor_{nullptr};
sensor::Sensor *humidity_sensor_{nullptr}; sensor::Sensor *humidity_sensor_{nullptr};
bool heater_enabled_{true}; bool heater_enabled_{true};
uint32_t serial_number_{0};
}; };
} // namespace sht3xd } // namespace sht3xd

View File

@ -236,6 +236,7 @@ void SSD1306::set_invert(bool invert) {
// Inverse display mode (0xA6, 0xA7) // Inverse display mode (0xA6, 0xA7)
this->command(SSD1306_COMMAND_NORMAL_DISPLAY | this->invert_); this->command(SSD1306_COMMAND_NORMAL_DISPLAY | this->invert_);
} }
float SSD1306::get_contrast() { return this->contrast_; };
void SSD1306::set_contrast(float contrast) { void SSD1306::set_contrast(float contrast) {
// validation // validation
this->contrast_ = clamp(contrast, 0.0F, 1.0F); 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(SSD1306_COMMAND_SET_CONTRAST);
this->command(int(SSD1306_MAX_CONTRAST * (this->contrast_))); this->command(int(SSD1306_MAX_CONTRAST * (this->contrast_)));
} }
float SSD1306::get_brightness() { return this->brightness_; };
void SSD1306::set_brightness(float brightness) { void SSD1306::set_brightness(float brightness) {
// validation // validation
if (!this->is_ssd1305_()) 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_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; }
void set_external_vcc(bool external_vcc) { this->external_vcc_ = external_vcc; } void set_external_vcc(bool external_vcc) { this->external_vcc_ = external_vcc; }
void init_contrast(float contrast) { this->contrast_ = contrast; } void init_contrast(float contrast) { this->contrast_ = contrast; }
float get_contrast();
void set_contrast(float contrast); void set_contrast(float contrast);
float get_brightness();
void init_brightness(float brightness) { this->brightness_ = brightness; } void init_brightness(float brightness) { this->brightness_ = brightness; }
void set_brightness(float brightness); void set_brightness(float brightness);
void init_flip_x(bool flip_x) { this->flip_x_ = flip_x; } void init_flip_x(bool flip_x) { this->flip_x_ = flip_x; }

View File

@ -30,37 +30,37 @@ CONFIG_SCHEMA = cv.All(
def determine_config_register(polling_period): def determine_config_register(polling_period):
if polling_period >= 16.0: if polling_period >= 16000:
# 64 averaged conversions, max conversion time # 64 averaged conversions, max conversion time
# 0000 00 111 11 00000 # 0000 00 111 11 00000
# 0000 0011 1110 0000 # 0000 0011 1110 0000
return 0x03E0 return 0x03E0
if polling_period >= 8.0: if polling_period >= 8000:
# 64 averaged conversions, high conversion time # 64 averaged conversions, high conversion time
# 0000 00 110 11 00000 # 0000 00 110 11 00000
# 0000 0011 0110 0000 # 0000 0011 0110 0000
return 0x0360 return 0x0360
if polling_period >= 4.0: if polling_period >= 4000:
# 64 averaged conversions, mid conversion time # 64 averaged conversions, mid conversion time
# 0000 00 101 11 00000 # 0000 00 101 11 00000
# 0000 0010 1110 0000 # 0000 0010 1110 0000
return 0x02E0 return 0x02E0
if polling_period >= 1.0: if polling_period >= 1000:
# 64 averaged conversions, min conversion time # 64 averaged conversions, min conversion time
# 0000 00 000 11 00000 # 0000 00 000 11 00000
# 0000 0000 0110 0000 # 0000 0000 0110 0000
return 0x0060 return 0x0060
if polling_period >= 0.5: if polling_period >= 500:
# 32 averaged conversions, min conversion time # 32 averaged conversions, min conversion time
# 0000 00 000 10 00000 # 0000 00 000 10 00000
# 0000 0000 0100 0000 # 0000 0000 0100 0000
return 0x0040 return 0x0040
if polling_period >= 0.25: if polling_period >= 250:
# 8 averaged conversions, mid conversion time # 8 averaged conversions, mid conversion time
# 0000 00 010 01 00000 # 0000 00 010 01 00000
# 0000 0001 0010 0000 # 0000 0001 0010 0000
return 0x0120 return 0x0120
if polling_period >= 0.125: if polling_period >= 125:
# 8 averaged conversions, min conversion time # 8 averaged conversions, min conversion time
# 0000 00 000 01 00000 # 0000 00 000 01 00000
# 0000 0000 0010 0000 # 0000 0000 0010 0000
@ -76,5 +76,5 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
update_period = config[CONF_UPDATE_INTERVAL].total_seconds update_period = config[CONF_UPDATE_INTERVAL].total_milliseconds
cg.add(var.set_config(determine_config_register(update_period))) cg.add(var.set_config(determine_config_register(update_period)))

View File

@ -59,17 +59,14 @@ def clone_or_update(
) )
repo_dir = _compute_destination_path(key, domain) repo_dir = _compute_destination_path(key, domain)
fetch_pr_branch = ref is not None and ref.startswith("pull/")
if not repo_dir.is_dir(): if not repo_dir.is_dir():
_LOGGER.info("Cloning %s", key) _LOGGER.info("Cloning %s", key)
_LOGGER.debug("Location: %s", repo_dir) _LOGGER.debug("Location: %s", repo_dir)
cmd = ["git", "clone", "--depth=1"] cmd = ["git", "clone", "--depth=1"]
if ref is not None and not fetch_pr_branch:
cmd += ["--branch", ref]
cmd += ["--", url, str(repo_dir)] cmd += ["--", url, str(repo_dir)]
run_git_command(cmd) run_git_command(cmd)
if fetch_pr_branch: if ref is not None:
# We need to fetch the PR branch first, otherwise git will complain # We need to fetch the PR branch first, otherwise git will complain
# about missing objects # about missing objects
_LOGGER.info("Fetching %s", ref) _LOGGER.info("Fetching %s", ref)

View File

@ -154,13 +154,12 @@ extra_scripts = post:esphome/components/esp32/post_build.py.script
; These are common settings for the RP2040 using Arduino. ; These are common settings for the RP2040 using Arduino.
[common:rp2040-arduino] [common:rp2040-arduino]
extends = common:arduino extends = common:arduino
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
platform = https://github.com/maxgerhardt/platform-raspberrypi.git platform = https://github.com/maxgerhardt/platform-raspberrypi.git
platform_packages = platform_packages =
; earlephilhower/framework-arduinopico@~1.20602.0 ; Cannot use the platformio package until old releases stop getting deleted ; earlephilhower/framework-arduinopico@~1.20602.0 ; Cannot use the platformio package until old releases stop getting deleted
earlephilhower/framework-arduinopico@https://github.com/earlephilhower/arduino-pico/releases/download/3.6.0/rp2040-3.6.0.zip earlephilhower/framework-arduinopico@https://github.com/earlephilhower/arduino-pico/releases/download/3.7.2/rp2040-3.7.2.zip
framework = arduino framework = arduino
lib_deps = lib_deps =

View File

@ -1,3 +1,4 @@
# Useful stuff when working in a development environment # Useful stuff when working in a development environment
clang-format==13.0.1 clang-format==13.0.1
clang-tidy==14.0.6 clang-tidy==14.0.6
yamllint==1.35.1

View File

@ -57,6 +57,7 @@ file_types = (
"", "",
) )
cpp_include = ("*.h", "*.c", "*.cpp", "*.tcc") cpp_include = ("*.h", "*.c", "*.cpp", "*.tcc")
py_include = ("*.py",)
ignore_types = (".ico", ".png", ".woff", ".woff2", "") ignore_types = (".ico", ".png", ".woff", ".woff2", "")
LINT_FILE_CHECKS = [] LINT_FILE_CHECKS = []
@ -265,7 +266,8 @@ def lint_end_newline(fname, content):
return None return None
CPP_RE_EOL = r"\s*?(?://.*?)?$" CPP_RE_EOL = r".*?(?://.*?)?$"
PY_RE_EOL = r".*?(?:#.*?)?$"
def highlight(s): def highlight(s):
@ -273,7 +275,7 @@ def highlight(s):
@lint_re_check( @lint_re_check(
r"^#define\s+([a-zA-Z0-9_]+)\s+([0-9bx]+)" + CPP_RE_EOL, r"^#define\s+([a-zA-Z0-9_]+)\s+(0b[10]+|0x[0-9a-fA-F]+|\d+)\s*?(?:\/\/.*?)?$",
include=cpp_include, include=cpp_include,
exclude=[ exclude=[
"esphome/core/log.h", "esphome/core/log.h",
@ -574,11 +576,6 @@ def lint_pragma_once(fname, content):
return None return None
@lint_re_check(
r"(whitelist|blacklist|slave)",
exclude=["script/ci-custom.py"],
flags=re.IGNORECASE | re.MULTILINE,
)
def lint_inclusive_language(fname, match): def lint_inclusive_language(fname, match):
# From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49decddd39e5f6132ccd7d9fdc3d7c470b0061bb # From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49decddd39e5f6132ccd7d9fdc3d7c470b0061bb
return ( return (
@ -596,6 +593,21 @@ def lint_inclusive_language(fname, match):
) )
lint_re_check(
r"(whitelist|blacklist|slave)" + PY_RE_EOL,
include=py_include,
exclude=["script/ci-custom.py"],
flags=re.IGNORECASE | re.MULTILINE,
)(lint_inclusive_language)
lint_re_check(
r"(whitelist|blacklist|slave)" + CPP_RE_EOL,
include=cpp_include,
flags=re.IGNORECASE | re.MULTILINE,
)(lint_inclusive_language)
@lint_re_check(r"[\t\r\f\v ]+$") @lint_re_check(r"[\t\r\f\v ]+$")
def lint_trailing_whitespace(fname, match): def lint_trailing_whitespace(fname, match):
return "Trailing whitespace detected" return "Trailing whitespace detected"

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"

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