pyhausbus 1.0.0__py2.py3-none-any.whl → 1.0.1__py2.py3-none-any.whl
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.
- pyhausbus/HausBusDevice.py +70 -0
- pyhausbus/HausBusUtils.py +140 -130
- {pyhausbus-1.0.0.dist-info → pyhausbus-1.0.1.dist-info}/METADATA +4 -1
- {pyhausbus-1.0.0.dist-info → pyhausbus-1.0.1.dist-info}/RECORD +6 -5
- {pyhausbus-1.0.0.dist-info → pyhausbus-1.0.1.dist-info}/WHEEL +1 -1
- {pyhausbus-1.0.0.dist-info → pyhausbus-1.0.1.dist-info}/LICENSE +0 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from pyhausbus.de.hausbus.homeassistant.proxy.controller.params.EFirmwareId import (
|
4
|
+
EFirmwareId,
|
5
|
+
)
|
6
|
+
|
7
|
+
LOGGER = logging.getLogger("pyhausbus")
|
8
|
+
|
9
|
+
device_type_map = {
|
10
|
+
EFirmwareId.ESP32: {
|
11
|
+
int("0x65", 16): "LAN-RS485 Brückenmodul",
|
12
|
+
int("0x18", 16): "6-fach Taster",
|
13
|
+
int("0x19", 16): "4-fach Taster",
|
14
|
+
int("0x1A", 16): "2-fach Taster",
|
15
|
+
int("0x1B", 16): "1-fach Taster",
|
16
|
+
int("0x1C", 16): "6-fach Taster Gira",
|
17
|
+
int("0x20", 16): "32-fach IO",
|
18
|
+
int("0x0C", 16): "16-fach Relais",
|
19
|
+
int("0x08", 16): "8-fach Relais",
|
20
|
+
int("0x10", 16): "22-fach UP-IO",
|
21
|
+
int("0x28", 16): "8-fach Dimmer",
|
22
|
+
int("0x30", 16): "2-fach RGB Dimmer",
|
23
|
+
int("0x00", 16): "4-fach 0-10V Dimmer",
|
24
|
+
int("0x01", 16): "4-fach 1-10V Dimmer",
|
25
|
+
},
|
26
|
+
EFirmwareId.HBC: {
|
27
|
+
int("0x18", 16): "6-fach Taster",
|
28
|
+
int("0x19", 16): "4-fach Taster",
|
29
|
+
int("0x1A", 16): "2-fach Taster",
|
30
|
+
int("0x1B", 16): "1-fach Taster",
|
31
|
+
int("0x1C", 16): "6-fach Taster Gira",
|
32
|
+
int("0x20", 16): "32-fach IO",
|
33
|
+
int("0x0C", 16): "16-fach Relais",
|
34
|
+
int("0x08", 16): "8-fach Relais",
|
35
|
+
int("0x10", 16): "24-fach UP-IO",
|
36
|
+
int("0x28", 16): "8-fach Dimmer",
|
37
|
+
int("0x29", 16): "8-fach Dimmer",
|
38
|
+
int("0x30", 16): "2-fach RGB Dimmer",
|
39
|
+
int("0x00", 16): "4-fach 0-10V Dimmer",
|
40
|
+
int("0x01", 16): "4-fach 1-10V Dimmer",
|
41
|
+
},
|
42
|
+
EFirmwareId.SD485: {
|
43
|
+
int("0x28", 16): "24-fach UP-IO",
|
44
|
+
int("0x1E", 16): "6-fach Taster",
|
45
|
+
int("0x2E", 16): "6-fach Taster",
|
46
|
+
int("0x2F", 16): "6-fach Taster",
|
47
|
+
int("0x2B", 16): "4-fach 0-10V Dimmer",
|
48
|
+
int("0x2C", 16): "4-fach Taster",
|
49
|
+
int("0x2D", 16): "4-fach 1-10V Dimmer",
|
50
|
+
int("0x2A", 16): "2-fach Taster",
|
51
|
+
int("0x29", 16): "1-fach Taster",
|
52
|
+
},
|
53
|
+
EFirmwareId.AR8: {
|
54
|
+
int("0x28", 16): "LAN Brückenmodul",
|
55
|
+
int("0x30", 16): "8-fach Relais",
|
56
|
+
},
|
57
|
+
EFirmwareId.SD6: {
|
58
|
+
int("0x14", 16): "Multitaster",
|
59
|
+
int("0x1E", 16): "Multitaster",
|
60
|
+
},
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
def get_device_type(firmware_id: EFirmwareId, type_id: int) -> str:
|
65
|
+
"""Get device type from firmware ID and type ID."""
|
66
|
+
firmware_model_id = device_type_map.get(firmware_id, {})
|
67
|
+
if len(firmware_model_id) == 0:
|
68
|
+
return "Controller"
|
69
|
+
else:
|
70
|
+
return firmware_model_id.get(type_id, "Controller")
|
pyhausbus/HausBusUtils.py
CHANGED
@@ -4,190 +4,200 @@ import traceback
|
|
4
4
|
|
5
5
|
LOGGER = logging.getLogger("pyhausbus")
|
6
6
|
|
7
|
-
HOMESERVER_DEVICE_ID:int = 9998
|
8
|
-
HOMESERVER_OBJECT_ID:int = (HOMESERVER_DEVICE_ID << 16) + (0 << 8) + 1
|
7
|
+
HOMESERVER_DEVICE_ID: int = 9998
|
8
|
+
HOMESERVER_OBJECT_ID: int = (HOMESERVER_DEVICE_ID << 16) + (0 << 8) + 1
|
9
9
|
|
10
10
|
UDP_PORT = 5855
|
11
11
|
|
12
|
-
def getObjectId(deviceId:int, classId:int, instanceId:int) -> int:
|
13
|
-
return (deviceId << 16) + (classId << 8) + instanceId
|
14
12
|
|
15
|
-
def
|
16
|
-
|
17
|
-
result = 0
|
18
|
-
result += (data[offset[0]] & 0xff)
|
19
|
-
offset[0] += 1
|
13
|
+
def getObjectId(deviceId: int, classId: int, instanceId: int) -> int:
|
14
|
+
return (deviceId << 16) + (classId << 8) + instanceId
|
20
15
|
|
21
|
-
result += (data[offset[0]] & 0xff) * 256
|
22
|
-
offset[0] += 1
|
23
16
|
|
24
|
-
|
25
|
-
|
17
|
+
def bytesToDWord(data: bytearray, offset) -> int:
|
18
|
+
try:
|
19
|
+
result = 0
|
20
|
+
result += data[offset[0]] & 0xFF
|
21
|
+
offset[0] += 1
|
26
22
|
|
27
|
-
|
28
|
-
|
23
|
+
result += (data[offset[0]] & 0xFF) * 256
|
24
|
+
offset[0] += 1
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
LOGGER.error(err,exc_info=True,stack_info=True)
|
33
|
-
return 0
|
26
|
+
result += (data[offset[0]] & 0xFF) * 65536
|
27
|
+
offset[0] += 1
|
34
28
|
|
29
|
+
result += (data[offset[0]] & 0xFF) * 16777216
|
30
|
+
offset[0] += 1
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
offset[0] += 1
|
32
|
+
return result
|
33
|
+
except Exception as err:
|
34
|
+
LOGGER.error(err, exc_info=True, stack_info=True)
|
35
|
+
return 0
|
41
36
|
|
42
|
-
result += (data[offset[0]] & 0xff) * 256
|
43
|
-
offset[0] += 1
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
38
|
+
def bytesToWord(data: bytearray, offset) -> int:
|
39
|
+
try:
|
40
|
+
result = 0
|
41
|
+
result += data[offset[0]] & 0xFF
|
42
|
+
offset[0] += 1
|
49
43
|
|
44
|
+
result += (data[offset[0]] & 0xFF) * 256
|
45
|
+
offset[0] += 1
|
50
46
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
result = data[offset[0]] & 0xff
|
56
|
-
offset[0] += 1
|
57
|
-
return result
|
58
|
-
except (Exception) as err:
|
59
|
-
LOGGER.error(err,exc_info=True,stack_info=True)
|
60
|
-
return 0
|
47
|
+
return result
|
48
|
+
except Exception as err:
|
49
|
+
LOGGER.error(err, exc_info=True, stack_info=True)
|
50
|
+
return 0
|
61
51
|
|
62
52
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
53
|
+
def bytesToInt(data: bytearray, offset) -> int:
|
54
|
+
try:
|
55
|
+
if len(data) <= offset[0]:
|
56
|
+
return 0
|
57
|
+
result = data[offset[0]] & 0xFF
|
58
|
+
offset[0] += 1
|
59
|
+
return result
|
60
|
+
except Exception as err:
|
61
|
+
LOGGER.error(err, exc_info=True, stack_info=True)
|
62
|
+
return 0
|
70
63
|
|
71
|
-
result += chr(data[i])
|
72
|
-
return result
|
73
|
-
except (Exception) as err:
|
74
|
-
LOGGER.error(err,exc_info=True,stack_info=True)
|
75
|
-
return ""
|
76
64
|
|
65
|
+
def bytesToString(data: bytearray, offset) -> str:
|
66
|
+
try:
|
67
|
+
result = ""
|
68
|
+
for i in range(offset[0], len(data)):
|
69
|
+
offset[0] += 1
|
70
|
+
if data[i] == 0:
|
71
|
+
break
|
72
|
+
|
73
|
+
result += chr(data[i])
|
74
|
+
return result
|
75
|
+
except Exception as err:
|
76
|
+
LOGGER.error(err, exc_info=True, stack_info=True)
|
77
|
+
return ""
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
79
|
+
|
80
|
+
def bytesToDebugString(message: bytearray) -> str:
|
81
|
+
result = ""
|
82
|
+
for byte in message:
|
83
|
+
if result != "":
|
84
|
+
result = result + ", "
|
85
|
+
result = result + hex(byte)
|
86
|
+
return result
|
85
87
|
|
86
88
|
|
87
89
|
def getInstanceId(objectId) -> int:
|
88
|
-
|
90
|
+
return (objectId) & 0xFF
|
89
91
|
|
90
92
|
|
91
93
|
def getDeviceId(objectId) -> int:
|
92
|
-
|
94
|
+
return ((objectId >> 24) & 0xFF) * 256 + ((objectId >> 16) & 0xFF)
|
93
95
|
|
94
96
|
|
95
97
|
def getClassId(objectId) -> int:
|
96
|
-
|
98
|
+
return (objectId >> 8) & 0xFF
|
97
99
|
|
98
100
|
|
99
101
|
def formatObjectId(objectId) -> str:
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
result = "[DeviceId: " + str(getDeviceId(objectId))
|
103
|
+
result += ", ClassId: " + str(getClassId(objectId))
|
104
|
+
result += ", Instance: " + str(getInstanceId(objectId)) + "]"
|
105
|
+
return result
|
104
106
|
|
105
107
|
|
106
108
|
def getClockIndependMillis():
|
107
|
-
|
109
|
+
return time.perf_counter() * 1000
|
108
110
|
|
109
111
|
|
110
112
|
def setBit(is_set: bool, bit: int, value: int) -> int:
|
111
113
|
if is_set:
|
112
|
-
value |=
|
114
|
+
value |= 1 << bit
|
113
115
|
else:
|
114
116
|
value &= ~(1 << bit)
|
115
117
|
return value
|
116
118
|
|
117
119
|
|
118
|
-
def isBitSet(bit:int, value:int) -> bool:
|
119
|
-
|
120
|
+
def isBitSet(bit: int, value: int) -> bool:
|
121
|
+
return ((value >> bit) & 1) > 0
|
120
122
|
|
121
123
|
|
122
|
-
def bytesToBlob(data:bytearray, offset) -> bytearray:
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
124
|
+
def bytesToBlob(data: bytearray, offset) -> bytearray:
|
125
|
+
try:
|
126
|
+
result = bytearray(len(data) - offset[0])
|
127
|
+
result[:] = data[offset[0] :]
|
128
|
+
offset[0] = offset[0] + len(data)
|
129
|
+
return result
|
130
|
+
except Exception as err:
|
131
|
+
LOGGER.error(err, exc_info=True, stack_info=True)
|
132
|
+
return 0
|
133
|
+
|
131
134
|
|
132
135
|
def dWordToBytes(value: int) -> bytearray:
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
result = bytearray(4)
|
137
|
+
result[0] = value & 0xFF
|
138
|
+
result[1] = (value >> 8) & 0xFF
|
139
|
+
result[2] = (value >> 16) & 0xFF
|
140
|
+
result[3] = (value >> 24) & 0xFF
|
141
|
+
return result
|
139
142
|
|
140
143
|
|
141
144
|
def addWord(value: int, inOutList):
|
142
|
-
|
143
|
-
|
145
|
+
inOutList.append(value & 0xFF)
|
146
|
+
inOutList.append((value >> 8) & 0xFF)
|
147
|
+
|
144
148
|
|
145
149
|
def addDword(value: int, inOutList):
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
inOutList.append(value & 0xFF)
|
151
|
+
inOutList.append((value >> 8) & 0xFF)
|
152
|
+
inOutList.append((value >> 16) & 0xFF)
|
153
|
+
inOutList.append((value >> 24) & 0xFF)
|
154
|
+
|
150
155
|
|
151
156
|
def wordToBytes(value: int) -> bytearray:
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
return result
|
156
|
-
|
157
|
-
def bytesToSInt(data:bytearray, offset) -> int:
|
158
|
-
result = data[offset[0]] & 0xff
|
159
|
-
offset[0]+=1
|
160
|
-
if (result > 127):
|
161
|
-
result -= 256
|
162
|
-
return result
|
163
|
-
|
164
|
-
def formatBytes(data:bytearray, offset:int=0, length:int=-1, asHex:bool=True) -> str:
|
165
|
-
if (length==-1):
|
166
|
-
length=len(data)
|
167
|
-
|
168
|
-
if (data == None):
|
169
|
-
return "NULL"
|
170
|
-
|
171
|
-
result=""
|
172
|
-
|
173
|
-
for i in range (offset,length):
|
174
|
-
if (asHex):
|
175
|
-
result+="0x"+hex(data[i])
|
176
|
-
else:
|
177
|
-
result+=data[i] & 0xff
|
157
|
+
result = bytearray(2)
|
158
|
+
result[0] = value & 0xFF
|
159
|
+
result[1] = (value >> 8) & 0xFF
|
178
160
|
return result
|
179
161
|
|
180
|
-
|
181
|
-
|
182
|
-
result =
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
value = data[i + 1] & 0xff
|
187
|
-
result.append(key)
|
188
|
-
result.append(value)
|
189
|
-
offset[0]+=2
|
162
|
+
|
163
|
+
def bytesToSInt(data: bytearray, offset) -> int:
|
164
|
+
result = data[offset[0]] & 0xFF
|
165
|
+
offset[0] += 1
|
166
|
+
if result > 127:
|
167
|
+
result -= 256
|
190
168
|
return result
|
191
|
-
|
192
|
-
|
193
|
-
|
169
|
+
|
170
|
+
|
171
|
+
def formatBytes(
|
172
|
+
data: bytearray, offset: int = 0, length: int = -1, asHex: bool = True
|
173
|
+
) -> str:
|
174
|
+
if length == -1:
|
175
|
+
length = len(data)
|
176
|
+
|
177
|
+
if data == None:
|
178
|
+
return "NULL"
|
179
|
+
|
180
|
+
result = ""
|
181
|
+
|
182
|
+
for i in range(offset, length):
|
183
|
+
if asHex:
|
184
|
+
result += "0x" + hex(data[i])
|
185
|
+
else:
|
186
|
+
result += data[i] & 0xFF
|
187
|
+
return result
|
188
|
+
|
189
|
+
|
190
|
+
def bytesToList(data: bytearray, offset):
|
191
|
+
try:
|
192
|
+
result = bytearray()
|
193
|
+
offsetStart = offset[0]
|
194
|
+
for i in range(offsetStart, len(data), 2):
|
195
|
+
key = data[i] & 0xFF
|
196
|
+
value = data[i + 1] & 0xFF
|
197
|
+
result.append(key)
|
198
|
+
result.append(value)
|
199
|
+
offset[0] += 2
|
200
|
+
return result
|
201
|
+
except Exception as err:
|
202
|
+
LOGGER.error(err, exc_info=True, stack_info=True)
|
203
|
+
return bytearray()
|
@@ -1,7 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyhausbus
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.1
|
4
4
|
Summary: Python based library for accessing haus-bus.de modules. Inteded to be used in a Home Assistant integration.
|
5
|
+
Home-page: https://haus-bus.secure-stores.de/
|
5
6
|
Author: Hermann Hoeschen
|
6
7
|
Author-email: info@haus-bus.de
|
7
8
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -18,6 +19,8 @@ Classifier: Programming Language :: Python :: 3.9
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.10
|
19
20
|
Classifier: Programming Language :: Python :: 3.11
|
20
21
|
Classifier: Programming Language :: Python :: 3.12
|
22
|
+
Project-URL: Bug Tracker, https://github.com/hausbus/homeassistant/issues
|
23
|
+
Project-URL: Repository, https://github.com/hausbus/homeassistant
|
21
24
|
Description-Content-Type: text/markdown
|
22
25
|
|
23
26
|
# pyhausbus
|
@@ -2,7 +2,8 @@ pyhausbus/ABusFeature.py,sha256=CoXamHLNnuVt4KKOj8m7aGu60EAkapTwF7jXlOy6wdA,556
|
|
2
2
|
pyhausbus/BusDataMessage.py,sha256=riHYPByCZbE2nm_Zi6Vtg0niDCMPw2j1QK4pgSdSfnU,613
|
3
3
|
pyhausbus/BusHandler.py,sha256=eRDuZHUywIO5c419eC_QMNS-jk3kEUSyv6eTRH6VWD0,4013
|
4
4
|
pyhausbus/HausBusCommand.py,sha256=q-0NH0exPdWWPoKeyi8rCEJsX6le7xRxUE4hOCerG1g,2386
|
5
|
-
pyhausbus/
|
5
|
+
pyhausbus/HausBusDevice.py,sha256=NRzaV-TZQ7P31yzL3dlY3TsB7xHxwCYcKwwNg8fFo5w,2441
|
6
|
+
pyhausbus/HausBusUtils.py,sha256=bPi2W-iIWIpXtRaSa_qxhZbYenRuodD0-w0rUmAo9AY,4909
|
6
7
|
pyhausbus/HomeServer.py,sha256=5V9GWY-dWL7DFwFMg3peK_h2mcEEX2gjcDX7g75FDGA,2801
|
7
8
|
pyhausbus/IBusDataListener.py,sha256=2iakwRz-dg-wPVutAYeCm0cFykSl9bkTlxAU79GyycU,145
|
8
9
|
pyhausbus/Main.py,sha256=tlYdZPiqodVioDHraxPype04r8McZFBMCSDMM4_6b1k,4333
|
@@ -519,7 +520,7 @@ pyhausbus/de/hausbus/homeassistant/proxy/wiFi/data/EvError.py,sha256=heTZfYOQ6lw
|
|
519
520
|
pyhausbus/de/hausbus/homeassistant/proxy/wiFi/data/_init_.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
520
521
|
pyhausbus/de/hausbus/homeassistant/proxy/wiFi/params/EErrorCode.py,sha256=VFr7nVTg9RiCHiE9M7Lk2vEMyj5O7whrC2bJGCKT1CA,378
|
521
522
|
pyhausbus/de/hausbus/homeassistant/proxy/wiFi/params/_init_.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
522
|
-
pyhausbus-1.0.
|
523
|
-
pyhausbus-1.0.
|
524
|
-
pyhausbus-1.0.
|
525
|
-
pyhausbus-1.0.
|
523
|
+
pyhausbus-1.0.1.dist-info/LICENSE,sha256=o5kWncdm1-QwSPPsPlLL8BhpXCt6u3Kj7jWPsPSDcs4,1073
|
524
|
+
pyhausbus-1.0.1.dist-info/METADATA,sha256=Oh2fk3AqSqTEWpeRpO0BEdOz5OTdOGoxXOqyDD11hKY,1273
|
525
|
+
pyhausbus-1.0.1.dist-info/WHEEL,sha256=IrRNNNJ-uuL1ggO5qMvT1GGhQVdQU54d6ZpYqEZfEWo,92
|
526
|
+
pyhausbus-1.0.1.dist-info/RECORD,,
|
File without changes
|