Skip to content
This repository was archived by the owner on Dec 4, 2020. It is now read-only.

Commit 55870eb

Browse files
committed
Merge branch 'release/v3.3.1'
2 parents 1364bf2 + 6c8f92c commit 55870eb

13 files changed

Lines changed: 470 additions & 223 deletions

Pipfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ black = "*"
1010
mypy = "*"
1111
flake8 = "*"
1212
pylint = "*"
13-
docutils = "==0.14"
13+
docutils = "*"
14+
bleach = ">=3.1.4"
1415
pytest-mock = "*"
1516
pytest-cov = "*"
1617
requests-mock = "*"

Pipfile.lock

Lines changed: 178 additions & 185 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/weatherstation_data_simple.json

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,196 @@
269269
}
270270
}
271271
]
272+
},
273+
{
274+
"_id": "12:34:56:32:a7:60",
275+
"station_name": "Ateljen",
276+
"date_setup": 1566714693,
277+
"last_setup": 1566714693,
278+
"type": "NAMain",
279+
"last_status_store": 1588481079,
280+
"module_name": "Indoor",
281+
"firmware": 177,
282+
"last_upgrade": 1566714694,
283+
"wifi_status": 50,
284+
"reachable": true,
285+
"co2_calibrating": false,
286+
"data_type": [
287+
"Temperature",
288+
"CO2",
289+
"Humidity",
290+
"Noise",
291+
"Pressure"
292+
],
293+
"place": {
294+
"altitude": 93,
295+
"city": "Gothenburg",
296+
"country": "SE",
297+
"timezone": "Europe/Stockholm",
298+
"location": [
299+
11.6136629,
300+
57.7006827
301+
]
302+
},
303+
"dashboard_data": {
304+
"time_utc": 1588481073,
305+
"Temperature": 18.2,
306+
"CO2": 542,
307+
"Humidity": 45,
308+
"Noise": 45,
309+
"Pressure": 1013,
310+
"AbsolutePressure": 1001.9,
311+
"min_temp": 18.2,
312+
"max_temp": 19.5,
313+
"date_max_temp": 1588456861,
314+
"date_min_temp": 1588479561,
315+
"temp_trend": "stable",
316+
"pressure_trend": "up"
317+
},
318+
"modules": [
319+
{
320+
"_id": "12:34:56:32:db:06",
321+
"type": "NAModule1",
322+
"last_setup": 1587635819,
323+
"data_type": [
324+
"Temperature",
325+
"Humidity"
326+
],
327+
"battery_percent": 100,
328+
"reachable": false,
329+
"firmware": 255,
330+
"last_message": 0,
331+
"last_seen": 0,
332+
"rf_status": 255,
333+
"battery_vp": 65535
334+
}
335+
]
336+
},
337+
{
338+
"_id": "12:34:56:1c:68:2e",
339+
"station_name": "Bol\u00e5s",
340+
"date_setup": 1470935400,
341+
"last_setup": 1470935400,
342+
"type": "NAMain",
343+
"last_status_store": 1588481399,
344+
"module_name": "Inne - Nere",
345+
"firmware": 177,
346+
"last_upgrade": 1470935401,
347+
"wifi_status": 13,
348+
"reachable": true,
349+
"co2_calibrating": false,
350+
"data_type": [
351+
"Temperature",
352+
"CO2",
353+
"Humidity",
354+
"Noise",
355+
"Pressure"
356+
],
357+
"place": {
358+
"altitude": 93,
359+
"city": "Gothenburg",
360+
"country": "SE",
361+
"timezone": "Europe/Stockholm",
362+
"location": [
363+
11.6136629,
364+
57.7006827
365+
]
366+
},
367+
"dashboard_data": {
368+
"time_utc": 1588481387,
369+
"Temperature": 20.8,
370+
"CO2": 674,
371+
"Humidity": 41,
372+
"Noise": 34,
373+
"Pressure": 1012.1,
374+
"AbsolutePressure": 1001,
375+
"min_temp": 20.8,
376+
"max_temp": 22.2,
377+
"date_max_temp": 1588456859,
378+
"date_min_temp": 1588480176,
379+
"temp_trend": "stable",
380+
"pressure_trend": "up"
381+
},
382+
"modules": [
383+
{
384+
"_id": "12:34:56:02:b3:da",
385+
"type": "NAModule3",
386+
"module_name": "Regnm\u00e4tare",
387+
"last_setup": 1470937706,
388+
"data_type": [
389+
"Rain"
390+
],
391+
"battery_percent": 81,
392+
"reachable": true,
393+
"firmware": 12,
394+
"last_message": 1588481393,
395+
"last_seen": 1588481386,
396+
"rf_status": 67,
397+
"battery_vp": 5582,
398+
"dashboard_data": {
399+
"time_utc": 1588481386,
400+
"Rain": 0,
401+
"sum_rain_1": 0,
402+
"sum_rain_24": 0.1
403+
}
404+
},
405+
{
406+
"_id": "12:34:56:03:76:60",
407+
"type": "NAModule4",
408+
"module_name": "Inne - Uppe",
409+
"last_setup": 1470938089,
410+
"data_type": [
411+
"Temperature",
412+
"CO2",
413+
"Humidity"
414+
],
415+
"battery_percent": 14,
416+
"reachable": true,
417+
"firmware": 50,
418+
"last_message": 1588481393,
419+
"last_seen": 1588481374,
420+
"rf_status": 70,
421+
"battery_vp": 4448,
422+
"dashboard_data": {
423+
"time_utc": 1588481374,
424+
"Temperature": 19.6,
425+
"CO2": 696,
426+
"Humidity": 41,
427+
"min_temp": 19.6,
428+
"max_temp": 20.5,
429+
"date_max_temp": 1588456817,
430+
"date_min_temp": 1588481374,
431+
"temp_trend": "stable"
432+
}
433+
},
434+
{
435+
"_id": "12:34:56:32:db:06",
436+
"type": "NAModule1",
437+
"module_name": "Ute",
438+
"last_setup": 1566326027,
439+
"data_type": [
440+
"Temperature",
441+
"Humidity"
442+
],
443+
"battery_percent": 81,
444+
"reachable": true,
445+
"firmware": 50,
446+
"last_message": 1588481393,
447+
"last_seen": 1588481380,
448+
"rf_status": 61,
449+
"battery_vp": 5544,
450+
"dashboard_data": {
451+
"time_utc": 1588481380,
452+
"Temperature": 6.4,
453+
"Humidity": 91,
454+
"min_temp": 3.6,
455+
"max_temp": 6.4,
456+
"date_max_temp": 1588481380,
457+
"date_min_temp": 1588471383,
458+
"temp_trend": "up"
459+
}
460+
}
461+
]
272462
}
273463
],
274464
"user": {

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="pyatmo",
8-
version="3.3.0", # Should be updated with new versions
8+
version="3.3.1", # Should be updated with new versions
99
author="Hugo Dupras",
1010
author_email="jabesq@gmail.com",
1111
packages=find_packages(exclude=["tests"], where="src"),

src/pyatmo/__main__.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from .auth import ClientAuth
2-
from .camera import CameraData
3-
from .exceptions import NoDevice
4-
from .public_data import PublicData
5-
from .thermostat import HomeData
6-
from .weather_station import WeatherStationData
1+
from pyatmo.auth import ALL_SCOPES, ClientAuth
2+
from pyatmo.camera import CameraData
3+
from pyatmo.exceptions import NoDevice
4+
from pyatmo.public_data import PublicData
5+
from pyatmo.thermostat import HomeData
6+
from pyatmo.weather_station import WeatherStationData
77

88

99
def main():
@@ -33,11 +33,7 @@ def main():
3333
clientSecret=CLIENT_SECRET,
3434
username=USERNAME,
3535
password=PASSWORD,
36-
scope=(
37-
"read_station read_camera access_camera read_thermostat "
38-
"write_thermostat read_presence access_presence read_homecoach "
39-
"read_smokedetector"
40-
),
36+
scope=" ".join(ALL_SCOPES),
4137
)
4238

4339
try:

src/pyatmo/auth.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from json import JSONDecodeError
23
from time import sleep
34
from typing import Callable, Dict, Optional, Tuple, Union
45

@@ -114,6 +115,10 @@ def post_request(
114115
resp = requests.post(url, data=params, timeout=timeout)
115116
except requests.exceptions.ChunkedEncodingError:
116117
LOG.debug("Encoding error when connecting to '%s'", url)
118+
except requests.exceptions.ConnectTimeout:
119+
LOG.debug("Connection to %s timed out", url)
120+
except requests.exceptions.ConnectionError:
121+
LOG.debug("Remote end closed connection without response (%s)", url)
117122
else:
118123

119124
def query(url, params, timeout, retries):
@@ -147,18 +152,18 @@ def query(url, params, timeout, retries):
147152
elif not resp.ok:
148153
LOG.debug("The Netatmo API returned %s", resp.status_code)
149154
LOG.debug("Netato API error: %s", resp.content)
150-
if resp.status_code == 404:
155+
try:
151156
raise ApiError(
152157
f"{resp.status_code} - "
153-
f"{ERRORS[resp.status_code]} - "
158+
f"{ERRORS.get(resp.status_code, '')} - "
159+
f"{resp.json()['error']['message']} "
160+
f"({resp.json()['error']['code']}) "
154161
f"when accessing '{url}'"
155162
)
156-
else:
163+
except JSONDecodeError:
157164
raise ApiError(
158165
f"{resp.status_code} - "
159-
f"{ERRORS[resp.status_code]} - "
160-
f"{resp.json()['error']['message']} "
161-
f"({resp.json()['error']['code']}) "
166+
f"{ERRORS.get(resp.status_code, '')} - "
162167
f"when accessing '{url}'"
163168
)
164169

@@ -168,7 +173,7 @@ def query(url, params, timeout, retries):
168173
if "application/json" in resp.headers.get("content-type")
169174
else resp.content
170175
)
171-
except TypeError:
176+
except (TypeError, AttributeError):
172177
LOG.debug("Invalid response %s", resp)
173178
return None
174179

src/pyatmo/camera.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ def set_state(
804804
Arguments:
805805
camera_id {str} -- ID of a camera
806806
home_id {str} -- ID of a home
807-
floodlight {str} -- Mode for floodlight (on/auto)
807+
floodlight {str} -- Mode for floodlight (on/off/auto)
808808
monitoring {str} -- Mode for monitoring (on/off)
809809
810810
Returns:
@@ -817,8 +817,8 @@ def set_state(
817817

818818
if floodlight:
819819
param, val = "floodlight", floodlight.lower()
820-
if val not in ["on", "auto"]:
821-
LOG.error("Invalid value für floodlight")
820+
if val not in ["on", "off", "auto"]:
821+
LOG.error("Invalid value for floodlight")
822822
else:
823823
module[param] = val
824824

src/pyatmo/helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
404: "Not found",
1515
406: "Not Acceptable",
1616
500: "Internal Server Error",
17+
502: "Bad Gateway",
18+
503: "Service Unavailable",
1719
}
1820

1921

src/pyatmo/thermostat.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,12 @@ def switch_home_schedule(self, schedule_id: str, home_id: str) -> bool:
172172

173173

174174
class HomeStatus:
175-
def __init__(self, authData, home_id=None, home=None):
175+
def __init__(self, authData, home_data=None, home_id=None, home=None):
176176
self.authData = authData
177-
self.home_data = HomeData(authData)
177+
if home_data is None:
178+
self.home_data = HomeData(authData)
179+
else:
180+
self.home_data = home_data
178181

179182
if home_id is not None:
180183
self.home_id = home_id
@@ -316,7 +319,7 @@ def measuredTemperature(self, rid=None):
316319
temperature = None
317320
room_data = self.roomById(rid=rid)
318321
if room_data:
319-
temperature = room_data["therm_measured_temperature"]
322+
temperature = room_data.get("therm_measured_temperature")
320323
return temperature
321324

322325
def boilerStatus(self, rid=None):

src/pyatmo/weather_station.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ def modulesNamesList(self, station=None, station_id=None):
5555
elif station is not None:
5656
station_data = self.stationByName(station)
5757
if station_data is not None:
58-
res.add(station_data["module_name"])
58+
res.add(station_data.get("module_name", station_data.get("type")))
5959
for m in station_data["modules"]:
60-
res.add(m["module_name"])
60+
res.add(m.get("module_name", m.get("type")))
6161
else:
6262
res.update([m["module_name"] for m in self.modules.values()])
6363
for s in self.stations.values():
64-
res.add(s.get("module_name", "Station"))
64+
res.add(s.get("module_name", s.get("type")))
6565
return list(res)
6666

6767
def getModules(self, station=None, station_id=None):
@@ -79,14 +79,14 @@ def getModules(self, station=None, station_id=None):
7979
for s in stations:
8080
res[s["_id"]] = {
8181
"station_name": s["station_name"],
82-
"module_name": s.get("module_name", "Station"),
82+
"module_name": s.get("module_name", s.get("type")),
8383
"id": s["_id"],
8484
}
8585

8686
for m in s["modules"]:
8787
res[m["_id"]] = {
8888
"station_name": m.get("station_name", s["station_name"]),
89-
"module_name": m["module_name"],
89+
"module_name": m.get("module_name", m.get("type")),
9090
"id": m["_id"],
9191
}
9292
return res

0 commit comments

Comments
 (0)