From e2937430a0880a711b4cb975ed302001544c26f0 Mon Sep 17 00:00:00 2001 From: mvturnho Date: Sun, 2 Jun 2019 09:11:59 +0200 Subject: [PATCH] update for timings. does not compile yet --- esphome/components/sx1509/__init__.py | 22 ++++++-- esphome/components/sx1509/binary_sensor.py | 29 ++++++++++ esphome/components/sx1509/sensor.py | 9 +-- esphome/components/sx1509/sx1509.cpp | 55 +++++++------------ esphome/components/sx1509/sx1509.h | 7 +-- esphome/components/sx1509/sx1509_gpio_pin.cpp | 18 +++++- esphome/components/sx1509/sx1509_gpio_pin.h | 23 +++++--- .../sx1509/sx1509_keypad_sensor.cpp | 22 +++----- .../components/sx1509/sx1509_keypad_sensor.h | 19 ++++++- 9 files changed, 132 insertions(+), 72 deletions(-) create mode 100644 esphome/components/sx1509/binary_sensor.py diff --git a/esphome/components/sx1509/__init__.py b/esphome/components/sx1509/__init__.py index 1a438764f4..d0654c0070 100644 --- a/esphome/components/sx1509/__init__.py +++ b/esphome/components/sx1509/__init__.py @@ -4,7 +4,12 @@ from esphome import pins from esphome.components import i2c from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED -CONF_TIME_ON = 'time_on' +CONF_ON_TIME = 'on_time' +CONF_OFF_TIME = 'off_time' +CONF_RISE_TIME = 'rise_time' +CONF_FALL_TIME = 'fall_time' +CONF_ON_INT = 'on_intemsity' +CONF_OFF_INT = 'off_intensity' DEPENDENCIES = ['i2c'] MULTI_CONF = True @@ -39,8 +44,12 @@ SX1509_OUTPUT_PIN_SCHEMA = cv.Schema({ cv.Required(CONF_NUMBER): cv.int_, cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(SX1509_GPIO_MODES, upper=True), cv.Optional(CONF_INVERTED, default=False): cv.boolean, - cv.Optional(CONF_TIME_ON): cv.int_, -}) + cv.Optional(CONF_ON_TIME, default=500): cv.int_, + cv.Optional(CONF_OFF_TIME, default=500): cv.int_, + cv.Optional(CONF_RISE_TIME, default=500): cv.int_, + cv.Optional(CONF_FALL_TIME, default=500): cv.int_, + cv.Optional(CONF_ON_INT, default=7): cv.int_range(min=0, max=7), + cv.Optional(CONF_OFF_INT, default=0): cv.int_range(min=0, max=7), }) SX1509_INPUT_PIN_SCHEMA = cv.Schema({ cv.Required(CONF_SX1509): cv.use_id(SX1509Component), cv.Required(CONF_NUMBER): cv.int_, @@ -53,4 +62,9 @@ SX1509_INPUT_PIN_SCHEMA = cv.Schema({ (SX1509_OUTPUT_PIN_SCHEMA, SX1509_INPUT_PIN_SCHEMA)) def sx1509_pin_to_code(config): parent = yield cg.get_variable(config[CONF_SX1509]) - yield SX1509GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]) + if(config[CONF_MODE] == 'BREATHE_OUTPUT' or config[CONF_MODE] == 'BLINK_OUTPUT'): + yield SX1509GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED], + config[CONF_ON_TIME], config[CONF_OFF_TIME], + config[CONF_RISE_TIME], config[CONF_FALL_TIME]) + else: + yield SX1509GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]) diff --git a/esphome/components/sx1509/binary_sensor.py b/esphome/components/sx1509/binary_sensor.py new file mode 100644 index 0000000000..d49e954355 --- /dev/null +++ b/esphome/components/sx1509/binary_sensor.py @@ -0,0 +1,29 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import binary_sensor +from esphome.const import CONF_ID +from sensor import SX1509KeypadSensor, sx1509_ns + +CONF_ROW = 'row' +CONF_COL = 'col' + + +SX1509BinarySensor = sx1509_ns.class_('SX1509BinarySensor', binary_sensor.BinarySensor) + +CONF_SX1509_KEYPAD_ID = 'sx1509_keypad_id' + +CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({ + cv.GenerateID(): cv.declare_id(SX1509BinarySensor), + cv.GenerateID(CONF_SX1509_KEYPAD_ID): cv.use_id(SX1509KeypadSensor), + cv.Required(CONF_ROW): cv.int_range(min=0, max=4), + cv.Required(CONF_COL): cv.int_range(min=0, max=4), +}) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield binary_sensor.register_binary_sensor(var, config) + hub = yield cg.get_variable(config[CONF_SX1509_KEYPAD_ID]) + cg.add(var.set_row_col(config[CONF_ROW], config[CONF_COL])) + + cg.add(hub.register_binary_sensor(var)) diff --git a/esphome/components/sx1509/sensor.py b/esphome/components/sx1509/sensor.py index 19049a9c3b..8ca57fb6c0 100644 --- a/esphome/components/sx1509/sensor.py +++ b/esphome/components/sx1509/sensor.py @@ -2,7 +2,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import pins from esphome.components import sensor -from esphome.const import CONF_ID,UNIT_EMPTY, ICON_EMPTY +from esphome.const import CONF_ID, UNIT_EMPTY, ICON_EMPTY from . import SX1509Component, sx1509_ns CONF_KEY_ROWS = 'key_rows' @@ -13,7 +13,7 @@ CONF_DEBOUNCE_TIME = 'debounce_time' DEPENDENCIES = ['sx1509'] -SX1509KeypadSensor = sx1509_ns.class_('SX1509KeypadSensor',sensor.Sensor, cg.Component) +SX1509KeypadSensor = sx1509_ns.class_('SX1509KeypadSensor', sensor.Sensor, cg.Component) CONF_SX1509_ID = 'sx1509_id' @@ -35,5 +35,6 @@ def to_code(config): yield sensor.register_sensor(var, config) cg.add(var.set_parent(parent)) - cg.add(var.set_rows_cols(config[CONF_KEY_ROWS] ,config[CONF_KEY_COLUMNS] )) - cg.add(var.set_timers(config[CONF_SLEEP_TIME],config[CONF_SCAN_TIME], config[CONF_DEBOUNCE_TIME] )) + cg.add(var.set_rows_cols(config[CONF_KEY_ROWS], config[CONF_KEY_COLUMNS])) + cg.add(var.set_timers(config[CONF_SLEEP_TIME], config[CONF_SCAN_TIME], \ + config[CONF_DEBOUNCE_TIME])) diff --git a/esphome/components/sx1509/sx1509.cpp b/esphome/components/sx1509/sx1509.cpp index 7dfbdc3d09..5a74a1765f 100644 --- a/esphome/components/sx1509/sx1509.cpp +++ b/esphome/components/sx1509/sx1509.cpp @@ -28,8 +28,6 @@ void SX1509Component::setup() { // channel->setup(); delayMicroseconds(500); - - this->loop(); } void SX1509Component::dump_config() { @@ -39,15 +37,6 @@ void SX1509Component::dump_config() { } } -void SX1509Component::loop() {} - -// SX1509FloatOutputChannel *SX1509Component::create_float_output_channel(uint8_t pin) { -// ESP_LOGD(TAG, "Create float channel for pin %d", pin); -// auto *channel = new SX1509FloatOutputChannel(this, pin); -// float_output_channels_.push_back(channel); -// return channel; -// } - uint8_t SX1509Component::digital_read(uint8_t pin) { uint16_t tempRegDir; this->read_byte_16(REG_DIR_B, &tempRegDir); @@ -120,10 +109,6 @@ void SX1509Component::pin_mode(uint8_t pin, uint8_t mode) { if (mode == ANALOG_OUTPUT) { led_driver_init(pin); } - - if (mode == BREATHE_OUTPUT) { - breathe(pin, 1000, 1000, 1000, 1000); - } } void SX1509Component::led_driver_init(uint8_t pin, uint8_t freq, bool log) { @@ -174,41 +159,41 @@ void SX1509Component::led_driver_init(uint8_t pin, uint8_t freq, bool log) { this->write_byte_16(REG_DATA_B, temp_word); } -void SX1509Component::breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, - unsigned long fall, uint8_t onInt, uint8_t offInt, bool log) { - offInt = constrain(offInt, 0, 7); +void SX1509Component::breathe(uint8_t pin, uint16_t t_on, uint16_t t_off,uint16_t t_rise, + uint16_t t_fall, uint8_t on_intensity, uint8_t off_intensity, bool log) { + off_intensity = constrain(off_intensity, 0, 7); - uint8_t onReg = calculate_led_t_register(tOn); - uint8_t offReg = calculate_led_t_register(tOff); + uint8_t onReg = calculate_led_t_register(t_on); + uint8_t offReg = calculate_led_t_register(t_off); - uint8_t riseTime = calculate_slope_register(rise, onInt, offInt); - uint8_t fallTime = calculate_slope_register(fall, onInt, offInt); + uint8_t rise_time = calculate_slope_register(t_rise, on_intensity, off_intensity); + uint8_t fall_time = calculate_slope_register(t_fall, on_intensity, off_intensity); - setup_blink(pin, onReg, offReg, onInt, offInt, riseTime, fallTime, log); + setup_blink(pin, onReg, offReg, on_intensity, off_intensity, rise_time, fall_time, log); } -void SX1509Component::setup_blink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t onIntensity, uint8_t offIntensity, - uint8_t tRise, uint8_t tFall, bool log) { +void SX1509Component::setup_blink(uint8_t pin, uint8_t t_on, uint8_t t_off, uint8_t on_intensity, uint8_t off_intensity, + uint8_t t_rise, uint8_t t_fall, bool log) { led_driver_init(pin, log); - tOn &= 0x1F; // tOn should be a 5-bit value - tOff &= 0x1F; // tOff should be a 5-bit value - offIntensity &= 0x07; + t_on &= 0x1F; // t_on should be a 5-bit value + t_off &= 0x1F; // t_off should be a 5-bit value + off_intensity &= 0x07; // Write the time on - this->write_byte(REG_T_ON[pin], tOn); + this->write_byte(REG_T_ON[pin], t_on); - this->write_byte(REG_OFF[pin], (tOff << 3) | offIntensity); + this->write_byte(REG_OFF[pin], (t_off << 3) | off_intensity); - this->write_byte(REG_I_ON[pin], onIntensity); + this->write_byte(REG_I_ON[pin], on_intensity); - tRise &= 0x1F; - tFall &= 0x1F; + t_rise &= 0x1F; + t_fall &= 0x1F; if (REG_T_RISE[pin] != 0xFF) - this->write_byte(REG_T_RISE[pin], tRise); + this->write_byte(REG_T_RISE[pin], t_rise); if (REG_T_FALL[pin] != 0xFF) - this->write_byte(REG_T_FALL[pin], tFall); + this->write_byte(REG_T_FALL[pin], t_fall); } void SX1509Component::clock(byte oscSource, byte oscPinFunction, byte oscFreqOut, byte oscDivider) { diff --git a/esphome/components/sx1509/sx1509.h b/esphome/components/sx1509/sx1509.h index 0376625085..12fdd56f83 100644 --- a/esphome/components/sx1509/sx1509.h +++ b/esphome/components/sx1509/sx1509.h @@ -34,7 +34,6 @@ class SX1509Component : public Component, public i2c::I2CDevice { void setup() override; void dump_config() override; float get_setup_priority() const override { return setup_priority::HARDWARE; } - void loop() override; void pin_mode(uint8_t pin, uint8_t in_out); void led_driver_init(uint8_t pin, uint8_t freq = 1, bool log = false); void clock(uint8_t osc_source = 2, uint8_t osc_divider = 1, uint8_t osc_pin_function = 0, uint8_t osc_freq_out = 0); @@ -44,9 +43,9 @@ class SX1509Component : public Component, public i2c::I2CDevice { void setup_blink(uint8_t pin, uint8_t t_on, uint8_t t_off, uint8_t on_intensity = 255, uint8_t off_intensity = 0, uint8_t t_rise = 0, uint8_t t_fall = 0, bool log = false); - void blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t on_intensity = 255, uint8_t off_intensity = 0); - void breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, - uint8_t onInt = 255, uint8_t offInt = 0, bool log = LINEAR); + void blink(uint8_t pin, uint16_t tOn, uint16_t tOff, uint8_t on_intensity = 255, uint8_t off_intensity = 0); + void breathe(uint8_t pin, uint16_t tOn, uint16_t tOff, uint16_t rise, uint16_t fall, + uint8_t on_intensity = 255, uint8_t off_intensity = 0, bool log = LINEAR); uint8_t calculate_led_t_register(uint16_t ms); uint8_t calculate_slope_register(uint16_t ms, uint8_t on_intensity, uint8_t off_intensity); void setup_keypad(uint8_t rows, uint8_t columns, uint16_t sleep_time = 0, uint8_t scan_time = 1, diff --git a/esphome/components/sx1509/sx1509_gpio_pin.cpp b/esphome/components/sx1509/sx1509_gpio_pin.cpp index ec7b42309d..076e715a85 100644 --- a/esphome/components/sx1509/sx1509_gpio_pin.cpp +++ b/esphome/components/sx1509/sx1509_gpio_pin.cpp @@ -7,11 +7,25 @@ namespace sx1509 { static const char *TAG = "sx1509_gpio_pin"; -SX1509GPIOPin::SX1509GPIOPin(SX1509Component *parent, uint8_t pin, uint8_t mode, bool inverted) - : GPIOPin(pin, mode, inverted), parent_(parent) {} +SX1509GPIOPin::SX1509GPIOPin(SX1509Component *parent, uint8_t pin, uint8_t mode, bool inverted, uint16_t t_on, + uint16_t t_off, uint16_t t_rise, uint16_t t_fall) + : GPIOPin(pin, mode, inverted), parent_(parent) { + t_on_ = t_on; + t_off_ = t_off; + t_rise_ = t_rise; + t_fall_ = t_fall; +} void SX1509GPIOPin::setup() { ESP_LOGD(TAG, "setup pin %d", this->pin_); this->pin_mode(this->mode_); + switch (this->mode_) { + case BREATHE_OUTPUT: + this->parent_->breathe(this->pin_, t_on_, t_off_, t_rise_, t_fall_); + break; + case BLINK_OUTPUT: + this->parent_->blink(this->pin_, t_on_, t_off_); + break; + } } void SX1509GPIOPin::pin_mode(uint8_t mode) { this->parent_->pin_mode(this->pin_, mode); } bool SX1509GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } diff --git a/esphome/components/sx1509/sx1509_gpio_pin.h b/esphome/components/sx1509/sx1509_gpio_pin.h index 7c5625b090..11ffd32549 100644 --- a/esphome/components/sx1509/sx1509_gpio_pin.h +++ b/esphome/components/sx1509/sx1509_gpio_pin.h @@ -3,26 +3,26 @@ #include "sx1509.h" #define BREATHE_OUTPUT 0x04 -#define BLINK_OUTPUT 0x04 +#define BLINK_OUTPUT 0x05 namespace esphome { namespace sx1509 { /// Modes for SX1509 pins enum SX1509GPIOMode : uint8_t { - SX1509_INPUT = INPUT, // 0x00 - SX1509_INPUT_PULLUP = INPUT_PULLUP, // 0x02 - SX1509_OUTPUT = OUTPUT, // 0x01 - SX1509_BREATHE_OUTPUT = BREATHE_OUTPUT, // 0x04 - SX1509_BLINK_OUTPUT = BLINK_OUTPUT // 0x05 + SX1509_INPUT = INPUT, // 0x00 + SX1509_INPUT_PULLUP = INPUT_PULLUP, // 0x02 + SX1509_OUTPUT = OUTPUT, // 0x01 + SX1509_BREATHE_OUTPUT = BREATHE_OUTPUT, // 0x04 + SX1509_BLINK_OUTPUT = BLINK_OUTPUT // 0x05 }; class SX1509Component; class SX1509GPIOPin : public GPIOPin { public: - SX1509GPIOPin(SX1509Component *parent, uint8_t pin, uint8_t mode, bool inverted = false); - + SX1509GPIOPin(SX1509Component *parent, uint8_t pin, uint8_t mode, bool inverted = false, uint16_t t_on = 500, + uint16_t t_off = 500, uint16_t t_rise = 250, uint16_t t_fall = 250); void setup() override; void pin_mode(uint8_t mode) override; bool digital_read() override; @@ -30,6 +30,11 @@ class SX1509GPIOPin : public GPIOPin { protected: SX1509Component *parent_; + uint16_t t_on_ = {0}; + uint16_t t_off_ = {0}; + uint16_t t_rise_ = {0}; + uint16_t t_fall_ = {0}; }; -}} \ No newline at end of file +} // namespace sx1509 +} // namespace esphome \ No newline at end of file diff --git a/esphome/components/sx1509/sx1509_keypad_sensor.cpp b/esphome/components/sx1509/sx1509_keypad_sensor.cpp index 03cdf3f2c0..98e50a71b5 100644 --- a/esphome/components/sx1509/sx1509_keypad_sensor.cpp +++ b/esphome/components/sx1509/sx1509_keypad_sensor.cpp @@ -10,13 +10,6 @@ static const char *TAG = "sx1509_keypad_sensor"; void SX1509KeypadSensor::setup() { ESP_LOGD(TAG, "setup rows: %d , cols: %d", this->rows_, this->cols_); this->parent_->setup_keypad(this->rows_, this->cols_, this->sleep_time_, this->scan_time_, this->debounce_time_); - keypad_values_ = new uint8_t *[this->rows_]; - for (uint8_t i = 0; i < this->rows_; ++i) { - keypad_values_[i] = new uint8_t[this->cols_]; - for (uint8_t j = 0; j < this->cols_; j++) { - keypad_values_[i][j] = i * j; - } - } } void SX1509KeypadSensor::dump_config() { @@ -27,11 +20,11 @@ void SX1509KeypadSensor::dump_config() { void SX1509KeypadSensor::loop() { uint16_t key_data = this->parent_->read_key_data(); if (key_data != 0) { - byte row = get_row_(key_data); - byte col = get_col_(key_data); - uint8_t key = this->keypad_values_[row][col]; + uint8_t row = get_row_(key_data); + uint8_t col = get_col_(key_data); + uint8_t key = (row * cols_) + col; if (key_data != last_key_press_) { - ESP_LOGD(TAG, "'%s' - Publishing %d", this->name_.c_str(), key); + ESP_LOGD(TAG, "'%s' - Publishing %d rawdata: %04x", this->name_.c_str(), key, key_data); this->publish_state(key); } } else if (this->last_key_press_ != 0ULL) { @@ -40,9 +33,12 @@ void SX1509KeypadSensor::loop() { this->publish_state(NAN); } this->last_key_press_ = key_data; + + for (auto *binary_sensor : this->binary_sensors_) + binary_sensor->process(key_data); } -byte SX1509KeypadSensor::get_row_(uint16_t key_data) { +uint8_t SX1509KeypadSensor::get_row_(uint16_t key_data) { uint8_t row_data = uint8_t(key_data & 0x00FF); for (uint16_t i = 0; i < 8; i++) { if (row_data & (1 << i)) @@ -51,7 +47,7 @@ byte SX1509KeypadSensor::get_row_(uint16_t key_data) { return 0; } -byte SX1509KeypadSensor::get_col_(uint16_t key_data) { +uint8_t SX1509KeypadSensor::get_col_(uint16_t key_data) { uint8_t col_data = uint8_t((key_data & 0xFF00) >> 8); for (uint16_t i = 0; i < 8; i++) { if (col_data & (1 << i)) diff --git a/esphome/components/sx1509/sx1509_keypad_sensor.h b/esphome/components/sx1509/sx1509_keypad_sensor.h index d28d56b29d..142578c58c 100644 --- a/esphome/components/sx1509/sx1509_keypad_sensor.h +++ b/esphome/components/sx1509/sx1509_keypad_sensor.h @@ -3,12 +3,28 @@ #include "sx1509.h" #include "esphome/components/output/float_output.h" #include "esphome/components/sensor/sensor.h" +#include "esphome/components/binary_sensor/binary_sensor.h" +#include "esphome/core/log.h" namespace esphome { namespace sx1509 { class SX1509Component; +class SX1509BinarySensor : public binary_sensor::BinarySensor { + friend class SX1509KeypadSensor; + + public: + void set_row_col(uint8_t row, uint8_t col) { + this->key_ = (1 << (row + 8)) | (1 << col); + ESP_LOGD("SX1509BinarySensor", "register row: %d , col: %d , key: %04x", row, col, key_); + } + void process(uint16_t keydata) { this->publish_state(static_cast(keydata == key_)); } + + protected: + uint16_t key_{0}; +}; + class SX1509KeypadSensor : public sensor::Sensor, public Component { public: void set_parent(SX1509Component *parent) { this->parent_ = parent; } @@ -25,16 +41,17 @@ class SX1509KeypadSensor : public sensor::Sensor, public Component { void dump_config() override; float get_setup_priority() const override { return setup_priority::HARDWARE; } void loop() override; + void register_binary_sensor(SX1509BinarySensor *binary_sensor) { this->binary_sensors_.push_back(binary_sensor); }; protected: SX1509Component *parent_; - uint8_t **keypad_values_; uint8_t rows_ = {}; uint8_t cols_ = {}; uint16_t sleep_time_ = {}; uint8_t scan_time_ = {}; uint8_t debounce_time_ = {}; uint16_t last_key_press_ = {0}; + std::vector binary_sensors_{}; uint8_t get_row_(uint16_t key_data); uint8_t get_col_(uint16_t key_data);