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 |
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
@wolph Mind giving me a hint on how to actually backup the stock firmware? I tried the read_flash
command of esptool
but it keeps throwing me the same error, even though I made sure that I'm in boot mode:
$ esptool.py -p /dev/cu.usbserial-210 -b 460800 read_flash 0 ALL tx-ultimate-stock.bin
esptool.py v4.8.1
Serial port /dev/cu.usbserial-210
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP32
Chip is ESP32-D0WDR2-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: fe:b4:67:b8:f6:11
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Detected flash size: 8MB
A fatal error occurred: Invalid head of packet (0x7F): Possible serial noise or corruption.
@0xAhmed You can try lowering the baud rate, I've found that 460800 (or higher) only works with short high quality USB cables and even in those cases it's not guaranteed to work.
Try it with 115200 and see if you still get the error.
Alternatively... it could be that the flash size is detected incorrectly, but I think I remember the tx ultimate having 8MB so it should be correct.
You can read the flash size with this command:
esptool.py -p /dev/cu.usbserial-210 flash_id
[Edit]
I just remember another potential issue with these... they draw quite a bit of power so it could be that you need an extra/external 5v power supply. I can't get the tx ultimate to work reliably off my usb2serial adapter alone.
Thank you so much @wolph. I completed overlooked the fact that the baud rate might be the problem. I just tried with an ESP32-WROOM chip (was getting the same error message on it) and it worked fine. Shall try with another TX Ultimate switch later.
Anybody ever get the sound to be as loud as the stock firmware. mine works but its very , very low.
media_player:
- platform: i2s_audio
id: media_out
name: ${friendly_name} Player
dac_type: external
i2s_dout_pin: ${audio_sdata_pin}
i2s_audio_id: audio_i2s
i2s_comm_fmt: lsb
mode: mono
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