diff --git a/binary_sensor/__init__.py b/binary_sensor/__init__.py index 782aa57..5a7549a 100644 --- a/binary_sensor/__init__.py +++ b/binary_sensor/__init__.py @@ -25,26 +25,9 @@ PARTS = { XiaomiBslamp2TouchBinarySensor = bslamp2_ns.class_( "XiaomiBslamp2TouchBinarySensor", binary_sensor.BinarySensor, cg.Component) -def get_part_id(value): - normalized = re.sub('\s+', '_', value.upper()) - try: - return PARTS[normalized] - except KeyError: - raise cv.Invalid(f"[{value}] is not a valid part identifier") - def validate_for(value): - parts = set() - if isinstance(value, str): - parts.add(get_part_id(value)) - elif isinstance(value, list): - for x in value: - parts.add(get_part_id(x)) - else: - cv.Invalid("The value must be a single part identifier or a list of identifiers.") - return list(parts) - -def validate_part(value): - return [ get_part_id(value) ] + value = cv.string(value) + return cv.enum(PARTS, upper=True, space='_')(value) def validate_binary_sensor(conf): if CONF_PART in conf and CONF_FOR in conf: @@ -63,7 +46,7 @@ CONFIG_SCHEMA = cv.All( # This option is not advertised in the documentation. It must be # considered deprecated. I'm not announcing it as such yet. Not sure # if it's useful to do so. - cv.Optional(CONF_PART): validate_part, + cv.Optional(CONF_PART): validate_for, cv.Optional(CONF_FOR): validate_for, } ).extend(cv.COMPONENT_SCHEMA), @@ -77,5 +60,4 @@ def to_code(config): front_panel_hal_var = yield cg.get_variable(config[CONF_FRONT_PANEL_HAL_ID]) cg.add(var.set_parent(front_panel_hal_var)) - for part_id in config[CONF_FOR]: - cg.add(var.include_part(part_id)) + cg.add(var.set_for(config[CONF_FOR])) diff --git a/binary_sensor/touch_binary_sensor.h b/binary_sensor/touch_binary_sensor.h index a4930fc..974fe94 100644 --- a/binary_sensor/touch_binary_sensor.h +++ b/binary_sensor/touch_binary_sensor.h @@ -18,44 +18,34 @@ public: front_panel_ = front_panel; } - void include_part(int part) { - match_ = match_ | part; + void set_for(int part) { + for_ = part; } void setup() { front_panel_->add_on_event_callback( [this](EVENT ev) { - auto part = ev & FLAG_PART_MASK; - auto is_touch = (ev & FLAG_TYPE_MASK) == FLAG_TYPE_TOUCH; - if (is_touch) { - active_ = active_ | part; - } else { - active_ = active_ & ~part; + auto part_in_event = ev & FLAG_PART_MASK; + if (for_ == 0 || part_in_event == for_) { + auto is_touch = (ev & FLAG_TYPE_MASK) == FLAG_TYPE_TOUCH; + this->publish_state(is_touch); } - - this->publish_state(active_ == match_); } ); } void dump_config() { ESP_LOGCONFIG(TAG, "Front panel binary_sensor:"); - ESP_LOGCONFIG(TAG, " Part(s):"); - if ((match_ & FLAG_PART_POWER) == FLAG_PART_POWER) { - ESP_LOGCONFIG(TAG, " - Power button"); - } - if ((match_ & FLAG_PART_COLOR) == FLAG_PART_COLOR) { - ESP_LOGCONFIG(TAG, " - Color button"); - } - if ((match_ & FLAG_PART_SLIDER) == FLAG_PART_SLIDER) { - ESP_LOGCONFIG(TAG, " - Slider"); - } + ESP_LOGCONFIG(TAG, " For: %s", + for_ & FLAG_PART_POWER ? "power button" : + for_ & FLAG_PART_COLOR ? "color button" : + for_ & FLAG_PART_SLIDER ? "slider" : "ERR"); } protected: FrontPanelHAL *front_panel_; EVENT match_ = 0; - EVENT active_ = 0; + EVENT for_ = 0; }; } // namespace bslamp2 diff --git a/doc/configuration.md b/doc/configuration.md index 76bc006..ee88dcf 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -258,41 +258,29 @@ is already well on its way.* Binary sensors can be added to the configuration for handling touch/release events for the front panel. On touch, a binary_sensor will publish `True`, on release it will publish `False`. The configuration of a binary_sensor -determines what part or parts of the front panel are involved in the touch -events. - -For referencing the parts of the front panel, the following identifiers are -available: - -* POWER_BUTTON (or POWER) -* COLOR_BUTTON (or its alias: COLOR) -* SLIDER - -If personal taste dictates so, you can use lower case characters and spaces -instead of underscores. This means that for example "Power Button" would also -be a valid identifier. +determines what part of the front panel is involved in the touch events. ```yaml binary_sensor: - platform: xiaomi_bslamp2 id: my_bedside_lamp_power_button for: POWER_BUTTON - on_release: - then: - - light.toggle: my_bedside_lamp - - - platform: xiaomi_bslamp2 - id: my_bedside_lamp_power_plus_color_button - for: - - POWER_BUTTON - - COLOR_BUTTON on_press: then: - - light.turn_on: - id: my_bedside_lamp - effect: BlinkyBlink + - light.toggle: my_bedside_lamp ``` +For referencing the parts of the front panel, the following part identifiers +are available: + +* POWER_BUTTON (or its alias: POWER) +* COLOR_BUTTON (or its alias: COLOR) +* SLIDER + +If personal taste dictates so, you can use lower case characters and spaces +instead of underscores. This means that for example "Power Button" and +"power" would be valid identifiers for the power button. + ### Configuration variables: * **name** (*Optional*, string): The name of the binary sensor. Setting a @@ -301,62 +289,11 @@ binary_sensor: * **id** (*Optional*, ID): Manually specify the ID used for code generation. By providing an id, you can reference the binary_sensor from automation rules (to retrieve the current state of the binary_sensor). -* **for** (*Mandatory*, single identifier or a list): This specifies what part - or parts of the front panel the binary sensor must look at. When multiple - parts are specified here, the binary_sensor will handle multi-touch events - using those parts. +* **for** (*Mandatory*, part identifier): This specifies to for part of the + front panel the binary sensor must report touch events. * All other options from [Binary Sensor](https://esphome.io/components/binary_sensor/index.html#config-binary-sensor). -### Multi-touch support - -When using a multi-touch binary-sensor, beware to use non-conflicting -triggers for any related binary sensors. For example, when you implement a -multi-touch binary sensor for the power + color button, then you probably -should not also be using `on_press` triggers for the two individual buttons. - -First a few definitions: - -* **multi-touch binary sensor**: when two or more parts of the front panel - can be touched concurrently to trigger an automation. A binary sensor can - be defined as multi-touch by configuring two or more parts in the `for:` - parameter. -* **lower order binary sensors**: binary sensors that use a subset of the - parts of a multi-touch binary sensor. For example a binary sensor for the - power button is a lower order binary sensor for a multi-touch binary - sensor for the power + color button. - -Why not use `on_press` for every binary sensor: - -The user of your lamp will very likely not touch the power and color buttons -at the *exact same time*. Therefore, you would first get an `on_press` -trigger for one of these buttons, followed by the `on_press` trigger for the -multi-touch binary sensor. Thus, if you have defined `on_press` for every -binary sensor, then two automations would be triggered. Most likely, this -would be unwanted behavior. - -Interlocking to the rescue: - -Multi-touch binary sensors provide a form of interlocking behavior, to -facilitate their use. - -* When multi-touch binary sensors trigger `on_press`, they will block all - further triggers for their lower order binary sensors. -* These blocks will be released after all involved parts have been released. - -Because of interlocking, in the above example you might first have gotten -an `on_press` trigger for the power button, followed by an `on_press` -trigger for the multi-touch power + color buttons. When after this the -buttons are released, then only the multi-touch binary sensor will trigger -`on_release`. - -TL;DR: - -* If a sensor is a lower order sensor for a multi-touch sensor, then it is - best to only use an `on_release` trigger. -* A multi-touch sensor can also act on other triggers. - - ## Component: sensor The sensor component publishes touch events for the front panel slider. The diff --git a/doc/example.yaml b/doc/example.yaml index 919876b..ffefd90 100644 --- a/doc/example.yaml +++ b/doc/example.yaml @@ -64,8 +64,8 @@ esphome: board: esp32doit-devkit-v1 platformio_options: platform: espressif32@3.2.0 - platform_packages: |-4 - framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.6 + platform_packages: |- + framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.6 # This component controls the LED lights of the lamp. light: