Add on_clockwise and on_anticlockwise triggers to rotary encoder (#1330)

This commit is contained in:
Jesse Hills 2020-11-02 06:24:26 +13:00 committed by GitHub
parent e4636b99f7
commit 20dd744680
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 1 deletions

View file

@ -94,10 +94,12 @@ void ICACHE_RAM_ATTR HOT RotaryEncoderSensorStore::gpio_intr(RotaryEncoderSensor
if ((new_state & arg->resolution & STATE_HAS_INCREMENTED) != 0) {
if (arg->counter < arg->max_value)
arg->counter++;
arg->on_clockwise_callback_.call();
}
if ((new_state & arg->resolution & STATE_HAS_DECREMENTED) != 0) {
if (arg->counter > arg->min_value)
arg->counter--;
arg->on_anticlockwise_callback_.call();
}
arg->state = new_state;

View file

@ -27,6 +27,9 @@ struct RotaryEncoderSensorStore {
int32_t last_read{0};
uint8_t state{0};
CallbackManager<void()> on_clockwise_callback_;
CallbackManager<void()> on_anticlockwise_callback_;
static void gpio_intr(RotaryEncoderSensorStore *arg);
};
@ -62,6 +65,14 @@ class RotaryEncoderSensor : public sensor::Sensor, public Component {
float get_setup_priority() const override;
void add_on_clockwise_callback(std::function<void()> callback) {
this->store_.on_clockwise_callback_.add(std::move(callback));
}
void add_on_anticlockwise_callback(std::function<void()> callback) {
this->store_.on_anticlockwise_callback_.add(std::move(callback));
}
protected:
GPIOPin *pin_a_;
GPIOPin *pin_b_;
@ -81,5 +92,19 @@ template<typename... Ts> class RotaryEncoderSetValueAction : public Action<Ts...
RotaryEncoderSensor *encoder_;
};
class RotaryEncoderClockwiseTrigger : public Trigger<> {
public:
explicit RotaryEncoderClockwiseTrigger(RotaryEncoderSensor *parent) {
parent->add_on_clockwise_callback([this]() { this->trigger(); });
}
};
class RotaryEncoderAnticlockwiseTrigger : public Trigger<> {
public:
explicit RotaryEncoderAnticlockwiseTrigger(RotaryEncoderSensor *parent) {
parent->add_on_anticlockwise_callback([this]() { this->trigger(); });
}
};
} // namespace rotary_encoder
} // namespace esphome

View file

@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome import pins, automation
from esphome.components import sensor
from esphome.const import CONF_ID, CONF_RESOLUTION, CONF_MIN_VALUE, CONF_MAX_VALUE, UNIT_STEPS, \
ICON_ROTATE_RIGHT, CONF_VALUE, CONF_PIN_A, CONF_PIN_B
ICON_ROTATE_RIGHT, CONF_VALUE, CONF_PIN_A, CONF_PIN_B, CONF_TRIGGER_ID
rotary_encoder_ns = cg.esphome_ns.namespace('rotary_encoder')
RotaryEncoderResolution = rotary_encoder_ns.enum('RotaryEncoderResolution')
@ -14,11 +14,18 @@ RESOLUTIONS = {
}
CONF_PIN_RESET = 'pin_reset'
CONF_ON_CLOCKWISE = 'on_clockwise'
CONF_ON_ANTICLOCKWISE = 'on_anticlockwise'
RotaryEncoderSensor = rotary_encoder_ns.class_('RotaryEncoderSensor', sensor.Sensor, cg.Component)
RotaryEncoderSetValueAction = rotary_encoder_ns.class_('RotaryEncoderSetValueAction',
automation.Action)
RotaryEncoderClockwiseTrigger = rotary_encoder_ns.class_('RotaryEncoderClockwiseTrigger',
automation.Trigger)
RotaryEncoderAnticlockwiseTrigger = rotary_encoder_ns.class_('RotaryEncoderAnticlockwiseTrigger',
automation.Trigger)
def validate_min_max_value(config):
if CONF_MIN_VALUE in config and CONF_MAX_VALUE in config:
@ -40,6 +47,12 @@ CONFIG_SCHEMA = cv.All(sensor.sensor_schema(UNIT_STEPS, ICON_ROTATE_RIGHT, 0).ex
cv.Optional(CONF_RESOLUTION, default=1): cv.enum(RESOLUTIONS, int=True),
cv.Optional(CONF_MIN_VALUE): cv.int_,
cv.Optional(CONF_MAX_VALUE): cv.int_,
cv.Optional(CONF_ON_CLOCKWISE): automation.validate_automation({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(RotaryEncoderClockwiseTrigger),
}),
cv.Optional(CONF_ON_ANTICLOCKWISE): automation.validate_automation({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(RotaryEncoderAnticlockwiseTrigger),
}),
}).extend(cv.COMPONENT_SCHEMA), validate_min_max_value)
@ -61,6 +74,13 @@ def to_code(config):
if CONF_MAX_VALUE in config:
cg.add(var.set_max_value(config[CONF_MAX_VALUE]))
for conf in config.get(CONF_ON_CLOCKWISE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
yield automation.build_automation(trigger, [], conf)
for conf in config.get(CONF_ON_ANTICLOCKWISE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
yield automation.build_automation(trigger, [], conf)
@automation.register_action('sensor.rotary_encoder.set_value', RotaryEncoderSetValueAction,
cv.Schema({

View file

@ -586,6 +586,10 @@ sensor:
- sensor.rotary_encoder.set_value:
id: rotary_encoder1
value: !lambda 'return -1;'
on_clockwise:
- logger.log: "Clockwise"
on_anticlockwise:
- logger.log: "Anticlockwise"
- platform: pulse_width
name: Pulse Width
pin: GPIO12