Browse Source

Added the front panel I2CComponent to the hub component.

pull/4/head
Maurice Makaay 3 years ago
parent
commit
dcfe951307
3 changed files with 37 additions and 27 deletions
  1. +31
    -8
      __init__.py
  2. +1
    -19
      doc/example.yaml
  3. +5
    -0
      yeelight_bs2_hub.h

+ 31
- 8
__init__.py View File

@ -3,6 +3,7 @@ import esphome.config_validation as cv
from esphome import pins from esphome import pins
from esphome.components.ledc.output import LEDCOutput, validate_frequency from esphome.components.ledc.output import LEDCOutput, validate_frequency
from esphome.components.gpio.output import GPIOBinaryOutput from esphome.components.gpio.output import GPIOBinaryOutput
from esphome.components.i2c import I2CComponent
from esphome.core import coroutine from esphome.core import coroutine
from esphome.core import CORE from esphome.core import CORE
from esphome.const import ( from esphome.const import (
@ -12,6 +13,8 @@ from esphome.const import (
CONF_BLUE, CONF_BLUE,
CONF_WHITE, CONF_WHITE,
CONF_TRIGGER_PIN, CONF_TRIGGER_PIN,
CONF_SDA,
CONF_SCL,
CONF_OUTPUT_ID, CONF_OUTPUT_ID,
CONF_TRIGGER_ID, CONF_TRIGGER_ID,
CONF_PIN, CONF_PIN,
@ -29,15 +32,12 @@ CONF_MASTER1 = "master1"
CONF_MASTER1_ID = "master1_id" CONF_MASTER1_ID = "master1_id"
CONF_MASTER2 = "master2" CONF_MASTER2 = "master2"
CONF_MASTER2_ID = "master2_id" CONF_MASTER2_ID = "master2_id"
CONF_FP_I2C_ID = "front_panel_i2c_id"
CONF_ON_BRIGHTNESS = "on_brightness" CONF_ON_BRIGHTNESS = "on_brightness"
CODEOWNERS = ["@mmakaay"] CODEOWNERS = ["@mmakaay"]
AUTO_LOAD = ["ledc", "output"]
yeelight_ns = cg.esphome_ns.namespace("yeelight")
bs2_ns = yeelight_ns.namespace("bs2")
YeelightBS2Hub = bs2_ns.class_("YeelightBS2Hub", cg.Component)
AUTO_LOAD = ["ledc", "output", "i2c"]
PINS = { PINS = {
# Config key TYPE, ID GPIO, PARAMS # Config key TYPE, ID GPIO, PARAMS
@ -46,13 +46,27 @@ PINS = {
CONF_BLUE : ( LEDCOutput, CONF_BLUE_ID, "GPIO5", 3000, 2 ), CONF_BLUE : ( LEDCOutput, CONF_BLUE_ID, "GPIO5", 3000, 2 ),
CONF_WHITE : ( LEDCOutput, CONF_WHITE_ID, "GPIO12", 10000, 4 ), CONF_WHITE : ( LEDCOutput, CONF_WHITE_ID, "GPIO12", 10000, 4 ),
CONF_MASTER1 : ( GPIOBinaryOutput, CONF_MASTER1_ID, "GPIO33" ), CONF_MASTER1 : ( GPIOBinaryOutput, CONF_MASTER1_ID, "GPIO33" ),
CONF_MASTER2 : ( GPIOBinaryOutput, CONF_MASTER2_ID, "GPIO4" ),
CONF_MASTER2 : ( GPIOBinaryOutput, CONF_MASTER2_ID, "GPIO4" )
} }
FRONT_PANEL = {
CONF_SDA: "GPIO21",
CONF_SCL: "GPIO19",
CONF_TRIGGER_PIN: "GPIO16"
}
yeelight_ns = cg.esphome_ns.namespace("yeelight")
bs2_ns = yeelight_ns.namespace("bs2")
YeelightBS2Hub = bs2_ns.class_("YeelightBS2Hub", cg.Component)
def make_config_schema(): def make_config_schema():
schema = cv.COMPONENT_SCHEMA.extend({ schema = cv.COMPONENT_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(YeelightBS2Hub), cv.GenerateID(): cv.declare_id(YeelightBS2Hub),
cv.Optional(CONF_TRIGGER_PIN, default="GPIO16"): cv.All(
cv.GenerateID(CONF_FP_I2C_ID): cv.use_id(I2CComponent),
cv.Optional(CONF_SDA, default=FRONT_PANEL[CONF_SDA]): pins.validate_gpio_pin,
cv.Optional(CONF_SCL, default=FRONT_PANEL[CONF_SCL]): pins.validate_gpio_pin,
cv.Optional(CONF_TRIGGER_PIN, default=FRONT_PANEL[CONF_TRIGGER_PIN]): cv.All(
pins.validate_gpio_pin, pins.validate_gpio_pin,
pins.validate_has_interrupt pins.validate_has_interrupt
), ),
@ -67,7 +81,6 @@ def make_config_schema():
return schema; return schema;
CONFIG_SCHEMA = make_config_schema() CONFIG_SCHEMA = make_config_schema()
@coroutine @coroutine
@ -120,6 +133,16 @@ def to_code(config):
}) })
cg.add(hub_var.set_trigger_pin(trigger_pin)) cg.add(hub_var.set_trigger_pin(trigger_pin))
# The i2c component automatically sets up one I2C bus.
# Take that bus and update is to make it work for the
# front panel I2C communication.
fp_i2c_var = yield cg.get_variable(config[CONF_FP_I2C_ID])
cg.add(fp_i2c_var.set_sda_pin(config[CONF_SDA]))
cg.add(fp_i2c_var.set_scl_pin(config[CONF_SCL]))
cg.add(fp_i2c_var.set_scan(True))
cg.add(hub_var.set_front_panel_i2c(fp_i2c_var))
for conf in config.get(CONF_ON_BRIGHTNESS, []): for conf in config.get(CONF_ON_BRIGHTNESS, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
yield automation.build_automation(trigger, [(float, "x")], conf) yield automation.build_automation(trigger, [(float, "x")], conf)

+ 1
- 19
doc/example.yaml View File

@ -32,6 +32,7 @@ esphome:
platform_packages: |-4 platform_packages: |-4
framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.4 framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.4
# This component controls the light of the device.
light: light:
- platform: yeelight_bs2 - platform: yeelight_bs2
name: ${friendly_name} RGBW Light name: ${friendly_name} RGBW Light
@ -47,22 +48,3 @@ light:
transition_length: 3s transition_length: 3s
update_interval: 3s update_interval: 3s
# The device uses two I2C busses.
i2c:
# This bus is very likely connected to an EEPROM that can be found
# on the lamp's board, right next to the GND, TX, RX and GPIO0 debug
# pads. The exact use of this component has not yet been reverse
# engineered.
- id: eeprom_i2c
sda: GPIO17
scl: GPIO18
scan: True
# This bus is connected to the front panel with the touch buttons.
# The touch panel is fully separated form the main board and ESP32,
# and communication is done strictly through I2C. The exact protocol
# has been reverse engineered and can be found in the file
# "doc/reverse_engineering/I2C protocol/i2c_commands.txt".
- id: front_panel_i2c
sda: GPIO21
scl: GPIO19
scan: True

+ 5
- 0
yeelight_bs2_hub.h View File

@ -5,6 +5,7 @@
#include "esphome/core/esphal.h" #include "esphome/core/esphal.h"
#include "esphome/components/ledc/ledc_output.h" #include "esphome/components/ledc/ledc_output.h"
#include "esphome/components/gpio/output/gpio_binary_output.h" #include "esphome/components/gpio/output/gpio_binary_output.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome { namespace esphome {
namespace yeelight { namespace yeelight {
@ -45,6 +46,7 @@ public:
void set_white_pin(ledc::LEDCOutput *pin) { white = pin; } void set_white_pin(ledc::LEDCOutput *pin) { white = pin; }
void set_master1_pin(gpio::GPIOBinaryOutput *pin) { master1 = pin; } void set_master1_pin(gpio::GPIOBinaryOutput *pin) { master1 = pin; }
void set_master2_pin(gpio::GPIOBinaryOutput *pin) { master2 = pin; } void set_master2_pin(gpio::GPIOBinaryOutput *pin) { master2 = pin; }
void set_front_panel_i2c(i2c::I2CComponent *fp_i2c) { fp_i2c_ = fp_i2c; }
void setup() { void setup() {
ESP_LOGCONFIG(TAG, "Setting up I2C trigger pin interrupt..."); ESP_LOGCONFIG(TAG, "Setting up I2C trigger pin interrupt...");
@ -72,6 +74,9 @@ protected:
// a touch/release event can be read using I2C. // a touch/release event can be read using I2C.
GPIOPin *i2c_trigger_pin_; GPIOPin *i2c_trigger_pin_;
// The I2C bus that is connected to the front panel.
i2c::I2CComponent *fp_i2c_;
// Fields that are used for trigger pin interrupt handling. // Fields that are used for trigger pin interrupt handling.
int counter_ = 0; int counter_ = 0;
TriggerPinStore trigger_pin_store_{}; TriggerPinStore trigger_pin_store_{};


Loading…
Cancel
Save