Coder Social home page Coder Social logo

ofalvai / home-assistant-candy Goto Github PK

View Code? Open in Web Editor NEW
119.0 10.0 27.0 114 KB

Unofficial Candy/Haier appliance integration for Home Assistant

Python 99.71% Shell 0.29%
home-assistant hacs home-assistant-component home-assistant-custom home-assistant-integration homeassistant candy haier

home-assistant-candy's Introduction

Candy Home Assistant component

Run tests hacs_badge codecov

Custom component for Home Assistant that integrates Candy/Haier/Simply-Fi home appliances.

Features

  • Supported appliances:
    • washing machine
    • tumble dryer
    • oven
    • dishwasher
  • Uses the local API and its status endpoint
  • Creates various sensors, such as device state and remaining time. Everything else is exposed as sensor attributes

Installation

  1. Install HACS
  2. Go to the integrations list in HACS and search for Candy Simply-Fi
  3. Restart Home Assistant
  4. Go to the Integrations page, click Add integrations and select Candy
  5. Complete the config flow

Configuration

You need the IP address of the machine and the encryption key. This can be guessed with CandySimplyFi-tool.

My device isn't supported. Can you help?

Yes. If you have an appliance that is not supported yet, or you see an error, head over to the Discussions section. Open a new thread or comment to an existing one with the following information:

  • The status API response of your device (use CandySimplyFi-tool to get the JSON)
  • A brief explanation of what each field means in the response and how it changes based on the device state, eg. The SpinSp field is probably the spin speed divided by 100, I have seen values 6, 8, 10 and 12 in the response

home-assistant-candy's People

Contributors

asiersan avatar carlosmfalves avatar dependabot[bot] avatar dzamlo avatar glebsterx avatar ofalvai avatar rogodra avatar terminet85 avatar thorin8k avatar wrt54g avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

home-assistant-candy's Issues

Hoover Washerdryer

Hey guys,

the Haier group also offers devices under the Hoover brand, so I was wondering if they are similar enough to be supported?

I got the HDPD696AMBC/1-S Model.

I tried the CandySimplyFi-tool but it shows only a connection error since port 80 is closed on the device.

Remaining minutes issue

Anyone know why my sensor.wash_cycle_remaining_time only displays the value 1 or 2 ? But on my washer it shows like this

PXL_20230129_091117747 MP

the intergration broke down

Integration stopped working on the version of Home Assistant 2023.8.1

2023-08-06 17:57:35.843 WARNING (MainThread) [homeassistant.config_entries] Config entry 'Candy' for candy integration not ready yet: Error communicating with API: JSONDecodeError('Expecting value: line 1 column 1 (char 0)'); Retrying in background

Problem with candy oven, no key required

Hi,

i've a problem with candy oven model fct896x-wifi.

by CLI

With command
curl -s http://IP/http-read.json?encrypted=1 | xxd -r -p | jq
i've reveived :

{

"statusForno": {
"StatoWiFi": "0",
"CodiceErrore": "E0",
"RecipeId": "0",
"RecipeStep": "0",
"StartStop": "0",
"Pausa": "0",
"SicurezzaBambini": "0",
"Selettore": "0",
"Program": "0",
"TempSet": "0",
"TempRead": "210",
"TempSetRaggiunta": "0",
"DelayStart": "0",
"RemainingTimeProgr": "65535",
"ora": "16",
"min": "11",
"sec": "2",
"FWver": "001A",
"ts": "0"

}
}

instead with this command
curl -s http://IP/http-read.json?encrypted=0 | xxd -r -p | jq
i've reveived no response
and with
curl -s http://IP/http-read.json?encrypted=0
i've reveived :
{"response":"BAD REQUEST"}
So, by HASSIO Integration, i've uncheck key but i've reveived the same error (BAD REQUEST)

Logger: homeassistant.config_entries
Source: config_entries.py:335
First occurred: 09:32:47 (4 occurrences)
Last logged: 16:10:32

Config entry 'Candy' for candy integration not ready yet: Error communicating with API: TimeoutError(); Retrying in background
Config entry 'Candy' for candy integration not ready yet: Error communicating with API: Exception('Unable to detect machine type >from API response', {'response': 'BAD REQUEST'}); Retrying in background

Thanks for support

Support for oven

hi,i have oven. You can add it on custom_component? If you want i can try some testing. tell me what i have to do.
For now i get this informations:

simplyfi 192.168.188.51 key read
{
"statusForno":{
"StatoWiFi":"0",
"CodiceErrore":"E0",
"RecipeId":"NULL",
"RecipeStep":"0",
"StartStop":"1",
"Pausa":"0",
"SicurezzaBambini":"0",
"Selettore":"1",
"Program":"2",
"TempSet":"0",
"TempRead":"310",
"TempSetRaggiunta":"0",
"DelayStart":"0",
"RemainingTimeProgr":"65535",
"ora":"9",
"min":"2",
"sec":"5",
"TimeProgr":"0",
"FWver":"004B",
"ts":"0"
}
}

Anyway i tried to integrate it but i have this error:

Error communicating with API: Exception('Unable to detect machine type from API response', {'statusForno': {'StatoWiFi': '0',

Ty so much.

Where should I put the key?

I get:

Traceback (most recent call last):
File "/config/custom_components/candy/client/init.py", line 62, in detect_encryption
assert resp_json.get("response") != "BAD REQUEST"
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/config/custom_components/candy/config_flow.py", line 45, in async_step_user
encryption_type, key = await detect_encryption(
File "/config/custom_components/candy/client/init.py", line 69, in detect_encryption
async with session.get(url) as resp:
File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 559, in _request
await resp.start(conn)
File "/usr/local/lib/python3.9/site-packages/aiohttp/client_reqrep.py", line 898, in start
message, payload = await protocol.read() # type: ignore[union-attr]
File "/usr/local/lib/python3.9/site-packages/aiohttp/streams.py", line 616, in read
await self._waiter
aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected

after I enter the ip
I see no way to enter the key

Retry configuration: Error communicating with API: TimeoutError()

Why does it not detect when the dryer is off ? This creates a lot of errors in home assistant ..... It would be nice to solve the problem otherwise I will have to remove this extension.

Capture d’écran 2022-02-10 134701

Réessayer la configuration: Error communicating with API: TimeoutError()

`2022-02-10 13:35:17 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 0.3s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])
2022-02-10 13:35:20 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 1.5s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])
2022-02-10 13:35:23 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 2.0s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])
2022-02-10 13:35:26 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 1.6s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])
2022-02-10 13:35:29 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 10.9s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])
2022-02-10 13:35:43 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 19.3s
Why does it not detect when the dryer is off? This creates a lot of errors in home assistant ..... It would be nice to solve the problem otherwise I will have to remove this extension.

(aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])`

2022-02-10 13:34:44 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 5.4s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.47:80 ssl:default [Connect call failed ('192.168.1.47', 80)])`

Find the encryption key automatically

This would avoid the need for the user to do the slightly complex process necessary by hand.

The script I posted on the forum should be robust enough if you handle the case where the key is full of zeros.

Failed to detect encryption

Getting Failed to detect encryption after entering IP in config flow.

Traceback (most recent call last):
  File "/config/custom_components/candy/client/__init__.py", line 62, in detect_encryption
    assert resp_json.get("response") != "BAD REQUEST"
AssertionError

I have obtained the key and can manually get JSON data in HASS terminal with:

curl -s http://192.168.1.24/http-read.json?encrypted=1 | xxd -r -p > ./coded.txt
./xorknown.py ./coded.txt --key=naedcjmhjdbgcejk > ./decoded.txt
tail -c +59 ./decoded.txt > ./candy.json

JSON values are:

{
        "statusLavatrice":{
                "WiFiStatus":"0",
                "Err":"255",
                "MachMd":"1",
                "Pr":"4",
                "PrPh":"0",
                "SLevel":"255",
                "Temp":"60",
                "SpinSp":"10",
                "Opt1":"0",
                "Opt2":"0",
                "Opt3":"0",
                "Opt4":"0",
                "Opt5":"0",
                "Opt6":"0",
                "Opt7":"0",
                "Opt8":"0",
                "Steam":"0",
                "DryT":"0",
                "DelVal":"255",
                "RemTime":"59",
                "RecipeId":"0",
                "CheckUpState":"0"
        }
}

Apologies if I have missed something obvious. Im pretty new to all this.

Possibility to not creating area

Please add the option to not automatic create an area when starting HA

After removed area loke kitchen or bathroom (automatic created from integration), restarting HA cause a re-creation

Dishwasher

Hi,
I can't integrate my dishwasher in home assistant:
I have this error:

Config entry 'Candy' for candy integration not ready yet: Error communicating with API: Exception('Unable to detect machine type from API response', {'statusDWash': {'StatoWiFi': '1', 'StatoDWash': '0', 'CodiceErrore': 'E0', 'StartStop': '0', 'Program': 'P1', 'OpzProg': 'p', 'DelayStart': '0', 'RemTime': '0', 'TreinUno': '0', 'Eco': '0', 'MetaCarico': '0', 'ExtraDry': '0', 'MissSalt': '0', 'MissRinse': '0', 'OpenDoor': '0', 'Reset': '0', 'FWver': 'L1.12'}}); Retrying in background

if i connect at site: http://x.x.x.x/http-read.json?encrypted=0 i view this parameters:
{ "statusDWash":{ "StatoWiFi":"1", "StatoDWash":"0", "CodiceErrore":"E0", "StartStop":"0", "Program":"P1", "OpzProg":"p", "DelayStart":"0", "RemTime":"0", "TreinUno":"0", "Eco":"0", "MetaCarico":"0", "ExtraDry":"0", "MissSalt":"0", "MissRinse":"0", "OpenDoor":"0", "Reset":"0", "FWver":"L1.12" } }

Have any suggestions?

Thank you!!!

Improve command retry

At the moment the integration query the washer every minute and if it does not get a reply it makes several (max_tries=10?) connection attempts. This behaviors is not good when the device is not available, for example because it is off or in sleep.

For example, in my case, the machine goes in sleep mode (wifi is disconnected) after 1-2 minutes it complete the washing cycle. This results in flooding the log with rows like this:

2021-09-22 08:57:05 INFO (MainThread) [backoff] Backing off status_with_retry(...) for 2.7s (aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.45:80 ssl:default [Connect call failed ('192.168.1.45', 80)])

In few days my home assistant log has grow to several megabytes with 30k+ errors as above.

--

Another related problem experienced is that the retry mechanism does not really avoid connection problem. For example, in the following chart, it is possible to see that the machine became unavailable several time during the washing cycles.
Cattura
This "unavailable time" is exactly 1 minute, the time between a query and the next one.
So the retry mechanism does not actually improve the connection reliability.

--

Possible improvements:

  • use another reply mechanism or function, e.g. make a single retry attempt after a certain time (10-30 seconds?), or just give up and wait the normal 1 minute cycle.
  • avoid logging all failed attempts; if necessary, just log the first the time the device became unavailable
  • if the device last query was "active", do not mark it unavailable the first time it does not reply, give it a "grace period" (this maybe not necessary if the retry mechanism is improved to be really effective)
  • if the device is disconnected, avoid additional retry

Thanks for the great job you are doing with the integration.

ip candy

hello, how do i find the ip of a connected candy washing machine? I can’t find it in the router ip of the connected devices

Initial Setup - 500 error

Just tried setting up integration for first time and get the following error

Error
Config flow could not be loaded: 500 Internal Server Error Server got itself in trouble

Autodiscovery

It would be nice to autodiscover the appliances. I see a few way:

  • Some (all?) appliance regularly broadcast an UDP packet.
  • I think you can do something with the existing dhcp discovery mechanism

State off

If the washing machine is off the sensors are "not available", could you do so to create an "Off" state?

Setup Error

Hi Oliver

Thanks for creating this integration.

I seem to be struggling to get it to execute. I have added the device IP and encryption key (detemined using CandySimplify-tool) but I get the following error on the integrations page in HA....

Retrying setup: Error communicating with API: 'FillR'

Any idea?
Thanks
Alan

Air Conditions support

Is there any chance that it will work with Haier air conditions? They are controlled via WiFi with hOn application.

Error setting up entry Candy for candy

Logger: homeassistant.config_entries
Source: custom_components/candy/init.py:54
Integration: Candy (documentation, issues)
First occurred: 16:24:24 (3 occurrences)
Last logged: 16:29:14

Error setting up entry Candy for candy
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 387, in async_setup
result = await component.async_setup_entry(hass, self)
File "/config/custom_components/candy/init.py", line 54, in async_setup_entry
hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)
AttributeError: 'ConfigEntries' object has no attribute 'async_setup_platforms'

backoff - Requirements not found

Logger: homeassistant.setup
Source: setup.py:184
First occurred: 09:57:27 (1 occurrences)
Last logged: 09:57:27

Home Assistant: 2022.11.0b0

Setup failed for custom integration candy: Requirements for candy not found: ['backoff>=1.8.0,<2.0.0'].

Washing machine status randomly updating to Idle while WM turned OFF

Hi! First of all thanks for your work on this integration, much appreciated! 😉
I'm having some weird behaviour with a binary sensor I made using the washing machine sensor..

template:
  - binary_sensor:
      - name: Washing Machine status
        state: >
          {{ states("sensor.washing_machine") | upper not in ["UNAVAILABLE"] }}
        icon: mdi:washing-machine

This should be pretty straightforward, however, it's randomly reporting as "On" (see image)

image

I used Developer Tools to check the template, and saw that the state was Idle, even if the washing machine is turned Off

image

Is my Washing Machine possessed by some weird wifi evil? 😄

Error communicating with API: KeyError('Pr')

Hello, my washing machine is Candy CO4 1062D3/2-S and im trying to add your integration to my Home Assistant.
I got needed ip and found a key with CandySimplyFi-tool then i completed your config flow.
But after, error appear in the integrations section
image
Am i doing something wrong or my model isnt supported?

Local control

Hi

I have managed to intercept the messages to control the washer. All of it are actually done locally.

Right now I'm able to start and stop the machine, and I have begun to "decode" the parameters.

Maybe you can extend this awesome plugin, so one are able to also control the washer from Home Assistant :-)

Failing initialization when appliance is offline

Hey,
may or may you not integrate some backoff mechanism, that does not make the complete intrgration fail, but only the offline device?
Like sync initialization an async the devices?
I'm not that python experienced, but i may try myself, if you are out of time (when i have enough time these days) and provide your a PR maybe?

best regards,
Michael

Drying machine

Hello,

I have a Candy Simply-fi dryer, but the integration fails.: "Error communicating with API: KeyError('statusLavatrice')"

The start of the chain is different, change statusLavatrice to statusTD. As well as other parameters, I can collaborate with tests.

I attach the extracted data with ./simplyfi IP KEY read

{
"statusTD":
{
"StatoWiFi":"1",
"StatoTD":"1",
"CodiceErrore":"0",
"Pr":"1",
"PrPh":"0",
"RemTime":"150",
"DryLev":"2",
"Time":"0",
"Rapido":"0",
"Opt1":"1",
"Opt2":"1",
"Opt3":"0",
"Opt4":"0",
"Opt5":"0",
"Opt6":"0",
"Opt7":"0",
"Opt8":"0",
"Refresh":"0",
"CleanFilter":"0",
"WaterTankFull":"0",
"DryingManagerLevel":"1",
"DelVal":"0",
"DoorState":"1",
"RecipeId":"NULL",
"CheckUpState":"0"
}
}

Thanks!

Support for NFC conectivity?

My washer has a NFC spot not a WiFi connection. I can use na Candy app on my phone to select or create program and run washing process. Also I'm able to get washing statistics from the device. It could be possible to install a permanent NFC Reader and connect it to the HA server. Do you have any plans for that kind integration? Thanks.

new sensor for your intagration based on my code appdaemon

# based on https://github.com/jezcooke/haier_appdaemon/blob/main/checkappliance.py
import hassapi as hass
import requests
import json
import codecs
from datetime import datetime, timedelta, timezone



encryption_key: "EEDcwokGsbwHqvjJ"
appliance_host: "192.168.1.129" 
appliance_entity = "sensor.candy_wifi" # The name of the entity to use/create in Home Assistant (value with '_stats' appended)
appliance_entity_binary_sensor = "binary_sensor.candy_wifi" # The name of the entity to use/create in Home Assistant (value with '_stats' appended)
status_root = "statusLavatrice"             # The root level JSON element returned by 'http-read'
power_attribute = "MachMd"                  # The name of the JSON attribute that containes the power on/off state.
stats_root = "statusCounters"               # The root level JSON element returned by 'http-getStatistics'
polling_interval = 60                       # How frequently check for the latest status.
request_timeout =  30                        # Request timeout should be less than the polling interval 
max_retry_before_unavailable = 3
PROGRAM_STATES = {
    0: "SPENTA",
    4: "DELICATI 59 MINUTI",
    7: "RAPIDO",
    8: "COTONE PERFETTO",
    12: "CICLO TEST",
    40: "IGIENE PLUS",
    72: "SPORT PLUS 39 MINUTI",
    104: "AUTO-PULIZIA",
    135: "MISTI & COLORATI 59 MINUTI",
    136: "SPECIAL 39 MINUTI"
}
POWER = {
    1: "STOP",
    2: "LAVAGGIO IN CORSO",
    3: "PAUSA",
    4: "PARTENZA RITARDATA SELEZIONATA",
    5: "PARTENZA RITARDATA",
    6: "ERRORE",
    7: "FINITO",
    8: "SCONOSCIUTO"
}

PORTA = {
    10: "aperta",
     6: "Chiusa",
     7: "Bloccata"
}
FASE_LAVAGGIO = {
                1: "prelavaggio",
                2: "lavaggio",
                3: "risciacquo",
                4: "ultimo risciacquo",
                5: "fine",
                6: "asciugatura",
                7: "ERRORE",
                8: "vapore",
                9: "centrifuga notturna",
                10: "centrifuga"

}
LIVELLI_SPORCO = {
                1: "Poco",
                2: "Normale",
                3: "Molto"
            }
n_risciacquo = {
}
class CandyWashingMachine(hass.Hass):
    def initialize(self):
        self.retry = 0
        self.previous_end = None
        self.run_every(self.check_appliance, "now", polling_interval)
        self.encryption_key = self.args["encryption_key"]
        self.log(f"encryption_key: {self.encryption_key!r}")
        self.appliance_host = self.args["appliance_host"]

    def check_appliance(self, kwargs):
        try:
            status = self.get_status()
            power = int(status[status_root][power_attribute])
            state_power = POWER.get(power, "UNKNOWN")
            attributes = status[status_root]
            self.set_state(appliance_entity, state=state_power, attributes=attributes) #{"friendly_name": "Candy Lavatrice", "icon": "mdi:washing-machine" })
            self.retry = 0
            remaining_minutes = int(attributes["RemTime"]) / 60 + int(attributes["DelVal"])
            now_rounded = datetime.now(timezone.utc).replace(second=0, microsecond=0) + timedelta(minutes=1)
            end = now_rounded + timedelta(minutes=remaining_minutes)
            if self.previous_end is not None:
                if abs(end - self.previous_end) <= timedelta(minutes=1):
                    end = max(end, self.previous_end)
            self.previous_end = end
            entity_id = appliance_entity + "_termine_programma"
            self.set_state(
                entity_id,
                state=remaining_minutes,
                attributes={"friendly_name": "Candy Fine ","icon": "mdi:av-timer", "unit_of_measurement": "minuti"},
            )
        except Exception as e:
            self.log(f"error when getting status: {e}")
            self.retry += 1
            if self.retry > max_retry_before_unavailable:
                self.set_state(appliance_entity, state="SPENTA")
                entity_id = appliance_entity + "_termine_programma"
                self.set_state(
                    entity_id,
                    state="unavailable",
                    attributes={"friendly_name": "Candy Lavatrice", "device_class": "timestamp", "icon": "mdi:timer-off-outline"},
                )
                previous_end = None
            return
        
####################################
        try:
          status = self.get_status()
          opta = int(status[status_root]["Opt5"])
          optb = int(status[status_root]["Opt6"])
          optc = int(status[status_root]["Opt7"])
    
          if opta == 1:
                  state_risc = "X 1"
          elif optb == 1:
                  state_risc = "X 2"
          elif optc == 1:
                  state_risc = "X 3"
          else:
                  state_risc = "OFF"

          entity_id = f"{appliance_entity}_risciacquo"
          attributes = {"friendly_name": "Risciacquo", "icon": "mdi:water"}
          self.set_state(entity_id, state=state_risc, attributes=attributes)
          self.retry = 0

        except Exception as e:
           # Gestione specifica dell'eccezione, se necessario
           pass

#livello sporco
        try:
            statussp = self.get_status()
            sporco = int(statussp[status_root]["SLevel"])
            statesp = LIVELLI_SPORCO.get(sporco, "ESCLUSO")
            entity_id = appliance_entity + "_livello_sporco"
            self.set_state(
                entity_id,
                state=statesp,
                attributes={ "friendly_name": "Livello di Sporco","icon": "mdi:car-brake-fluid-level",},
            )
        except:
            pass
               
#stato lavaggio
        try:
            status = self.get_status()
            macchine = int(status[status_root]["PrPh"])
            statemd = stati_lavatrice.get(macchine, "inattiva")
            entity_id = appliance_entity + "_stato_lavatrice"
            self.set_state( 
                entity_id, 
                state=statemd, 
                attributes={ "friendly_name": "Candy Stato", "icon": "mdi:washing-machine",  },  )
            self.retry = 0
        except:
            pass
            
            
                    
#porta
        try:
            status = self.get_status()
            ntcd = int(status[status_root]["NtcD"])
            stato_porta = PORTA.get(ntcd, "UNKNOW")
            
            entity_id = appliance_entity + "_ntcd"
            self.set_state(entity_id, state=stato_porta, attributes = {"friendly_name": "Porta", "icon":"mdi:door"})
            #self.retry = 0
        except:
            stato_porta = "UNKNOWN" 

    ###############    
#cicli conta
        try:
            entity_id = appliance_entity + "_stats"
            stats = self.get_stats()[stats_root]
            total = 0
            for (key, value) in stats.items():
                if key.startswith("Program"):
                    total += int(value)
            self.set_state(entity_id, state=total, 
                        attributes={ "friendly_name": "Candy Cicli totali", "icon": "mdi:washing-machine"},)
        except:
            pass
            
######################################
#programma


        try:
            status = self.get_status()
            programm = int(status[status_root]["PrCode"])
            rem = int(status[status_root]["RemTime"]) // 60
            state_program = PROGRAM_STATES.get(programm, "UNKNOWN")
            
            if programm == 7:
                state_program += f" {rem} MINUTI"
            entity_id = appliance_entity + "_programma"
            self.set_state(entity_id, state=state_program, attributes = {"friendly_name": "Programma", "icon":"mdi:format-list-bulleted-type"})
            #self.retry = 0
        except:
            state_program = "UNKNOWN" 

#errori
        try:
            # Ottieni lo stato del sistema
            status = self.get_status()
            error_code = int(status[status_root]["Err"])
            
            # Assegna una stringa di errore in base al codice di errore
            state_error = "E{}".format(error_code) if error_code in range(1, 22) else "---"
            
            # Imposta lo stato di errore sull'entità
            entity_id = appliance_entity + "_errore"
            self.set_state(entity_id, state=state_error, 
                           attributes = {"friendly_name": "ERRORI", "icon":"mdi:alert-circle-outline"})
        except:
            pass
            ###############    
#temp impostata
        try:
            status = self.get_status()
            temp = int(status[status_root]["Temp"])
            entity_id = appliance_entity + "_temp"
            self.set_state(entity_id, state=temp, attributes = {"friendly_name": "Temperatura impostata", "unit_of_measurement": "°C"})
        #    self.retry = 0
        except:
            pass
    ###############    
#temp interna
        try:
            status = self.get_status()
            temp1 = int(status[status_root]["NtcW"]) / 10

            entity_id = appliance_entity + "_temp_interna"
            self.set_state(entity_id, state=temp1, attributes = {"friendly_name": "Temperatura attuale", "unit_of_measurement": "°C"})
        #    self.retry = 0
        except:
            pass
    ###############           
    ###############  
#counter
        try:
            statusmv = self.get_stats()
            mov = int(statusmv[stats_root]["CounterMV"])
            mov = 0
            entity_id = appliance_entity + "_countmove"
            self.set_state(entity_id, state=mov, attributes = {"friendly_name": "Conta Movimenti", "icon":"mdi:vibrate"})
        #    self.retry = 0
        except:
            pass
    ###############  
#riempimento             
        try:
            statusfill = self.get_status()
            fill = int(statusfill[status_root]["FillR"])
            fill = 0
            entity_id = appliance_entity + "_riempimento"
            self.set_state(entity_id, state=fill, attributes = {"friendly_name": "Percentuale riempimento", "icon":"mdi:waves-arrow-up", "unit_of_measurement": "%"}) 
        #    self.retry = 0
        except:
            pass
    
    
    
    
    
#centrifuga impostata
        try:
            statusrpm = self.get_status()
            rpm = int(statusrpm[status_root]["SpinSp"]) * 100

            entity_id = appliance_entity + "_centrifuga"
            self.set_state(entity_id, state=rpm, attributes = {"friendly_name": "Giri Centrifuga", "unit_of_measurement": "rpm", "icon":"mdi:sync"})
            self.retry = 0
        except:
            pass
    ###############  
    ###############     
#motore
        try:
            status = self.get_status()
            value = int(status[status_root]["motS"]) // 10 

            entity_id = appliance_entity + "_motore"
            self.set_state(entity_id, state=value, 
                        attributes = {"friendly_name": "Giri Motore", "unit_of_measurement": "rpm", "icon": "mdi:engine"})
        #    self.retry = 0
        except:
            pass
#prelavaggio opt1
        try:
            status = self.get_status()
            prelavax = int(status[status_root]["Opt1"])
            if prelavax == 1:
                state = "on"
            else:
                state = "off"

            entity_id = appliance_entity_binary_sensor + "_opt1"
            self.set_state(entity_id, state=state, attributes = {"friendly_name": "Prelavaggio", "icon":"mdi:hand-wash"})
        #    self.retry = 0
        except:
            pass
    ###############     
#igiene opt2
        try:
            status = self.get_status()
            igieneplus = int(status[status_root]["Opt2"])
            if igieneplus == 1:
                state = "on"
            else:
                state = "off"

            entity_id = appliance_entity_binary_sensor + "_opt2"
            self.set_state(entity_id, state=state, attributes = {"friendly_name": "Igiene +", "icon":"mdi:hospital-box"})
        #    self.retry = 0
        except:
            pass
    ###############  
   
#antipiega opt3
        try:
            status = self.get_status()
            valueantip = int(status[status_root]["Opt3"])
            if valueantip == 1:
                state = "on"
            else:
                state = "off"

            entity_id = appliance_entity_binary_sensor + "_opt3"
            self.set_state(entity_id, state=state, attributes = {"friendly_name": "Antipiega", "icon":"mdi:tshirt-v"})
        #    self.retry = 0
        except:
            pass
    ###############            
#buonanotte opt4
        try:
            status = self.get_status()
            value = int(status[status_root]["Opt4"])
            if value == 1:
                state = "on"
            else:
                state = "off"

            entity_id = appliance_entity_binary_sensor + "_opt4"
            self.set_state(entity_id, state=state, attributes = {"friendly_name": "Buonanotte", "icon":"mdi:weather-night"})
        #    self.retry = 0
        except:
            pass
#acquaplus opt8
        try:
            status = self.get_status()
            valueacq = int(status[status_root]["Opt8"])
            if valueacq == 1:
                state = "on"
            else:
                state = "off"

            entity_id = appliance_entity_binary_sensor + "_opt8"
            self.set_state(entity_id, state=state, attributes = {"friendly_name": "Acquaplus", "icon":"mdi:water-plus"})
        #    self.retry = 0
        except:
            pass
    ###############     
#option9 opt9
        try:
            status = self.get_status()
            value = int(status[status_root]["Opt9"])
            if value == 1:
                state = "on"
            else:
                state = "off"

            entity_id = appliance_entity_binary_sensor + "_opt9"
            self.set_state( entity_id, state=state, attributes = {"friendly_name": "Opzione 9 sconosciuta"})
        #    self.retry = 0
        except:
            pass   
#vapore
        try:
            status = self.get_status()
            valuevap = int(status[status_root]["Steam"])
            states = ["ESCLUSO", "Basso", "Medio Basso", "Medio", "Medio Alto", "Massimo"]
            state = states[valuevap] if 0 <= valuevap <= 5 else "ESCLUSO"
        
            entity_id = f"{appliance_entity}_vapore"
            self.set_state(
                entity_id,
                state=state,
                attributes={"friendly_name": "Vapore", "icon": "mdi:cloud-outline"}
            )
        except Exception as e:
            # Logging dell'errore per una diagnostica futura
            logger.exception("Errore durante la gestione del vapore: %s", str(e))
       
###################################@@@@@@@@@@@@@@@@@@@@@##############################
       

#controllo remoto
        try:
            status = self.get_status()
            valueremoto = int(status[status_root]["WiFiStatus"])
        
            stato_wifi = {
                1: "on",
                0: "off",
            }
        
            controllorem = stato_wifi.get(valueremoto, "off")
            entity_id = appliance_entity_binary_sensor + "_wifi"
            self.set_state(
                entity_id,
                state=controllorem,
                attributes={
                    "friendly_name": "Controllo Remoto",
                    "WiFiStatus": valueremoto,
                    "icon": "mdi:wifi-cog",
                },
            )
            self.retry = 0
        except:
            pass

#filtro
        try:
            statsf = self.get_stats()[stats_root]
            totalef = sum(int(value) for key, value in statsf.items() if key.startswith("Program"))
            filtro_lav = 100 - totalef
        
            if filtro_lav < 1:
                statefiltros = "Da Pulire"
            elif filtro_lav < 70:
                statefiltros = "Medio Sporco"
            elif filtro_lav < 40:
                statefiltros = "Sporco"
            else:
                statefiltros = "Pulito"
        
            entity_id = f"{appliance_entity}_filtro"
            self.set_state(
                entity_id,
                state=statefiltros,
                attributes={
                    "friendly_name": "Filtro",
                    "Intasamento": filtro_lav,
                    "icon": "mdi:air-filter"
                }
            )
        except Exception as e:
            # Logging dell'errore per una diagnostica futura
            logger.exception("Errore durante la gestione del filtro: %s", str(e))
       
#filtro calcare
        try:
            statsfc = self.get_stats()[stats_root]
            totalefc = sum(int(value) for key, value in statsfc.items() if key.startswith("Program"))
            filtro_lav_c = 105 - totalefc
        
            if filtro_lav_c < 1:
                statefiltroc = "Da Pulire"
            elif filtro_lav_c < 70:
                statefiltroc = "Medio Sporco"
            elif filtro_lav_c < 40:
                statefiltroc = "Sporco"
            else:
                statefiltroc = "Pulito"
        
            entity_id = f"{appliance_entity}_filtro_calcare"
            self.set_state(
                entity_id,
                state=statefiltroc,
                attributes={
                    "friendly_name": "Filtro Calcare",
                    "Livello": filtro_lav_c,
                    "icon": "mdi:air-filter"
                }
            )
            self.retry = 0
        except Exception as e:
            # Logging dell'errore per una diagnostica futura
            logger.exception("Errore durante la gestione del filtro del calcare: %s", str(e))
       

####################################
#diagnosi
        try:
            status = self.get_status()
            diagnostics_test_on = int(status[status_root]["DisTestOn"])
            diagnostics_test_result = int(status[status_root]["DisTestRes"])
            
            if diagnostics_test_on == 1:
                state_diagnostics = "In Corso"
            elif diagnostics_test_result == 1:
                state_diagnostics = "OK"
            elif diagnostics_test_result == 2:
                state_diagnostics = "ERRORE"
            else:
                state_diagnostics = "---"
        
            entity_id = f"{appliance_entity}_diagnostics"
            self.set_state(
                entity_id,
                state=state_diagnostics,
                attributes={
                    "friendly_name": "Diagnosi",
                    "icon": "mdi:medical-bag"
                }
            )
            self.retry = 0
        except Exception as e:
            # Logging l'errore per una diagnostica futura
            logger.exception(f"Errore durante la gestione della diagnosi: {e}")
            pass
       
##################################
##################################
    def get_status(self):
        return self.get_data("read")

    def get_stats(self):
        self.get_data("prepareStatistics")
        return self.get_data("getStatistics")

    def get_data(self, command):
        res = requests.get(
            "http://" + self.appliance_host + "/http-" + command + ".json?encrypted=1",
            timeout=request_timeout,
        )
        return json.loads(self.decrypt(codecs.decode(res.text, "hex"), self.encryption_key))

    def decrypt(self, cipher_text, key):
        decrypted = ""

        for i in range(len(cipher_text)):
            decrypted += chr(cipher_text[i] ^ ord(key[i % len(key)]))

        return decrypted

New integration for Candy fridge cbl3518evw (hOn app)

Hello everyone. I have a candy cbl3518evw fridge connected through the app "hOn" distributed also for Hover connected products. Would an implementation be possible for the management of this fridge? I can also be of support and collaborate on a possible development used my fridge.

No entity after setup

Hello,

first of all thank you so much for creating this home assistant integration.

I was able to get the key through the tool and finished the setup in ha, but in the end no entity is added, as in the picture.

image

I can still read the data via the CLI

"statusWashing machine": {
"WiFiStatus": "1",
"Err": "0",
"MachMd": "1",
"Pr": "1",
"PrPh": "0",
"PrCode": "136",
"SLevel": "0",
"Temp": "40",
"SpinSp": "8",
"Opt1": "0",
"Opt2": "0",
"Opt3": "0",
"Opt4": "0",
"Opt5": "0",
"Opt6": "0",
"Opt7": "0",
"Opt8": "0",
"Opt9": "0",
"Steam": "0",
"DryT": "1",
"DelVal": "0",
"RemTime": "12540",
"RecipeId": "0",
"Lang": "0",
"FillR": "0",
"DisTestOn": "0",
"DisTestRes": "0",
"CheckUpState": "0",
"T0W": "0",
"TIW": "0",
"T0R": "0",
"numF": "0",
"unbF": "0",
"unbC": "0",
"NtcW": "381",
"NtcD": "631",
"motS": "0",
"APSoff": "0",
"APSfreq": "61881",
"chartL": "0"
}

The washer dryer model is the following ROW4964DWMSE / 1-S

Thanks

2023.3 - async_setup_platforms deprecated ?

Logger: homeassistant.helpers.frame
Source: helpers/frame.py:77
First occurred: 19:30:26 (1 occurrences)
Last logged: 19:30:26

Detected integration that called async_setup_platforms instead of awaiting async_forward_entry_setups; this will fail in version 2023.3. Please report issue to the custom integration author for candy using this method at custom_components/candy/init.py, line 54: hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)

Trying to add induction Hob Hoover HTPSJ644MCWIFI

I tried to add an Hoover induction hob, with works in candy simply-fi app, but I get this in the logs:

Logger: homeassistant.config_entries
Source: config_entries.py:1250
First occurred: 23:27:19 (1 occurrences)
Last logged: 23:27:19

Config entry 'Candy' for candy integration not ready yet: Error communicating with API: Exception('Unable to detect machine type from API response', {'statusHob': {'StatoWiFi': '1', 'Z1status': '0', 'Z1pan': '0', 'Z1hot': '0', 'Z1combi': '0', 'Z1low': '0', 'Z1power': '0', 'Z1error': '00', 'Z1timeh': '0', 'Z1timem': '0', 'Z2status': '0', 'Z2pan': '0', 'Z2hot': '0', 'Z2combi': '0', 'Z2low': '0', 'Z2power': '0', 'Z2error': '00', 'Z2timeh': '0', 'Z2timem': '0', 'Z3status': '0', 'Z3pan': '0', 'Z3hot': '0', 'Z3combi': '0', 'Z3low': '0', 'Z3power': '0', 'Z3error': '00', 'Z3timeh': '0', 'Z3timem': '0', 'Z4status': '0', 'Z4pan': '0', 'Z4hot': '0', 'Z4combi': '0', 'Z4low': '0', 'Z4power': '0', 'Z4error': '00', 'Z4timeh': '0', 'Z4timem': '0', 'lock': '0', 'alarmh': '0', 'alarmm': '0', 'JollyFunc': '0', 'PhaseZ1': '0', 'PhaseZ2': '0', 'PhaseZ3': '0', 'PhaseZ4': '0', 'PowerManagementLevel': '5'}}); Retrying in background

Is it possible to add this device?
Thank you!

Candy Oven in Celsius

Hi,
Thanks for creating this plugin 🙏🏼.

I tried the plugin with my Candy oven and noticed that the plugin is showing wrong temperature value, after investigating a little bit in the code I found out that you are using Fahrenheit to Celsius function which is completely unnecessary for me, I tried to create the request to the oven and saw that it gets the temperature already in Celsius but it needs to be devided by 10.

So I'm getting from the request 2200 for 220 degrees Celsius.

Hope you can make the proper adjustments to make it work.
Thanks again :)

Washing machine state isn't universal

I noticed that MachineState isn't applicable for each Machine. I got an state 6 that is a self-test in Tumble Dryer. Will be better create a class and extend it for each machine I guess.

{
        "statusTD":
{"StatoWiFi":"1",
                "StatoTD":"6",
                "CodiceErrore":"0",
                "Pr":"1",
                "PrPh":"2",
                "RemTime":"150",
                "DryLev":"2",
                "Time":"0",
                "Rapido":"0",
                "Opt1":"1",
                "Opt2":"1",
                "Opt3":"0",
                "Opt4":"0",
                "Opt5":"0",
                "Opt6":"0",
                "Opt7":"0",
                "Opt8":"0",
                "Refresh":"0",
                "CleanFilter":"0",
                "WaterTankFull":"0",
                "DryingManagerLevel":"2",
                "DelVal":"0",
                "DoorState":"1",
                "RecipeId":"NULL",
                "CheckUpState":"1"
        }
}
class MachineState(Enum):
    IDLE = 1
    RUNNING = 2
    PAUSED = 3
    DELAYED_START_SELECTION = 4
    DELAYED_START_PROGRAMMED = 5
    ERROR = 6
    FINISHED1 = 7
    FINISHED2 = 8

Time remaining before clean filter

Hello,
Someone can explain all this fileds what means?

{ "statusLavatrice":{ "WiFiStatus":"0", "Err":"0", "MachMd":"5", "Pr":"3", "PrPh":"0", "PrCode":"8", "SLevel":"0", "Temp":"40", "SpinSp":"14", "Opt1":"0", "Opt2":"0", "Opt3":"0", "Opt4":"0", "Opt5":"0", "Opt6":"0", "Opt7":"0", "Opt8":"0", "Opt9":"0", "Steam":"0", "DryT":"0", "DelVal":"435", "RemTime":"3540", "RecipeId":"0", "Lang":"0", "FillR":"0", "DisTestOn":"0", "DisTestRes":"0", "CheckUpState":"0", "T0W":"0", "TIW":"0", "T0R":"0", "numF":"0", "unbF":"0", "unbC":"0", "NtcW":"179", "NtcD":"9", "motS":"0", "APSoff":"0", "APSfreq":"62500", "chartL":"157242" } }

In particolar i need to know if i can extract the time remaining for clean filter like this image from the official app
Screenshot_2023-06-06-22-56-29-751_it candy simplyfi-edit

Error communicating with API: JSONDecodeError

Hi I've this error after configuration.

Error communicating with API: JSONDecodeError('unexpected content after document: line 1 column 2 (char 1)')

JSON

{
	"statusLavatrice":{
		"WiFiStatus":"1",
		"Err":"255",
		"MachMd":"1",
		"Pr":"15",
		"PrPh":"0",
		"SLevel":"2",
		"Temp":"90",
		"SpinSp":"4",
		"Opt1":"0",
		"Opt2":"0",
		"Opt3":"0",
		"Opt4":"0",
		"Opt5":"0",
		"Opt6":"0",
		"Opt7":"0",
		"Opt8":"0",
		"Steam":"0",
		"DryT":"0",
		"DelVal":"255",
		"RemTime":"136",
		"RecipeId":"0",
		"CheckUpState":"0"
	}
}

No encryption key, just hex
7B0D0A09227374617475734C6176617472696365223A7B0D0A09092257694669537461747573223A2231222C0D0A090922457272223A22323535222C0D0A0909224D6163684D64223A2231222C0D0A0909225072223A223135222C0D0A09092250725068223A2230222C0D0A090922534C6576656C223A2232222C0D0A09092254656D70223A223930222C0D0A0909225370696E5370223A2234222C0D0A0909224F707431223A2230222C0D0A0909224F707432223A2230222C0D0A0909224F707433223A2230222C0D0A0909224F707434223A2230222C0D0A0909224F707435223A2230222C0D0A0909224F707436223A2230222C0D0A0909224F707437223A2230222C0D0A0909224F707438223A2230222C0D0A090922537465616D223A2230222C0D0A09092244727954223A2230222C0D0A09092244656C56616C223A22323535222C0D0A09092252656D54696D65223A22313336222C0D0A0909225265636970654964223A2230222C0D0A090922436865636B55705374617465223A2230220D0A097D0D0A7D

debug log

2022-08-28 13:23:37.123 DEBUG (MainThread) [custom_components.candy] Finished fetching candy data in 2.259 seconds (success: False)
2022-08-28 13:23:48.724 DEBUG (MainThread) [custom_components.candy] Finished fetching candy data in 1.601 seconds (success: False)
2022-08-28 13:23:59.884 INFO (MainThread) [custom_components.candy.client] Trying to get a response without encryption (encrypted=0)...
2022-08-28 13:24:00.598 DEBUG (MainThread) [custom_components.candy.client]
2022-08-28 13:24:00.598 INFO (MainThread) [custom_components.candy.client] Failed to get a valid response without encryption, let's try with encrypted=1...
2022-08-28 13:24:07.543 INFO (MainThread) [custom_components.candy.client] Response is not encrypted (despite encryption=1 in request), no need to brute force the key
2022-08-28 13:24:27.631 INFO (MainThread) [custom_components.candy.client] Backing off status_with_retry(...) for 0.7s (aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected)
2022-08-28 13:24:29.990 DEBUG (MainThread) [custom_components.candy] Finished fetching candy data in 22.446 seconds (success: False)

Glad to help if needed

Thank you

Trying to add device crashes HA

I have previously used this integration with 3 Candy devices (dishwasher, dryer, and washing machine) and had it working fine. I've done a complete reinstall of HA recently, and whenever I try to add my washing machine, I enter the IP address and the screen just stays with the progress wheel spinning. No error, nothing in logs, and HA completely stops responding - I have to actually hard reset the HA machine by unplugging it.

Previously, I'm sure I was prompted for an encryption key for this device, as I've got the output from Melvin's tool written down with the key, I never get to this prompt now though.

I've tried several different versions (8.0, 8.1, 8.2, base) and the same thing happens each time.

Seems a similar issue to what is being discussed in recent posts in #61 , but I created a new issue as I never get the encryption key prompt.

Anyone any ideas?

Washing Machine & Tumble Dryer Setup Error

I get an error when trying to input the IP's. I'm in the UK if that makes any difference. Found the IP's through my router settings.

This error originated from a custom integration.

`Logger: custom_components.candy.config_flow
Source: custom_components/candy/client/init.py:69
Integration: Candy (documentation, issues)
First occurred: 21:08:58 (8 occurrences)
Last logged: 21:17:43

Cannot connect to host 192.168.1.115:80 ssl:default [Connect call failed ('192.168.1.115', 80)]
Cannot connect to host 192.168.1.75:80 ssl:default [Connect call failed ('192.168.1.75', 80)]
Cannot connect to host 192.168.1.240:80 ssl:default [Connect call failed ('192.168.1.240', 80)]
Cannot connect to host 192.168.1.208:80 ssl:default [Connect call failed ('192.168.1.208', 80)]
Cannot connect to host 192.168.1.175:80 ssl:default [Connect call failed ('192.168.1.175', 80)]
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 986, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
File "/usr/local/lib/python3.9/asyncio/base_events.py", line 1056, in create_connection
raise exceptions[0]
File "/usr/local/lib/python3.9/asyncio/base_events.py", line 1041, in create_connection
sock = await self._connect_sock(
File "/usr/local/lib/python3.9/asyncio/base_events.py", line 955, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/local/lib/python3.9/asyncio/selector_events.py", line 502, in sock_connect
return await fut
File "/usr/local/lib/python3.9/asyncio/selector_events.py", line 537, in _sock_connect_cb
raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 111] Connect call failed ('192.168.1.175', 80)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/config/custom_components/candy/config_flow.py", line 45, in async_step_user
encryption_type, key = await detect_encryption(
File "/config/custom_components/candy/client/init.py", line 69, in detect_encryption
async with session.get(url) as resp:
File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 535, in _request
conn = await self._connector.connect(
File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 542, in connect
proto = await self._create_connection(req, traces, timeout)
File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 907, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 1206, in _create_direct_connection
raise last_exc
File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 1175, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 992, in _wrap_create_connection
raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.175:80 ssl:default [Connect call failed ('192.168.1.175', 80)]`

please add support for additional parameters for dishwasher

Hello,

Please add support for additional parameters. Info is from dishwasher Candy CDIM 3T623PRDF.
CandySimplyFi-tool output:
./simplyfi '' '' read
{"statusDWash":{"StatoWiFi":"1","StatoDWash":"4","CodiceErrore":"E0","StartStop":"1","Program":"P2","OpzProg":"0","DelayStart":"0","RemTime":"58","TreinUno":"0","Eco":"1","MetaCarico":"0","ExtraDry":"0","OpenDoorOpt":"1","MissSalt":"0","MissRinse":"1","OpenDoor":"0","Reset":"0"}}

Additional parameters:
"DelayStart":"0" (info about delayed start)
"OpenDoorOpt":"1" (info about option for opening door during drying)
"MissSalt":"0" (info about missing salt)
"MissRinse":"1" (info about missing rinse aid)

Thank you.

Not all sensors available in HA for Tumble Dryer

Hello, I've got issue with sensors, with tumble dryer. I'm having only 3 entities in HA: "Dryer cycle remaining time", "Dryer cycle status", "Tumble dryer".
But in json data from device I can see all listed in your code params, it seems that in my situation HA can't see all sensors. There are missing "DoorState", "WaterTankFull", "CleanFilter" and some other items.

Here is data from device:

{
        "statusTD":
{"StatoWiFi":"0",
                "StatoTD":"2",
                "CodiceErrore":"0",
                "Pr":"5",
                "PrPh":"2",
                "RemTime":"76",
                "DryLev":"4",
                "Time":"0",
                "Rapido":"0",
                "Opt1":"1",
                "Opt2":"1",
                "Opt3":"0",
                "Opt4":"0",
                "Opt5":"0",
                "Opt6":"0",
                "Opt7":"0",
                "Opt8":"0",
                "Refresh":"0",
                "CleanFilter":"0",
                "WaterTankFull":"0",
                "DryingManagerLevel":"1",
                "DelVal":"0",
                "DoorState":"1",
                "RecipeId":"NULL",
                "CheckUpState":"0"
        }
}

Please add a setting to change the device's IP address

Today, I had an unexpected problem: my automation didn't report the washing machine's state. At first I thought that maybe the machine's wifi signal strength was too weak. But when looking through the DHCP logs, I discovered that rather it's IP address had changed.

So the wifi was working as expected, but the integration tried to connect to the wrong IP. Of course, I don't think there's a way to automatically update the integration with the new IP address. And it shouldn't happen too often, anyway. But the only way to set the new address was to go edit HA's config files manually. Therefore, I'd like to suggest exposing this vital setting via the GUI.

At the moment, the only settings for the device are in regards to name, area and enabled/disabled state of the device:
image

Candy missing in intergration page

HA 2021.10.3
HACS 1.15.2

I've successfully installed it from the HACS page, but the integration will not appears in the integration page.

2021-10-11 16:12:20 WARNING (SyncWorker_3) [homeassistant.loader] We found a custom integration candy which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.