Skip to content

Commit 856794b

Browse files
authored
Fix Deco offline handling and hassfest translation validation (#506)
1 parent 3bc1b23 commit 856794b

5 files changed

Lines changed: 59 additions & 24 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ Two types of sensors are available:
3535
- **Smoothed** → averaged values over time (stable, ideal for dashboards)
3636

3737
**Use raw for:**
38+
3839
- debugging
3940
- real-time monitoring
4041

4142
**Use smoothed for:**
43+
4244
- dashboards
4345
- automations
4446
- trend analysis
@@ -50,6 +52,7 @@ Two types of sensors are available:
5052
#### Runtime control
5153

5254
- Pause / resume polling:
55+
5356
- `tplink_deco.pause_polling`
5457
- `tplink_deco.resume_polling`
5558

@@ -68,6 +71,7 @@ Adjustable polling interval:
6871
- 120 sec
6972

7073
Configurable:
74+
7175
- during setup
7276
- via Home Assistant UI (select entity)
7377

custom_components/tplink_deco/binary_sensor.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,18 @@ def __init__(
7373
self._attr_unique_id = f"{deco_mac}_internet_online"
7474

7575
@property
76-
def _deco(self) -> TpLinkDeco:
76+
def _deco(self) -> TpLinkDeco | None:
7777
"""Return current deco object."""
78-
return self.coordinator.data.decos[self._deco_mac]
78+
return self.coordinator.data.decos.get(self._deco_mac)
7979

8080
@property
8181
def is_on(self) -> bool:
8282
"""Return true if internet is online."""
83-
value = self._deco.internet_online
83+
deco = self._deco
84+
if deco is None:
85+
return False
86+
87+
value = deco.internet_online
8488

8589
if isinstance(value, str):
8690
return value.lower() in ("online", "true", "1", "yes")
@@ -89,13 +93,17 @@ def is_on(self) -> bool:
8993

9094
@property
9195
def available(self) -> bool:
92-
return self._deco is not None and self._deco.internet_online is not None
96+
return True
9397

9498
@property
9599
def device_info(self):
96100
"""Return device info."""
101+
deco = self._deco
102+
if deco is None:
103+
return None
104+
97105
return create_device_info(
98-
self._deco,
106+
deco,
99107
self.coordinator.data.master_deco,
100108
)
101109

@@ -114,19 +122,26 @@ def __init__(self, coordinator_decos, deco_mac):
114122

115123
@property
116124
def _deco(self):
117-
return self.coordinator.data.decos[self._deco_mac]
125+
return self.coordinator.data.decos.get(self._deco_mac)
118126

119127
@property
120128
def is_on(self):
121-
return bool(self._deco.online)
129+
deco = self._deco
130+
if deco is None:
131+
return False
132+
return bool(deco.online)
122133

123134
@property
124135
def available(self):
125-
return self._deco is not None
136+
return True
126137

127138
@property
128139
def device_info(self):
140+
deco = self._deco
141+
if deco is None:
142+
return None
143+
129144
return create_device_info(
130-
self._deco,
145+
deco,
131146
self.coordinator.data.master_deco,
132147
)

custom_components/tplink_deco/coordinator.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,16 @@ async def _async_update_data(self):
211211
if deco.master:
212212
master_deco = deco
213213

214+
for mac, old_deco in old_decos.items():
215+
if mac not in decos:
216+
_LOGGER.debug(
217+
"_async_update_data: Deco mac=%s not returned by API, marking offline",
218+
mac,
219+
)
220+
old_deco.online = False
221+
old_deco.internet_online = False
222+
decos[mac] = old_deco
223+
214224
# Zet globale performance data op de master Deco
215225
result = performance_data.get("result", {})
216226
if master_deco is not None:

custom_components/tplink_deco/strings.json

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
"config": {
33
"step": {
44
"user": {
5-
"description": "Use the credentials for the admin web portal. See documentation for more information",
5+
"description": "Use the credentials for the admin web portal. See the documentation for setup details.",
66
"data": {
77
"host": "[%key:common::config_flow::data::host%]",
88
"username": "[%key:common::config_flow::data::username%]",
99
"password": "[%key:common::config_flow::data::password%]",
10-
"interval_seconds": "Seconds between updates",
11-
"consider_home": "Seconds to wait till marking a device tracker as not home after not being seen.",
10+
"scan_interval": "Seconds between updates",
11+
"consider_home": "Seconds to wait before marking a device tracker as not home after it is no longer seen.",
1212
"timeout_seconds": "Timeout seconds",
1313
"timeout_error_retries": "Timeout error retry count",
1414
"verify_ssl": "Verify SSL certificate is valid",
@@ -19,7 +19,7 @@
1919
}
2020
},
2121
"reauth_confirm": {
22-
"description": "Problem with login credentials. Maybe caused by logging in on a separate device. See documentation for more information",
22+
"description": "Problem with login credentials. This may be caused by logging in on a separate device. See the documentation for login requirements.",
2323
"data": {
2424
"username": "[%key:common::config_flow::data::username%]",
2525
"password": "[%key:common::config_flow::data::password%]"
@@ -31,18 +31,21 @@
3131
"invalid_host": "[%key:common::config_flow::error::invalid_host%]",
3232
"timeout_connect": "[%key:common::config_flow::error::timeout_connect%]",
3333
"unknown": "[%key:common::config_flow::error::unknown%]"
34+
},
35+
"abort": {
36+
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
3437
}
3538
},
3639
"options": {
3740
"step": {
3841
"init": {
39-
"description": "Use the credentials for the admin web portal. See documentation for more information",
42+
"description": "Use the credentials for the admin web portal. See the documentation for setup details.",
4043
"data": {
4144
"host": "[%key:common::config_flow::data::host%]",
4245
"username": "[%key:common::config_flow::data::username%]",
4346
"password": "[%key:common::config_flow::data::password%]",
44-
"interval_seconds": "Seconds between updates",
45-
"consider_home": "Seconds to wait till marking a device tracker as not home after not being seen.",
47+
"scan_interval": "Seconds between updates",
48+
"consider_home": "Seconds to wait before marking a device tracker as not home after it is no longer seen.",
4649
"timeout_seconds": "Timeout seconds",
4750
"timeout_error_retries": "Timeout error retry count",
4851
"verify_ssl": "Verify SSL certificate is valid",

custom_components/tplink_deco/translations/en.json

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
"config": {
33
"step": {
44
"user": {
5-
"description": "Use the credentials for the admin web portal. See documentation for more information",
5+
"description": "Use the credentials for the admin web portal. See the documentation for setup details.",
66
"data": {
77
"host": "Host",
88
"username": "Username",
99
"password": "Password",
10-
"interval_seconds": "Seconds between updates",
11-
"consider_home": "Seconds to wait till marking a device tracker as not home after not being seen.",
10+
"scan_interval": "Seconds between updates",
11+
"consider_home": "Seconds to wait before marking a device tracker as not home after it is no longer seen.",
1212
"timeout_seconds": "Timeout seconds",
1313
"timeout_error_retries": "Timeout error retry count",
1414
"verify_ssl": "Verify SSL certificate is valid",
@@ -19,15 +19,15 @@
1919
}
2020
},
2121
"reauth_confirm": {
22-
"description": "Problem with login credentials. Maybe caused by logging in on a separate device. See documentation for more information.",
22+
"description": "Problem with login credentials. This may be caused by logging in on a separate device. See the documentation for login requirements.",
2323
"data": {
2424
"username": "Username",
2525
"password": "Password"
2626
}
2727
}
2828
},
2929
"abort": {
30-
"reauth_successful": "Reauth successful"
30+
"reauth_successful": "Reauthentication successful"
3131
},
3232
"error": {
3333
"invalid_auth": "Invalid authentication",
@@ -39,13 +39,13 @@
3939
"options": {
4040
"step": {
4141
"init": {
42-
"description": "Use the credentials for the admin web portal. See documentation for more information",
42+
"description": "Use the credentials for the admin web portal. See the documentation for setup details.",
4343
"data": {
4444
"host": "Host",
4545
"username": "Username",
4646
"password": "Password",
47-
"interval_seconds": "Seconds between updates",
48-
"consider_home": "Seconds to wait till marking a device tracker as not home after not being seen.",
47+
"scan_interval": "Seconds between updates",
48+
"consider_home": "Seconds to wait before marking a device tracker as not home after it is no longer seen.",
4949
"timeout_seconds": "Timeout seconds",
5050
"timeout_error_retries": "Timeout error retry count",
5151
"verify_ssl": "Verify SSL certificate is valid",
@@ -56,6 +56,9 @@
5656
}
5757
}
5858
},
59+
"abort": {
60+
"reauth_successful": "Reauthentication successful"
61+
},
5962
"error": {
6063
"invalid_auth": "Invalid authentication",
6164
"invalid_host": "Unable to connect to host.",

0 commit comments

Comments
 (0)