protobin 0.0.46__tar.gz → 0.0.48__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.
- {protobin-0.0.46 → protobin-0.0.48}/PKG-INFO +1 -1
- {protobin-0.0.46 → protobin-0.0.48}/protobin/fields.py +26 -1
- {protobin-0.0.46 → protobin-0.0.48}/pyproject.toml +1 -1
- {protobin-0.0.46 → protobin-0.0.48}/tests/demo.json +33 -0
- {protobin-0.0.46 → protobin-0.0.48}/tests/tests.py +52 -0
- {protobin-0.0.46 → protobin-0.0.48}/.gitignore +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/LICENSE.txt +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/README.md +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/protobin/__init__.py +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/protobin/errors.py +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/protobin/interfaces.py +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/protobin/protocol.py +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/protobin/singleton.py +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/tests/codec8.json +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/tests/demo.yaml +0 -0
- {protobin-0.0.46 → protobin-0.0.48}/tests/teltonika.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protobin
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.48
|
|
4
4
|
Summary: Python library for encode and decode data in protobin format
|
|
5
5
|
Project-URL: Homepage, https://github.com/drmelectronic/protobin-python
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/drmelectronic/protobin-python/issues
|
|
@@ -130,6 +130,27 @@ class ArrayField(FieldBase):
|
|
|
130
130
|
return lista, binary
|
|
131
131
|
|
|
132
132
|
|
|
133
|
+
|
|
134
|
+
class BinaryField(FieldBase):
|
|
135
|
+
|
|
136
|
+
def __init__(self, k, js):
|
|
137
|
+
super().__init__(k, js)
|
|
138
|
+
self.length_size = js.get('length_size', 1)
|
|
139
|
+
|
|
140
|
+
def __repr__(self):
|
|
141
|
+
return f'BinaryField<key: {self.key}, bytes: {self.bytes}>'
|
|
142
|
+
|
|
143
|
+
def from_binary(self, binary):
|
|
144
|
+
return binary
|
|
145
|
+
|
|
146
|
+
def split(self, binary):
|
|
147
|
+
bytes = int.from_bytes(binary[:self.length_size], 'big', signed=False)
|
|
148
|
+
return binary[self.length_size:bytes + self.length_size], binary[bytes + self.length_size:]
|
|
149
|
+
|
|
150
|
+
def to_binary(self, val):
|
|
151
|
+
return len(val).to_bytes(self.length_size, 'big') + val
|
|
152
|
+
|
|
153
|
+
|
|
133
154
|
class BitsField(FieldBase):
|
|
134
155
|
length: int
|
|
135
156
|
|
|
@@ -306,7 +327,10 @@ class DateTimeField(FieldBase):
|
|
|
306
327
|
S, binary = self.get_nible(binary)
|
|
307
328
|
if y == 0 and m == 0 and d == 0 and H == 0 and M == 0 and S == 0:
|
|
308
329
|
return None
|
|
309
|
-
|
|
330
|
+
try:
|
|
331
|
+
return datetime.datetime(2000 + y, m, d, H, M, S)
|
|
332
|
+
except:
|
|
333
|
+
return None
|
|
310
334
|
|
|
311
335
|
|
|
312
336
|
class FlagsField(FieldBase):
|
|
@@ -525,6 +549,7 @@ class UnsignedField(FieldBase):
|
|
|
525
549
|
|
|
526
550
|
FIELD_MAP = {
|
|
527
551
|
'array': ArrayField,
|
|
552
|
+
'binary': BinaryField,
|
|
528
553
|
'bits': BitsField,
|
|
529
554
|
'bool': BoolField,
|
|
530
555
|
'char': CharField,
|
|
@@ -20,6 +20,39 @@
|
|
|
20
20
|
"schedule": {"type": "time"}
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
+
"report_alt": {
|
|
24
|
+
"header": "p",
|
|
25
|
+
"client": {
|
|
26
|
+
"positions": {
|
|
27
|
+
"type": "array", "array": {
|
|
28
|
+
"time": {"type": "datetime"},
|
|
29
|
+
"lng": {"bytes": 4, "type": "float", "decimals": 6},
|
|
30
|
+
"lat": {"bytes": 4, "type": "float", "decimals": 6},
|
|
31
|
+
"speed": {"bytes": 1, "type": "unsigned"},
|
|
32
|
+
"mark": {"bytes": 2, "type": "id"},
|
|
33
|
+
"busstop": {"bytes": 2, "type": "id"}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"trip": {"bytes": 4, "type": "id"},
|
|
37
|
+
"route": {"bytes": 1, "type": "id"},
|
|
38
|
+
"direction": {"type": "bool"},
|
|
39
|
+
"state": {"type": "char"},
|
|
40
|
+
"boletos": {
|
|
41
|
+
"type": "array", "array": {
|
|
42
|
+
"id": { "bytes": 2, "type": "unsigned"},
|
|
43
|
+
"cantidad": {"bytes": 2, "type": "unsigned"}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"sales": {"bytes": 3, "type": "unsigned"},
|
|
47
|
+
"events": {"type": "array", "array": {
|
|
48
|
+
"id": {"bytes": 2, "type": "unsigned"},
|
|
49
|
+
"value": {"bytes": 1, "type": "unsigned"}}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"server": {
|
|
53
|
+
"positions": {"bytes": 1, "type": "unsigned"}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
23
56
|
"report": {
|
|
24
57
|
"header": "PV",
|
|
25
58
|
"client": {
|
|
@@ -83,6 +83,10 @@ class BasicTest(unittest.TestCase):
|
|
|
83
83
|
"header": "b",
|
|
84
84
|
"fields": {'test': {'type': 'bits', 'length': 7}}
|
|
85
85
|
},
|
|
86
|
+
'binary': {
|
|
87
|
+
"header": "bin",
|
|
88
|
+
"fields": {'test': {'type': 'binary'}}
|
|
89
|
+
},
|
|
86
90
|
'bool': {
|
|
87
91
|
"header": "BO",
|
|
88
92
|
"fields": {'test': {'bytes': 1, 'type': 'bool'}}
|
|
@@ -182,6 +186,45 @@ class BasicTest(unittest.TestCase):
|
|
|
182
186
|
h, recv = self.protocol.decode(binary)
|
|
183
187
|
self.assertEqual(data, recv)
|
|
184
188
|
|
|
189
|
+
def test_binary(self):
|
|
190
|
+
data = {'test': b'S=RA\x05'}
|
|
191
|
+
binary = self.protocol.encode(data, 'binary')
|
|
192
|
+
h, recv = self.protocol.decode(binary)
|
|
193
|
+
self.assertEqual(data, recv)
|
|
194
|
+
|
|
195
|
+
def test_command_binary(self):
|
|
196
|
+
data = {'test': None}
|
|
197
|
+
with self.assertRaises(ValueError) as er:
|
|
198
|
+
self.protocol.encode(data, 'unsigned')
|
|
199
|
+
|
|
200
|
+
protocol = Protocol(js={
|
|
201
|
+
"length": 8,
|
|
202
|
+
"fake_prefix": True,
|
|
203
|
+
"crc": {"poly": "0x18005", "init": "0x0000", "reverse": True, "byte_order": "big", "size": 4},
|
|
204
|
+
'formats': {
|
|
205
|
+
"command": {
|
|
206
|
+
"codec": 12,
|
|
207
|
+
"fields": {
|
|
208
|
+
"#commands1": {"bytes": 1, "type": "unsigned"},
|
|
209
|
+
"type": {"bytes": 1, "type": "unsigned"},
|
|
210
|
+
"command": {"length_size": 4, "type": "binary"},
|
|
211
|
+
"#commands2": {"bytes": 1, "type": "unsigned"}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}})
|
|
215
|
+
binary = b'S=RA\x05CERES07:42\x08HUACHIPA2\nPZA VITART\x00>\n\x00\x07\x01\x00\x041\x00&\r\x00\x00\x00\x00\x00\x00(\xc4'
|
|
216
|
+
data = {
|
|
217
|
+
'#commands1': 1,
|
|
218
|
+
'type': 5,
|
|
219
|
+
'command': binary,
|
|
220
|
+
'#commands2': 1,
|
|
221
|
+
}
|
|
222
|
+
binary = protocol.encode(data, 'command')
|
|
223
|
+
print(binary)
|
|
224
|
+
h, recv = protocol.decode(binary)
|
|
225
|
+
print(recv)
|
|
226
|
+
self.assertEqual(data, recv)
|
|
227
|
+
|
|
185
228
|
def test_bits_false(self):
|
|
186
229
|
data = {'test': [False, False]}
|
|
187
230
|
binary = self.protocol.encode(data, 'bits')
|
|
@@ -918,3 +961,12 @@ report:
|
|
|
918
961
|
binary = client.encode(data, 'flag_array')
|
|
919
962
|
h, recv = client.decode(binary)
|
|
920
963
|
self.assertEqual(data, recv)
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
def test_report_teltonika_alt(self):
|
|
968
|
+
server = Protocol(file='demo.json', server=True)
|
|
969
|
+
binary = b'p=\x03\x14\x07%\x10YP\xfbh.\x18\xffG\xaa\x8c\x18\x00\x16\xee\xfa\x14\x07%\x10YU\xfbh/\x06\xffG\xa9\xc6\x15\x00\x16\xee\xfay\x01\xe7$\xba\x10o}\x00\xf7\xc1m\x10\xc3R\n\xffh\xbb\x00\x04\x06\xf8\x01\x01R\x00\x00\x00\x00\x00'
|
|
970
|
+
h, recv = server.decode(binary)
|
|
971
|
+
self.assertEqual(h, 'report_alt')
|
|
972
|
+
print(recv)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|