Refactor children state update mechanism (#24)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
8df1b9c0cb
commit
eee27761b2
|
@ -4,6 +4,7 @@ external_components:
|
|||
- source:
|
||||
type: git
|
||||
url: https://github.com/esphome-ratgdo/esphome-ratgdo
|
||||
ref: observer_callbacks
|
||||
refresh: 1s
|
||||
|
||||
preferences:
|
||||
|
|
|
@ -54,7 +54,7 @@ RATGDO_CLIENT_SCHMEA = cv.Schema(
|
|||
|
||||
async def register_ratgdo_child(var, config):
|
||||
parent = await cg.get_variable(config[CONF_RATGDO_ID])
|
||||
cg.add(parent.register_child(var))
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
|
|
|
@ -11,6 +11,24 @@ namespace ratgdo {
|
|||
{
|
||||
if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_MOTION || this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_OBSTRUCTION || this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_BUTTON)
|
||||
this->publish_state(false);
|
||||
|
||||
if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_MOTION) {
|
||||
this->parent_->subscribe_motion_state([=](MotionState state) {
|
||||
this->publish_state(state == MotionState::MOTION_STATE_DETECTED);
|
||||
});
|
||||
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_OBSTRUCTION) {
|
||||
this->parent_->subscribe_obstruction_state([=](ObstructionState state) {
|
||||
this->publish_state(state == ObstructionState::OBSTRUCTION_STATE_OBSTRUCTED);
|
||||
});
|
||||
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_MOTOR) {
|
||||
this->parent_->subscribe_motor_state([=](MotorState state) {
|
||||
this->publish_state(state == MotorState::MOTOR_STATE_ON);
|
||||
});
|
||||
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_BUTTON) {
|
||||
this->parent_->subscribe_button_state([=](ButtonState state) {
|
||||
this->publish_state(state == ButtonState::BUTTON_STATE_PRESSED);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOBinarySensor::dump_config()
|
||||
|
@ -26,30 +44,6 @@ namespace ratgdo {
|
|||
ESP_LOGCONFIG(TAG, " Type: Button");
|
||||
}
|
||||
}
|
||||
void RATGDOBinarySensor::on_motion_state(MotionState state)
|
||||
{
|
||||
if (this->binary_sensor_type_ != SensorType::RATGDO_SENSOR_MOTION)
|
||||
return;
|
||||
this->publish_state(state == MotionState::MOTION_STATE_DETECTED);
|
||||
}
|
||||
void RATGDOBinarySensor::on_obstruction_state(ObstructionState state)
|
||||
{
|
||||
if (this->binary_sensor_type_ != SensorType::RATGDO_SENSOR_OBSTRUCTION)
|
||||
return;
|
||||
this->publish_state(state == ObstructionState::OBSTRUCTION_STATE_OBSTRUCTED);
|
||||
}
|
||||
void RATGDOBinarySensor::on_motor_state(MotorState state)
|
||||
{
|
||||
if (this->binary_sensor_type_ != SensorType::RATGDO_SENSOR_MOTOR)
|
||||
return;
|
||||
this->publish_state(state == MotorState::MOTOR_STATE_ON);
|
||||
}
|
||||
void RATGDOBinarySensor::on_button_state(ButtonState state)
|
||||
{
|
||||
if (this->binary_sensor_type_ != SensorType::RATGDO_SENSOR_BUTTON)
|
||||
return;
|
||||
this->publish_state(state == ButtonState::BUTTON_STATE_PRESSED);
|
||||
}
|
||||
|
||||
} // namespace ratgdo
|
||||
} // namespace esphome
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../ratgdo.h"
|
||||
#include "../ratgdo_child.h"
|
||||
#include "../ratgdo_state.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
@ -22,11 +21,6 @@ namespace ratgdo {
|
|||
void dump_config() override;
|
||||
void set_binary_sensor_type(SensorType binary_sensor_type_) { this->binary_sensor_type_ = binary_sensor_type_; }
|
||||
|
||||
void on_motion_state(MotionState state) override;
|
||||
void on_obstruction_state(ObstructionState state) override;
|
||||
void on_motor_state(MotorState state) override;
|
||||
void on_button_state(ButtonState state) override;
|
||||
|
||||
protected:
|
||||
SensorType binary_sensor_type_;
|
||||
};
|
||||
|
|
|
@ -13,6 +13,14 @@ namespace ratgdo {
|
|||
{
|
||||
LOG_COVER("", "RATGDO Cover", this);
|
||||
}
|
||||
|
||||
void RATGDOCover::setup()
|
||||
{
|
||||
this->parent_->subscribe_door_state([=](DoorState state, float position) {
|
||||
this->on_door_state(state, position);
|
||||
});
|
||||
}
|
||||
|
||||
void RATGDOCover::on_door_state(DoorState state, float position)
|
||||
{
|
||||
switch (state) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../ratgdo.h"
|
||||
#include "../ratgdo_child.h"
|
||||
#include "../ratgdo_state.h"
|
||||
#include "esphome/components/cover/cover.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
@ -12,8 +11,10 @@ namespace ratgdo {
|
|||
class RATGDOCover : public cover::Cover, public RATGDOClient, public Component {
|
||||
public:
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
|
||||
cover::CoverTraits get_traits() override;
|
||||
void on_door_state(DoorState state, float position) override;
|
||||
void on_door_state(DoorState state, float position);
|
||||
|
||||
protected:
|
||||
void control(const cover::CoverCall& call) override;
|
||||
|
|
|
@ -13,6 +13,14 @@ namespace ratgdo {
|
|||
{
|
||||
ESP_LOGCONFIG("", "RATGDO Light");
|
||||
}
|
||||
|
||||
void RATGDOLightOutput::setup()
|
||||
{
|
||||
this->parent_->subscribe_light_state([=](LightState s) {
|
||||
this->on_light_state(s);
|
||||
});
|
||||
}
|
||||
|
||||
void RATGDOLightOutput::on_light_state(esphome::ratgdo::LightState state)
|
||||
{
|
||||
if (this->light_state_) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../ratgdo.h"
|
||||
#include "../ratgdo_child.h"
|
||||
#include "../ratgdo_state.h"
|
||||
#include "esphome/components/light/light_output.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
@ -12,13 +11,14 @@ namespace ratgdo {
|
|||
class RATGDOLightOutput : public light::LightOutput, public RATGDOClient, public Component {
|
||||
public:
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
light::LightTraits get_traits() override;
|
||||
void write_state(light::LightState* state) override;
|
||||
void setup_state(light::LightState* state) override;
|
||||
void set_state(esphome::ratgdo::LightState state);
|
||||
light::LightState* get_state() { return this->light_state_; }
|
||||
|
||||
void on_light_state(esphome::ratgdo::LightState state) override;
|
||||
void on_light_state(esphome::ratgdo::LightState state);
|
||||
|
||||
protected:
|
||||
light::LightState* light_state_;
|
||||
|
|
|
@ -19,6 +19,23 @@ namespace ratgdo {
|
|||
}
|
||||
}
|
||||
|
||||
void RATGDONumber::setup()
|
||||
{
|
||||
if (this->number_type_ == RATGDO_ROLLING_CODE_COUNTER) {
|
||||
this->parent_->subscribe_rolling_code_counter([=](uint32_t value) {
|
||||
this->publish_state(value);
|
||||
});
|
||||
} else if (this->number_type_ == RATGDO_OPENING_DURATION) {
|
||||
this->parent_->subscribe_opening_duration([=](float value) {
|
||||
this->publish_state(value);
|
||||
});
|
||||
} else if (this->number_type_ == RATGDO_CLOSING_DURATION) {
|
||||
this->parent_->subscribe_closing_duration([=](float value) {
|
||||
this->publish_state(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDONumber::set_number_type(NumberType number_type_)
|
||||
{
|
||||
this->number_type_ = number_type_;
|
||||
|
@ -27,30 +44,6 @@ namespace ratgdo {
|
|||
}
|
||||
}
|
||||
|
||||
void RATGDONumber::on_rolling_code_change(uint32_t rollingCodeCounter)
|
||||
{
|
||||
if (this->number_type_ != RATGDO_ROLLING_CODE_COUNTER) {
|
||||
return;
|
||||
}
|
||||
this->publish_state(rollingCodeCounter);
|
||||
}
|
||||
|
||||
void RATGDONumber::on_opening_duration_change(float duration)
|
||||
{
|
||||
if (this->number_type_ != RATGDO_OPENING_DURATION) {
|
||||
return;
|
||||
}
|
||||
this->publish_state(duration);
|
||||
}
|
||||
|
||||
void RATGDONumber::on_closing_duration_change(float duration)
|
||||
{
|
||||
if (this->number_type_ != RATGDO_CLOSING_DURATION) {
|
||||
return;
|
||||
}
|
||||
this->publish_state(duration);
|
||||
}
|
||||
|
||||
void RATGDONumber::control(float value)
|
||||
{
|
||||
if (this->number_type_ == RATGDO_ROLLING_CODE_COUNTER) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../ratgdo.h"
|
||||
#include "../ratgdo_child.h"
|
||||
#include "../ratgdo_state.h"
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
@ -18,12 +17,9 @@ namespace ratgdo {
|
|||
class RATGDONumber : public number::Number, public RATGDOClient, public Component {
|
||||
public:
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
void set_number_type(NumberType number_type_);
|
||||
|
||||
void on_rolling_code_change(uint32_t rollingCodeCounter) override;
|
||||
void on_opening_duration_change(float duration) override;
|
||||
void on_closing_duration_change(float duration) override;
|
||||
|
||||
void control(float value) override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
namespace esphome {
|
||||
namespace ratgdo {
|
||||
|
||||
template <typename T>
|
||||
class observable {
|
||||
public:
|
||||
observable(const T& value)
|
||||
: value_(value)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
observable& operator=(U value)
|
||||
{
|
||||
if (value != this->value_) {
|
||||
this->value_ = value;
|
||||
this->notify();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
T const* operator&() const { return &this->value_; }
|
||||
T const& operator*() const { return this->value_; }
|
||||
|
||||
template <typename Observer>
|
||||
void subscribe(Observer&& observer)
|
||||
{
|
||||
this->observers_.push_back(std::forward<Observer>(observer));
|
||||
}
|
||||
|
||||
void notify() const
|
||||
{
|
||||
for (const auto& observer : this->observers_) {
|
||||
observer(this->value_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T value_;
|
||||
std::vector<std::function<void(T)>> observers_;
|
||||
};
|
||||
|
||||
} // namespace ratgdo
|
||||
} // namespace esphome
|
|
@ -12,7 +12,6 @@
|
|||
************************************/
|
||||
|
||||
#include "ratgdo.h"
|
||||
#include "ratgdo_child.h"
|
||||
#include "ratgdo_state.h"
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
@ -46,22 +45,23 @@ namespace ratgdo {
|
|||
void RATGDOComponent::setup()
|
||||
{
|
||||
this->rollingCodePref_ = global_preferences->make_preference<int>(734874333U);
|
||||
if (!this->rollingCodePref_.load(&this->rollingCodeCounter)) {
|
||||
this->rollingCodeCounter = 0;
|
||||
}
|
||||
uint32_t rolling_code_counter = 0;
|
||||
this->rollingCodePref_.load(&rolling_code_counter);
|
||||
this->rollingCodeCounter = rolling_code_counter;
|
||||
// observers are subscribed in the setup() of children defer notify until after setup()
|
||||
defer([=] { this->rollingCodeCounter.notify(); });
|
||||
|
||||
this->openingDurationPref_ = global_preferences->make_preference<float>(734874334U);
|
||||
if (!this->openingDurationPref_.load(&this->openingDuration)) {
|
||||
this->setOpeningDuration(0);
|
||||
} else {
|
||||
this->sendOpeningDuration();
|
||||
}
|
||||
float opening_duration = 0;
|
||||
this->openingDurationPref_.load(&opening_duration);
|
||||
this->setOpeningDuration(opening_duration);
|
||||
defer([=] { this->openingDuration.notify(); });
|
||||
|
||||
this->closingDurationPref_ = global_preferences->make_preference<float>(734874335U);
|
||||
if (!this->closingDurationPref_.load(&this->closingDuration)) {
|
||||
this->setClosingDuration(0.f);
|
||||
} else {
|
||||
this->sendClosingDuration();
|
||||
}
|
||||
float closing_duration = 0;
|
||||
this->closingDurationPref_.load(&closing_duration);
|
||||
this->setClosingDuration(closing_duration);
|
||||
defer([=] { this->closingDuration.notify(); });
|
||||
|
||||
this->output_gdo_pin_->setup();
|
||||
this->input_gdo_pin_->setup();
|
||||
|
@ -87,7 +87,6 @@ namespace ratgdo {
|
|||
{
|
||||
obstructionLoop();
|
||||
gdoStateLoop();
|
||||
statusUpdateLoop();
|
||||
}
|
||||
|
||||
void RATGDOComponent::dump_config()
|
||||
|
@ -96,7 +95,7 @@ namespace ratgdo {
|
|||
LOG_PIN(" Output GDO Pin: ", this->output_gdo_pin_);
|
||||
LOG_PIN(" Input GDO Pin: ", this->input_gdo_pin_);
|
||||
LOG_PIN(" Input Obstruction Pin: ", this->input_obst_pin_);
|
||||
ESP_LOGCONFIG(TAG, " Rolling Code Counter: %d", this->rollingCodeCounter);
|
||||
ESP_LOGCONFIG(TAG, " Rolling Code Counter: %d", *this->rollingCodeCounter);
|
||||
ESP_LOGCONFIG(TAG, " Remote ID: %d", this->remote_id);
|
||||
}
|
||||
|
||||
|
@ -183,53 +182,53 @@ namespace ratgdo {
|
|||
|
||||
if (cmd == command::STATUS) {
|
||||
|
||||
this->doorState = static_cast<DoorState>(nibble);
|
||||
auto doorState = static_cast<DoorState>(nibble);
|
||||
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPENING && this->previousDoorState == DoorState::DOOR_STATE_CLOSED) {
|
||||
if (doorState == DoorState::DOOR_STATE_OPENING && *this->doorState == DoorState::DOOR_STATE_CLOSED) {
|
||||
this->startOpening = millis();
|
||||
}
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPEN && this->previousDoorState == DoorState::DOOR_STATE_OPENING) {
|
||||
if (doorState == DoorState::DOOR_STATE_OPEN && *this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
if (this->startOpening > 0) {
|
||||
auto duration = (millis() - this->startOpening) / 1000;
|
||||
duration = this->openingDuration > 0 ? (duration + this->openingDuration) / 2 : duration;
|
||||
duration = *this->openingDuration > 0 ? (duration + *this->openingDuration) / 2 : duration;
|
||||
this->setOpeningDuration(round(duration * 10) / 10);
|
||||
}
|
||||
}
|
||||
if (this->doorState == DoorState::DOOR_STATE_CLOSING && this->previousDoorState == DoorState::DOOR_STATE_OPEN) {
|
||||
if (doorState == DoorState::DOOR_STATE_CLOSING && *this->doorState == DoorState::DOOR_STATE_OPEN) {
|
||||
this->startClosing = millis();
|
||||
}
|
||||
if (this->doorState == DoorState::DOOR_STATE_CLOSED && this->previousDoorState == DoorState::DOOR_STATE_CLOSING) {
|
||||
if (doorState == DoorState::DOOR_STATE_CLOSED && *this->doorState == DoorState::DOOR_STATE_CLOSING) {
|
||||
if (this->startClosing > 0) {
|
||||
auto duration = (millis() - this->startClosing) / 1000;
|
||||
duration = this->closingDuration > 0 ? (duration + this->closingDuration) / 2 : duration;
|
||||
duration = *this->closingDuration > 0 ? (duration + *this->closingDuration) / 2 : duration;
|
||||
this->setClosingDuration(round(duration * 10) / 10);
|
||||
}
|
||||
}
|
||||
if (this->doorState == DoorState::DOOR_STATE_STOPPED) {
|
||||
if (doorState == DoorState::DOOR_STATE_STOPPED) {
|
||||
this->startOpening = -1;
|
||||
this->startClosing = -1;
|
||||
}
|
||||
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPEN) {
|
||||
if (doorState == DoorState::DOOR_STATE_OPEN) {
|
||||
this->doorPosition = 1.0;
|
||||
} else if (this->doorState == DoorState::DOOR_STATE_CLOSED) {
|
||||
} else if (doorState == DoorState::DOOR_STATE_CLOSED) {
|
||||
this->doorPosition = 0.0;
|
||||
} else {
|
||||
if (this->closingDuration == 0 || this->openingDuration == 0 || this->doorPosition == DOOR_POSITION_UNKNOWN) {
|
||||
if (*this->closingDuration == 0 || *this->openingDuration == 0 || *this->doorPosition == DOOR_POSITION_UNKNOWN) {
|
||||
this->doorPosition = 0.5; // best guess
|
||||
}
|
||||
}
|
||||
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPENING && !this->movingToPosition) {
|
||||
this->positionSyncWhileOpening(1.0 - this->doorPosition);
|
||||
if (doorState == DoorState::DOOR_STATE_OPENING && !this->movingToPosition) {
|
||||
this->positionSyncWhileOpening(1.0 - *this->doorPosition);
|
||||
this->movingToPosition = true;
|
||||
}
|
||||
if (this->doorState == DoorState::DOOR_STATE_CLOSING && !this->movingToPosition) {
|
||||
this->positionSyncWhileClosing(this->doorPosition);
|
||||
if (doorState == DoorState::DOOR_STATE_CLOSING && !this->movingToPosition) {
|
||||
this->positionSyncWhileClosing(*this->doorPosition);
|
||||
this->movingToPosition = true;
|
||||
}
|
||||
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPEN || this->doorState == DoorState::DOOR_STATE_CLOSED || this->doorState == DoorState::DOOR_STATE_STOPPED) {
|
||||
if (doorState == DoorState::DOOR_STATE_OPEN || doorState == DoorState::DOOR_STATE_CLOSED || doorState == DoorState::DOOR_STATE_STOPPED) {
|
||||
this->cancelPositionSyncCallbacks();
|
||||
}
|
||||
|
||||
|
@ -239,41 +238,43 @@ namespace ratgdo {
|
|||
this->motorState = MotorState::MOTOR_STATE_OFF; // when the status message is read, reset motor state to 0|off
|
||||
// this->obstructionState = static_cast<ObstructionState>((byte1 >> 6) & 1);
|
||||
|
||||
if (this->doorState == DoorState::DOOR_STATE_CLOSED && this->doorState != this->previousDoorState) {
|
||||
if (doorState == DoorState::DOOR_STATE_CLOSED && doorState != *this->doorState) {
|
||||
transmit(command::GET_OPENINGS);
|
||||
}
|
||||
|
||||
this->doorState = doorState;
|
||||
|
||||
ESP_LOGD(TAG, "Status: door=%s light=%s lock=%s",
|
||||
door_state_to_string(this->doorState),
|
||||
light_state_to_string(this->lightState),
|
||||
lock_state_to_string(this->lockState));
|
||||
door_state_to_string(*this->doorState),
|
||||
light_state_to_string(*this->lightState),
|
||||
lock_state_to_string(*this->lockState));
|
||||
} else if (cmd == command::LIGHT) {
|
||||
if (nibble == 0) {
|
||||
this->lightState = LightState::LIGHT_STATE_OFF;
|
||||
} else if (nibble == 1) {
|
||||
this->lightState = LightState::LIGHT_STATE_ON;
|
||||
} else if (nibble == 2) { // toggle
|
||||
this->lightState = light_state_toggle(this->lightState);
|
||||
this->lightState = light_state_toggle(*this->lightState);
|
||||
}
|
||||
ESP_LOGD(TAG, "Light: action=%s state=%s",
|
||||
nibble == 0 ? "OFF" : nibble == 1 ? "ON"
|
||||
: "TOGGLE",
|
||||
light_state_to_string(this->lightState));
|
||||
light_state_to_string(*this->lightState));
|
||||
} else if (cmd == command::MOTOR_ON) {
|
||||
this->motorState = MotorState::MOTOR_STATE_ON;
|
||||
ESP_LOGD(TAG, "Motor: state=%s", motor_state_to_string(this->motorState));
|
||||
ESP_LOGD(TAG, "Motor: state=%s", motor_state_to_string(*this->motorState));
|
||||
} else if (cmd == command::OPEN) {
|
||||
this->buttonState = (byte1 & 1) == 1 ? ButtonState::BUTTON_STATE_PRESSED : ButtonState::BUTTON_STATE_RELEASED;
|
||||
ESP_LOGD(TAG, "Open: button=%s", button_state_to_string(this->buttonState));
|
||||
ESP_LOGD(TAG, "Open: button=%s", button_state_to_string(*this->buttonState));
|
||||
} else if (cmd == command::OPENINGS) {
|
||||
this->openings = (byte1 << 8) | byte2;
|
||||
ESP_LOGD(TAG, "Openings: %d", this->openings);
|
||||
ESP_LOGD(TAG, "Openings: %d", *this->openings);
|
||||
} else if (cmd == command::MOTION) {
|
||||
this->motionState = MotionState::MOTION_STATE_DETECTED;
|
||||
if (this->lightState == LightState::LIGHT_STATE_OFF) {
|
||||
if (*this->lightState == LightState::LIGHT_STATE_OFF) {
|
||||
transmit(command::GET_STATUS);
|
||||
}
|
||||
ESP_LOGD(TAG, "Motion: %s", motion_state_to_string(this->motionState));
|
||||
ESP_LOGD(TAG, "Motion: %s", motion_state_to_string(*this->motionState));
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Unhandled command: cmd=%03x nibble=%02x byte1=%02x byte2=%02x fixed=%010" PRIx64 " data=%08" PRIx32, cmd, nibble, byte1, byte2, fixed, data);
|
||||
}
|
||||
|
@ -285,8 +286,8 @@ namespace ratgdo {
|
|||
uint64_t fixed = ((command & ~0xff) << 24) | this->remote_id;
|
||||
uint32_t send_data = (data << 8) | (command & 0xff);
|
||||
|
||||
ESP_LOGD(TAG, "[%ld] Encode for transmit rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), this->rollingCodeCounter, fixed, send_data);
|
||||
encode_wireline(this->rollingCodeCounter, fixed, send_data, this->txRollingCode);
|
||||
ESP_LOGD(TAG, "[%ld] Encode for transmit rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), *this->rollingCodeCounter, fixed, send_data);
|
||||
encode_wireline(*this->rollingCodeCounter, fixed, send_data, this->txRollingCode);
|
||||
|
||||
printRollingCode();
|
||||
if (increment) {
|
||||
|
@ -300,68 +301,38 @@ namespace ratgdo {
|
|||
this->openingDuration = duration;
|
||||
this->openingDurationPref_.save(&this->openingDuration);
|
||||
|
||||
sendOpeningDuration();
|
||||
|
||||
if (this->closingDuration == 0 && duration != 0) {
|
||||
if (*this->closingDuration == 0 && duration != 0) {
|
||||
this->setClosingDuration(duration);
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOComponent::sendOpeningDuration()
|
||||
{
|
||||
for (auto* child : this->children_) {
|
||||
child->on_opening_duration_change(this->openingDuration);
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOComponent::setClosingDuration(float duration)
|
||||
{
|
||||
ESP_LOGD(TAG, "Set closing duration: %.1fs", duration);
|
||||
this->closingDuration = duration;
|
||||
this->closingDurationPref_.save(&this->closingDuration);
|
||||
|
||||
sendClosingDuration();
|
||||
|
||||
if (this->openingDuration == 0 && duration != 0) {
|
||||
if (*this->openingDuration == 0 && duration != 0) {
|
||||
this->setOpeningDuration(duration);
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOComponent::sendClosingDuration()
|
||||
{
|
||||
for (auto* child : this->children_) {
|
||||
child->on_closing_duration_change(this->closingDuration);
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOComponent::setRollingCodeCounter(uint32_t counter)
|
||||
{
|
||||
ESP_LOGV(TAG, "Set rolling code counter to %d", counter);
|
||||
this->rollingCodeCounter = counter;
|
||||
this->rollingCodePref_.save(&this->rollingCodeCounter);
|
||||
sendRollingCodeChanged();
|
||||
}
|
||||
|
||||
void RATGDOComponent::incrementRollingCodeCounter(int delta)
|
||||
{
|
||||
this->rollingCodeCounter = (this->rollingCodeCounter + delta) & 0xfffffff;
|
||||
sendRollingCodeChanged();
|
||||
}
|
||||
|
||||
void RATGDOComponent::sendRollingCodeChanged()
|
||||
{
|
||||
if (!this->rollingCodeUpdatesEnabled_) {
|
||||
return;
|
||||
}
|
||||
for (auto* child : this->children_) {
|
||||
child->on_rolling_code_change(this->rollingCodeCounter);
|
||||
}
|
||||
this->rollingCodeCounter = (*this->rollingCodeCounter + delta) & 0xfffffff;
|
||||
}
|
||||
|
||||
void RATGDOComponent::printRollingCode()
|
||||
{
|
||||
ESP_LOGV(TAG, "Counter: %d Send code: [%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X]",
|
||||
this->rollingCodeCounter,
|
||||
*this->rollingCodeCounter,
|
||||
this->txRollingCode[0],
|
||||
this->txRollingCode[1],
|
||||
this->txRollingCode[2],
|
||||
|
@ -455,88 +426,15 @@ namespace ratgdo {
|
|||
if (byte_count == CODE_LENGTH) {
|
||||
reading_msg = false;
|
||||
byte_count = 0;
|
||||
if (readRollingCode() == command::STATUS && this->forceUpdate_) {
|
||||
this->forceUpdate_ = false;
|
||||
this->previousDoorState = DoorState::DOOR_STATE_UNKNOWN;
|
||||
this->previousLightState = LightState::LIGHT_STATE_UNKNOWN;
|
||||
this->previousLockState = LockState::LOCK_STATE_UNKNOWN;
|
||||
}
|
||||
readRollingCode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOComponent::statusUpdateLoop()
|
||||
{
|
||||
if (this->doorState != this->previousDoorState) {
|
||||
ESP_LOGV(TAG, "Door state: %s", door_state_to_string(this->doorState));
|
||||
for (auto* child : this->children_) {
|
||||
child->on_door_state(this->doorState, this->doorPosition);
|
||||
}
|
||||
this->previousDoorState = this->doorState;
|
||||
}
|
||||
if (this->doorPosition != this->previousDoorPosition) {
|
||||
ESP_LOGV(TAG, "Door position: %f", this->doorPosition);
|
||||
for (auto* child : this->children_) {
|
||||
child->on_door_state(this->doorState, this->doorPosition);
|
||||
}
|
||||
this->previousDoorPosition = this->doorPosition;
|
||||
}
|
||||
if (this->lightState != this->previousLightState) {
|
||||
ESP_LOGV(TAG, "Light state %s (%d)", light_state_to_string(this->lightState), this->lightState);
|
||||
for (auto* child : this->children_) {
|
||||
child->on_light_state(this->lightState);
|
||||
}
|
||||
this->previousLightState = this->lightState;
|
||||
}
|
||||
if (this->lockState != this->previousLockState) {
|
||||
ESP_LOGV(TAG, "Lock state %s", lock_state_to_string(this->lockState));
|
||||
for (auto* child : this->children_) {
|
||||
child->on_lock_state(this->lockState);
|
||||
}
|
||||
this->previousLockState = this->lockState;
|
||||
}
|
||||
if (this->obstructionState != this->previousObstructionState) {
|
||||
ESP_LOGV(TAG, "Obstruction state %s", obstruction_state_to_string(this->obstructionState));
|
||||
for (auto* child : this->children_) {
|
||||
child->on_obstruction_state(this->obstructionState);
|
||||
}
|
||||
this->previousObstructionState = this->obstructionState;
|
||||
}
|
||||
if (this->motorState != this->previousMotorState) {
|
||||
ESP_LOGV(TAG, "Motor state %s", motor_state_to_string(this->motorState));
|
||||
for (auto* child : this->children_) {
|
||||
child->on_motor_state(this->motorState);
|
||||
}
|
||||
this->previousMotorState = this->motorState;
|
||||
}
|
||||
if (this->motionState != this->previousMotionState) {
|
||||
ESP_LOGV(TAG, "Motion state %s", motion_state_to_string(this->motionState));
|
||||
for (auto* child : this->children_) {
|
||||
child->on_motion_state(this->motionState);
|
||||
}
|
||||
this->previousMotionState = this->motionState;
|
||||
}
|
||||
if (this->buttonState != this->previousButtonState) {
|
||||
ESP_LOGV(TAG, "Button state %s", button_state_to_string(this->buttonState));
|
||||
for (auto* child : this->children_) {
|
||||
child->on_button_state(this->buttonState);
|
||||
}
|
||||
this->previousButtonState = this->buttonState;
|
||||
}
|
||||
if (this->openings != this->previousOpenings) {
|
||||
ESP_LOGV(TAG, "Openings: %d", this->openings);
|
||||
for (auto* child : this->children_) {
|
||||
child->on_openings_change(this->openings);
|
||||
}
|
||||
this->previousOpenings = this->openings;
|
||||
}
|
||||
}
|
||||
|
||||
void RATGDOComponent::query_status()
|
||||
{
|
||||
this->forceUpdate_ = true;
|
||||
transmit(command::GET_STATUS);
|
||||
}
|
||||
|
||||
|
@ -574,9 +472,9 @@ namespace ratgdo {
|
|||
this->incrementRollingCodeCounter(MAX_CODES_WITHOUT_FLASH_WRITE);
|
||||
|
||||
set_retry(
|
||||
300, 10, [=](auto r) {
|
||||
if (this->doorState != DoorState::DOOR_STATE_UNKNOWN) { // have status
|
||||
if (this->openings != 0) { // have openings
|
||||
300, 10, [=](uint8_t r) {
|
||||
if (*this->doorState != DoorState::DOOR_STATE_UNKNOWN) { // have status
|
||||
if (*this->openings != 0) { // have openings
|
||||
return RetryResult::DONE;
|
||||
} else {
|
||||
transmit(command::GET_OPENINGS);
|
||||
|
@ -592,7 +490,7 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::openDoor()
|
||||
{
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
if (*this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
return; // gets ignored by opener
|
||||
}
|
||||
this->cancelPositionSyncCallbacks();
|
||||
|
@ -602,7 +500,7 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::closeDoor()
|
||||
{
|
||||
if (this->doorState == DoorState::DOOR_STATE_CLOSING || this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
if (*this->doorState == DoorState::DOOR_STATE_CLOSING || *this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
return; // gets ignored by opener
|
||||
}
|
||||
this->cancelPositionSyncCallbacks();
|
||||
|
@ -612,7 +510,7 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::stopDoor()
|
||||
{
|
||||
if (this->doorState != DoorState::DOOR_STATE_OPENING && this->doorState != DoorState::DOOR_STATE_CLOSING) {
|
||||
if (*this->doorState != DoorState::DOOR_STATE_OPENING && *this->doorState != DoorState::DOOR_STATE_CLOSING) {
|
||||
ESP_LOGW(TAG, "The door is not moving.");
|
||||
return;
|
||||
}
|
||||
|
@ -621,7 +519,7 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::toggleDoor()
|
||||
{
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
if (*this->doorState == DoorState::DOOR_STATE_OPENING) {
|
||||
return; // gets ignored by opener
|
||||
}
|
||||
this->cancelPositionSyncCallbacks();
|
||||
|
@ -631,54 +529,54 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::positionSyncWhileOpening(float delta, float update_period)
|
||||
{
|
||||
if (this->openingDuration == 0) {
|
||||
if (*this->openingDuration == 0) {
|
||||
ESP_LOGW(TAG, "I don't know opening duration, ignoring position sync");
|
||||
return;
|
||||
}
|
||||
auto updates = this->openingDuration * 1000 * delta / update_period;
|
||||
auto updates = *this->openingDuration * 1000 * delta / update_period;
|
||||
auto position_update = delta / updates;
|
||||
auto count = int(updates);
|
||||
ESP_LOGD(TAG, "[Opening] Position sync %d times: ", count);
|
||||
// try to keep position in sync while door is moving
|
||||
set_retry("position_sync_while_moving", update_period, count, [=](uint8_t r) {
|
||||
ESP_LOGD(TAG, "[Opening] Position sync: %d: ", r);
|
||||
this->doorPosition += position_update;
|
||||
this->doorPosition = *this->doorPosition + position_update;
|
||||
return RetryResult::RETRY;
|
||||
});
|
||||
}
|
||||
|
||||
void RATGDOComponent::positionSyncWhileClosing(float delta, float update_period)
|
||||
{
|
||||
if (this->closingDuration == 0) {
|
||||
if (*this->closingDuration == 0) {
|
||||
ESP_LOGW(TAG, "I don't know closing duration, ignoring position sync");
|
||||
return;
|
||||
}
|
||||
auto updates = this->closingDuration * 1000 * delta / update_period;
|
||||
auto updates = *this->closingDuration * 1000 * delta / update_period;
|
||||
auto position_update = delta / updates;
|
||||
auto count = int(updates);
|
||||
ESP_LOGD(TAG, "[Closing] Position sync %d times: ", count);
|
||||
// try to keep position in sync while door is moving
|
||||
set_retry("position_sync_while_moving", update_period, count, [=](uint8_t r) {
|
||||
ESP_LOGD(TAG, "[Closing] Position sync: %d: ", r);
|
||||
this->doorPosition -= position_update;
|
||||
this->doorPosition = *this->doorPosition - position_update;
|
||||
return RetryResult::RETRY;
|
||||
});
|
||||
}
|
||||
|
||||
void RATGDOComponent::setDoorPosition(float position)
|
||||
{
|
||||
if (this->doorState == DoorState::DOOR_STATE_OPENING || this->doorState == DoorState::DOOR_STATE_CLOSING) {
|
||||
if (*this->doorState == DoorState::DOOR_STATE_OPENING || *this->doorState == DoorState::DOOR_STATE_CLOSING) {
|
||||
ESP_LOGW(TAG, "The door is moving, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto delta = position - this->doorPosition;
|
||||
auto delta = position - *this->doorPosition;
|
||||
if (delta == 0) {
|
||||
ESP_LOGD(TAG, "Door is already at position %.2f", position);
|
||||
return;
|
||||
}
|
||||
|
||||
auto duration = delta > 0 ? this->openingDuration : this->closingDuration;
|
||||
auto duration = delta > 0 ? *this->openingDuration : *this->closingDuration;
|
||||
if (duration == 0) {
|
||||
ESP_LOGW(TAG, "I don't know duration, ignoring move to position");
|
||||
return;
|
||||
|
@ -738,7 +636,7 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::toggleLight()
|
||||
{
|
||||
this->lightState = light_state_toggle(this->lightState);
|
||||
this->lightState = light_state_toggle(*this->lightState);
|
||||
transmit(command::LIGHT, data::LIGHT_TOGGLE);
|
||||
}
|
||||
|
||||
|
@ -756,7 +654,7 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::toggleLock()
|
||||
{
|
||||
this->lockState = lock_state_toggle(this->lockState);
|
||||
this->lockState = lock_state_toggle(*this->lockState);
|
||||
transmit(command::LOCK, data::LOCK_TOGGLE);
|
||||
}
|
||||
|
||||
|
@ -768,14 +666,61 @@ namespace ratgdo {
|
|||
// we have configured preferences to write every 5s
|
||||
}
|
||||
|
||||
void RATGDOComponent::register_child(RATGDOClient* obj)
|
||||
{
|
||||
this->children_.push_back(obj);
|
||||
obj->set_parent(this);
|
||||
}
|
||||
LightState RATGDOComponent::getLightState()
|
||||
{
|
||||
return this->lightState;
|
||||
return *this->lightState;
|
||||
}
|
||||
|
||||
void RATGDOComponent::subscribe_rolling_code_counter(std::function<void(uint32_t)>&& f)
|
||||
{
|
||||
// change update to children is defered until after component loop
|
||||
// if multiple changes occur during component loop, only the last one is notified
|
||||
this->rollingCodeCounter.subscribe([=](uint32_t state) { defer("rolling_code_counter", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_opening_duration(std::function<void(float)>&& f)
|
||||
{
|
||||
this->openingDuration.subscribe([=](float state) { defer("opening_duration", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_closing_duration(std::function<void(float)>&& f)
|
||||
{
|
||||
this->closingDuration.subscribe([=](float state) { defer("closing_duration", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_openings(std::function<void(uint16_t)>&& f)
|
||||
{
|
||||
this->openings.subscribe([=](uint16_t state) { defer("openings", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_door_state(std::function<void(DoorState, float)>&& f)
|
||||
{
|
||||
this->doorState.subscribe([=](DoorState state) {
|
||||
defer("door_state", [=] { f(state, *this->doorPosition); });
|
||||
});
|
||||
this->doorPosition.subscribe([=](float position) {
|
||||
defer("door_state", [=] { f(*this->doorState, position); });
|
||||
});
|
||||
}
|
||||
void RATGDOComponent::subscribe_light_state(std::function<void(LightState)>&& f)
|
||||
{
|
||||
this->lightState.subscribe([=](LightState state) { defer("light_state", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_lock_state(std::function<void(LockState)>&& f)
|
||||
{
|
||||
this->lockState.subscribe([=](LockState state) { defer("lock_state", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_obstruction_state(std::function<void(ObstructionState)>&& f)
|
||||
{
|
||||
this->obstructionState.subscribe([=](ObstructionState state) { defer("obstruction_state", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_motor_state(std::function<void(MotorState)>&& f)
|
||||
{
|
||||
this->motorState.subscribe([=](MotorState state) { defer("motor_state", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_button_state(std::function<void(ButtonState)>&& f)
|
||||
{
|
||||
this->buttonState.subscribe([=](ButtonState state) { defer("button_state", [=] { f(state); }); });
|
||||
}
|
||||
void RATGDOComponent::subscribe_motion_state(std::function<void(MotionState)>&& f)
|
||||
{
|
||||
this->motionState.subscribe([=](MotionState state) { defer("motion_state", [=] { f(state); }); });
|
||||
}
|
||||
|
||||
} // namespace ratgdo
|
||||
|
|
|
@ -17,19 +17,19 @@
|
|||
#include "esphome/core/gpio.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "observable.h"
|
||||
|
||||
extern "C" {
|
||||
#include "secplus.h"
|
||||
}
|
||||
|
||||
#include "ratgdo_child.h"
|
||||
#include "ratgdo_state.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ratgdo {
|
||||
|
||||
// Forward declare RATGDOClient
|
||||
class RATGDOClient;
|
||||
class RATGDOComponent;
|
||||
typedef Parented<RATGDOComponent> RATGDOClient;
|
||||
|
||||
static const uint8_t CODE_LENGTH = 19;
|
||||
|
||||
|
@ -128,44 +128,29 @@ namespace ratgdo {
|
|||
|
||||
EspSoftwareSerial::UART swSerial;
|
||||
|
||||
uint32_t rollingCodeCounter { 0 };
|
||||
observable<uint32_t> rollingCodeCounter { 0 };
|
||||
uint32_t lastSyncedRollingCodeCounter { 0 };
|
||||
|
||||
float startOpening { -1 };
|
||||
float openingDuration { 0 };
|
||||
observable<float> openingDuration { 0 };
|
||||
float startClosing { -1 };
|
||||
float closingDuration { 0 };
|
||||
observable<float> closingDuration { 0 };
|
||||
|
||||
uint8_t txRollingCode[CODE_LENGTH];
|
||||
uint8_t rxRollingCode[CODE_LENGTH];
|
||||
|
||||
uint16_t previousOpenings { 0 }; // number of times the door has been opened
|
||||
uint16_t openings { 0 }; // number of times the door has been opened
|
||||
observable<uint16_t> openings { 0 }; // number of times the door has been opened
|
||||
|
||||
DoorState previousDoorState { DoorState::DOOR_STATE_UNKNOWN };
|
||||
DoorState doorState { DoorState::DOOR_STATE_UNKNOWN };
|
||||
|
||||
float doorPosition { DOOR_POSITION_UNKNOWN };
|
||||
float previousDoorPosition { DOOR_POSITION_UNKNOWN };
|
||||
observable<DoorState> doorState { DoorState::DOOR_STATE_UNKNOWN };
|
||||
observable<float> doorPosition { DOOR_POSITION_UNKNOWN };
|
||||
bool movingToPosition { false };
|
||||
|
||||
LightState previousLightState { LightState::LIGHT_STATE_UNKNOWN };
|
||||
LightState lightState { LightState::LIGHT_STATE_UNKNOWN };
|
||||
|
||||
LockState previousLockState { LockState::LOCK_STATE_UNKNOWN };
|
||||
LockState lockState { LockState::LOCK_STATE_UNKNOWN };
|
||||
|
||||
ObstructionState previousObstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
||||
ObstructionState obstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
||||
|
||||
MotorState previousMotorState { MotorState::MOTOR_STATE_UNKNOWN };
|
||||
MotorState motorState { MotorState::MOTOR_STATE_UNKNOWN };
|
||||
|
||||
ButtonState previousButtonState { ButtonState::BUTTON_STATE_UNKNOWN };
|
||||
ButtonState buttonState { ButtonState::BUTTON_STATE_UNKNOWN };
|
||||
|
||||
MotionState previousMotionState { MotionState::MOTION_STATE_UNKNOWN };
|
||||
MotionState motionState { MotionState::MOTION_STATE_UNKNOWN };
|
||||
observable<LightState> lightState { LightState::LIGHT_STATE_UNKNOWN };
|
||||
observable<LockState> lockState { LockState::LOCK_STATE_UNKNOWN };
|
||||
observable<ObstructionState> obstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
||||
observable<MotorState> motorState { MotorState::MOTOR_STATE_UNKNOWN };
|
||||
observable<ButtonState> buttonState { ButtonState::BUTTON_STATE_UNKNOWN };
|
||||
observable<MotionState> motionState { MotionState::MOTION_STATE_UNKNOWN };
|
||||
|
||||
void set_output_gdo_pin(InternalGPIOPin* pin) { this->output_gdo_pin_ = pin; };
|
||||
void set_input_gdo_pin(InternalGPIOPin* pin) { this->input_gdo_pin_ = pin; };
|
||||
|
@ -180,7 +165,6 @@ namespace ratgdo {
|
|||
|
||||
void gdoStateLoop();
|
||||
void obstructionLoop();
|
||||
void statusUpdateLoop();
|
||||
|
||||
void saveCounter();
|
||||
|
||||
|
@ -210,25 +194,30 @@ namespace ratgdo {
|
|||
void getRollingCode(command::cmd command, uint32_t data, bool increment);
|
||||
uint16_t readRollingCode();
|
||||
void incrementRollingCodeCounter(int delta = 1);
|
||||
void sendRollingCodeChanged();
|
||||
void setRollingCodeCounter(uint32_t counter);
|
||||
|
||||
void setOpeningDuration(float duration);
|
||||
void sendOpeningDuration();
|
||||
void setClosingDuration(float duration);
|
||||
void sendClosingDuration();
|
||||
|
||||
LightState getLightState();
|
||||
/** Register a child component. */
|
||||
void register_child(RATGDOClient* obj);
|
||||
|
||||
void subscribe_rolling_code_counter(std::function<void(uint32_t)>&& f);
|
||||
void subscribe_opening_duration(std::function<void(float)>&& f);
|
||||
void subscribe_closing_duration(std::function<void(float)>&& f);
|
||||
void subscribe_openings(std::function<void(uint16_t)>&& f);
|
||||
void subscribe_door_state(std::function<void(DoorState, float)>&& f);
|
||||
void subscribe_light_state(std::function<void(LightState)>&& f);
|
||||
void subscribe_lock_state(std::function<void(LockState)>&& f);
|
||||
void subscribe_obstruction_state(std::function<void(ObstructionState)>&& f);
|
||||
void subscribe_motor_state(std::function<void(MotorState)>&& f);
|
||||
void subscribe_button_state(std::function<void(ButtonState)>&& f);
|
||||
void subscribe_motion_state(std::function<void(MotionState)>&& f);
|
||||
|
||||
protected:
|
||||
ESPPreferenceObject rollingCodePref_;
|
||||
ESPPreferenceObject openingDurationPref_;
|
||||
ESPPreferenceObject closingDurationPref_;
|
||||
std::vector<RATGDOClient*> children_;
|
||||
bool rollingCodeUpdatesEnabled_ { true };
|
||||
bool forceUpdate_ { false };
|
||||
RATGDOStore store_ {};
|
||||
|
||||
InternalGPIOPin* output_gdo_pin_;
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include "ratgdo.h"
|
||||
#include "ratgdo_state.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ratgdo {
|
||||
|
||||
void RATGDOClient::on_door_state(DoorState state, float position) {};
|
||||
void RATGDOClient::on_light_state(LightState state) {};
|
||||
void RATGDOClient::on_lock_state(LockState state) {};
|
||||
void RATGDOClient::on_motion_state(MotionState state) {};
|
||||
void RATGDOClient::on_obstruction_state(ObstructionState state) {};
|
||||
void RATGDOClient::on_motor_state(MotorState state) {};
|
||||
void RATGDOClient::on_rolling_code_change(uint32_t rollingCodeCounter) {};
|
||||
void RATGDOClient::on_opening_duration_change(float duration) {};
|
||||
void RATGDOClient::on_closing_duration_change(float duration) {};
|
||||
void RATGDOClient::on_openings_change(uint32_t openings) {};
|
||||
void RATGDOClient::on_button_state(ButtonState state) {};
|
||||
|
||||
} // namespace ratgdo
|
||||
} // namespace esphome
|
|
@ -1,33 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include "ratgdo.h"
|
||||
#include "ratgdo_state.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ratgdo {
|
||||
|
||||
// Forward declare RATGDOComponent
|
||||
class RATGDOComponent;
|
||||
|
||||
class RATGDOClient : public Parented<RATGDOComponent> {
|
||||
public:
|
||||
virtual void on_door_state(DoorState state, float position);
|
||||
virtual void on_light_state(LightState state);
|
||||
virtual void on_lock_state(LockState state);
|
||||
virtual void on_motion_state(MotionState state);
|
||||
virtual void on_obstruction_state(ObstructionState state);
|
||||
virtual void on_motor_state(MotorState state);
|
||||
virtual void on_rolling_code_change(uint32_t rollingCodeCounter);
|
||||
virtual void on_opening_duration_change(float duration);
|
||||
virtual void on_closing_duration_change(float duration);
|
||||
virtual void on_openings_change(uint32_t openings);
|
||||
virtual void on_button_state(ButtonState state);
|
||||
|
||||
protected:
|
||||
friend RATGDOComponent;
|
||||
};
|
||||
|
||||
} // namespace ratgdo
|
||||
} // namespace esphome
|
|
@ -12,9 +12,12 @@ namespace ratgdo {
|
|||
LOG_SENSOR("", "RATGDO Sensor", this);
|
||||
ESP_LOGCONFIG(TAG, " Type: Openings");
|
||||
}
|
||||
void RATGDOSensor::on_openings_change(uint32_t openings)
|
||||
|
||||
void RATGDOSensor::setup()
|
||||
{
|
||||
this->publish_state(openings);
|
||||
this->parent_->subscribe_openings([=](uint16_t value) {
|
||||
this->publish_state(value);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace ratgdo
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../ratgdo.h"
|
||||
#include "../ratgdo_child.h"
|
||||
#include "../ratgdo_state.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
@ -16,10 +15,9 @@ namespace ratgdo {
|
|||
class RATGDOSensor : public sensor::Sensor, public RATGDOClient, public Component {
|
||||
public:
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
void set_ratgdo_sensor_type(RATGDOSensorType ratgdo_sensor_type_) { this->ratgdo_sensor_type_ = ratgdo_sensor_type_; }
|
||||
|
||||
void on_openings_change(uint32_t openings) override;
|
||||
|
||||
protected:
|
||||
RATGDOSensorType ratgdo_sensor_type_;
|
||||
};
|
||||
|
|
|
@ -13,6 +13,13 @@ namespace ratgdo {
|
|||
ESP_LOGCONFIG(TAG, " Type: Lock");
|
||||
}
|
||||
|
||||
void RATGDOSwitch::setup()
|
||||
{
|
||||
this->parent_->subscribe_lock_state([=](LockState state) {
|
||||
this->on_lock_state(state);
|
||||
});
|
||||
}
|
||||
|
||||
void RATGDOSwitch::on_lock_state(LockState state)
|
||||
{
|
||||
bool value = state == LockState::LOCK_STATE_LOCKED;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../ratgdo.h"
|
||||
#include "../ratgdo_child.h"
|
||||
#include "../ratgdo_state.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
@ -16,9 +15,10 @@ namespace ratgdo {
|
|||
class RATGDOSwitch : public switch_::Switch, public RATGDOClient, public Component {
|
||||
public:
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
void set_switch_type(SwitchType switch_type_) { this->switch_type_ = switch_type_; }
|
||||
|
||||
void on_lock_state(LockState state) override;
|
||||
void on_lock_state(LockState state);
|
||||
void write_state(bool state) override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -33,6 +33,7 @@ packages:
|
|||
url: https://github.com/esphome-ratgdo/esphome-ratgdo
|
||||
files: [base.yaml]
|
||||
refresh: 1s
|
||||
ref: observer_callbacks
|
||||
|
||||
# Sync time with Home Assistant.
|
||||
time:
|
||||
|
|
Loading…
Reference in New Issue