home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
73.62k stars 30.78k forks source link

Freebox : KeyError while testing temperature sensors during setup #67685

Closed jaroslawp closed 2 years ago

jaroslawp commented 2 years ago

The problem

While trying to setup Freebox integration it connects to freebox OK (can see HA access in 'Gestion des acces' -> 'Applications' in Freebox OS interface) but fails to set up the integration. (My freebox is the Delta model).

The problem happens in: https://github.com/home-assistant/core/blob/dev/homeassistant/components/freebox/router.py#L107| and my guess is that freebox reports undef value for some of the sensors ? (in Freebox OS interface I can see that 2 of 4 installed hard drives are not reporting temperatures correctly - maybe these are causing the problem ? .. see attached image) freebox-state

What version of Home Assistant Core has the issue?

core-2022.3.1

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant OS

Integration causing the issue

Freebox

Link to integration documentation on our website

https://www.home-assistant.io/integrations/freebox/

Diagnostics information

No response

Example YAML snippet

No response

Anything in the logs that might be useful for us?

2022-03-05 10:27:38 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry *********.fbxos.fr for freebox
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 335, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/usr/src/homeassistant/homeassistant/components/freebox/__init__.py", line 60, in async_setup_entry
    await router.update_all()
  File "/usr/src/homeassistant/homeassistant/components/freebox/router.py", line 75, in update_all
    await self.update_sensors()
  File "/usr/src/homeassistant/homeassistant/components/freebox/router.py", line 115, in update_sensors
    self.sensors_temperature[sensor["name"]] = sensor["value"]
KeyError: 'value'

Additional information

Freebox model: Delta, Freebox OS: 4.5.4

probot-home-assistant[bot] commented 2 years ago

freebox documentation freebox source (message by IssueLinks)

probot-home-assistant[bot] commented 2 years ago

Hey there @hacf-fr, @quentame, mind taking a look at this issue as it has been labeled with an integration (freebox) you are listed as a code owner for? Thanks! (message by CodeOwnersMention)

hles commented 2 years ago

I can confirm this bug for the Freebox revolution as well. From other threads I read, a simple fix could be to test the state of each sensor in the loop.

KurbysS commented 2 years ago

Hey, same mistake since 2022.3.5

moi-001 commented 2 years ago

Hello

I have the same problem

Logger: homeassistant.config_entries Source: components/freebox/router.py:115 First occurred: 15:14:43 (1 occurrences) Last logged: 15:14:43

Error setting up entry xxx.fbxos.fr for freebox Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/config_entries.py", line 335, in async_setup result = await component.async_setup_entry(hass, self) File "/usr/src/homeassistant/homeassistant/components/freebox/init.py", line 60, in async_setup_entry await router.update_all() File "/usr/src/homeassistant/homeassistant/components/freebox/router.py", line 75, in update_all await self.update_sensors() File "/usr/src/homeassistant/homeassistant/components/freebox/router.py", line 115, in update_sensors self.sensors_temperature[sensor["name"]] = sensor["value"] KeyError: 'value'

Before that worked correctly what must I have followed the instructions I reinstalled it several times

GitHubRousseau commented 2 years ago

Same issue

qnpns commented 2 years ago

Hello,

I have the same issue on a Freebox Delta with an old hdd and it seems that someone found a solution to it in this post from 1 feb 2021 :

https://github.com/home-assistant/core/issues/43812#issuecomment-770875769

Could someone modifiy the code of the Freebox integration please ?

sidwin9 commented 2 years ago

Hello, Exactly the same problem with my Freebox Delta

Error setting up entry xxxxxxxx.fbxos.fr for freebox Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/config_entries.py", line 335, in async_setup result = await component.async_setup_entry(hass, self) File "/usr/src/homeassistant/homeassistant/components/freebox/init.py", line 60, in async_setup_entry await router.update_all() File "/usr/src/homeassistant/homeassistant/components/freebox/router.py", line 75, in update_all await self.update_sensors() File "/usr/src/homeassistant/homeassistant/components/freebox/router.py", line 115, in update_sensors self.sensors_temperature[sensor["name"]] = sensor["value"] KeyError: 'value'

I have a disk that does not show a temperature value in the Freebox OS interface.

froggy974 commented 2 years ago

same error on my side on a freebox revolution.

Logger: homeassistant.config_entries
Source: components/freebox/__init__.py:57
First occurred: 16:07:30 (1 occurrences)
Last logged: 16:07:30

Error setting up entry xxxxx.fbxos.fr for freebox
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 339, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/usr/src/homeassistant/homeassistant/components/freebox/__init__.py", line 57, in async_setup_entry
    freebox_config = await api.system.get_config()
  File "/usr/local/lib/python3.9/site-packages/freebox_api/api/system.py", line 9, in get_config
    return await self._access.get("system/")
  File "/usr/local/lib/python3.9/site-packages/freebox_api/access.py", line 122, in get
    return await self._perform_request(self.session.get, end_url)
  File "/usr/local/lib/python3.9/site-packages/freebox_api/access.py", line 86, in _perform_request
    await self._refresh_session_token()
  File "/usr/local/lib/python3.9/site-packages/freebox_api/access.py", line 69, in _refresh_session_token
    session_token, session_permissions = await self._get_session_token(
  File "/usr/local/lib/python3.9/site-packages/freebox_api/access.py", line 45, in _get_session_token
    challenge = await self._get_challenge(base_url, timeout)
  File "/usr/local/lib/python3.9/site-packages/freebox_api/access.py", line 28, in _get_challenge
    r = await self.session.get(url, timeout=timeout)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 634, in _request
    break
  File "/usr/local/lib/python3.9/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
FredWst commented 2 years ago

Hi,

I've the same issue and can't connect to Freebox. in .storage/freebox/ file created with a token and so on, but plugin said not connected. One thing i must do to get approved screen on freebox is to validate acces from outside. :( Homeassistant is installed on Debian bullseye supervisor mode. My Freebox Delta is in bridge mode with pfsense and full ipv4 and ipv6 access. kxxxxxf.fbxos.fr return me ipv6 address of my box.

i've wrote in DZvent domoticz code witch is working fine without to get external access enable on the box.

I just use mafreebox.free.fr -> 212.27.38.253 as ip 443 port. let me show u code.

it works without expose freebox to external side.

Fred

-Freebox-Delta --local Freebox_ip = '192.168.5.1' local Freebox_ip ='212.27.38.253' local Freebox_app_id = 'fr.freebox.domoticz' local Freebox_app_name = 'Domoticz' local Freebox_app_version = '0.0.1' local Freebox_device_name = 'Serveur freebox'

local function hmac_sha1(challenge,app_token) --linux cmd = ("echo -n "..challenge.." | openssl dgst -sha1 -hmac "..app_token.." | cut -c10-200") --MacOs -- cmd = ("/bin/echo -n "..challenge.." | /usr/local/opt/openssl/bin/openssl dgst -sha1 -hmac "..app_token.." | cut -c10-200") f = assert(io.popen(cmd, 'r')) s = assert(f:read('*all')) f:close() return s:gsub("\n", "") end

local function round(num, dec) if num == 0 then return 0 else local mult = 10^(dec or 0) return math.floor(num * mult + 0.5) / mult end end

return { active = true, on = { devices = { 'Freebox reboot' }, timer = {'every minute'}, httpResponses = { 'authorize', 'granted', 'login', 'session', 'call', 'logout', 'loginreboot', 'sessionreboot', 'reboot' } }, data = { app_token = { initial = '' }, track_id = { initial = 0 }, session_token = { initial = '' } }, execute = function(domoticz, triggeredItem)

    if triggeredItem.isDevice then
        domoticz.devices('Freebox reboot').toggleSwitch().silent()
        domoticz.openURL({
                            url =  'http://'..Freebox_ip..'/api/v8/login/',
                            headers =  {
                                            ["Content-Type"] = "application/json",
                                            ["charset"] = "utf-8"
                                        },
                            method = 'GET',
                            callback = 'loginreboot'
                        })              
    elseif triggeredItem.isTimer then
        if domoticz.data.app_token == '' then
            domoticz.openURL({
                                url =  'http://'..Freebox_ip..'/api/v8/login/authorize/',
                                headers =  {
                                                ["Content-Type"] = "application/json",
                                                ["charset"] = "utf-8"
                                            },
                                method = 'POST',
                                callback = 'authorize',
                                postData = {
                                                app_id = Freebox_app_id,
                                                app_name = Freebox_app_name,
                                                app_version = Freebox_app_version,
                                                device_name = Freebox_device_name
                                            }
                            })   
        else
            domoticz.openURL({
                                url =  'http://'..Freebox_ip..'/api/v8/login/',
                                headers =  {
                                                ["Content-Type"] = "application/json",
                                                ["charset"] = "utf-8"
                                            },
                                method = 'GET',
                                callback = 'login'
                            })    
        end
    elseif triggeredItem.isHTTPResponse and triggeredItem.ok then
        if (triggeredItem.isJSON) then
            if triggeredItem.callback == 'authorize' then 
                domoticz.data.app_token = triggeredItem.json.result.app_token
                domoticz.data.track_id = triggeredItem.json.result.track_id
                domoticz.openURL({
                                        url =  'http://'..Freebox_ip..'/api/v8/login/authorize/'..domoticz.data.track_id,
                                        headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8"
                                                    },
                                        method = 'GET',
                                        callback = 'granted'
                                }).afterSec(10)          

            elseif triggeredItem.callback == 'granted' then
            elseif triggeredItem.callback == 'login' then 
                pwd = hmac_sha1(triggeredItem.json.result.challenge,domoticz.data.app_token)
                domoticz.openURL({
                                    url =  'http://'..Freebox_ip..'/api/v8/login/session/',
                                    headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8"
                                                },
                                    method = 'POST',
                                    callback = 'session',
                                    postData = {
                                        app_id = Freebox_app_id,
                                        password = pwd
                                    }
                                })
            elseif triggeredItem.callback == 'loginreboot' then 
                pwd = hmac_sha1(triggeredItem.json.result.challenge,domoticz.data.app_token)
                domoticz.openURL({
                                    url =  'http://'..Freebox_ip..'/api/v8/login/session/',
                                    headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8"
                                                },
                                    method = 'POST',
                                    callback = 'sessionreboot',
                                    postData = {
                                        app_id = Freebox_app_id,
                                        password = pwd
                                    }
                                }) 
            elseif triggeredItem.callback == 'session' then 
                domoticz.data.session_token = triggeredItem.json.result.session_token
                domoticz.openURL({
                                    url =  'http://'..Freebox_ip..'/api/v8/rrd/',
                                    headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8",
                                                        ["X-Fbx-App-Auth"] = domoticz.data.session_token
                                                },
                                    method = 'POST',
                                    callback = 'call',
                                    postData = {
                                                    db = "net",
                                                    fields = {"bw_up","bw_down","rate_up","rate_down"},
                                                    date_start = domoticz.time.dDate,
                                                    date_stop = domoticz.time.dDate,
                                                    precision = 1
                                    }
                                })
            elseif triggeredItem.callback == 'sessionreboot' then 
                domoticz.data.session_token = triggeredItem.json.result.session_token
                domoticz.openURL({
                                    url =  'http://'..Freebox_ip..'/api/v8/rrd/',
                                    headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8",
                                                        ["X-Fbx-App-Auth"] = domoticz.data.session_token
                                                },
                                    method = 'POST',
                                    callback = 'reboot'
                                })  
            elseif triggeredItem.callback == 'call' then  
                if triggeredItem.json.result  ~= nil then
                    domoticz.devices('Freebox up').updateCustomSensor(round(triggeredItem.json.result.data[1].bw_up/1000000,1))
                    domoticz.devices('Freebox down').updateCustomSensor(round(triggeredItem.json.result.data[1].bw_down/1000000,1))
                    domoticz.devices('Freebox rate up').updateCustomSensor(round(triggeredItem.json.result.data[1].rate_up/1000000,1))
                    domoticz.devices('Freebox rate down').updateCustomSensor(round(triggeredItem.json.result.data[1].rate_down/1000000,1))
                end
                domoticz.openURL({
                                    url =  'http://'..Freebox_ip..'/api/v8/login/logout/',
                                    headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8",
                                                        ["X-Fbx-App-Auth"] = domoticz.data.session_token
                                                },
                                    method = 'POST',
                                    callback = 'logout'
                                })
            elseif triggeredItem.callback == 'reboot' then  
                domoticz.openURL({
                                    url =  'http://'..Freebox_ip..'/api/v8/system/reboot/',
                                    headers =  {
                                                        ["Content-Type"] = "application/json",
                                                        ["charset"] = "utf-8",
                                                        ["X-Fbx-App-Auth"] = domoticz.data.session_token
                                                },
                                    method = 'POST',
                                    callback = 'logout'
                                })  
            elseif triggeredItem.callback == 'logout' then
            end
        end
    end

end }

Quentame commented 2 years ago

Hi all !

Can you fill this model to answer some questions regarding the issue ?

Your country: 
Freebox model: 
Freebox firmware version: 
Integration working before or new integration setup: before/new
Integration working since the creation of the issue: yes/no
Other notes: 

(you can copy it by hovering the block and click on the top right corner)

Thanks

Quentame commented 2 years ago

Comments that are not linked to this issue: @froggy974 : see #73631 and/or #69942 @FredWst : see #50954

I hided your comments as off topic.

Quentame commented 2 years ago

@jaroslawp : That's odd, you are having working hardware & firmware, I suppose there are some differences depending on countries. I'll fix that soon, but not sure it could go on 2022.10.x

jaroslawp commented 2 years ago

@jaroslawp : That's odd, you are having working hardware & firmware, I suppose there are some differences depending on countries. I'll fix that soon, but not sure it could go on 2022.10.x

Yes: it's kind of strange since all 4 drives are of same type .. anyway - I can confirm that just checking for not null 'fixes' the problem

Thanks!

Quentame commented 2 years ago

Fixed by #74718 on 2022.7.2