esphome/esphome/components/shelly_dimmer/shelly_dimmer.h

122 lines
3.8 KiB
C++

#pragma once
#ifdef USE_ESP8266
#include "esphome/core/component.h"
#include "esphome/core/log.h"
#include "esphome/components/light/light_output.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
#include <array>
namespace esphome {
namespace shelly_dimmer {
class ShellyDimmer : public PollingComponent, public light::LightOutput, public uart::UARTDevice {
private:
static constexpr uint16_t SHELLY_DIMMER_BUFFER_SIZE = 256;
public:
float get_setup_priority() const override { return setup_priority::LATE; }
void setup() override;
void update() override;
void dump_config() override;
light::LightTraits get_traits() override {
auto traits = light::LightTraits();
traits.set_supported_color_modes({light::ColorMode::BRIGHTNESS});
return traits;
}
void setup_state(light::LightState *state) override { this->state_ = state; }
void write_state(light::LightState *state) override;
void set_nrst_pin(GPIOPin *nrst_pin) { this->pin_nrst_ = nrst_pin; }
void set_boot0_pin(GPIOPin *boot0_pin) { this->pin_boot0_ = boot0_pin; }
void set_leading_edge(bool leading_edge) { this->leading_edge_ = leading_edge; }
void set_warmup_brightness(uint16_t warmup_brightness) { this->warmup_brightness_ = warmup_brightness; }
void set_warmup_time(uint16_t warmup_time) { this->warmup_time_ = warmup_time; }
void set_fade_rate(uint16_t fade_rate) { this->fade_rate_ = fade_rate; }
void set_min_brightness(uint16_t min_brightness) { this->min_brightness_ = min_brightness; }
void set_max_brightness(uint16_t max_brightness) { this->max_brightness_ = max_brightness; }
void set_power_sensor(sensor::Sensor *power_sensor) { this->power_sensor_ = power_sensor; }
void set_voltage_sensor(sensor::Sensor *voltage_sensor) { this->voltage_sensor_ = voltage_sensor; }
void set_current_sensor(sensor::Sensor *current_sensor) { this->current_sensor_ = current_sensor; }
protected:
GPIOPin *pin_nrst_;
GPIOPin *pin_boot0_;
// Frame parser state.
uint8_t seq_{0};
std::array<uint8_t, SHELLY_DIMMER_BUFFER_SIZE> buffer_;
uint8_t buffer_pos_{0};
// Firmware version.
uint8_t version_major_;
uint8_t version_minor_;
// Configuration.
bool leading_edge_{false};
uint16_t warmup_brightness_{100};
uint16_t warmup_time_{20};
uint16_t fade_rate_{0};
uint16_t min_brightness_{0};
uint16_t max_brightness_{1000};
light::LightState *state_{nullptr};
sensor::Sensor *power_sensor_{nullptr};
sensor::Sensor *voltage_sensor_{nullptr};
sensor::Sensor *current_sensor_{nullptr};
bool ready_{false};
uint16_t brightness_;
/// Convert relative brightness into a dimmer brightness value.
uint16_t convert_brightness_(float brightness);
/// Sends the given brightness value.
void send_brightness_(uint16_t brightness);
/// Sends dimmer configuration.
void send_settings_();
/// Performs a firmware upgrade.
bool upgrade_firmware_();
/// Sends a command and waits for an acknowledgement.
bool send_command_(uint8_t cmd, const uint8_t *payload, uint8_t len);
/// Frames a given command payload.
size_t frame_command_(uint8_t *data, uint8_t cmd, const uint8_t *payload, size_t len);
/// Handles a single byte as part of a protocol frame.
///
/// Returns -1 on failure, 0 when finished and 1 when more bytes needed.
int handle_byte_(uint8_t c);
/// Reads a response frame.
bool read_frame_();
/// Handles a complete frame.
bool handle_frame_();
/// Reset STM32 with the BOOT0 pin set to the given value.
void reset_(bool boot0);
/// Reset STM32 to boot the regular firmware.
void reset_normal_boot_();
/// Reset STM32 to boot into DFU mode to enable firmware upgrades.
void reset_dfu_boot_();
};
} // namespace shelly_dimmer
} // namespace esphome
#endif // USE_ESP8266