kireque / esphome_nebula_light

50 stars 2 forks source link

Any chance you can update the config for a cloud-cutter'd device #8

Open Deep-Six opened 6 months ago

Deep-Six commented 6 months ago

Heya,

I managed to get one of these things running esphome-kickstart but haven't been successful in getting a more robust config installed. Any chance you have some guidance on how to make this work?

kireque commented 6 months ago

Could you explain what you mean with esphome-kickstart device (link to the website) and robust config?

Deep-Six commented 6 months ago

Sorry , I didn't see this until now! Esp-home kickstart is here: https://github.com/libretiny-eu/esphome-kickstart and was installed via this system:

https://github.com/tuya-cloudcutter/tuya-cloudcutter

Which allows you to flash the esphome kickstart binary instead of having to desolder and resolder. There's some relationship to libchiptool as well which I've used successfully before, but this link shows there's no profile.

https://upk.libretiny.eu/?profile=tuya-generic-sk20-smart-star-projector

Essentially I was able to use cloud cutter, to replace the factory software, and now effectively have a device that's got the factory chipset, but running a base level of esp-home which I need to be able to update with a more advanced configuration. The configuration that's here, is based on the esp8266, but I need it to be based on the beken firmware. I've just not had the time to research how to convert. Was hoping you might have an idea.

M4GNV5 commented 5 months ago

@Deep-Six this fork by @fonix232 seems to include a WB3S esphome config (at the bottom of the readme), which should be what you are looking for? https://github.com/fonix232/esphome_nebula_light

Do you mind sharing the steps to flash it using cloudcutter? I got one of these (model: SK20) for christmas and was reading the cloudcutter docs the other day, but failed putting it into AP mode. What power/button press sequence did you use?

fonix232 commented 5 months ago

@M4GNV5 the cloudcutter docs aren't the best for this light. It took me a while to get it working properly. You need to LONG PRESS the power button until the light starts flashing fast - that's when it enters into AP mode. Just keep holding the button, first it will flash slowly (BT pairing mode), then after about 10 seconds it begins flashing fast. You'll need to repeat this process twice during the CloudCutter steps.

The configuration in my fork is also incomplete, however I did create a working ESPHome Package:

---
light:
  - platform: rgb
    name: Light
    id: rgb_light
    red: red
    green: green
    blue: blue
    restore_mode: ALWAYS_OFF
    effects:
      - random:
          name: Random Slow
          transition_length: 10s
          update_interval: 5s
      - pulse:
      - pulse:
          name: Pulse Slow
          update_interval: 2s
      - pulse:
          name: Pulse Fast
          transition_length: 0.5s
          update_interval: 0.5s
          min_brightness: 0%
          max_brightness: 100%
      - pulse:
          name: "Pulse Asymmetrical"
          transition_length:
            on_length: 1s
            off_length: 500ms
          update_interval: 1.5s
  - platform: monochromatic
    name: Laser
    id: laser
    output: laser_pwm
    restore_mode: ALWAYS_OFF
  - platform: binary
    name: bled
    id: bled
    output: bled_pwm
    restore_mode: ALWAYS_OFF
    internal: true
  - platform: monochromatic
    name: rled
    id: rled
    output: rled_pwm
    restore_mode: ALWAYS_OFF
    internal: true

fan:
  platform: speed
  name: "Motor"
  id: motor
  output: motor_pwm
  restore_mode: ALWAYS_OFF

output:
  - platform: libretiny_pwm
    id: red
    pin: PWM3
    inverted: true
  - platform: libretiny_pwm
    id: green
    pin: PWM4
    inverted: true
  - platform: libretiny_pwm
    id: blue
    pin: PWM5
    inverted: true

  - platform: libretiny_pwm
    id: laser_pwm
    pin: PWM2
    inverted: true
    max_power: 50%
  - platform: libretiny_pwm
    id: motor_pwm
    pin: PWM0
    min_power: 15%
    max_power: 50%

  - platform: gpio
    id: bled_pwm
    pin: P1
    inverted: true
  - platform: libretiny_pwm
    id: rled_pwm
    pin: PWM1
    inverted: true

binary_sensor:
  - platform: gpio
    pin: 
      number: P14
      mode: INPUT_PULLDOWN_16
      inverted: true
    name: Button
    # on_press:
    #   then:
    #     - light.turn_on: 
    #         id: rgb_light
    #         brightness: 30%
    #     - light.turn_on: 
    #         id: laser
    #         brightness: 65%
    #     - delay : 1h
    #     - light.turn_off: 
    #         id: rgb_light
    #     - light.turn_off: 
    #         id: laser

wifi:
  on_connect:
    light.turn_on: bled
  on_disconnect:
    light.turn_off: bled

api:
  on_client_connected:
    if:
      condition:
        api.connected:
      then:
        - light.turn_on: rled
      else:
        - light.turn_off: rled
  on_client_disconnected:
    if:
      condition:
        api.connected:
      then:
        - light.turn_on: rled
      else:
        - light.turn_off: rled

Just copy the above into a separate YAML and include it in your config as a package.

Some noteworthy changes I made:

Also a few small notes:

M4GNV5 commented 5 months ago

Hey wow, thanks for the very long description. Especially the last part is very helpful. I did not notice any sounds, but it's not very quiet in my lab anyways. Over the last 7 hours I put some more work into it using (and fixing) the config file from your fork. I do not use homeassistant, but rather just MQTT+node-red+zigbee2mqtt at home, which is why i have a (disabled) MQTT config in my yaml.

Anyways, I created a new repository, since I assume this repo is based more on a hardware modification rather than reflashing the original: https://github.com/M4GNV5/esphome-SK20-Nebula-Light

fonix232 commented 5 months ago

That config is okay, however:

Deep-Six commented 5 months ago

@Deep-Six this fork by @fonix232 seems to include a WB3S esphome config (at the bottom of the readme), which should be what you are looking for? https://github.com/fonix232/esphome_nebula_light

Do you mind sharing the steps to flash it using cloudcutter? I got one of these (model: SK20) for christmas and was reading the cloudcutter docs the other day, but failed putting it into AP mode. What power/button press sequence did you use?

As @fonix232 mentioned,I believe it was a long press, but I think I did a whole bunch of other things, before figuring that out. including holding the button before plugging it in etc.

seberm commented 4 months ago

Hello everyone, First of all, I would like to express my gratitude to all of you for your ideas and references shared above. They are very helpful, leading me to discover the tuya-cloudcutter and libretiny initially

Now, I have a question: Does the device somehow support the red (or RGB) button LED? I distinctly remember seeing the red button color in the past, whereas currently, both button LEDs are blue

I have successfully flashed my nebula with ESPHome firmware and I would like to share my enhanced configuration with you. You can find it here:

My modifications / hints

  1. Consider utilizing a Status LED Light component instead of relying on interval, wifi.{on_connect,on_disconnect}, or api.on_client_{connected,disconnected}. I have employed the button LED0 (pin P1) as a status LED because this pin does not support PWM. It's just sufficient to display the device status.
  2. I've introduced the switch template switch_main, which consolidates the states of the motor, laser, and RGB light. Essentially, it informs you whether the device is currently in use or not. If any of these components are turned on, this switch is also activated. Conversely, if all of these components are switched off, the main switch is turned off as well.
  3. I'm utilizing the LED1 (pin P7) to indicate whether the device is currently in use (i.e., if the light, laser, or motor is activated).

The switch switch_main is equipped with turn_on_action and turn_off_action, defining the default settings for lights/motor when turned on and turning all of them off when turned off, respectively

Thanks to the switch_main template, you can effortlessly toggle all these components using a button's binary sensor action. Personally, I prefer using switch.toggle: switch_main in the on_press sensor's action

f you wish to incorporate an automatic "turn off" functionality, I recommend utilizing a script - for more information, refer to the script_switch_main_timer script definition

I would appreciate if you could share additional hints or suggestions for improvement. Thank you!

fonix232 commented 4 months ago

@seberm I'd really recommend you look into the ESPHome Package format, as it would make it much easier to share only the relevant part of the config (and also importing it could be done in essentially two lines: one to define the github import and one importing the package).

status_led is a good option, but don't forget that it is meant for error/warning reporting, which is not always optimal for an actual status display. In my case, I'd like to know quickly if the device is 1, connected to WiFi 2, connected to HA, to make debugging issues easier, hence the setup. If you only want warnings, status_led is a good option, but I personally wouldn't rely on it solely.

Similarly, the switch_main approach might work for you, but not for others - I for one do not want the laser turned on at any time, and want just the RGB projection, for which I specifically made some changes in my script that isn't in the above snippet.

Another thing I'd attempt if my C-fu wasn't abysmal, is scripting the default behaviour of the button, namely transitioning from OFF to the first effect, then through all the effects on each press, then finally again to OFF when on the last effect and the button is pressed.

As for the red LED - I think you saw it, like myself, on other people's photos. The SK20 has a few variations, not just in case but internals used too. I've seen pictures off it with a red status LED, but mine is definitely blue only - the PCB responsible for the button and LED status has 5 pins, of which 4 are used: Ground, Button GPIO, and two pins for two pairs of LEDs. There's definitely no colour variation going on. In fact the PCB is incredibly barebones, it has the connector, 2 resistors, 4 LEDs and the push button.

Also, have you guys noticed an increase in noise from the motor/gear assembly? My unit, which is usually on 24/7, has been making a quite loud rattle when the motor is over 50% for a longer period. Turning it off, or running it on 100% for an hour or two helps for a while, but the noise keeps returning and ends up being loud enough that I can't fall asleep next to it even at 20%. If you did notice this, have you managed to (physically) fix it?

seberm commented 4 months ago

Hello @fonix232, thanks for your insights.

Regarding the esphome package: Yes, I am aware of it. I may consider modifying the code to incorporate the esphome package in the future. The code I've shared differs slightly from the one I am currently using. My intention was simply to share my observations and suggestions. I understand that we may not necessarily have the same default settings and behaviors.

Regarding the status_led: I agree. I wanted to also inform other users about the possibility of using the status LED.

Regarding the effect transition: That is indeed a very good idea! I will implement modifications to the configuration so that users can iterate over different light/motor/laser pre-configurations (which I refer to as scenes) by clicking the button. Additionally, I would prefer to allow users to turn off all components by long-pressing a button instead of relying on a special "OFF" scene.

Regarding noise: Fortunately, I do not encounter any issues with noise (it is barely audible to me). However, in my case, the device is typically operational for a maximum of 1-2 hours per day.

seberm commented 4 months ago

Here I've added support for pre-defined scenes:

Now, users can turn off the device components either by toggling the switch_main or by holding down the button for one second. Additionally, I've implemented functionality for the device to remember the last scene used. To achieve this, I've utilized a global variable named global_scene_id to store the last state. Although the code has become more complex due to the inclusion of various lambdas, everything appears to be functioning smoothly.

M4GNV5 commented 4 months ago

@seberm your changes look very cool. Currently for my nebula light the button simply does nothing. I would love to integrate your scene, button & status led changes into my repo. Feel free to open a pull request!

We should however find a way to allow users to select wether they want to use the webinterface, the API, homeassitant or MQTT for controlling their nebula light (apart from the button). I have not looked at esphome modules yet, but they might be the missing ingredient for separating nebula light specifics from control mechanisms

fonix232 commented 4 months ago

@M4GNV5 yes, ESPHome packages are the way to go - they allow you to compartmentalise definitions and merge them in a final config.

For example my ESPHome configs are split into a number of packages in a hierarchy:

This is incredibly useful because this way you can break up your configs into reusable pieces - the base config for example is shared by ALL my devices, regardless if they're ESP8266/32/-S2/-S3, or Beken based. Then I have chip-specific configs that define the baseline for the MCU alone, and import the base. On top of that, I have the board-specific configs, which import the chip-specific config, and expand on it by adding board-specific details (e.g. an ESP32-S3 devkit board would combine the ESP32-S3 chip config + config for the onboard LED). Finally, I have the device-specific configs, which take the base board-specific config, and expand upon it with details specific to that device (e.g. I have a SEN55 hooked up to an ESP32-S3 devkit, which I call aqm-1 - and aqm-1 combines the esp32-s3-devkit_espidf.yaml config, and the sen55.yaml config with params specific to the device, i.e. which pins are in use)

Or, in case of my Nebula light without replacing the MCU, my setup is:

This makes it incredibly easy to bring up a new device. Just create the root device_name.yaml, add the basic substitutions, then import the board package, stack on your own additions, and bam, done.

Also, if I need to change ALL my devices' configuration, it's a single file change before updating each manually.