lubeda / EspHoMaTriXv2

A simple DIY status display with a 8x32 RGB LED matrix, implemented with esphome.io and Home Assistant.
MIT License
276 stars 25 forks source link

[BUG] Clock Color Service Error in HA 2023.12.x #181

Open danieljkemp opened 8 months ago

danieljkemp commented 8 months ago

Bug report

Describe the bug

After updating to v2, the following error occurs in HA when attempting to call the clock_color servie

Logger: homeassistant.components.websocket_api.http.connection
Source: components/esphome/manager.py:746
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 9:55:21 AM (18 occurrences)
Last logged: 10:52:04 AM

[140424121830592] Error handling message: Unknown error (unknown_error) Dan from 10.0.3.174 (Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0)
[140423300251968] Error handling message: Unknown error (unknown_error) Dan from 10.0.3.174 (Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0)
[140423299760704] Error handling message: Unknown error (unknown_error) Dan from 10.0.3.174 (Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0)
[140423246990528] Error handling message: Unknown error (unknown_error) Dan from 10.0.3.174 (Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 26, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 782, in handle_execute_script
    script_result = await script_obj.async_run(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2067, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2104, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/esphome/manager.py", line 746, in execute_service
    await entry_data.client.execute_service(service, call.data)
  File "/usr/local/lib/python3.11/site-packages/aioesphomeapi/client.py", line 1175, in execute_service
    int_type = "int_" if apiv >= APIVersion(1, 3) else "legacy_int"
                         ^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>=' not supported between instances of 'NoneType' and 'APIVersion'

Additional information

To Reproduce

Steps to reproduce the behavior:

Expected behavior

Clock color change without a error log

Configuration

substitutions:
  devicename: ulanzi
  matrix_pin: GPIO32 
  buzzer_pin: GPIO15
  battery_pin: GPIO34 
  ldr_pin: GPIO35 
  left_button_pin: GPIO26 
  mid_button_pin: GPIO27 
  right_button_pin: GPIO14 
  scl_pin: GPIO22 
  sda_pin: GPIO21 

external_components:
  - source:
      type: git
      url: https://github.com/lubeda/EspHoMaTriXv2
    refresh: 60s 
    components: [ ehmtxv2 ]   

esphome:
  comment: "Ulanzi TC001"
  name: bedroom-clock
  on_boot:
    then:
      - ds1307.read_time:

esp32:
  board: esp32dev

ota:

wifi:
  domain: .automation.especiallyrelative.net
  ssid: !secret wifi_ssid
  password: !secret wifi_password

web_server:

font: 
  # adapt the filename to your local settings
  - file: Calcium.ttf
    id: ehmtx_font
    size: 16
    glyphs:  |
      !?"%‰()+*=,-_.:°µ²³0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnÖÄÜöäüopqrstuvwxyz€$@<>/

ehmtxv2:
  id: rgb8x32
  time_component: ehmtx_time
  matrix_component: ehmtx_display
  default_font_id: ehmtx_font
  default_font_yoffset: 8
  special_font_id: ehmtx_font
  special_font_yoffset: 6
  #clock_time: 5           # duration to display the clock after this time the date is display until next "show_screen"
  clock_interval: 60      # show the clock at least each x seconds
  #screen_time: 6          # duration to display a screen or a clock/date sequence
  date_format: "%m.%d"    # defaults "%d.%m." (use "%m.%d." for the US)
  time_format: "%H:%M"    # defaults "%H:%M" (use "%I:%M%p" for the US)
  show_dow: false         # draw the day indicator on the bottom of the screen, defaults to true
  show_date: false         # show the date for show_screen - show_clock seconds otherwise only shows the clock for show_screen seconds, defaults to true
  week_start_monday: false # default monday is first day of week, false = sunday
  #yoffset: 8              # the text is aligned BASELINE_LEFT, the baseline defaults to 6
  #xoffset: 1              # the text is aligned BASELINE_LEFT, the left defaults to 1
  scroll_interval: 80    # the interval in ms to scroll the text (default=80), should be a multiple of the update_interval from the display (default: 16ms)
  frame_interval: 192     # the interval in ms to display the next anim frame (default=192), should be a multiple of the update_interval from the display (default: 16ms)
  icons: 
    - id: ha
      lameid: 7956
    - id: tempc
      lameid: 2422
    - id: plug
      lameid: 403
    - id: humidity
      lameid: 51764
    - id: co2
      lameid: 30662

binary_sensor:
  - platform: status
    name: "$devicename Status"
  - platform: gpio
    pin:
      number: $left_button_pin
      inverted: true
    name: "$devicename left button"
    on_press:
      then:
        - number.decrement: screen_brightness
  - platform: gpio
    pin: 
      inverted: true
      number: $mid_button_pin
      mode: INPUT_PULLUP
    name: "$devicename middle button"
    on_press:
      then:
        - switch.toggle: displaycontrol
  - platform: gpio
    pin: 
      number: $right_button_pin
      inverted: true
    name: "$devicename right button"
    on_press:
      then:
        - number.increment: screen_brightness
# example to switch to next screen
#        lambda: |-
#          id(rgb8x32)->skip_screen();
logger:
  level: INFO

image:
   - file: 1pixel.gif
     id: breaking20237

animation:
  - file: 1pixel.gif
    id: breaking202371

# Enable Home Assistant API
api:
  services:
    #- service: alarm
    #  variables:
    #    icon_name: string
    #    screentext: string
    #  then:
    #    lambda: |-
    #      id(rgb8x32)->hold_screen(icon_name,screentext,7,20,true);
    #      id(rgb8x32)->force_screen(icon_name);
    - service: brightness
      variables:
        brightness: int
      then:
        lambda: |-
          id(rgb8x32)->set_brightness(brightness);
    #- service: icons
    #  then:
    #    lambda: |-
    #      id(rgb8x32)->show_all_icons();
    #- service: skip_screen
    #  then:
    #    lambda: |-
    #      id(rgb8x32)->skip_screen();
    #- service: tuneplay
    #  variables:
    #    tune: string
    #  then:
    #    - rtttl.play:
    #        rtttl: !lambda 'return tune;'

number:
  - platform: template
    name: "$devicename brightness"
    id: screen_brightness
    min_value: 0
    max_value: 255
    update_interval: 1s
    step: 25
    lambda: |-
      return id(rgb8x32)->get_brightness();
    set_action:
      lambda: |-
        id(rgb8x32)->set_brightness(x);

switch:
  - platform: template
    name: "$devicename Display"
    id: displaycontrol
    icon: "mdi:power"
    restore_mode: ALWAYS_ON
    lambda: |-
      return id(rgb8x32)->show_display;
    turn_on_action:
      lambda: |-
        id(rgb8x32)->set_display_on();
    turn_off_action:
      lambda: |-
        id(rgb8x32)->set_display_off();

sensor:
  - platform: sht3xd
    temperature:
      name: "$devicename Temperature"
    humidity:
      name: "$devicename Humidity"
    update_interval: 60s
  - platform: adc
    pin: $battery_pin
    name: "$devicename Battery"
    id: battery_voltage
    update_interval: 10s
    device_class: battery
    accuracy_decimals: 0
    attenuation: auto
    filters:
      - sliding_window_moving_average:
          window_size: 15
          send_every: 15
          send_first_at: 1
      - multiply: 1.6
      - lambda: |-
          return ((x - 3) / 0.69 * 100.00);
    unit_of_measurement: '%'
  - platform: adc
    id: light_sensor
    name: "$devicename Illuminance"
    pin: $ldr_pin
    update_interval: 10s
    attenuation: auto
    unit_of_measurement: lx
    accuracy_decimals: 0
    filters:
      - lambda: |-
          return (x / 10000.0) * 2000000.0 - 15 ;

output:
  - platform: ledc
    pin: $buzzer_pin
    id: rtttl_out

rtttl:
  output: rtttl_out

i2c:
  sda: 21
  scl: 22
  scan: true
  id: bus_a

light:
  - platform: neopixelbus
    id: ehmtx_light
    type: GRB
    variant: WS2812
    pin: $matrix_pin
    num_leds: 256
    color_correct: [30%, 30%, 30%]
    name: "$devicename Light"
    restore_mode: ALWAYS_OFF
    on_turn_on:
      lambda: |-
         id(ehmtx_display)->set_enabled(false);
    on_turn_off:
       lambda: |-
         id(ehmtx_display)->set_enabled(true);

time:
  - platform: homeassistant
    timezone: America/New_York
    on_time_sync:
      then:
        ds1307.write_time:
  - platform: ds1307
    update_interval: never
    id: ehmtx_time

display:
  - platform: addressable_light
    id: ehmtx_display
    addressable_light_id: ehmtx_light
    width: 32
    height: 8
    pixel_mapper: |-
      if (y % 2 == 0) {
        return (y * 32) + x;
      }
      return (y * 32) + (31 - x);
    rotation: 0°
    update_interval: 16ms
    auto_clear_enabled: true
    lambda: |-
      id(rgb8x32)->tick();
      id(rgb8x32)->draw();

Logs

see above

Services calls

service: esphome.bedroom_clock_clock_color
data:
  g: 0
  b: 0
  r: 255
lubeda commented 8 months ago

can you try this?

service: esphome.bedroom_clock_set_clock_color
data:
  r: 255
  g: 0
  b: 0

assuming your ulanzi is named "bedroom_clock"

andrewjswan commented 8 months ago
  • EspHoMaTriXv2 version: 2023.7.0

In readme i see:

2023.7.0

danieljkemp commented 8 months ago

can you try this?

service: esphome.bedroom_clock_set_clock_color
data:
  r: 255
  g: 0
  b: 0

assuming your ulanzi is named "bedroom_clock"

Aww heck well first, yeah it works, but it thinks I have a 6 pixel font and throws the 8 pixel font up so I am gonna have to figure out how that is configured, also it goes black for a moment after setting it, that is probably a result of how I set up the clock screen (current goal is to use it 100% as a clock)

and then is there a way to clear out the old functions from HA? I had deleted it from HA then re-added it and the old servie shows still

Thanks for the help! :D

danieljkemp commented 8 months ago

the pixel change was a pretty simple oversight

Huh, seems like there is some other empty screen that the clock is alternating with some other screen (that I don't think I have set???) so ends up alternating black/clock

the clock_time setting was removed at some point I used to set clock_time=clock_interval to make it function as a pure clock and it was great

so I set my auto-adjust automation to match the color to the room lights (and red if below a threshhold) and now.... it alternates between red and blue? Blue? Why blue, I have no clue I feel like I am slowly going insane. Is there no longer a way to lock the screen to a clock with a certain color?

service: esphome.bedroom_clock_clock_screen
data:
  default_font: true
  lifetime: 5
  screen_time: 5
  r: 255
  g: 0
  b: 0

After calling that with clock_interval=5 it alternates between red and blue somehow?

lubeda commented 8 months ago

Hi, nice idea with the color synchronization to your room light!

can you provide a esphome-log of the red blue toggle effect?

danieljkemp commented 8 months ago
[15:32:16][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %
[15:32:26][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %
[15:32:26][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %
[15:32:36][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %
[15:32:36][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %
[15:32:46][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %
[15:32:46][I][EHMTXv2:1007]: set_brightness 100 => 39.22 %

Here is the HA automation that I am using to control the clock (I see in the docs I could do the brightness on-device, and I might eventually do that)

alias: "Bedroom Clock: Auto Brightness"
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.ulanzi_illuminance
condition: []
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.ulanzi_illuminance
            below: 100
        sequence:
          - service: esphome.bedroom_clock_brightness
            data:
              value: 30
      - conditions:
          - condition: numeric_state
            entity_id: sensor.ulanzi_illuminance
            above: 101
            below: 199
        sequence:
          - service: esphome.bedroom_clock_brightness
            data:
              value: 75
      - conditions:
          - condition: numeric_state
            entity_id: sensor.ulanzi_illuminance
            above: 200
            below: 299
        sequence:
          - service: esphome.bedroom_clock_brightness
            data:
              value: 100
      - conditions:
          - condition: numeric_state
            entity_id: sensor.ulanzi_illuminance
            above: 300
        sequence:
          - service: esphome.bedroom_clock_brightness
            data:
              value: 150
  - if:
      - condition: numeric_state
        entity_id: sensor.ulanzi_illuminance
        above: 100
    then:
      - condition: state
        entity_id: light.bedroom
        state: "on"
      - service: esphome.bedroom_clock_set_clock_color
        data:
          r: "{{ state_attr('light.bedroom', 'rgb_color').0 | int }}"
          g: "{{ state_attr('light.bedroom', 'rgb_color').1 | int }}"
          b: "{{ state_attr('light.bedroom', 'rgb_color').2 | int }}"
        enabled: false
      - service: esphome.bedroom_clock_clock_screen
        data:
          lifetime: 5
          screen_time: 5
          default_font: true
          r: "{{ state_attr('light.bedroom', 'rgb_color').0 | int }}"
          g: "{{ state_attr('light.bedroom', 'rgb_color').1 | int }}"
          b: "{{ state_attr('light.bedroom', 'rgb_color').2 | int }}"
    else:
      - service: esphome.bedroom_clock_set_clock_color
        data:
          r: 255
          g: 0
          b: 0
        enabled: false
      - service: esphome.bedroom_clock_clock_screen
        data:
          default_font: true
          lifetime: 5
          screen_time: 5
          r: 255
          g: 0
          b: 0
mode: single

Now it is flashing between the light color and white? For now the goal is for it to just be a clock/light sensor. It feels like there are two clock screens it is alternating between for some reason?

lubeda commented 8 months ago

I think there are two clock screens in your queue, one with the default color ("white") and your adapted color so you should delete all clock_screens in the queue before setting the color.

service: esphome.ulanzi_del_screen
data:
  icon_name: "*"
  mode: 2
danieljkemp commented 8 months ago

ahha I thik I figured it out

since I'm not using other screens at the moment when set_clock_color is called, it deletes the clock screens (https://github.com/lubeda/EspHoMaTriXv2/blob/4df039378c86203316f0c8f23f08b166350f1e9a/components/ehmtxv2/EHMTX.cpp#L397) which then triggers the clock to reboot and go black for a moment, if there was a queue it wouldn't be as noticeable

using the clock_screen function an additional clock is added to the queue which ends up alternating with other screens if I was to change color

For now I am gonna set the color to red (least harsh at night) and disable the color changing in my HA script.

just thinking/rambling sorry in advance....

using the clock_screen directly, lifetime can't be super long or it'll never change colors, and if it is too short it'll fizzle and cause the screen to reset, goal is keep the clock from flashing unpredictably, maybe an option for lifetime in seconds could help in general?

the set_clock_color probably deletes because it can't actually change a live screen? maybe it should only do that if the color would actually be changed, like a check for current color vs parameter?

I am thinking of adding an indicator dot or changing colors based on HA assist, like changing the : or adding a corner dot when a wake-word is triggered or command received but gotta get the rest figured out first

andrewjswan commented 7 months ago

since I'm not using other screens at the moment when set_clock_color is called, it deletes the clock screens

Its reworked in 2024.1.0

https://github.com/lubeda/EspHoMaTriXv2/blob/8e3f8d73f9196bfe84ba0b8b2dec44b1be4e8765/components/ehmtxv2/EHMTX.cpp#L864-L879