Eikkargh / Candy-API-to-JSON

Communicates with Candy/Hoover washer dryers to produce a JSON readable by Home Assistant
7 stars 2 forks source link

Output values not populating in configuration #3

Closed BenGlossop09 closed 2 months ago

BenGlossop09 commented 3 months ago

Thank you for taking the time to put this together!

I have Hoover washer/dryer model H3DS4965TACBE-80. I have got the encryption key for the model and have followed the configuration steps given for this integration. I believe configuration.yaml is not taking the output of candy.py as HA is giving the error log: Failed to set state for sensor.candy_washer_dryer, fall back to unknown Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1209, in _async_write_ha_state hass.states.async_set_internal( File "/usr/src/homeassistant/homeassistant/core.py", line 2334, in async_set_internal state = State( ^^^^^^ File "/usr/src/homeassistant/homeassistant/core.py", line 1778, in __init__ validate_state(state) File "/usr/src/homeassistant/homeassistant/core.py", line 239, in validate_state raise InvalidStateError( homeassistant.exceptions.InvalidStateError: Invalid state with length 364. State max length is 255 characters.

HA is seeing a length of 364 and only supports 255, as you state. candy.py is not producing the json correctly or the json is not being interpreted/seen. I ran a test of candy.py and I get a successful output from my machine - candy.py works as intended. Output here:

Our command line:
$ ha help
➜  /config /bin/python /config/pyscript/candy.py
{
    "WiFiStatus": "0",
    "Err": "0",
    "MachMd": "1",
    "PrNm": "1",
    "PrCode": "122",
    "PrPh": "0",
    "Temp": "0",
    "SpinSp": "14",
    "DelVal": "0",
    "DryT": "8",
    "RemTime": "1800",
    "Lang": "1",
    "FillR": "0",
    "Det": "0",
    "Soft": "0",
    "DetWarn": "0",
    "SoftWarn": "0",
    "DetPreW": "0",
    "SoftPreW": "0",
    "DPrgCnt": "0",
    "SPrgCnt": "0",
    "WaterHard": "0",
    "rED": "0",
    "TotalTime": "1800"

This leads me to believe the json is somehow not being used by the code in configuration.yaml. For reference here is my configuration.yaml code:

command_line:
###################
## Other Sensors ##
###################
  - sensor:
      name: 'Candy Washer Dryer'
      unique_id: candy_washer_dryer
      scan_interval: 60
      command_timeout: 30
      command: python3 ./pyscript/candy.py
      value_template: '{{ value_json }}'
      json_attributes:
        - WiFiStatus
        - Err
        - MachMd
        - Pr
        - PrPh
        - Temp
        - SpinSp
        - RemTime
        - DryT
        - DelVal
        - TotalTime

# Configuration for Candy sensors (Washer/Dryer)
template:
#####################
## Other Templates ##
#####################
#   Washer Dryer
  - sensor:
      - name: 'Washer/Dryer - WiFi'
        icon: mdi:washing-machine
        state: >
          {% set WiFi = state_attr('sensor.candy_washer_dryer', 'WiFiStatus') | default(1) %}
          {% if WiFi == '0' %}On
          {% elif WiFi == '1' %}Off
          {% else %}{{ WiFi }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Error'
        icon: mdi:alert-circle
        state: >
          {% set Error = state_attr('sensor.candy_washer_dryer', 'Err') | default(255) %}
          {% if Error == '255' %}No Errors
          {% elif Error is number %}{{ Error }}
          {% else %}Off
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Status'
        icon: mdi:chart-pie
        state: >
          {% set Status = state_attr('sensor.candy_washer_dryer', 'MachMd') %}
          {% if Status == "1" %}Not Started
          {% elif Status == "2" %}Running
          {% elif Status == "3" %}Paused
          {% elif Status == "4" %}Setting Up
          {% elif Status == "5" %}Delayed
          {% elif Status == "7" %}Finished
          {% elif Status == None %}Off
          {% else %}{{ Status }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Program'
        icon: mdi:progress-star
        state: >
          {% set Prog = state_attr('sensor.candy_washer_dryer', 'Pr') %}
          {% if Prog == "1" %}Special
          {% elif Prog == "2" %}Cotton
          {% elif Prog == "3" %}Colour
          {% elif Prog == "4" %}Daily
          {% elif Prog == "5" %}Rapid
          {% elif Prog == "9" %}Spin/ Drain
          {% elif Prog == "11" %}Bed Linen
          {% elif Prog == "12" %}Dry Low
          {% elif Prog == "13" %}Dry High
          {% elif Prog == "17" %}Hygeine
          {% elif Prog == None %}Off
          {% else %}{{ Prog }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Phase'
        icon: mdi:progress-question
        state: >
          {% set Phase = state_attr('sensor.candy_washer_dryer', 'PrPh') %} 
          {% if Phase == "0" %}Delayed
          {% elif Phase == "1" %}Prewash
          {% elif Phase == "2" %}Wash
          {% elif Phase == "3" %}Rinse
          {% elif Phase == "4" %}Spin/ Drain
          {% elif Phase == "5" %}End
          {% elif Phase == "6" %}Drying
          {% elif Phase == "7" %}Error
          {% elif Phase == "8" %}Steam
          {% elif Phase == "9" %}Goodnight
          {% elif Phase == "10" %}Spin
          {% elif Phase == None %}Off
          {% else %}{{ Phase }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Wash Temp'
        icon: mdi:thermometer-lines
        unit_of_measurement: '°C'
        state: >
          {% set Temp = state_attr('sensor.candy_washer_dryer', 'Temp') %}
          {% if Temp == None %}0
          {% elif Temp == "0" %}0
          {% else %}{{ Temp }}
          {% endif %} 
  - sensor:
      - name: 'Washer/Dryer - Spin Speed'
        icon: mdi:speedometer
        unit_of_measurement: rpm
        state: >
          {% set Spin = state_attr('sensor.candy_washer_dryer', 'SpinSp') %}
          {% if Spin == None %}0
          {% elif  Spin == "0" %}0
          {% else %}{{ (Spin | int) * 100  }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Wash Time'
        icon: mdi:timer
        unit_of_measurement: 'mins'
        state: >
          {% set WashT = state_attr('sensor.candy_washer_dryer', 'RemTime') %}
          {% if WashT == None %}0
          {% else %}{{ WashT | int }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Dry Time'
        icon: mdi:clock-time-four
        state: >
          {% set DryT = state_attr('sensor.candy_washer_dryer', 'DryT') %}
          {% if DryT == None %}Off
          {% elif DryT == "0" %}Dry Off
          {% elif DryT == "3" %}Iron Dry
          {% elif DryT == "4" %}Dry Finished
          {% elif DryT == "5" %}Dry Ending
          {% else %}{{ DryT }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Delay Time'
        icon: mdi:timer
        unit_of_measurement: 'hours'
        state: >
          {% set DelT = state_attr('sensor.candy_washer_dryer', 'DelVal') %}
          {% if DelT == None %}0
          {% else %}{{ DelT | int }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Total Time'
        icon: mdi:timer
        state: >
          {% set TotalT = state_attr('sensor.candy_washer_dryer', 'TotalTime') %}
          {% if TotalT == None %}0
          {% else %}{{ TotalT }}
          {% endif %}
  - sensor:
      - name: 'Washer/Dryer - Max Delay'
        icon: mdi:timer
        state: >
          {% set Status = states('sensor.washer_dryer_wifi') %}
          {% set Delay = states('sensor.washer_dryer_delay_time') | int(default=0) * 60 %}
          {% set DelayMax = states('sensor.washer_dryer_max_delay') | int(default=0) %}
          {% set Total = states('sensor.washer_dryer_total_time') | int %}
          {% if Total == 0 %}0
          {% elif Status == 'Off' %}{{ DelayMax }}
          {% elif DelayMax >= Delay %}{{ DelayMax }}
          {% else %}{{ Delay }}
          {% endif %}              
  - sensor:
      - name: 'Washer/Dryer - Max Time'
        icon: mdi:timer
        state: >
          {% set Status = states('sensor.washer_dryer_wifi') %}
          {% set Total = states('sensor.washer_dryer_total_time') | int(default=0) %}
          {% set TMax = states('sensor.washer_dryer_max_time') | int(default=0) %}
          {% set DelayMax = states('sensor.washer_dryer_delay_max') | int(default=0) %}
          {% if Total == 0 %}0
          {% elif Status == 'Off' %}{{ TMax }}
          {% elif Total <= (TMax - DelayMax) %}{{ TMax }}
          {% else %}{{ Total }}
          {% endif %}

I thought the file path could be an issue, though it looks ok to me. The file path for reference is /config/pyscript/candy.py

Eikkargh commented 3 months ago

Looks like you have a few return codes I dont have. This has put you over the 255 character limit, when this happens Home Assistant just blanks. I have created a New Device PR updating candy.py that should filter out these extra values bringing back under the limit. Everything else you have done looks spot on.

You may find your programs codes differ from the actual mode set. If you spot any feel free to let me know what your numbers correspond to so I can include this for your machine.

BenGlossop09 commented 2 months ago

Thanks for the revision, that has solved the issue. Note that when an update (to the code) is made a new entity is created eg sensor.candy_washer_dryer_2. The original needs to be deleted (possible through the UI) then restart Home Assistant. This will convert sensor.candy_washer_dryer_2 back to sensor.candy_washer_dryer allowing the configuration.yaml/lovelace entities to update.

When I have a bit more time I will go through all of the programme settings on the machine and identify them. I'd imagine it would be best to make another GitHub issue for this as it is separate to the original issue.

Eikkargh commented 2 months ago

Glad it worked. Good note on changes creating a new sensor. Alternatively opening the file in a text editor and pasting the updated code over the top avoids this too.

Program confirmation would be great if you get time, no problem if not.