blueair-api 1.33.2__tar.gz → 1.34.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {blueair_api-1.33.2 → blueair_api-1.34.1}/PKG-INFO +3 -2
  2. {blueair_api-1.33.2 → blueair_api-1.34.1}/pyproject.toml +1 -1
  3. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/__init__.py +1 -1
  4. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/device.py +3 -1
  5. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/device_aws.py +8 -4
  6. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/http_aws_blueair.py +4 -4
  7. blueair_api-1.34.1/src/blueair_api/model_enum.py +13 -0
  8. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api.egg-info/PKG-INFO +3 -2
  9. {blueair_api-1.33.2 → blueair_api-1.34.1}/tests/test_device_aws.py +108 -0
  10. blueair_api-1.33.2/src/blueair_api/model_enum.py +0 -90
  11. {blueair_api-1.33.2 → blueair_api-1.34.1}/LICENSE +0 -0
  12. {blueair_api-1.33.2 → blueair_api-1.34.1}/README.md +0 -0
  13. {blueair_api-1.33.2 → blueair_api-1.34.1}/setup.cfg +0 -0
  14. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/callbacks.py +0 -0
  15. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/const.py +0 -0
  16. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/errors.py +0 -0
  17. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/http_blueair.py +0 -0
  18. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/intermediate_representation_aws.py +0 -0
  19. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/stub.py +0 -0
  20. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/util.py +0 -0
  21. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/util_bootstrap.py +0 -0
  22. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api/util_http.py +0 -0
  23. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api.egg-info/SOURCES.txt +0 -0
  24. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api.egg-info/dependency_links.txt +0 -0
  25. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api.egg-info/requires.txt +0 -0
  26. {blueair_api-1.33.2 → blueair_api-1.34.1}/src/blueair_api.egg-info/top_level.txt +0 -0
  27. {blueair_api-1.33.2 → blueair_api-1.34.1}/tests/test_intermediate_representation_aws.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: blueair_api
3
- Version: 1.33.2
3
+ Version: 1.34.1
4
4
  Summary: Blueair Api Wrapper
5
5
  Author-email: Brendan Dahl <dahl.brendan@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dahlb/blueair_api
@@ -17,6 +17,7 @@ Requires-Python: <4,>=3.12.0
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  Requires-Dist: aiohttp>=3.8.1
20
+ Dynamic: license-file
20
21
 
21
22
  [![GitHub Release][releases-shield]][releases]
22
23
  [![GitHub Activity][commits-shield]][commits]
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
8
8
 
9
9
  [project]
10
10
  name = "blueair_api"
11
- version = "1.33.2"
11
+ version = "1.34.1"
12
12
  authors = [
13
13
  { name="Brendan Dahl", email="dahl.brendan@gmail.com" },
14
14
  ]
@@ -4,4 +4,4 @@ from .http_aws_blueair import HttpAwsBlueair
4
4
  from .util_bootstrap import get_devices, get_aws_devices
5
5
  from .device import Device
6
6
  from .device_aws import DeviceAws
7
- from .model_enum import ModelEnum, FeatureEnum
7
+ from .model_enum import ModelEnum
@@ -1,3 +1,5 @@
1
+ from typing import Any
2
+
1
3
  from .callbacks import CallbacksMixin
2
4
  from .http_blueair import HttpBlueair
3
5
  from .util import transform_data_points, safely_get_json_value, convert_none_to_not_implemented
@@ -32,7 +34,7 @@ class Device(CallbacksMixin):
32
34
  return device
33
35
 
34
36
  api: HttpBlueair = field(repr=False)
35
- raw_info : dict[str: any] = field(repr=False, init=False)
37
+ raw_info: dict[str, Any] = field(repr=False, init=False)
36
38
 
37
39
  uuid: str | None = None
38
40
  name: str | None = None
@@ -1,4 +1,6 @@
1
- import logging
1
+ from typing import Any
2
+
3
+ from logging import getLogger
2
4
  from json import dumps
3
5
 
4
6
  from .callbacks import CallbacksMixin
@@ -7,7 +9,7 @@ from .model_enum import ModelEnum
7
9
  from . import intermediate_representation_aws as ir
8
10
  from dataclasses import dataclass, field
9
11
 
10
- _LOGGER = logging.getLogger(__name__)
12
+ _LOGGER = getLogger(__name__)
11
13
 
12
14
  type AttributeType[T] = T | None
13
15
 
@@ -29,7 +31,7 @@ class DeviceAws(CallbacksMixin):
29
31
  return device_aws
30
32
 
31
33
  api: HttpAwsBlueair = field(repr=False)
32
- raw_info : dict[str: any] = field(repr=False, init=False)
34
+ raw_info : dict[str, Any] = field(repr=False, init=False)
33
35
 
34
36
  uuid : str | None = None
35
37
  name : str | None = None
@@ -241,10 +243,12 @@ class DeviceAws(CallbacksMixin):
241
243
  return ModelEnum.PROTECT_7470I
242
244
  if self.sku == "110059":
243
245
  return ModelEnum.MAX_211I
244
- if self.sku == "110092":
246
+ if self.sku in ["110092", "110829"]:
245
247
  return ModelEnum.MAX_311I
246
248
  if self.sku == "110057":
247
249
  return ModelEnum.MAX_411I
248
250
  if self.sku == "112124":
249
251
  return ModelEnum.T10I
252
+ if self.sku == "109539":
253
+ return ModelEnum.MAX_311I_PLUS
250
254
  return ModelEnum.UNKNOWN
@@ -1,14 +1,14 @@
1
- from typing import Any
2
1
  import functools
3
- import logging
4
2
 
3
+ from logging import getLogger
4
+ from typing import Any
5
5
  from aiohttp import ClientSession, ClientResponse, FormData
6
- from .const import AWS_APIKEYS
7
6
 
7
+ from .const import AWS_APIKEYS
8
8
  from .util_http import request_with_logging
9
9
  from .errors import SessionError, LoginError
10
10
 
11
- _LOGGER = logging.getLogger(__name__)
11
+ _LOGGER = getLogger(__name__)
12
12
 
13
13
 
14
14
  def request_with_active_session(func):
@@ -0,0 +1,13 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class ModelEnum(StrEnum):
5
+ UNKNOWN = "Unknown"
6
+ HUMIDIFIER_H35I = "Blueair Humidifier H35i"
7
+ PROTECT_7440I = "Blueair Protect 7440i"
8
+ PROTECT_7470I = "Blueair Protect 7470i"
9
+ MAX_211I = "Blueair Blue Pure 211i Max"
10
+ MAX_311I = "Blueair Blue Pure 311i Max"
11
+ MAX_311I_PLUS = "Blueair Blue Pure 311i+ Max"
12
+ MAX_411I = "Blueair Blue Pure 411i Max"
13
+ T10I = "T10i ComfortPure 3-in-1 Filter/Heater/Fan"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: blueair_api
3
- Version: 1.33.2
3
+ Version: 1.34.1
4
4
  Summary: Blueair Api Wrapper
5
5
  Author-email: Brendan Dahl <dahl.brendan@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dahlb/blueair_api
@@ -17,6 +17,7 @@ Requires-Python: <4,>=3.12.0
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  Requires-Dist: aiohttp>=3.8.1
20
+ Dynamic: license-file
20
21
 
21
22
  [![GitHub Release][releases-shield]][releases]
22
23
  [![GitHub Activity][commits-shield]][commits]
@@ -440,6 +440,60 @@ class H35iTest(DeviceAwsTestBase):
440
440
  assert device.fan_speed_0 is NotImplemented
441
441
  assert device.temperature_unit is NotImplemented
442
442
 
443
+
444
+ class Max311iTest(DeviceAwsTestBase):
445
+ """Tests for H35i."""
446
+
447
+ def setUp(self):
448
+ super().setUp()
449
+ with open(resources.files().joinpath('device_info/max_311i.json')) as sample_file:
450
+ info = json.load(sample_file)
451
+ self.device_info_helper.info.update(info)
452
+
453
+ async def test_attributes(self):
454
+ await self.device.refresh()
455
+ self.api.device_info.assert_awaited_with("fake-name-api", "fake-uuid")
456
+
457
+ with assert_fully_checked(self.device) as device:
458
+
459
+ assert device.model == ModelEnum.MAX_311I
460
+
461
+ assert device.pm1 is NotImplemented
462
+ assert device.pm2_5 == 0
463
+ assert device.pm10 is NotImplemented
464
+ assert device.tVOC is NotImplemented
465
+ assert device.temperature is NotImplemented
466
+ assert device.humidity is NotImplemented
467
+ assert device.name == "Loft"
468
+ assert device.firmware == "1.0.4"
469
+ assert device.mcu_firmware == "1.0.4"
470
+ assert device.serial_number == "111082900302313210005018"
471
+ assert device.sku == "110829"
472
+
473
+ assert device.standby is False
474
+ assert device.night_mode is False
475
+ assert device.germ_shield is NotImplemented
476
+ assert device.brightness == 35
477
+ assert device.child_lock is True
478
+ assert device.fan_speed == 11
479
+ assert device.fan_auto_mode is True
480
+ assert device.filter_usage_percentage == 12
481
+ assert device.wifi_working is True
482
+ assert device.wick_usage_percentage is NotImplemented
483
+ assert device.auto_regulated_humidity is NotImplemented
484
+ assert device.water_shortage is NotImplemented
485
+ assert device.wick_dry_mode is NotImplemented
486
+ assert device.main_mode is NotImplemented
487
+ assert device.ap_sub_mode is NotImplemented
488
+ assert device.heat_temp is NotImplemented
489
+ assert device.heat_sub_mode is NotImplemented
490
+ assert device.heat_fan_speed is NotImplemented
491
+ assert device.cool_sub_mode is NotImplemented
492
+ assert device.cool_fan_speed is NotImplemented
493
+ assert device.fan_speed_0 is NotImplemented
494
+ assert device.temperature_unit is NotImplemented
495
+
496
+
443
497
  class T10iTest(DeviceAwsTestBase):
444
498
  """Tests for T10i."""
445
499
 
@@ -546,3 +600,57 @@ class Protect7470iTest(DeviceAwsTestBase):
546
600
  assert device.ap_sub_mode is NotImplemented
547
601
  assert device.fan_speed_0 is NotImplemented
548
602
  assert device.temperature_unit is NotImplemented
603
+
604
+
605
+ class Max211iTest(DeviceAwsTestBase):
606
+ """Tests for Max 211i."""
607
+
608
+ def setUp(self):
609
+ super().setUp()
610
+ with open(resources.files().joinpath('device_info/max_211i.json')) as sample_file:
611
+ info = json.load(sample_file)
612
+ self.device_info_helper.info.update(info)
613
+
614
+ async def test_attributes(self):
615
+
616
+ await self.device.refresh()
617
+ self.api.device_info.assert_awaited_with("fake-name-api", "fake-uuid")
618
+
619
+ with assert_fully_checked(self.device) as device:
620
+
621
+ assert device.model == ModelEnum.MAX_211I
622
+
623
+ assert device.pm1 == 0
624
+ assert device.pm2_5 == 0
625
+ assert device.pm10 == 0
626
+ assert device.tVOC is NotImplemented
627
+ assert device.temperature is NotImplemented
628
+ assert device.humidity is NotImplemented
629
+ assert device.name == "Bedroom Purifier"
630
+ assert device.firmware == "1.1.6"
631
+ assert device.mcu_firmware == "1.1.6"
632
+ assert device.serial_number == "111005900201111210085956"
633
+ assert device.sku == "110059"
634
+
635
+ assert device.standby is False
636
+ assert device.night_mode is False
637
+ assert device.germ_shield is NotImplemented
638
+ assert device.brightness == 0
639
+ assert device.child_lock is False
640
+ assert device.fan_speed == 15
641
+ assert device.fan_auto_mode is False
642
+ assert device.filter_usage_percentage == 55
643
+ assert device.wifi_working is True
644
+ assert device.wick_usage_percentage is NotImplemented
645
+ assert device.auto_regulated_humidity is NotImplemented
646
+ assert device.water_shortage is NotImplemented
647
+ assert device.wick_dry_mode is NotImplemented
648
+ assert device.main_mode is NotImplemented
649
+ assert device.heat_temp is NotImplemented
650
+ assert device.heat_sub_mode is NotImplemented
651
+ assert device.heat_fan_speed is NotImplemented
652
+ assert device.cool_sub_mode is NotImplemented
653
+ assert device.cool_fan_speed is NotImplemented
654
+ assert device.ap_sub_mode is NotImplemented
655
+ assert device.fan_speed_0 is NotImplemented
656
+ assert device.temperature_unit is NotImplemented
@@ -1,90 +0,0 @@
1
- from enum import Enum, StrEnum
2
-
3
-
4
- class FeatureEnum(StrEnum):
5
- TEMPERATURE = "Temperature"
6
- HUMIDITY = "Humidity"
7
- VOC = "VOC"
8
- PM1 = "PM1"
9
- PM10 = "PM10"
10
- PM25 = "PM25"
11
- WATER_SHORTAGE = "Water Shortage"
12
- FILTER_EXPIRED = "Filter Expired"
13
- CHILD_LOCK = "Child Lock"
14
-
15
-
16
- class ModelEnum(Enum):
17
- def __new__(cls, *args, **kwds):
18
- value = len(cls.__members__) + 1
19
- obj = object.__new__(cls)
20
- obj._value_ = value
21
- return obj
22
-
23
- def __init__(self,
24
- name,
25
- supported_features):
26
- self.model_name = name
27
- self.supported_features = supported_features
28
-
29
- def supports_feature(self, supported_features) -> bool:
30
- return supported_features in self.supported_features
31
-
32
- UNKNOWN = "Unknown", [
33
- FeatureEnum.TEMPERATURE,
34
- FeatureEnum.HUMIDITY,
35
- FeatureEnum.WATER_SHORTAGE,
36
- FeatureEnum.VOC,
37
- FeatureEnum.PM1,
38
- FeatureEnum.PM10,
39
- FeatureEnum.PM25,
40
- FeatureEnum.FILTER_EXPIRED,
41
- FeatureEnum.CHILD_LOCK,
42
- ]
43
- HUMIDIFIER_H35I = "Blueair Humidifier H35i", [
44
- FeatureEnum.TEMPERATURE,
45
- FeatureEnum.HUMIDITY,
46
- FeatureEnum.WATER_SHORTAGE,
47
- ]
48
- PROTECT_7440I = "Blueair Protect 7440i", [
49
- FeatureEnum.TEMPERATURE,
50
- FeatureEnum.HUMIDITY,
51
- FeatureEnum.VOC,
52
- FeatureEnum.PM1,
53
- FeatureEnum.PM10,
54
- FeatureEnum.PM25,
55
- FeatureEnum.FILTER_EXPIRED,
56
- FeatureEnum.CHILD_LOCK,
57
- ]
58
- PROTECT_7470I = "Blueair Protect 7470i", [
59
- FeatureEnum.TEMPERATURE,
60
- FeatureEnum.HUMIDITY,
61
- FeatureEnum.VOC,
62
- FeatureEnum.PM1,
63
- FeatureEnum.PM10,
64
- FeatureEnum.PM25,
65
- FeatureEnum.FILTER_EXPIRED,
66
- FeatureEnum.CHILD_LOCK,
67
- ]
68
- MAX_211I = "Blueair Blue Pure 211i Max", [
69
- FeatureEnum.PM1,
70
- FeatureEnum.PM10,
71
- FeatureEnum.PM25,
72
- FeatureEnum.FILTER_EXPIRED,
73
- FeatureEnum.CHILD_LOCK,
74
- ]
75
- MAX_311I = "Blueair Blue Pure 311i Max", [
76
- FeatureEnum.PM25,
77
- FeatureEnum.FILTER_EXPIRED,
78
- FeatureEnum.CHILD_LOCK,
79
- ]
80
- MAX_411I = "Blueair Blue Pure 411i Max", [
81
- FeatureEnum.PM25,
82
- FeatureEnum.FILTER_EXPIRED,
83
- FeatureEnum.CHILD_LOCK,
84
- ]
85
- T10I = "T10i ComfortPure 3-in-1 Filter/Heater/Fan", [
86
- FeatureEnum.TEMPERATURE,
87
- FeatureEnum.HUMIDITY,
88
- FeatureEnum.PM25,
89
- FeatureEnum.FILTER_EXPIRED,
90
- ]
File without changes
File without changes
File without changes