feat: add external component and some test configurations

This commit is contained in:
Philip Stark 2023-05-03 20:55:22 +02:00
parent 4c612fc462
commit 5b0930d616
11 changed files with 511 additions and 6 deletions

View file

@ -0,0 +1,53 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import light
from esphome.components import uart
from esphome.components import sensor
from esphome.const import CONF_ID, CONF_HEIGHT, CONF_TIMEOUT, ICON_GAUGE
DEPENDENCIES = ['time']
AUTO_LOAD = ['light']
wordclock_ns = cg.esphome_ns.namespace('wordcl')
Wordclock = wordclock_ns.class_('Wordclock', cg.Component, light.)
Desky = desky_ns.class_('Desky', cg.Component, uart.UARTDevice)
CONF_UP = "up"
CONF_DOWN = "down"
CONF_REQUEST = "request"
CONF_STOPPING_DISTANCE = "stopping_distance"
CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(Desky),
cv.Optional(CONF_UP): pins.gpio_output_pin_schema,
cv.Optional(CONF_DOWN): pins.gpio_output_pin_schema,
cv.Optional(CONF_REQUEST): pins.gpio_output_pin_schema,
cv.Optional(CONF_HEIGHT): sensor.sensor_schema(icon=ICON_GAUGE, accuracy_decimals=0),
cv.Optional(CONF_STOPPING_DISTANCE, default=15): cv.positive_int,
cv.Optional(CONF_TIMEOUT): cv.time_period,
}).extend(uart.UART_DEVICE_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await uart.register_uart_device(var, config)
if CONF_UP in config:
pin = await cg.gpio_pin_expression(config[CONF_UP])
cg.add(var.set_up_pin(pin))
if CONF_DOWN in config:
pin = await cg.gpio_pin_expression(config[CONF_DOWN])
cg.add(var.set_down_pin(pin))
if CONF_REQUEST in config:
pin = await cg.gpio_pin_expression(config[CONF_REQUEST])
cg.add(var.set_request_pin(pin))
if CONF_HEIGHT in config:
sens = await sensor.new_sensor(config[CONF_HEIGHT])
cg.add(var.set_height_sensor(sens))
cg.add(var.set_stopping_distance(config[CONF_STOPPING_DISTANCE]))
if CONF_TIMEOUT in config:
cg.add(var.set_timeout(config[CONF_TIMEOUT].total_milliseconds))

116
components/wordcl/desky.cpp Normal file
View file

@ -0,0 +1,116 @@
#include "desky.h"
#include "esphome/core/log.h"
namespace esphome {
namespace desky {
static const char *TAG = "desky";
const char *desky_operation_to_str(DeskyOperation op) {
switch (op) {
case DESKY_OPERATION_IDLE:
return "IDLE";
case DESKY_OPERATION_RAISING:
return "RAISING";
case DESKY_OPERATION_LOWERING:
return "LOWERING";
default:
return "UNKNOWN";
}
}
void Desky::setup() {
if (this->up_pin_ != nullptr)
this->up_pin_->digital_write(false);
if (this->down_pin_ != nullptr)
this->down_pin_->digital_write(false);
if (this->request_pin_ != nullptr) {
this->request_pin_->digital_write(true);
this->request_time_ = millis();
}
}
void Desky::loop() {
static int state = 0;
static uint8_t high_byte;
while (this->available()) {
uint8_t c;
int value;
this->read_byte(&c);
switch (state) {
case 0:
if (c == 1)
state = 1;
break;
case 1:
if (c == 1)
state = 2;
else
state = 0;
break;
case 2:
high_byte = c;
state = 3;
break;
case 3:
value = (high_byte << 8) + c;
this->current_pos_ = value;
if (this->height_sensor_ != nullptr)
this->height_sensor_->publish_state(value);
state = 0;
break;
}
}
if (this->target_pos_ >= 0) {
if (abs(this->target_pos_ - this->current_pos_) < this->stopping_distance_)
this->stop();
if ((this->timeout_ >= 0) && (millis() - this->start_time_ >= this->timeout_))
this->stop();
}
if ((this->request_time_ > 0) && (millis() - this->request_time_ >= 100)) {
this->request_pin_->digital_write(false);
this->request_time_ = 0;
}
}
void Desky::dump_config() {
ESP_LOGCONFIG(TAG, "Desky desk:");
LOG_SENSOR("", "Height", this->height_sensor_);
LOG_PIN("Up pin: ", this->up_pin_);
LOG_PIN("Down pin: ", this->down_pin_);
LOG_PIN("Request pin: ", this->request_pin_);
}
void Desky::move_to(int target_pos) {
if (abs(target_pos - this->current_pos_) < this->stopping_distance_)
return;
if (target_pos > this->current_pos_) {
if (this->up_pin_ == nullptr)
return;
this->up_pin_->digital_write(true);
this->current_operation = DESKY_OPERATION_RAISING;
} else {
if (this->down_pin_ == nullptr)
return;
this->down_pin_->digital_write(true);
this->current_operation = DESKY_OPERATION_LOWERING;
}
this->target_pos_ = target_pos;
if (this->timeout_ >= 0)
this->start_time_ = millis();
}
void Desky::stop() {
this->target_pos_ = -1;
if (this->up_pin_ != nullptr)
this->up_pin_->digital_write(false);
if (this->down_pin_ != nullptr)
this->down_pin_->digital_write(false);
this->current_operation = DESKY_OPERATION_IDLE;
}
} // namespace desky
} // namespace esphome

52
components/wordcl/desky.h Normal file
View file

@ -0,0 +1,52 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
#include "esphome/core/hal.h"
namespace esphome {
namespace desky {
enum DeskyOperation : uint8_t {
DESKY_OPERATION_IDLE = 0,
DESKY_OPERATION_RAISING,
DESKY_OPERATION_LOWERING,
};
const char *desky_operation_to_str(DeskyOperation op);
class Desky : public Component, public sensor::Sensor, public uart::UARTDevice {
public:
float get_setup_priority() const override { return setup_priority::LATE; }
void setup() override;
void loop() override;
void dump_config() override;
void set_height_sensor(sensor::Sensor *sensor) { this->height_sensor_ = sensor; }
void set_up_pin(GPIOPin *pin) { this->up_pin_ = pin; }
void set_down_pin(GPIOPin *pin) { this->down_pin_ = pin; }
void set_request_pin(GPIOPin *pin) { this->request_pin_ = pin; }
void set_stopping_distance(int distance) { this->stopping_distance_ = distance; }
void set_timeout(int timeout) { this->timeout_ = timeout; }
void move_to(int height);
void stop();
DeskyOperation current_operation{DESKY_OPERATION_IDLE};
protected:
sensor::Sensor *height_sensor_{nullptr};
GPIOPin *up_pin_{nullptr};
GPIOPin *down_pin_{nullptr};
GPIOPin *request_pin_{nullptr};
int stopping_distance_;
int current_pos_{0};
int target_pos_{-1};
int timeout_{-1};
uint64_t start_time_;
uint64_t request_time_{0};
};
} // namespace desky
} // namespace esphome