-
-
Save wolph/42024a983e4dfb0bc1dcbe6882979d21 to your computer and use it in GitHub Desktop.
light: | |
- platform: neopixelbus | |
type: GRB | |
variant: WS2812 | |
pin: GPIO1 | |
num_leds: 1 | |
name: "NeoPixel 1" | |
internal: true | |
- platform: neopixelbus | |
type: GRB | |
variant: WS2812 | |
pin: GPIO3 | |
num_leds: 1 | |
name: "NeoPixel 3" | |
internal: true | |
- platform: neopixelbus | |
type: GRB | |
variant: WS2812 | |
pin: GPIO5 | |
num_leds: 1 | |
name: "NeoPixel 5" | |
internal: true | |
- platform: neopixelbus | |
type: GRB | |
variant: WS2812 | |
pin: GPIO13 | |
num_leds: 1 | |
name: "NeoPixel 13" | |
internal: true | |
- platform: neopixelbus | |
type: GRB | |
variant: WS2812 | |
pin: GPIO32 | |
num_leds: 1 | |
name: "NeoPixel 32" | |
internal: true | |
- platform: neopixelbus | |
type: GRB | |
variant: WS2812 | |
# pin: GPIO20 | |
pin: GPIO33 | |
num_leds: 28 | |
name: "Ambience Nightlight" | |
id: rgb_light | |
effects: | |
- addressable_twinkle: | |
- addressable_random_twinkle: | |
- addressable_rainbow: | |
name: 'rainbow slow' | |
speed: 5 | |
- addressable_rainbow: | |
name: 'rainbow fast' | |
speed: 50 | |
- addressable_rainbow: | |
name: 'rainbow superfast' | |
speed: 100 | |
restore_mode: RESTORE_DEFAULT_OFF | |
# - platform: partition | |
# id: light_left_top | |
# name: "light left top" | |
# segments: | |
# - id: rgb_light | |
# from: 20 | |
# to: 20 | |
# - platform: partition | |
# id: light_middle_top | |
# name: "light middle top" | |
# segments: | |
# - id: rgb_light | |
# from: 23 | |
# to: 23 | |
# - platform: partition | |
# id: light_right_top | |
# name: "light right top" | |
# segments: | |
# - id: rgb_light | |
# from: 26 | |
# to: 27 | |
# - platform: partition | |
# id: light_left_bottom | |
# name: "light left bottom" | |
# segments: | |
# - id: rgb_light | |
# from: 6 | |
# to: 7 | |
# - platform: partition | |
# id: light_middle_bottom | |
# name: "light middle bottom" | |
# segments: | |
# - id: rgb_light | |
# from: 8 | |
# to: 10 | |
# - platform: partition | |
# id: light_right_bottom | |
# name: "light right bottom" | |
# segments: | |
# - id: rgb_light | |
# from: 11 | |
# to: 12 | |
- platform: partition | |
restore_mode: RESTORE_DEFAULT_OFF | |
id: light_left_both | |
name: "light left both" | |
segments: | |
- id: rgb_light | |
from: 11 | |
to: 21 | |
effects: | |
- addressable_twinkle: | |
- addressable_random_twinkle: | |
- addressable_rainbow: | |
speed: 5 | |
- platform: partition | |
restore_mode: RESTORE_DEFAULT_OFF | |
id: light_middle_both | |
name: "light middle both" | |
segments: | |
- id: rgb_light | |
from: 22 | |
to: 24 | |
- id: rgb_light | |
from: 8 | |
to: 10 | |
effects: | |
- addressable_twinkle: | |
- addressable_random_twinkle: | |
- addressable_rainbow: | |
speed: 5 | |
- platform: partition | |
restore_mode: RESTORE_DEFAULT_OFF | |
id: light_right_both | |
name: "light right both" | |
segments: | |
- id: rgb_light | |
from: 0 | |
to: 7 | |
- id: rgb_light | |
from: 25 | |
to: 27 | |
effects: | |
- addressable_twinkle: | |
- addressable_random_twinkle: | |
- addressable_rainbow: | |
speed: 5 | |
- platform: partition | |
restore_mode: RESTORE_DEFAULT_OFF | |
id: light_right | |
name: "light right" | |
segments: | |
- id: rgb_light | |
from: 0 | |
to: 5 | |
# - platform: partition | |
# id: light_bottom | |
# name: "light bottom" | |
# segments: | |
# - id: rgb_light | |
# from: 6 | |
# to: 12 | |
- platform: partition | |
restore_mode: RESTORE_DEFAULT_OFF | |
id: light_left | |
name: "light left" | |
segments: | |
- id: rgb_light | |
from: 13 | |
to: 19 | |
# - platform: partition | |
# id: light_top | |
# name: "light top" | |
# segments: | |
# - id: rgb_light | |
# from: 20 | |
# to: 26 |
condition: | |
switch.is_on: ${switch} | |
then: | |
- light.turn_on: | |
id: ${light} | |
brightness: ${on_brightness} | |
red: ${on_red} | |
green: ${on_green} | |
blue: ${on_blue} | |
transition_length: 500ms | |
else: | |
- if: | |
condition: | |
and: | |
- lambda: |- | |
return id(htime).now().hour < ${nightlight_on_hour}; | |
- lambda: |- | |
return id(htime).now().hour > ${nightlight_off_hour}; | |
then: | |
- light.turn_off: | |
id: ${light} | |
transition_length: 500ms | |
else: | |
- light.turn_on: | |
id: ${light} | |
brightness: ${nightlight_brightness} | |
red: ${nightlight_red} | |
green: ${nightlight_green} | |
blue: ${nightlight_blue} | |
transition_length: 500ms |
substitutions: | |
name: 'sonoff_tx_ultimate_00' | |
on_brightness: 50% | |
on_red: 100% | |
on_green: 40% | |
on_blue: 0% | |
nightlight_brightness: 20% | |
nightlight_red: 100% | |
nightlight_green: 40% | |
nightlight_blue: 0% | |
nightlight_on_hour: '19' # turn on at 7 in the evening | |
nightlight_off_hour: '9' # turn off at 9 in the morning | |
esphome: | |
name: $name | |
platform: ESP32 | |
board: esp32dev | |
on_boot: | |
priority: -100.0 | |
then: | |
- script.execute: light_relays | |
includes: | |
- touch_panel.hpp | |
- touch_panel.cpp | |
uart: | |
id: uart_bus | |
tx_pin: GPIO19 | |
rx_pin: GPIO22 | |
baud_rate: 115200 | |
script: | |
- id: light_relays | |
then: | |
- if: !include | |
file: relays_light.yaml | |
vars: | |
switch: relay1 | |
light: light_left_both | |
- if: !include | |
file: relays_light.yaml | |
vars: | |
switch: relay2 | |
light: light_middle_both | |
- if: !include | |
file: relays_light.yaml | |
vars: | |
switch: relay3 | |
light: light_right_both | |
binary_sensor: | |
- platform: custom | |
lambda: |- | |
auto touch_panel = new touch_panel::TouchPanel(id(uart_bus)); | |
App.register_component(touch_panel); | |
return { | |
touch_panel->left, | |
touch_panel->middle, | |
touch_panel->right, | |
touch_panel->two_finger, | |
touch_panel->dragged_ltr, | |
touch_panel->dragged_rtl, | |
}; | |
binary_sensors: | |
- id: button_left | |
name: "Left Button" | |
on_press: | |
- switch.toggle: relay1 | |
- switch.turn_on: haptics | |
- id: button_middle | |
name: "Middle Button" | |
on_press: | |
- switch.toggle: relay2 | |
- switch.turn_on: haptics | |
- id: button_right | |
name: "Right Button" | |
on_press: | |
- switch.toggle: relay3 | |
- switch.turn_on: haptics | |
- id: button_two_finger | |
name: "Two Fingers" | |
- id: button_dragged_ltr | |
name: "Dragged Left to Right" | |
- id: button_dragged_rtl | |
name: "Dragged Right to Left" |
switch: | |
- platform: gpio | |
name: "relay left" | |
pin: GPIO18 | |
id: relay1 | |
on_turn_on: | |
script.execute: light_relays | |
on_turn_off: | |
script.execute: light_relays | |
- platform: gpio | |
name: "relay middle" | |
pin: GPIO17 | |
id: relay2 | |
on_turn_on: | |
script.execute: light_relays | |
on_turn_off: | |
script.execute: light_relays | |
- platform: gpio | |
name: "relay right" | |
pin: GPIO27 | |
id: relay3 | |
on_turn_on: | |
script.execute: light_relays | |
on_turn_off: | |
script.execute: light_relays | |
- platform: gpio | |
name: "relay right" | |
pin: GPIO23 | |
id: relay4 | |
on_turn_on: | |
script.execute: light_relays | |
on_turn_off: | |
script.execute: light_relays | |
- platform: gpio | |
name: "sound amplifier power" | |
pin: GPIO26 | |
id: pa_sw | |
- platform: gpio | |
name: "touch panel power" | |
pin: | |
number: GPIO5 | |
inverted: true | |
id: ca51_pow | |
restore_mode: ALWAYS_ON | |
- platform: gpio | |
pin: GPIO21 | |
name: "Haptics" | |
id: "haptics" | |
restore_mode: ALWAYS_OFF | |
on_turn_on: | |
- delay: 300ms | |
- switch.turn_off: haptics |
#include "touch_panel.hpp" | |
#include <stdio.h> | |
namespace esphome | |
{ | |
namespace touch_panel | |
{ | |
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) | |
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) | |
const uint8_t PREFIX[] = {0xAA, 0x55, 0x01, 0x02}; | |
const unsigned int PREFIX_LENGTH = sizeof(PREFIX) / sizeof(PREFIX[0]); | |
// Messages consist of a prefix, a type of action and a position. | |
// There's probably other stuff but that's not relevant for us | |
const unsigned int MESSAGE_SIZE = PREFIX_LENGTH + 4; | |
const unsigned int BUFFER_SIZE = 32; | |
TouchPanel::TouchPanel(uart::UARTComponent *parent) : uart::UARTDevice(parent) {} | |
void TouchPanel::setup() | |
{ | |
for (int i = 0; i < button_map.size(); i++) | |
button_map[i]->publish_state(i < TwoFinger); | |
} | |
void TouchPanel::loop() | |
{ | |
static uint8_t buffer[BUFFER_SIZE]; | |
while (available() >= MESSAGE_SIZE) | |
{ | |
read_array(buffer, MIN(available(), BUFFER_SIZE)); | |
bool match = true; | |
if (memcmp(buffer, PREFIX, PREFIX_LENGTH) != 0) | |
{ | |
continue; | |
} | |
if (match) | |
{ | |
TouchEvent event = static_cast<TouchEvent>(buffer[4]); | |
uint8_t released_position = buffer[5]; | |
uint8_t pressed_position = buffer[6]; | |
if (event == Pressed) | |
{ | |
// ESP_LOGD("custom", "Pressed: %d", pressed_position); | |
button_map[pressed_position]->publish_state(true); | |
// Always trigger the two-fingered and drag events since we can only detect when they are released | |
two_finger->publish_state(true); | |
dragged_ltr->publish_state(true); | |
dragged_rtl->publish_state(true); | |
} | |
else if (event == Released || event == Dragged) | |
{ | |
// Make sure to reset all buttons | |
for (int i = 0; i < TwoFinger; i++) | |
button_map[i]->publish_state(false); | |
button_map[released_position]->publish_state(false); | |
} | |
else | |
{ | |
ESP_LOGD("custom", "Unknown event: %d", event); | |
} | |
} | |
} | |
} | |
} // namespace touch_panel | |
} // namespace esphome |
#pragma once | |
#include "esphome/core/component.h" | |
#include "esphome/components/uart/uart.h" | |
#include "esphome/components/binary_sensor/binary_sensor.h" | |
#include <vector> | |
namespace esphome | |
{ | |
namespace touch_panel | |
{ | |
enum TouchEvent | |
{ | |
Released = 1, | |
Pressed = 2, | |
Dragged = 3 | |
}; | |
enum TouchPosition | |
{ | |
Left = 1, | |
Middle = 4, | |
Right = 7, | |
TwoFinger = 11, | |
DraggedLTR = 12, | |
DraggedRTL = 13 | |
}; | |
class TouchPanel : public Component, public uart::UARTDevice | |
{ | |
public: | |
TouchPanel(uart::UARTComponent *parent); | |
void setup() override; | |
void loop() override; | |
float get_setup_priority() const override { return esphome::setup_priority::BUS; } | |
binary_sensor::BinarySensor *left = new binary_sensor::BinarySensor(); | |
binary_sensor::BinarySensor *middle = new binary_sensor::BinarySensor(); | |
binary_sensor::BinarySensor *right = new binary_sensor::BinarySensor(); | |
binary_sensor::BinarySensor *two_finger = new binary_sensor::BinarySensor(); | |
binary_sensor::BinarySensor *dragged_ltr = new binary_sensor::BinarySensor(); | |
binary_sensor::BinarySensor *dragged_rtl = new binary_sensor::BinarySensor(); | |
protected: | |
// For positional tracking | |
std::vector<binary_sensor::BinarySensor *> button_map = { | |
left, // 0 never occurs but is here for completeness | |
left, // 1-3 is left | |
left, | |
left, | |
middle, // 4-6 is middle | |
middle, | |
middle, | |
right, // 7-10 is right | |
right, | |
right, | |
right, | |
two_finger, // 11 is two fingers (released only) | |
dragged_ltr, // 12 is drag left to right | |
dragged_rtl, // 13 is drag right to left | |
}; | |
}; | |
} // namespace adalight | |
} // namespace esphome |
I've been trying out the code on a 1 gang version but I always get touch press trigger together with two finger or drag gestures.
Do you have any notes on the UART protocol used?
Sound is working but it's quite terrible https://twitter.com/blakadder_/status/1661863695788433409?s=20
On the other hand you can use the motor as a buzzer ;) https://twitter.com/blakadder_/status/1661866776303480832?s=20
@blakadder I got the motor working perfectly. Just want to add a bit of sarcasm to the switch.
When user turns on the toilet light a breaking wind sound. Not essential, just me being quirky.
As like you with the swipe left & swipe right I also get the left or right button on my 3 gang
I've been trying out the code on a 1 gang version but I always get touch press trigger together with two finger or drag gestures.
Do you have any notes on the UART protocol used?
Sound is working but it's quite terrible https://twitter.com/blakadder_/status/1661863695788433409?s=20
On the other hand you can use the motor as a buzzer ;) https://twitter.com/blakadder_/status/1661866776303480832?s=20
Hi blakadder,
I'm currently trying to make the sound work. Can you share you code snippet for the sound? Thanks!!
I've been trying out the code on a 1 gang version but I always get touch press trigger together with two finger or drag gestures.
Do you have any notes on the UART protocol used?
As far as I've been able to decode, all UART messages start with the same prefix and after that you get an event with value 1, 2 or 3 for released, pressed or dragged respectively.
The pressed event is always sent when you touch the device and depending on what you do after that you either get a released or dragged event.
Additionally the released event can either return a position from 1 to 10, or 11 for two fingered release.
When dragging it's 12 or 13 for left-to-right or right-to-left respectively.
Sound is working but it's quite terrible https://twitter.com/blakadder_/status/1661863695788433409?s=20
Awesome! I'd love to see how you got it working. I don't have any specific use for the sounds currently but it could be fun :)
Thanks for this it works well after a few personalisations. Any chance you will be looking at getting the sound working?
I don't have any concrete plans for it yet. But if blakadder shares his code (I'm assuming he's using tasmota) I might be able to port it.
There is no code, I'm not really a coder. I have difficulties reading this one 😃
Here's the sound snippet. It sounds equally terrible in Tasmota and esphome. I have no idea what Sonoff did extra to make it sound good. Maybe its just that the volume is too high and its clipping af but I can't lower it
# I2S audio component
i2s_audio:
i2s_bclk_pin: GPIO2 # BCK
i2s_lrclk_pin: GPIO4 # WS
# Player component for I2S
media_player:
- platform: i2s_audio
name: Speaker
dac_type: external
mode: mono
i2s_dout_pin: GPIO15
Thank you, i'll give it a try!
There's still something that I need to figure out about the device though... for some reason it mostly stopped working for me now.
That is... with the original firmware it works great, with the esphome version the touchpanel doesn't respond and the lights won't go on. It is fully repeatable as well. I've gone back and forth between the firmwares and I have even reverted to earlier versions of my esphome configuration and it does nothing...
Here's the sound snippet. It sounds equally terrible in Tasmota and esphome. I have no idea what Sonoff did extra to make it sound good. Maybe its just that the volume is too high and its clipping af but I can't lower it
This might be related but I'm not sure. I don't notice any real difference with different encodings: esphome/issues#4106
Can somebody with the original firmware verify how much the volume can be pushed to?
I've been able to play music in the TX, but volume is a little bit too low: https://streamable.com/mxw6ms
Can somebody with the original firmware verify how much the volume can be pushed to? I've been able to play music in the TX, but volume is a little bit too low: https://streamable.com/mxw6ms
I've got a backup of the original firmware that I can restore, but I'm not entirely sure what you want me to do. I have a sound level meter that I can keep at a fixed distance before I click the button but I'm not sure it's loud enough to give any useful results at 1 meter
Can somebody with the original firmware verify how much the volume can be pushed to? I've been able to play music in the TX, but volume is a little bit too low: https://streamable.com/mxw6ms
I've got a backup of the original firmware that I can restore, but I'm not entirely sure what you want me to do. I have a sound level meter that I can keep at a fixed distance before I click the button but I'm not sure it's loud enough to give any useful results at 1 meter
Not sure either... hahaha
I will try to finish the modifications in the esphome branch and push a PR with the new config option
If you want to test, I've pushed a PR with enables a new yaml parameter to be able to use the sound output.
esphome/esphome#4918
loudish https://twitter.com/blakadder_/status/1664434497826312192?s=20
have you tried setting i2s to stereo
loudish https://twitter.com/blakadder_/status/1664434497826312192?s=20
have you tried setting i2s to stereo
Very nice! Can you share your configuration so I can try as well? I'm planning to install these permanently in about a week or so and I would like to have them include sound as well :)
I've been trying out the code on a 1 gang version but I always get touch press trigger together with two finger or drag gestures.
Do you have any notes on the UART protocol used?
Sound is working but it's quite terrible https://twitter.com/blakadder_/status/1661863695788433409?s=20
On the other hand you can use the motor as a buzzer ;) https://twitter.com/blakadder_/status/1661866776303480832?s=20
I got the sound working ok and commented on https://www.youtube.com/watch?v=naDLhX89enQ&t
Copy his i2saudio and media player settings, then add "i2s_comm_fmt: lsb"
media_player:
- platform: i2s_audio
i2s_comm_fmt: lsb
does this work with the 4 gang switch?
does this work with the 4 gang switch?
You'll have to modify it slightly to do that. Currently it goes up to relay3
but relay4
is already defined because I suspected that they would come out with a 4-relay version. To modify it you'll have to adjust which section of the lights you want to turn on and what part of the button it should respond to.
Can somebody with the original firmware verify how much the volume can be pushed to? I've been able to play music in the TX, but volume is a little bit too low: https://streamable.com/mxw6ms
I've got a backup of the original firmware that I can restore, but I'm not entirely sure what you want me to do. I have a sound level meter that I can keep at a fixed distance before I click the button but I'm not sure it's loud enough to give any useful results at 1 meter
Please, please could you share your backup with me. I wasn't able to make a backup before I flashed my test unit and would like to go back to factory for a bit.
@MantasGSXR sorry to tell you but that backup won't help you. The firmwares are locked to the mac address so the backup won't work on your device unless it was made by your device
Thanks for this it works well after a few personalisations. Any chance you will be looking at getting the sound working?