python-aidot 0.3.54b3__tar.gz → 0.3.54b4__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 (22) hide show
  1. {python_aidot-0.3.54b3/python_aidot.egg-info → python_aidot-0.3.54b4}/PKG-INFO +1 -1
  2. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/discover.py +2 -2
  3. python_aidot-0.3.54b4/aidot/models/__init__.py +37 -0
  4. python_aidot-0.3.54b4/aidot/models/device_client_model.py +210 -0
  5. python_aidot-0.3.54b4/aidot/models/device_model.py +83 -0
  6. python_aidot-0.3.54b4/aidot/models/discover_model.py +102 -0
  7. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4/python_aidot.egg-info}/PKG-INFO +1 -1
  8. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/python_aidot.egg-info/SOURCES.txt +4 -0
  9. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/setup.py +1 -1
  10. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/LICENSE +0 -0
  11. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/README.md +0 -0
  12. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/__init__.py +0 -0
  13. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/aes_utils.py +0 -0
  14. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/client.py +0 -0
  15. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/const.py +0 -0
  16. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/device_client.py +0 -0
  17. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/exceptions.py +0 -0
  18. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/aidot/login_const.py +0 -0
  19. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/python_aidot.egg-info/dependency_links.txt +0 -0
  20. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/python_aidot.egg-info/requires.txt +0 -0
  21. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/python_aidot.egg-info/top_level.txt +0 -0
  22. {python_aidot-0.3.54b3 → python_aidot-0.3.54b4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot
3
- Version: 0.3.54b3
3
+ Version: 0.3.54b4
4
4
  Summary: aidot control wifi lights
5
5
  Home-page: https://github.com/Aidot-Development-Team/python-aidot
6
6
  Author: aidotdev2024
@@ -35,7 +35,7 @@ class BroadcastProtocol:
35
35
  try:
36
36
  request = DiscoverRequest.from_params(userId=self.user_id)
37
37
  message = request.to_dict()
38
- _LOGGER.info(f"send_broadcast {message}")
38
+ _LOGGER.warning(f"send_broadcast {message}")
39
39
  send_data = aes_encrypt(json.dumps(message).encode(), self.aes_key)
40
40
  self.transport.sendto(send_data, ("255.255.255.255", 6666))
41
41
  except Exception as error:
@@ -46,7 +46,7 @@ class BroadcastProtocol:
46
46
  data_str = aes_decrypt(data, self.aes_key)
47
47
  data_json = json.loads(data_str)
48
48
  response = DiscoverResponse.from_json(data=data_json)
49
- _LOGGER.info(f"datagram_received {data_json}")
49
+ _LOGGER.warning(f"datagram_received {data_json}")
50
50
  if response.payload and response.payload.devId and self._discover_cb:
51
51
  self._discover_cb(response.payload.devId, {CONF_IPADDRESS: addr[0]})
52
52
  except Exception as error:
@@ -0,0 +1,37 @@
1
+ """Models for AiDot."""
2
+
3
+ from .device_client_model import (
4
+ DeviceAck,
5
+ DeviceAttr,
6
+ DeviceAttrPayload,
7
+ DeviceResponse,
8
+ DeviceActionPayload,
9
+ DeviceActionRequest,
10
+ LoginPayload,
11
+ LoginRequest,
12
+ PingRequest,
13
+ PingResponse,
14
+ )
15
+ from .device_model import (
16
+ DeviceFading,
17
+ DeviceProperties,
18
+ DeviceProduct,
19
+ DeviceInformation,
20
+ )
21
+
22
+ __all__ = [
23
+ "DeviceAck",
24
+ "DeviceAttr",
25
+ "DeviceAttrPayload",
26
+ "DeviceResponse",
27
+ "DeviceActionPayload",
28
+ "DeviceActionRequest",
29
+ "LoginPayload",
30
+ "LoginRequest",
31
+ "PingRequest",
32
+ "PingResponse",
33
+ "DeviceFading",
34
+ "DeviceProperties",
35
+ "DeviceProduct",
36
+ "DeviceInformation",
37
+ ]
@@ -0,0 +1,210 @@
1
+ """Models for AiDot device client."""
2
+
3
+ from dataclasses import dataclass, asdict, field
4
+ from typing import Any, Optional
5
+
6
+ from dacite import Config, from_dict
7
+
8
+
9
+ @dataclass
10
+ class PingRequest:
11
+ """Ping request (heartbeat)."""
12
+
13
+ service: str = "test"
14
+ method: str = "pingreq"
15
+ seq: str = "123456"
16
+ srcAddr: str = "123456"
17
+ payload: dict[str, Any] = field(default_factory=dict)
18
+
19
+ def to_dict(self) -> dict[str, Any]:
20
+ """Convert to dictionary."""
21
+ return asdict(self)
22
+
23
+
24
+ @dataclass
25
+ class PingResponse:
26
+ """Ping response."""
27
+
28
+ service: str = None
29
+ method: str = None
30
+ seq: str = None
31
+ srcAddr: str = None
32
+ payload: dict[str, Any] = None
33
+
34
+ @staticmethod
35
+ def from_json(data: dict[str, Any]) -> "PingResponse":
36
+ """Create PingResponse from JSON dict."""
37
+ return from_dict(
38
+ data_class=PingResponse, data=data, config=Config(check_types=False)
39
+ )
40
+
41
+ def to_dict(self) -> dict[str, Any]:
42
+ """Convert to dictionary."""
43
+ return asdict(self)
44
+
45
+
46
+ @dataclass
47
+ class LoginPayload:
48
+ """Login request payload."""
49
+
50
+ userId: str = None
51
+ password: str = None
52
+ timestamp: str = field(default=None)
53
+ ascNumber: int = 1
54
+
55
+ def __post_init__(self):
56
+ """Auto-generate timestamp if not provided."""
57
+ if self.timestamp is None:
58
+ from datetime import datetime
59
+ self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
60
+
61
+
62
+ @dataclass
63
+ class LoginRequest:
64
+ """Login request."""
65
+
66
+ service: str = "device"
67
+ method: str = "loginReq"
68
+ seq: str = None
69
+ srcAddr: str = None
70
+ deviceId: str = None
71
+ payload: LoginPayload = None
72
+
73
+ def to_dict(self) -> dict[str, Any]:
74
+ """Convert to dictionary."""
75
+ return asdict(self)
76
+
77
+ @dataclass
78
+ class DeviceAck:
79
+ """Device response ack."""
80
+
81
+ code: int = 0
82
+ tst: str = ""
83
+
84
+
85
+ @dataclass
86
+ class DeviceAttr:
87
+ """Device attribute."""
88
+
89
+ OnOff: int = None
90
+ Dimming: int = None
91
+ RGBW: int = None
92
+ CCT: int = None
93
+
94
+
95
+ @dataclass
96
+ class DeviceAttrPayload:
97
+ """Device payload."""
98
+
99
+ devId: str = ""
100
+ parentId: str = ""
101
+ userId: str = ""
102
+ password: str = ""
103
+ timestamp: str = ""
104
+ channel: str = ""
105
+ ascNumber: int = 0
106
+ attr: Optional[DeviceAttr] = None
107
+
108
+
109
+ @dataclass
110
+ class DeviceResponse:
111
+ """Generic device response."""
112
+
113
+ service: str = ""
114
+ method: str = ""
115
+ seq: str = ""
116
+ srcAddr: str = ""
117
+ deviceId: str = ""
118
+ clientId: str = ""
119
+ payload: DeviceAttrPayload = field(default_factory=DeviceAttrPayload)
120
+ ack: DeviceAck = field(default_factory=DeviceAck)
121
+ tst: int = 0
122
+
123
+ @staticmethod
124
+ def from_json(data: dict[str, Any]) -> "DeviceResponse":
125
+ """Create DeviceResponse from JSON dict."""
126
+ return from_dict(
127
+ data_class=DeviceResponse, data=data, config=Config(check_types=False)
128
+ )
129
+
130
+ def to_dict(self) -> dict[str, Any]:
131
+ """Convert to dictionary."""
132
+ return asdict(self)
133
+
134
+
135
+ @dataclass
136
+ class DeviceActionPayload:
137
+ """Device action payload."""
138
+
139
+ devId: str = ""
140
+ parentId: str = ""
141
+ userId: str = ""
142
+ password: str = ""
143
+ attr: dict[str, Any] = field(default_factory=dict)
144
+ channel: str = "tcp"
145
+ ascNumber: int = 0
146
+
147
+
148
+ @dataclass
149
+ class DeviceActionRequest:
150
+ """Device action request."""
151
+
152
+ method: str = ""
153
+ service: str = "device"
154
+ clientId: str = ""
155
+ srcAddr: str = ""
156
+ seq: str = ""
157
+ payload: DeviceActionPayload = field(default_factory=DeviceActionPayload)
158
+ tst: int = 0
159
+ deviceId: str = ""
160
+
161
+ def __post_init__(self):
162
+ """Auto-generate timestamp if not provided."""
163
+ if self.tst == 0:
164
+ import time
165
+ self.tst = int(time.time() * 1000)
166
+
167
+ def to_dict(self) -> dict[str, Any]:
168
+ """Convert to dictionary."""
169
+ return asdict(self)
170
+
171
+ @staticmethod
172
+ def from_params(
173
+ method: str,
174
+ user_id: str,
175
+ device_id: str,
176
+ password: str,
177
+ ascNumber: int,
178
+ attr: dict[str, Any],
179
+ seq: str,
180
+ simpleVersion: str = None,
181
+ ) -> "DeviceActionRequest":
182
+ """Create DeviceActionRequest from params."""
183
+ if simpleVersion is not None:
184
+ return DeviceActionRequest(
185
+ method=method,
186
+ clientId="ha-" + user_id,
187
+ srcAddr="0." + user_id,
188
+ seq=seq,
189
+ payload=DeviceActionPayload(
190
+ devId=device_id,
191
+ parentId=device_id,
192
+ userId=user_id,
193
+ password=password,
194
+ attr=attr,
195
+ ascNumber=ascNumber,
196
+ ),
197
+ deviceId=device_id,
198
+ )
199
+ else:
200
+ return DeviceActionRequest(
201
+ method=method,
202
+ srcAddr="0." + user_id,
203
+ seq=seq,
204
+ payload=DeviceActionPayload(
205
+ attr=attr,
206
+ ascNumber=ascNumber,
207
+ ),
208
+ deviceId=device_id,
209
+ )
210
+
@@ -0,0 +1,83 @@
1
+ """Models for AiDot device."""
2
+
3
+ from dataclasses import dataclass, asdict, field
4
+ from typing import Any, Optional, List
5
+
6
+ from dacite import Config, from_dict
7
+
8
+
9
+ @dataclass
10
+ class DeviceFading:
11
+ """Device fading config."""
12
+
13
+ in_value: Optional[int] = field(default=None, metadata={"alias": "in"})
14
+ out: Optional[int] = None
15
+
16
+
17
+ @dataclass
18
+ class DeviceProperties:
19
+ """Device properties."""
20
+
21
+ ssidName: str = None
22
+ ipAddress: str = None
23
+ macAddress: str = None
24
+ networkRssi: str = None
25
+ networkSecurity: str = None
26
+ wifiChannel: str = None
27
+ OnOff: str = None
28
+ Dimming: str = None
29
+ CCT: str = None
30
+ RGBW: str = None
31
+ EffectMode: str = None
32
+ Area: str = None
33
+ city: str = None
34
+ CityTimezone: str = None
35
+ lastNotifyCctRgbw: str = None
36
+
37
+
38
+ @dataclass
39
+ class DeviceProduct:
40
+ """Device product info."""
41
+
42
+ id: str = None
43
+ name: str = None
44
+ type: str = None
45
+ modelId: str = None
46
+ picture: str = None
47
+ icon: str = None
48
+ isDirectDevice: int = None
49
+
50
+
51
+ @dataclass
52
+ class DeviceInformation:
53
+ """Device information."""
54
+
55
+ id: str = None
56
+ name: str = None
57
+ mac: str = None
58
+ type: str = None
59
+ modelId: str = None
60
+ productId: str = None
61
+ houseId: str = None
62
+ roomId: str = None
63
+ online: bool = None
64
+ firmwareVersion: str = None
65
+ hardwareVersion: str = None
66
+ protocolVersion: str = None
67
+ picture: str = None
68
+ aesKey: List[str] = field(default_factory=list)
69
+ password: str = None
70
+ fading: Optional[DeviceFading] = None
71
+ properties: Optional[DeviceProperties] = None
72
+ product: Optional[DeviceProduct] = None
73
+
74
+ @staticmethod
75
+ def from_json(data: dict[str, Any]) -> "DeviceInformation":
76
+ """Create DeviceInformation from JSON dict."""
77
+ return from_dict(
78
+ data_class=DeviceInformation, data=data, config=Config(check_types=False)
79
+ )
80
+
81
+ def to_dict(self) -> dict[str, Any]:
82
+ """Convert to dictionary."""
83
+ return asdict(self)
@@ -0,0 +1,102 @@
1
+ """Models for AiDot discover."""
2
+ import time
3
+ from dataclasses import dataclass, asdict, field
4
+ from typing import Any, Optional
5
+
6
+ from dacite import Config, from_dict
7
+
8
+
9
+ @dataclass
10
+ class DiscoverAck:
11
+ """Discover response ack."""
12
+
13
+ code: int = None
14
+ tst: str = None
15
+
16
+
17
+ @dataclass
18
+ class DiscoverExtends:
19
+ """Discover payload extends."""
20
+
21
+ srvHost: str = None
22
+
23
+
24
+ @dataclass
25
+ class DiscoverPayload:
26
+ """Discover response payload."""
27
+
28
+ ip: str = None
29
+ mac: str = None
30
+ devId: str = None
31
+ productModel: str = None
32
+ bindFlag: int = None
33
+ conMode: int = None
34
+ lanMode: int = None
35
+ wifiMode: int = None
36
+ wifiBand: int = None
37
+ version: int = None
38
+ extends: Optional[DiscoverExtends] = None
39
+
40
+
41
+ @dataclass
42
+ class DiscoverResponse:
43
+ """Discover device response."""
44
+
45
+ srcAddr: str = None
46
+ seq: str = None
47
+ service: str = None
48
+ method: str = None
49
+ ack: DiscoverAck = None
50
+ protocolVer: str = None
51
+ payload: DiscoverPayload = None
52
+
53
+ @staticmethod
54
+ def from_json(data: dict[str, Any]) -> "DiscoverResponse":
55
+ """Create DiscoverResponse from JSON dict."""
56
+ return from_dict(
57
+ data_class=DiscoverResponse, data=data, config=Config(check_types=False)
58
+ )
59
+
60
+ def to_dict(self) -> dict[str, Any]:
61
+ """Convert to dictionary."""
62
+ return asdict(self)
63
+
64
+
65
+ @dataclass
66
+ class DiscoverRequestPayload:
67
+ """Discover request payload."""
68
+
69
+ extends: dict[str, Any] = field(default_factory=dict)
70
+ localCtrFlag: int = 1
71
+ timestamp: str = None
72
+
73
+
74
+ @dataclass
75
+ class DiscoverRequest:
76
+ """Discover device request."""
77
+
78
+ protocolVer: str = "2.0.0"
79
+ service: str = "device"
80
+ method: str = "devDiscoveryReq"
81
+ seq: str = None
82
+ srcAddr: str = None
83
+ tst: int = None
84
+ payload: DiscoverRequestPayload = field(default_factory=DiscoverRequestPayload)
85
+
86
+ @staticmethod
87
+ def from_params(userId: str) -> "DiscoverResponse":
88
+ """Create DiscoverResponse from JSON dict."""
89
+ current_timestamp_milliseconds = int(time.time() * 1000)
90
+ seq = str(current_timestamp_milliseconds + 1)[-9:]
91
+ return DiscoverRequest(
92
+ seq=seq,
93
+ srcAddr=f"0.{userId}",
94
+ tst=current_timestamp_milliseconds,
95
+ payload=DiscoverRequestPayload(
96
+ timestamp=str(current_timestamp_milliseconds)
97
+ )
98
+ )
99
+
100
+ def to_dict(self) -> dict[str, Any]:
101
+ """Convert to dictionary."""
102
+ return asdict(self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot
3
- Version: 0.3.54b3
3
+ Version: 0.3.54b4
4
4
  Summary: aidot control wifi lights
5
5
  Home-page: https://github.com/Aidot-Development-Team/python-aidot
6
6
  Author: aidotdev2024
@@ -10,6 +10,10 @@ aidot/device_client.py
10
10
  aidot/discover.py
11
11
  aidot/exceptions.py
12
12
  aidot/login_const.py
13
+ aidot/models/__init__.py
14
+ aidot/models/device_client_model.py
15
+ aidot/models/device_model.py
16
+ aidot/models/discover_model.py
13
17
  python_aidot.egg-info/PKG-INFO
14
18
  python_aidot.egg-info/SOURCES.txt
15
19
  python_aidot.egg-info/dependency_links.txt
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="python-aidot",
8
- version="0.3.54b3",
8
+ version="0.3.54b4",
9
9
  author="aidotdev2024",
10
10
  url='https://github.com/Aidot-Development-Team/python-aidot',
11
11
  description="aidot control wifi lights",
File without changes