Browse Source

Added a binary sensor component, which can be used to handle touch/release events for the parts of the front panel (power button, color button and slider). Note that for the slider, this binary_sensor only detects the touch events. This cannot be used for detecting the actual slider level that was touch. For that purpose, a separate sensor will be created.

pull/4/head
Maurice Makaay 3 years ago
parent
commit
ec8205d32e
3 changed files with 100 additions and 2 deletions
  1. +43
    -0
      binary_sensor/__init__.py
  2. +52
    -0
      binary_sensor/button.h
  3. +5
    -2
      front_panel_hal.h

+ 43
- 0
binary_sensor/__init__.py View File

@ -0,0 +1,43 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor
#from esphome import automation
from esphome.const import CONF_DEVICE_CLASS, CONF_ID
from .. import (
bs2_ns, CODEOWNERS,
CONF_FRONT_PANEL_HAL_ID, FrontPanelHAL
)
AUTO_LOAD = ["yeelight_bs2"]
CONF_PART = "part"
PARTS = {
"ANY" : 0,
"POWER_BUTTON" : 1,
"COLOR_BUTTON" : 2,
"SLIDER" : 3.
}
def validate_part(value):
value = cv.string(value)
return cv.enum(PARTS, upper=True)(value)
YeelightBS2Button = bs2_ns.class_("YeelightBS2Button", binary_sensor.BinarySensor, cg.Component)
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(YeelightBS2Button),
cv.GenerateID(CONF_FRONT_PANEL_HAL_ID): cv.use_id(FrontPanelHAL),
cv.Optional(CONF_PART, default="ANY"): validate_part,
}
).extend(cv.COMPONENT_SCHEMA)
def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield binary_sensor.register_binary_sensor(var, config)
front_panel_hal_var = yield cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID])
cg.add(var.set_front_panel_hal(front_panel_hal_var))
cg.add(var.set_part(config[CONF_PART]))

+ 52
- 0
binary_sensor/button.h View File

@ -0,0 +1,52 @@
#pragma once
#include "../common.h"
#include "../front_panel_hal.h"
#include "esphome/components/binary_sensor/binary_sensor.h"
namespace esphome {
namespace yeelight {
namespace bs2 {
/**
* This class implements a binary sensor for the buttons on the
* Yeelight Bedside Lamp 2.
*/
class YeelightBS2Button : public binary_sensor::BinarySensor, public Component {
public:
void set_front_panel_hal(FrontPanelHAL *front_panel) {
front_panel_ = front_panel;
}
void set_part(int part) {
part_ = part;
}
void setup() {
ESP_LOGCONFIG(TAG, "Setting up binary_sensor ...");
ESP_LOGCONFIG(TAG, " Part id: %d", part_);
front_panel_->add_on_event_callback(
[this](EVENT ev) {
// Filter events by part, when requested.
ESP_LOGI(TAG, "FILTER event=%d, part=%d", ev, part_);
if (part_ > 0) {
if ((ev & FLAG_PART_MASK) != (part_ << FLAG_PART_SHIFT)) {
return;
}
}
// Publish the new state, based on the touch/release status..
auto on_or_off = (ev & FLAG_TYPE_MASK) == FLAG_TYPE_TOUCH;
this->publish_state(on_or_off);
}
);
}
protected:
FrontPanelHAL *front_panel_;
EVENT part_;
};
} // namespace bs2
} // namespace yeelight
} // namespace esphome

+ 5
- 2
front_panel_hal.h View File

@ -54,17 +54,20 @@ static const EVENT FLAG_INIT = 0b0000000000;
static const EVENT FLAG_ERR = 0b0000000000; static const EVENT FLAG_ERR = 0b0000000000;
static const EVENT FLAG_OK = 0b0000000001; static const EVENT FLAG_OK = 0b0000000001;
static const EVENT FLAG_PART_SHIFT = 1;
static const EVENT FLAG_PART_MASK = 0b0000000110; static const EVENT FLAG_PART_MASK = 0b0000000110;
static const EVENT FLAG_PART_UNKNOWN = 0b0000000000; static const EVENT FLAG_PART_UNKNOWN = 0b0000000000;
static const EVENT FLAG_PART_POWER = 0b0000000010; static const EVENT FLAG_PART_POWER = 0b0000000010;
static const EVENT FLAG_PART_COLOR = 0b0000000100; static const EVENT FLAG_PART_COLOR = 0b0000000100;
static const EVENT FLAG_PART_SLIDER = 0b0000000110; static const EVENT FLAG_PART_SLIDER = 0b0000000110;
static const EVENT FLAG_TYPE_SHIFT = 3;
static const EVENT FLAG_TYPE_MASK = 0b0000011000; static const EVENT FLAG_TYPE_MASK = 0b0000011000;
static const EVENT FLAG_TYPE_UNKNOWN = 0b0000000000; static const EVENT FLAG_TYPE_UNKNOWN = 0b0000000000;
static const EVENT FLAG_TYPE_TOUCH = 0b0000001000; static const EVENT FLAG_TYPE_TOUCH = 0b0000001000;
static const EVENT FLAG_TYPE_RELEASE = 0b0000010000; static const EVENT FLAG_TYPE_RELEASE = 0b0000010000;
static const EVENT FLAG_LEVEL_SHIFT = 5;
static const EVENT FLAG_LEVEL_MASK = 0b1111100000; static const EVENT FLAG_LEVEL_MASK = 0b1111100000;
static const EVENT FLAG_LEVEL_UNKNOWN = 0b0000000000; static const EVENT FLAG_LEVEL_UNKNOWN = 0b0000000000;
@ -110,7 +113,7 @@ public:
return error_(ev, m, "out of bounds slider value"); return error_(ev, m, "out of bounds slider value");
} else { } else {
auto level = 0x17 - m[5]; auto level = 0x17 - m[5];
ev |= (level << 5);
ev |= (level << FLAG_LEVEL_SHIFT);
} }
break; break;
default: default:
@ -143,7 +146,7 @@ protected:
(has_(ev, FLAG_TYPE_MASK, FLAG_TYPE_TOUCH) ? "touch" : (has_(ev, FLAG_TYPE_MASK, FLAG_TYPE_TOUCH) ? "touch" :
has_(ev, FLAG_TYPE_MASK, FLAG_TYPE_RELEASE) ? "release" : "n/a")); has_(ev, FLAG_TYPE_MASK, FLAG_TYPE_RELEASE) ? "release" : "n/a"));
if (has_(ev, FLAG_PART_MASK, FLAG_PART_SLIDER)) { if (has_(ev, FLAG_PART_MASK, FLAG_PART_SLIDER)) {
auto level = (ev & FLAG_LEVEL_MASK) >> 5;
auto level = (ev & FLAG_LEVEL_MASK) >> FLAG_LEVEL_SHIFT;
if (level > 0) { if (level > 0) {
ESP_LOGE(TAG, " Parsed slider level: %d", level); ESP_LOGE(TAG, " Parsed slider level: %d", level);
} }


Loading…
Cancel
Save