mirror of
https://github.com/esphome/esphome.git
synced 2026-10-26 16:02:13 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0ecd7a20c |
No files matched your search
@@ -212,10 +212,9 @@ file does, and it is the authority when they disagree. The most useful starting
|
||||
logged with `get_log_str` and `LOG_STR_ARG`, copied out with `ESPHOME_strncpy_P` before `publish_state`.
|
||||
A `dump_config` helper that picks a name returns `const LogString *` from `LOG_STR(...)`.
|
||||
* **CRCs and bit tricks** come from `esphome/core/helpers.h` (`crc8`, `crc16`, `xor_bytes`, `sum16_bytes`,
|
||||
`reverse_bits`, `encode_uint16`, `encode_value_le`, `sign_extend<BITS>`, `bcd_to_uint8`, `assign_bits`,
|
||||
`bit_at`); pick the helper's arguments instead of writing a loop. 7-byte BCD RTC calendars use
|
||||
`time::decode_bcd_calendar<LAYOUT>` and `encode_bcd_calendar<LAYOUT>` with `EPSON_BCD_CALENDAR`,
|
||||
`DS_BCD_CALENDAR` or `PCF_BCD_CALENDAR`.
|
||||
`reverse_bits`, `encode_uint16`, `encode_value_le`, `sign_extend<BITS>`, `bcd_to_uint8`, `assign_bits`); pick
|
||||
the helper's arguments instead of writing a loop. 7-byte BCD RTC calendars use `time::decode_bcd_calendar<LAYOUT>`
|
||||
and `encode_bcd_calendar<LAYOUT>` with `EPSON_BCD_CALENDAR`, `DS_BCD_CALENDAR` or `PCF_BCD_CALENDAR`.
|
||||
* **Bus helpers:** UART drains with `read_available(on_byte)` and `discard_available()`, text lines with
|
||||
`LineReader<N>`; I2C has `update_register`, `write_registers` (PROGMEM `I2CRegValue` table), `check_chip_id`
|
||||
and `read_bytes_16_le`. `if (!this->status_comm_result(ok)) return;` sets or clears the warning.
|
||||
@@ -447,6 +446,8 @@ file does, and it is the authority when they disagree. The most useful starting
|
||||
switches = switch.sub_switches(config, parent=hub)
|
||||
await switches(CONF_BLUETOOTH, None, apply="set_bluetooth(state)", publish="after")
|
||||
```
|
||||
Restore an owned or standalone switch in `setup()` with `sw->restore_state()`, or
|
||||
`restore_state(default)` to still drive a state when the restore mode is disabled.
|
||||
|
||||
- **Other codegen helpers:** `uart.new_uart_component(config, *ctor_args)` (and `i2c.new_i2c_component`,
|
||||
`spi.new_spi_component`, `modbus.new_modbus_client_component`, `ble_client.new_ble_node_component`)
|
||||
|
||||
@@ -53,6 +53,13 @@ optional<bool> Switch::get_initial_state_with_restore_mode() {
|
||||
}
|
||||
return initial_state;
|
||||
}
|
||||
void Switch::restore_state() {
|
||||
if (auto initial = this->get_initial_state_with_restore_mode())
|
||||
this->control(*initial);
|
||||
}
|
||||
void Switch::restore_state(bool when_disabled) {
|
||||
this->control(this->get_initial_state_with_restore_mode().value_or(when_disabled));
|
||||
}
|
||||
void Switch::publish_state(bool state) {
|
||||
if (!this->publish_dedup_.next(state))
|
||||
return;
|
||||
|
||||
@@ -110,6 +110,11 @@ class Switch : public EntityBase {
|
||||
*/
|
||||
optional<bool> get_initial_state_with_restore_mode();
|
||||
|
||||
/// Drive the switch to the state its restore mode yields, through control(), so inversion and
|
||||
/// write_state() apply; a disabled restore mode drives `when_disabled`, or nothing without one.
|
||||
void restore_state();
|
||||
void restore_state(bool when_disabled);
|
||||
|
||||
/** Return whether this switch uses an assumed state - i.e. if both the ON/OFF actions should be displayed in Home
|
||||
* Assistant because the real state is unknown.
|
||||
*
|
||||
|
||||
@@ -1077,9 +1077,6 @@ template<typename T> ESPHOME_ALWAYS_INLINE constexpr void assign_bits(T &value,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether bit \p bit (0 is the LSB) of \p value is set; the read side of assign_bits().
|
||||
template<typename T> ESPHOME_ALWAYS_INLINE constexpr bool bit_at(T value, unsigned bit) { return (value >> bit) & 1; }
|
||||
|
||||
/// Reverse the order of 8 bits.
|
||||
inline uint8_t reverse_bits(uint8_t x) {
|
||||
x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome::core::testing {
|
||||
|
||||
static_assert(bit_at(uint8_t{0b1010'0001}, 0));
|
||||
static_assert(!bit_at(uint8_t{0b1010'0001}, 1));
|
||||
static_assert(bit_at(uint8_t{0b1010'0001}, 7));
|
||||
static_assert(bit_at(uint64_t{1} << 63, 63));
|
||||
static_assert(!bit_at(uint64_t{1} << 63, 62));
|
||||
static_assert(bit_at(int32_t{-1}, 31));
|
||||
static_assert(!bit_at(int32_t{0x7FFF'FFFF}, 31));
|
||||
|
||||
TEST(BitAt, IsTheReadSideOfAssignBits) {
|
||||
uint16_t reg = 0;
|
||||
assign_bits(reg, 1 << 9, true);
|
||||
EXPECT_TRUE(bit_at(reg, 9));
|
||||
assign_bits(reg, 1 << 9, false);
|
||||
EXPECT_FALSE(bit_at(reg, 9));
|
||||
}
|
||||
|
||||
} // namespace esphome::core::testing
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
|
||||
namespace esphome::switch_::testing {
|
||||
|
||||
class RecordingSwitch : public Switch {
|
||||
public:
|
||||
std::vector<bool> writes;
|
||||
|
||||
protected:
|
||||
void write_state(bool state) override {
|
||||
this->writes.push_back(state);
|
||||
this->publish_state(state);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(RestoreState, DrivesTheRestoreModeStateThroughInversion) {
|
||||
RecordingSwitch on, off, inverted;
|
||||
on.set_restore_mode(SWITCH_ALWAYS_ON);
|
||||
off.set_restore_mode(SWITCH_ALWAYS_OFF);
|
||||
inverted.set_restore_mode(SWITCH_ALWAYS_ON);
|
||||
inverted.set_inverted(true);
|
||||
on.restore_state();
|
||||
off.restore_state();
|
||||
inverted.restore_state();
|
||||
EXPECT_EQ(on.writes, std::vector<bool>{true});
|
||||
EXPECT_EQ(off.writes, std::vector<bool>{false});
|
||||
EXPECT_EQ(inverted.writes, std::vector<bool>{false}); // the hardware level
|
||||
EXPECT_TRUE(on.state);
|
||||
EXPECT_FALSE(off.state);
|
||||
EXPECT_TRUE(inverted.state);
|
||||
}
|
||||
|
||||
TEST(RestoreState, DefaultAppliesOnlyWhenTheModeIsDisabled) {
|
||||
RecordingSwitch disabled, on;
|
||||
disabled.set_restore_mode(SWITCH_RESTORE_DISABLED);
|
||||
on.set_restore_mode(SWITCH_ALWAYS_ON);
|
||||
disabled.restore_state();
|
||||
EXPECT_TRUE(disabled.writes.empty());
|
||||
disabled.restore_state(true);
|
||||
on.restore_state(false);
|
||||
EXPECT_EQ(disabled.writes, std::vector<bool>{true});
|
||||
EXPECT_EQ(on.writes, std::vector<bool>{true});
|
||||
}
|
||||
|
||||
} // namespace esphome::switch_::testing
|
||||
Reference in new issue
Block a user