protobin 0.0.30__tar.gz → 0.0.32__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.30 → protobin-0.0.32}/PKG-INFO +3 -2
- {protobin-0.0.30 → protobin-0.0.32}/protobin/fields.py +4 -1
- {protobin-0.0.30 → protobin-0.0.32}/protobin/protocol.py +2 -0
- {protobin-0.0.30 → protobin-0.0.32}/pyproject.toml +1 -1
- protobin-0.0.32/tests/teltonika.json +150 -0
- {protobin-0.0.30 → protobin-0.0.32}/tests/tests.py +39 -2
- {protobin-0.0.30 → protobin-0.0.32}/.gitignore +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/LICENSE.txt +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/README.md +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/protobin/__init__.py +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/protobin/errors.py +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/protobin/interfaces.py +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/protobin/singleton.py +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/tests/codec8.json +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/tests/demo.json +0 -0
- {protobin-0.0.30 → protobin-0.0.32}/tests/demo.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: protobin
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.32
|
|
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
|
|
@@ -28,6 +28,7 @@ License: MIT License
|
|
|
28
28
|
SOFTWARE. 1
|
|
29
29
|
1. en.wikipedia.org
|
|
30
30
|
en.wikipedia.org
|
|
31
|
+
License-File: LICENSE.txt
|
|
31
32
|
Classifier: License :: OSI Approved :: MIT License
|
|
32
33
|
Classifier: Operating System :: OS Independent
|
|
33
34
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -433,7 +433,10 @@ class TimeField(FieldBase):
|
|
|
433
433
|
return bytes([0] * 2)
|
|
434
434
|
elif isinstance(val, str):
|
|
435
435
|
try:
|
|
436
|
-
|
|
436
|
+
if len(val) > 5:
|
|
437
|
+
val = datetime.datetime.strptime(val, '%Y-%m-%d %H:%M:%S').time()
|
|
438
|
+
else:
|
|
439
|
+
val = datetime.datetime.strptime(val, '%H:%M').time()
|
|
437
440
|
except:
|
|
438
441
|
raise ValueError(f'Error in field "{self.key}", a datetime or time is expected but "{val}" is received')
|
|
439
442
|
|
|
@@ -25,6 +25,8 @@ class Format:
|
|
|
25
25
|
input_mode = 'client' if server else 'server'
|
|
26
26
|
output_mode = 'server' if server else 'client'
|
|
27
27
|
for k, f in format[input_mode].items():
|
|
28
|
+
if 'type' not in f:
|
|
29
|
+
raise FormatError(f'Not found type in field {k} of format {name}')
|
|
28
30
|
if f['type'] not in FIELD_MAP:
|
|
29
31
|
raise FormatError(f'Invalid protobin type {f["type"]}')
|
|
30
32
|
self.input_fields.append(FIELD_MAP[f['type']](k, f))
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"length": 8,
|
|
3
|
+
"crc": {"poly": "0x18005", "init": "0x0000", "reverse": true, "byte_order": "big", "size": 4},
|
|
4
|
+
"formats": {
|
|
5
|
+
"login": {
|
|
6
|
+
"crc": false,
|
|
7
|
+
"fields": {
|
|
8
|
+
"serial": {"type": "string", "length_size": 2}
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"login_status": {
|
|
12
|
+
"crc": false,
|
|
13
|
+
"header": "P",
|
|
14
|
+
"fields": {
|
|
15
|
+
"bus_number": {"type": "string"},
|
|
16
|
+
"company": {"type": "string"},
|
|
17
|
+
"route": {"type": "string"}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"report": {
|
|
21
|
+
"codec": 8,
|
|
22
|
+
"fields": {
|
|
23
|
+
"positions": {"type": "array", "array": {
|
|
24
|
+
"time": {"type": "timestamp", "decimals": 3},
|
|
25
|
+
"priority": {"type": "unsigned", "bytes": 1},
|
|
26
|
+
"lng": {"type": "float", "bytes": 4, "decimals": 7},
|
|
27
|
+
"lat": {"type": "float", "bytes": 4, "decimals": 7},
|
|
28
|
+
"alt": {"type": "unsigned", "bytes": 2},
|
|
29
|
+
"angle": {"type": "unsigned", "bytes": 2},
|
|
30
|
+
"satellites": {"type": "unsigned", "bytes": 1},
|
|
31
|
+
"speed": {"type": "unsigned", "bytes": 2},
|
|
32
|
+
"event_io": {"type": "unsigned", "bytes": 1},
|
|
33
|
+
"#events": {"type": "unsigned", "bytes": 1},
|
|
34
|
+
"events1b": {"type": "array", "array": {
|
|
35
|
+
"id": {"type": "id", "bytes": 1},
|
|
36
|
+
"value": {"type": "unsigned", "bytes": 1
|
|
37
|
+
}}
|
|
38
|
+
},
|
|
39
|
+
"events2b": {"type": "array", "array": {
|
|
40
|
+
"id": {"type": "id", "bytes": 1},
|
|
41
|
+
"value": {"type": "unsigned", "bytes": 2}
|
|
42
|
+
}},
|
|
43
|
+
"events4b": {"type": "array", "array": {
|
|
44
|
+
"id": {"type": "id", "bytes": 1},
|
|
45
|
+
"value": {"type": "unsigned", "bytes": 4}
|
|
46
|
+
}},
|
|
47
|
+
"events8b": {"type": "array", "array": {
|
|
48
|
+
"id": {"type": "id", "bytes": 1},
|
|
49
|
+
"value": {"type": "unsigned", "bytes": 8}
|
|
50
|
+
}}
|
|
51
|
+
}},
|
|
52
|
+
"#reports": {"type": "unsigned", "bytes": 1}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"report_ack": {
|
|
56
|
+
"crc": false,
|
|
57
|
+
"fields": {
|
|
58
|
+
"positions": {"bytes": 4, "type": "unsigned"}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"STATUS": {
|
|
62
|
+
"crc": false,
|
|
63
|
+
"header": "ST",
|
|
64
|
+
"fields": {
|
|
65
|
+
"status": {"type": "char"},
|
|
66
|
+
"direction": {"type": "char"},
|
|
67
|
+
"next_control": {"type": "string"},
|
|
68
|
+
"next_time": {"type": "string", "bytes": 5},
|
|
69
|
+
"previous_control": {"type": "string"},
|
|
70
|
+
"delay": {"type": "signed", "bytes": 1},
|
|
71
|
+
"back_control": {"type": "string"},
|
|
72
|
+
"datero_bus_0": {"type": "unsigned", "bytes": 2},
|
|
73
|
+
"datero_dif_0": {"type": "unsigned", "bytes": 1},
|
|
74
|
+
"datero_bus_1": {"type": "unsigned", "bytes": 2},
|
|
75
|
+
"datero_dif_1": {"type": "unsigned", "bytes": 1},
|
|
76
|
+
"datero_bus_2": {"type": "unsigned", "bytes": 2},
|
|
77
|
+
"datero_dif_2": {"type": "unsigned", "bytes": 1},
|
|
78
|
+
"datero_bus_3": {"type": "unsigned", "bytes": 2},
|
|
79
|
+
"datero_dif_3": {"type": "unsigned", "bytes": 1},
|
|
80
|
+
"datero_bus_4": {"type": "unsigned", "bytes": 2},
|
|
81
|
+
"datero_dif_4": {"type": "unsigned", "bytes": 1},
|
|
82
|
+
"datero_bus_5": {"type": "unsigned", "bytes": 2},
|
|
83
|
+
"datero_dif_5": {"type": "unsigned", "bytes": 1}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"status1": {
|
|
87
|
+
"header": "S",
|
|
88
|
+
"fields": {
|
|
89
|
+
"status": {"type": "char"},
|
|
90
|
+
"direction": {"type": "char"},
|
|
91
|
+
"next_control": {"type": "string"},
|
|
92
|
+
"next_time": {"type": "string", "bytes": 5},
|
|
93
|
+
"previous_control": {"type": "string"},
|
|
94
|
+
"delay": {"type": "signed", "bytes": 1},
|
|
95
|
+
"back_control": {"type": "string"},
|
|
96
|
+
"datero_bus_0": {"type": "unsigned", "bytes": 2},
|
|
97
|
+
"datero_dif_0": {"type": "unsigned", "bytes": 1},
|
|
98
|
+
"datero_bus_1": {"type": "unsigned", "bytes": 2},
|
|
99
|
+
"datero_dif_1": {"type": "unsigned", "bytes": 1},
|
|
100
|
+
"datero_bus_2": {"type": "unsigned", "bytes": 2},
|
|
101
|
+
"datero_dif_2": {"type": "unsigned", "bytes": 1},
|
|
102
|
+
"datero_bus_3": {"type": "unsigned", "bytes": 2},
|
|
103
|
+
"datero_dif_3": {"type": "unsigned", "bytes": 1},
|
|
104
|
+
"datero_bus_4": {"type": "unsigned", "bytes": 2},
|
|
105
|
+
"datero_dif_4": {"type": "unsigned", "bytes": 1},
|
|
106
|
+
"datero_bus_5": {"type": "unsigned", "bytes": 2},
|
|
107
|
+
"datero_dif_5": {"type": "unsigned", "bytes": 1}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"status3": {
|
|
111
|
+
"header": "s",
|
|
112
|
+
"fields": {
|
|
113
|
+
"status": {"type": "char"},
|
|
114
|
+
"direction": {"type": "char"},
|
|
115
|
+
"next_next_control": {"type": "string"},
|
|
116
|
+
"next_next_time": {"type": "string", "bytes": 5},
|
|
117
|
+
"next_control": {"type": "string"},
|
|
118
|
+
"next_time": {"type": "string", "bytes": 5},
|
|
119
|
+
"previous_control": {"type": "string"},
|
|
120
|
+
"delay": {"type": "signed", "bytes": 1},
|
|
121
|
+
"front_control": {"type": "string"},
|
|
122
|
+
"back_control": {"type": "string"},
|
|
123
|
+
"back_back_control": {"type": "string"},
|
|
124
|
+
"datero_bus_-1": {"type": "unsigned", "bytes": 2},
|
|
125
|
+
"datero_dif_-1": {"type": "unsigned", "bytes": 1},
|
|
126
|
+
"datero_bus_0": {"type": "unsigned", "bytes": 2},
|
|
127
|
+
"datero_dif_0": {"type": "unsigned", "bytes": 1},
|
|
128
|
+
"datero_bus_1": {"type": "unsigned", "bytes": 2},
|
|
129
|
+
"datero_dif_1": {"type": "unsigned", "bytes": 1},
|
|
130
|
+
"datero_bus_2": {"type": "unsigned", "bytes": 2},
|
|
131
|
+
"datero_dif_2": {"type": "unsigned", "bytes": 1},
|
|
132
|
+
"datero_bus_3": {"type": "unsigned", "bytes": 2},
|
|
133
|
+
"datero_dif_3": {"type": "unsigned", "bytes": 1},
|
|
134
|
+
"datero_bus_4": {"type": "unsigned", "bytes": 2},
|
|
135
|
+
"datero_dif_4": {"type": "unsigned", "bytes": 1},
|
|
136
|
+
"datero_bus_5": {"type": "unsigned", "bytes": 2},
|
|
137
|
+
"datero_dif_5": {"type": "unsigned", "bytes": 1}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"command": {
|
|
141
|
+
"codec": 12,
|
|
142
|
+
"fields": {
|
|
143
|
+
"commands": {"type": "array", "array": {
|
|
144
|
+
"value": {"type": "string"}
|
|
145
|
+
}},
|
|
146
|
+
"#commands": {"bytes": 1, "type": "unsigned"}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -451,10 +451,10 @@ report:
|
|
|
451
451
|
'order': 5,
|
|
452
452
|
'logged': False,
|
|
453
453
|
'data': None,
|
|
454
|
-
'schedule':
|
|
454
|
+
'schedule': None
|
|
455
455
|
}
|
|
456
456
|
binary = server.encode(data, 'login')
|
|
457
|
-
print('server', binary)
|
|
457
|
+
print(f'server ({len(binary)})', binary)
|
|
458
458
|
header, recv = client.decode(binary)
|
|
459
459
|
self.assertEqual(header, 'login')
|
|
460
460
|
self.assertEqual(data, recv)
|
|
@@ -645,6 +645,22 @@ report:
|
|
|
645
645
|
header, recv = client.decode(binary)
|
|
646
646
|
print(header, recv)
|
|
647
647
|
|
|
648
|
+
def test_decode_sergio(self):
|
|
649
|
+
val = {'id': '675882972c030d7f86188ee9', 'command': 'C', 'value': 'value'}
|
|
650
|
+
client = Protocol(js={"formats": {"command": {
|
|
651
|
+
"header": "$",
|
|
652
|
+
"server": {
|
|
653
|
+
"comando": {"bytes": 1, "type": "char"},
|
|
654
|
+
"id": {"bytes": 0, "type": "string"},
|
|
655
|
+
"value": {"bytes": 0, "type": "string"}
|
|
656
|
+
},
|
|
657
|
+
"client": {
|
|
658
|
+
"id": {"bytes": 0, "type": "string"}
|
|
659
|
+
}
|
|
660
|
+
}}}, server=True)
|
|
661
|
+
binary = client.encode(val, 'command')
|
|
662
|
+
print(binary)
|
|
663
|
+
|
|
648
664
|
def test_singleton(self):
|
|
649
665
|
protocol1 = ProtobinLoader('codec8.json')
|
|
650
666
|
protocol2 = ProtobinLoader('codec8.json')
|
|
@@ -654,3 +670,24 @@ report:
|
|
|
654
670
|
protocol6 = ProtobinLoader('demo.json', server=True)
|
|
655
671
|
protocol7 = ProtobinLoader('demo.json', server=True)
|
|
656
672
|
protocol8 = ProtobinLoader('demo.json', server=True)
|
|
673
|
+
|
|
674
|
+
def test_error_type(self):
|
|
675
|
+
with self.assertRaises(FormatError):
|
|
676
|
+
Protocol(js={"formats": {"command": {
|
|
677
|
+
"header": "$",
|
|
678
|
+
"server": {
|
|
679
|
+
"comando": {"bytes": 1, "type": "char"},
|
|
680
|
+
"id": {"bytes": 0, "type": "string"},
|
|
681
|
+
"value": {"bytes": 0, "type": "string"}
|
|
682
|
+
},
|
|
683
|
+
"client": {
|
|
684
|
+
"id": {"bytes": 0}
|
|
685
|
+
}
|
|
686
|
+
}}}, server=True)
|
|
687
|
+
|
|
688
|
+
def test_teltonika_binary(self):
|
|
689
|
+
binary = b'\x00\x00\x00\x00\x00\x00\x04\x1d\x08#\x00\x00\x01\x93x\xb7T\xc8\x00\xd2\x0f\xa2\xd0\xf8\xdbz\x81\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb7\xa2\xe8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb7\xf1\x08\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb8?(\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb8\x8dH\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbae\xf0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbc6\xc8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbe\x0fp\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbf\xe40\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc1\xb8\xf0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc3\x91\x98\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc5bp\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc7;\x18\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc9\x13\xc0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xca\xe4\x98\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xcc\xbd@\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xce\x92\x00\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd0f\xc0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd2;\x80\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd4\x10@\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd5\xe8\xe8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd7\xbd\xa8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd9\x92h\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xdbg(\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xdd?\xd0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xdf\x14\x90\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe0\xe9P\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe2\xbe\x10\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe4\x92\xd0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe6kx\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe8<P\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xea\x14\xf8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xeb\xed\xa0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xed\xbex\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xef\x97 \x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00v\x92'
|
|
690
|
+
client = Protocol(file='teltonika.json', server=None)
|
|
691
|
+
header, recv = client.decode(binary)
|
|
692
|
+
print(recv)
|
|
693
|
+
|
|
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
|