feat: add external component and some test configurations
This commit is contained in:
parent
4c612fc462
commit
5b0930d616
11 changed files with 511 additions and 6 deletions
53
components/wordcl/__init__.py
Normal file
53
components/wordcl/__init__.py
Normal 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
116
components/wordcl/desky.cpp
Normal 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
52
components/wordcl/desky.h
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue