protobin 0.0.6__tar.gz → 0.0.7__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.6 → protobin-0.0.7}/PKG-INFO +1 -1
- {protobin-0.0.6 → protobin-0.0.7}/protobin/fields.py +50 -30
- {protobin-0.0.6 → protobin-0.0.7}/protobin/protocol.py +25 -18
- {protobin-0.0.6 → protobin-0.0.7}/pyproject.toml +1 -1
- protobin-0.0.7/tests/demo.json +30 -0
- {protobin-0.0.6 → protobin-0.0.7}/tests/demo.yaml +51 -49
- {protobin-0.0.6 → protobin-0.0.7}/tests/tests.py +126 -94
- protobin-0.0.6/tests/demo.json +0 -291
- {protobin-0.0.6 → protobin-0.0.7}/.gitignore +0 -0
- {protobin-0.0.6 → protobin-0.0.7}/LICENSE.txt +0 -0
- {protobin-0.0.6 → protobin-0.0.7}/README.md +0 -0
- {protobin-0.0.6 → protobin-0.0.7}/protobin/__init__.py +0 -0
- {protobin-0.0.6 → protobin-0.0.7}/protobin/errors.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: protobin
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
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
|
|
@@ -27,9 +27,9 @@ class FieldBase:
|
|
|
27
27
|
key: Union[str, List[str]]
|
|
28
28
|
type: FieldEnum
|
|
29
29
|
|
|
30
|
-
def __init__(self, js):
|
|
30
|
+
def __init__(self, k, js):
|
|
31
|
+
self.key = k
|
|
31
32
|
self.type = js['type']
|
|
32
|
-
self.key = js.get('key')
|
|
33
33
|
self.bytes = js.get('bytes')
|
|
34
34
|
|
|
35
35
|
def decode(self, binary):
|
|
@@ -88,8 +88,8 @@ class FieldBase:
|
|
|
88
88
|
class FieldArray(FieldBase):
|
|
89
89
|
length: int
|
|
90
90
|
|
|
91
|
-
def __init__(self, js):
|
|
92
|
-
super().__init__(js)
|
|
91
|
+
def __init__(self, k, js):
|
|
92
|
+
super().__init__(k, js)
|
|
93
93
|
self.array = js['array']
|
|
94
94
|
|
|
95
95
|
def decode(self, binary):
|
|
@@ -108,7 +108,7 @@ class FieldArray(FieldBase):
|
|
|
108
108
|
length = len(val)
|
|
109
109
|
binary += length.to_bytes(1, 'big')
|
|
110
110
|
for i in range(length):
|
|
111
|
-
fields = [FIELD_MAP[f['type']](f) for f in self.array]
|
|
111
|
+
fields = [FIELD_MAP[f['type']](k, f) for k, f in self.array.items()]
|
|
112
112
|
for f in fields:
|
|
113
113
|
binary += f.encode(val[i])
|
|
114
114
|
return binary
|
|
@@ -117,7 +117,7 @@ class FieldArray(FieldBase):
|
|
|
117
117
|
lista = []
|
|
118
118
|
for i in range(self.length):
|
|
119
119
|
data = {}
|
|
120
|
-
fields = [FIELD_MAP[f['type']](f) for f in self.array]
|
|
120
|
+
fields = [FIELD_MAP[f['type']](k, f) for k, f in self.array.items()]
|
|
121
121
|
for f in fields:
|
|
122
122
|
val, binary = f.decode(binary)
|
|
123
123
|
data[f.key] = val
|
|
@@ -128,8 +128,8 @@ class FieldArray(FieldBase):
|
|
|
128
128
|
class FieldBits(FieldBase):
|
|
129
129
|
length: int
|
|
130
130
|
|
|
131
|
-
def __init__(self, js):
|
|
132
|
-
super().__init__(js)
|
|
131
|
+
def __init__(self, k, js):
|
|
132
|
+
super().__init__(k, js)
|
|
133
133
|
self.length = js.get('length', 0)
|
|
134
134
|
self.bytes = math.ceil(self.length / 8)
|
|
135
135
|
|
|
@@ -177,10 +177,21 @@ class FieldBool(FieldBase):
|
|
|
177
177
|
bytes = 1
|
|
178
178
|
|
|
179
179
|
def to_binary(self, val):
|
|
180
|
-
|
|
180
|
+
if val is None:
|
|
181
|
+
val = 2
|
|
182
|
+
else:
|
|
183
|
+
val = bool(val)
|
|
184
|
+
|
|
185
|
+
return val.to_bytes(1, 'big', signed=False)
|
|
181
186
|
|
|
182
187
|
def from_binary(self, binary):
|
|
183
|
-
|
|
188
|
+
val = int.from_bytes(binary, 'big', signed=False)
|
|
189
|
+
if val == 0:
|
|
190
|
+
return False
|
|
191
|
+
elif val == 1:
|
|
192
|
+
return True
|
|
193
|
+
else:
|
|
194
|
+
return None
|
|
184
195
|
|
|
185
196
|
|
|
186
197
|
class FieldChar(FieldBase):
|
|
@@ -197,8 +208,8 @@ class FieldChar(FieldBase):
|
|
|
197
208
|
|
|
198
209
|
class FieldDate(FieldBase):
|
|
199
210
|
|
|
200
|
-
def __init__(self, js):
|
|
201
|
-
super().__init__(js)
|
|
211
|
+
def __init__(self, k, js):
|
|
212
|
+
super().__init__(k, js)
|
|
202
213
|
self.bytes = 3
|
|
203
214
|
|
|
204
215
|
def to_binary(self, val: datetime.datetime | str):
|
|
@@ -219,12 +230,16 @@ class FieldDate(FieldBase):
|
|
|
219
230
|
|
|
220
231
|
class FieldDateTime(FieldBase):
|
|
221
232
|
|
|
222
|
-
def __init__(self, js):
|
|
223
|
-
super().__init__(js)
|
|
233
|
+
def __init__(self, k, js):
|
|
234
|
+
super().__init__(k, js)
|
|
224
235
|
self.bytes = 6
|
|
225
236
|
|
|
226
237
|
def to_binary(self, val: datetime.datetime | str):
|
|
227
|
-
if
|
|
238
|
+
if val is None:
|
|
239
|
+
val = datetime.datetime(2000, 1, 1)
|
|
240
|
+
elif not isinstance(val, datetime.datetime):
|
|
241
|
+
raise ValueError(f'Error en el campo "{self.key}" se espera un datetime pero se recibe {val}')
|
|
242
|
+
elif isinstance(val, str):
|
|
228
243
|
val = datetime.datetime.strptime(val, '%Y-%m-%d %H:%M:%S').date()
|
|
229
244
|
return bytes([
|
|
230
245
|
self.to_nible(val.day),
|
|
@@ -246,12 +261,11 @@ class FieldDateTime(FieldBase):
|
|
|
246
261
|
|
|
247
262
|
|
|
248
263
|
class FieldFlags(FieldBase):
|
|
249
|
-
keys: List[str]
|
|
250
264
|
|
|
251
|
-
def __init__(self, js):
|
|
252
|
-
super().__init__(js)
|
|
253
|
-
self.
|
|
254
|
-
self.length = len(self.
|
|
265
|
+
def __init__(self, k, js):
|
|
266
|
+
super().__init__(k, js)
|
|
267
|
+
self.key = self.key.split(',')
|
|
268
|
+
self.length = len(self.key)
|
|
255
269
|
self.bytes = math.ceil(self.length / 8)
|
|
256
270
|
|
|
257
271
|
def encode(self, data):
|
|
@@ -264,23 +278,23 @@ class FieldFlags(FieldBase):
|
|
|
264
278
|
for b in bits:
|
|
265
279
|
flags.append(b == '1')
|
|
266
280
|
val = {}
|
|
267
|
-
order = -len(self.
|
|
268
|
-
for k in self.
|
|
281
|
+
order = -len(self.key)
|
|
282
|
+
for k in self.key:
|
|
269
283
|
val[k] = flags[order]
|
|
270
284
|
order += 1
|
|
271
285
|
return val
|
|
272
286
|
|
|
273
287
|
def to_binary(self, data):
|
|
274
|
-
bits = '0' * (8 - (len(self.
|
|
275
|
-
for k in self.
|
|
288
|
+
bits = '0' * (8 - (len(self.key) % 8))
|
|
289
|
+
for k in self.key:
|
|
276
290
|
bits += '1' if data[k] else '0'
|
|
277
291
|
return int(bits, 2).to_bytes(self.bytes, 'big', signed=False)
|
|
278
292
|
|
|
279
293
|
|
|
280
294
|
class FieldFloat(FieldBase):
|
|
281
295
|
|
|
282
|
-
def __init__(self, js):
|
|
283
|
-
super().__init__(js)
|
|
296
|
+
def __init__(self, k, js):
|
|
297
|
+
super().__init__(k, js)
|
|
284
298
|
self.decimals = js['decimals']
|
|
285
299
|
|
|
286
300
|
def from_binary(self, binary):
|
|
@@ -327,8 +341,12 @@ class FieldTime(FieldBase):
|
|
|
327
341
|
|
|
328
342
|
bytes = 2
|
|
329
343
|
|
|
330
|
-
def to_binary(self, val: datetime.datetime | str):
|
|
331
|
-
if
|
|
344
|
+
def to_binary(self, val: datetime.datetime | datetime.time | str):
|
|
345
|
+
if val is None:
|
|
346
|
+
val = datetime.time(0, 0)
|
|
347
|
+
elif not isinstance(val, datetime.datetime) and not isinstance(val, datetime.time):
|
|
348
|
+
raise ValueError(f'Error en el campo "{self.key}" se espera un datetime o time pero se recibe {val}')
|
|
349
|
+
elif isinstance(val, str):
|
|
332
350
|
val = datetime.datetime.strptime(val, '%H:%M').date()
|
|
333
351
|
return bytes([
|
|
334
352
|
self.to_nible(val.hour),
|
|
@@ -338,13 +356,15 @@ class FieldTime(FieldBase):
|
|
|
338
356
|
def from_binary(self, binary):
|
|
339
357
|
H, binary = self.get_nible(binary)
|
|
340
358
|
M, binary = self.get_nible(binary)
|
|
359
|
+
if H == 0 and M == 0:
|
|
360
|
+
return None
|
|
341
361
|
return datetime.time(H, M)
|
|
342
362
|
|
|
343
363
|
|
|
344
364
|
class FieldTimestamp(FieldBase):
|
|
345
365
|
|
|
346
|
-
def __init__(self, js):
|
|
347
|
-
super().__init__(js)
|
|
366
|
+
def __init__(self, k, js):
|
|
367
|
+
super().__init__(k, js)
|
|
348
368
|
self.bytes = 8
|
|
349
369
|
|
|
350
370
|
def to_binary(self, val: datetime.datetime | str):
|
|
@@ -9,13 +9,14 @@ class Format:
|
|
|
9
9
|
|
|
10
10
|
fields: [FieldBase]
|
|
11
11
|
|
|
12
|
-
def __init__(self,
|
|
12
|
+
def __init__(self, format: [object]):
|
|
13
13
|
self.fields = []
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
self.header = format['header']
|
|
15
|
+
for k, f in format['fields'].items():
|
|
16
|
+
self.fields.append(FIELD_MAP[f['type']](k, f))
|
|
16
17
|
|
|
17
18
|
def encode(self, data):
|
|
18
|
-
binary = b''
|
|
19
|
+
binary = self.header.encode('utf') + b'='
|
|
19
20
|
for f in self.fields:
|
|
20
21
|
binary += f.encode(data)
|
|
21
22
|
return binary
|
|
@@ -24,11 +25,11 @@ class Format:
|
|
|
24
25
|
data = {}
|
|
25
26
|
for f in self.fields:
|
|
26
27
|
val, binary = f.decode(binary)
|
|
27
|
-
if f.key:
|
|
28
|
-
|
|
29
|
-
else:
|
|
30
|
-
for k in f.keys:
|
|
28
|
+
if isinstance(f.key, list):
|
|
29
|
+
for k in f.key:
|
|
31
30
|
data[k] = val[k]
|
|
31
|
+
else:
|
|
32
|
+
data[f.key] = val
|
|
32
33
|
return data
|
|
33
34
|
|
|
34
35
|
def to_dict(self):
|
|
@@ -38,25 +39,31 @@ class Format:
|
|
|
38
39
|
class Protocol:
|
|
39
40
|
|
|
40
41
|
def __init__(self, file=None, js=None):
|
|
42
|
+
self.headers = {}
|
|
41
43
|
if file:
|
|
42
44
|
with open(file, 'r') as f:
|
|
43
45
|
if 'json' in file:
|
|
44
46
|
js = json.loads(f.read())
|
|
45
|
-
self.
|
|
46
|
-
for k in js.keys():
|
|
47
|
-
self.formats[k] = Format(js[k])
|
|
47
|
+
self.load_format(js)
|
|
48
48
|
elif 'yaml' in file:
|
|
49
49
|
js = yaml.full_load(f.read())
|
|
50
|
-
self.
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
self.load_format(js)
|
|
51
|
+
else:
|
|
52
|
+
self.load_format(js)
|
|
53
53
|
|
|
54
|
+
def load_format(self, js):
|
|
55
|
+
self.formats = {}
|
|
56
|
+
for k in js.keys():
|
|
57
|
+
self.formats[k] = Format(js[k])
|
|
58
|
+
self.headers[js[k]['header']] = k
|
|
54
59
|
|
|
55
|
-
def
|
|
56
|
-
return self.formats[
|
|
60
|
+
def get_format(self, h):
|
|
61
|
+
return self.formats[self.headers[h.decode('utf')]]
|
|
57
62
|
|
|
58
63
|
def encode(self, data, format):
|
|
59
64
|
return self.formats[format].encode(data)
|
|
60
65
|
|
|
61
|
-
def decode(self, binary
|
|
62
|
-
|
|
66
|
+
def decode(self, binary):
|
|
67
|
+
h, binary = binary.split(b'=')
|
|
68
|
+
format = self.get_format(h)
|
|
69
|
+
return h.decode('utf'), format.decode(binary)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"login": {
|
|
3
|
+
"header": "T",
|
|
4
|
+
"fields": {
|
|
5
|
+
"serial": {"bytes": 0, "type": "string"}
|
|
6
|
+
}
|
|
7
|
+
},
|
|
8
|
+
"report": {
|
|
9
|
+
"header": "P",
|
|
10
|
+
"fields": {
|
|
11
|
+
"positions": {"bytes": 19, "type": "array", "array": {
|
|
12
|
+
"time": {"bytes": 6, "type": "datetime"},
|
|
13
|
+
"lng": {"bytes": 4, "type": "float", "decimals": 6},
|
|
14
|
+
"lat": {"bytes": 4, "type": "float", "decimals": 6},
|
|
15
|
+
"speed": {"bytes": 1, "type": "unsigned"},
|
|
16
|
+
"mark": {"bytes": 2, "type": "unsigned"},
|
|
17
|
+
"busstop": {"bytes": 2, "type": "unsigned"}}
|
|
18
|
+
},
|
|
19
|
+
"trip": {"bytes": 4, "type": "unsigned"},
|
|
20
|
+
"route": {"bytes": 1, "type": "unsigned"},
|
|
21
|
+
"direction": {"bytes": 1, "type": "bool"},
|
|
22
|
+
"state": {"bytes": 1, "type": "char"},
|
|
23
|
+
"sales": {"bytes": 3, "type": "unsigned"},
|
|
24
|
+
"events": {"bytes": 3, "type": "array", "array": {
|
|
25
|
+
"id": {"bytes": 2, "type": "unsigned"},
|
|
26
|
+
"value": {"bytes": 1, "type": "unsigned"}}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,53 +1,55 @@
|
|
|
1
1
|
report:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
2
|
+
header: P
|
|
3
|
+
format:
|
|
4
|
+
positions:
|
|
5
|
+
bytes: 19
|
|
6
|
+
type: array
|
|
7
|
+
array:
|
|
8
|
+
time:
|
|
9
|
+
bytes: 6
|
|
10
|
+
type: datetime
|
|
11
|
+
lng:
|
|
12
|
+
bytes: 4
|
|
13
|
+
decimals: 6
|
|
14
|
+
type: float
|
|
15
|
+
lat:
|
|
16
|
+
bytes: 4
|
|
17
|
+
decimals: 6
|
|
18
|
+
type: float
|
|
19
|
+
speed:
|
|
20
|
+
bytes: 1
|
|
21
|
+
type: unsigned
|
|
22
|
+
mark:
|
|
23
|
+
bytes: 2
|
|
24
|
+
type: unsigned
|
|
25
|
+
busstop:
|
|
26
|
+
bytes: 2
|
|
27
|
+
type: unsigned
|
|
28
|
+
trip:
|
|
29
|
+
bytes: 4
|
|
30
|
+
type: unsigned
|
|
31
|
+
route:
|
|
32
|
+
bytes: 1
|
|
33
|
+
type: unsigned
|
|
34
|
+
direction:
|
|
35
|
+
bytes: 1
|
|
36
|
+
type: bool
|
|
37
|
+
state:
|
|
38
|
+
bytes: 1
|
|
39
|
+
type: char
|
|
40
|
+
sales:
|
|
41
|
+
bytes: 3
|
|
42
|
+
type: unsigned
|
|
43
|
+
events:
|
|
44
|
+
bytes: 3
|
|
45
|
+
type: array
|
|
46
|
+
array:
|
|
47
|
+
id:
|
|
48
|
+
bytes: 2
|
|
49
|
+
type: unsigned
|
|
50
|
+
value:
|
|
51
|
+
bytes: 1
|
|
52
|
+
type: unsigned
|
|
51
53
|
|
|
52
54
|
ask_schedule:
|
|
53
55
|
id:
|
|
@@ -62,73 +62,69 @@ DATA = {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
class FormatTest(unittest.TestCase):
|
|
66
|
-
|
|
67
|
-
def test_format_array(self):
|
|
68
|
-
parser = Protocol(js={
|
|
69
|
-
'array': [{'key': 'test', 'bytes': 0, 'type': 'array', 'array': [
|
|
70
|
-
{'key': 'test', 'bytes': 0, 'type': 'string'}
|
|
71
|
-
]}]
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
def test_format_bits(self):
|
|
75
|
-
parser = Protocol(js={
|
|
76
|
-
'bits': [{'key': 'test', 'bytes': 2, 'type': 'bits'}],
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
def test_format_date(self):
|
|
80
|
-
|
|
81
|
-
self.parser = Protocol(js={
|
|
82
|
-
'date': [{'key': 'test', 'bytes': 1, 'type': 'date'}],
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
def test_format_flags(self):
|
|
86
|
-
|
|
87
|
-
self.parser = Protocol(js={
|
|
88
|
-
'flags': [{'keys': ['f1', 'f2', 'f3', 'f4'], 'bytes': 1, 'type': 'flags'}],
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
def test_format(self):
|
|
92
|
-
|
|
93
|
-
self.parser = Protocol(js={
|
|
94
|
-
'array': [{'key': 'test', 'bytes': 0, 'type': 'array', 'array': [
|
|
95
|
-
{'key': 'test', 'bytes': 0, 'type': 'string'}
|
|
96
|
-
]}],
|
|
97
|
-
'bits': [{'key': 'test', 'bytes': 2, 'type': 'bits'}],
|
|
98
|
-
'bool': [{'key': 'test', 'bytes': 1, 'type': 'bool'}],
|
|
99
|
-
'char': [{'key': 'test', 'bytes': 1, 'type': 'char'}],
|
|
100
|
-
'date': [{'key': 'test', 'bytes': 3, 'type': 'date'}],
|
|
101
|
-
'datetime': [{'key': 'test', 'bytes': 6, 'type': 'datetime'}],
|
|
102
|
-
'flags': [{'keys': ['f1', 'f2', 'f3', 'f4'], 'bytes': 1, 'type': 'flags'}],
|
|
103
|
-
'float': [{'key': 'test', 'bytes': 4, 'decimals': 6, 'type': 'float'}],
|
|
104
|
-
'signed': [{'key': 'test', 'bytes': 2, 'type': 'signed'}],
|
|
105
|
-
'string': [{'key': 'test', 'bytes': 0, 'type': 'string'}],
|
|
106
|
-
'time': [{'key': 'test', 'bytes': 1, 'type': 'time'}],
|
|
107
|
-
'timestamp': [{'key': 'test', 'bytes': 8, 'type': 'string'}],
|
|
108
|
-
'unsigned': [{'key': 'test', 'bytes': 3, 'type': 'unsigned'}]
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
|
|
112
65
|
class BasicTest(unittest.TestCase):
|
|
113
66
|
|
|
114
67
|
def setUp(self):
|
|
115
68
|
self.protocol = Protocol(js={
|
|
116
|
-
'array':
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
'
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
'
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
'
|
|
69
|
+
'array': {
|
|
70
|
+
"header": "A",
|
|
71
|
+
"fields": {
|
|
72
|
+
'test': {'bytes': 0, 'type': 'array', 'array': {
|
|
73
|
+
'test': {'bytes': 0, 'type': 'string'}
|
|
74
|
+
}}}
|
|
75
|
+
},
|
|
76
|
+
'bits': {
|
|
77
|
+
"header": "B",
|
|
78
|
+
"fields": {'test': {'type': 'bits'}}
|
|
79
|
+
},
|
|
80
|
+
'bits_fixed': {
|
|
81
|
+
"header": "b",
|
|
82
|
+
"fields": {'test': {'type': 'bits', 'length': 7}}
|
|
83
|
+
},
|
|
84
|
+
'bool': {
|
|
85
|
+
"header": "BO",
|
|
86
|
+
"fields": {'test': {'bytes': 1, 'type': 'bool'}}
|
|
87
|
+
},
|
|
88
|
+
'char': {
|
|
89
|
+
"header": "C",
|
|
90
|
+
"fields": {'test': {'bytes': 1, 'type': 'char'}}
|
|
91
|
+
},
|
|
92
|
+
'date': {
|
|
93
|
+
"header": "D",
|
|
94
|
+
"fields": {'test': {'bytes': 1, 'type': 'date'}}
|
|
95
|
+
},
|
|
96
|
+
'datetime': {
|
|
97
|
+
"header": "d",
|
|
98
|
+
"fields": {'test': {'bytes': 1, 'type': 'datetime'}}
|
|
99
|
+
},
|
|
100
|
+
'flags': {
|
|
101
|
+
"header": "F",
|
|
102
|
+
"fields": {'f1,f2,f3,f4': {'type': 'flags'}}
|
|
103
|
+
},
|
|
104
|
+
'float': {
|
|
105
|
+
"header": "f",
|
|
106
|
+
"fields": {'test': {'bytes': 4, 'decimals': 6, 'type': 'float'}}
|
|
107
|
+
},
|
|
108
|
+
'signed': {
|
|
109
|
+
"header": "+",
|
|
110
|
+
"fields": {'test': {'bytes': 2, 'type': 'signed'}}
|
|
111
|
+
},
|
|
112
|
+
'string': {
|
|
113
|
+
"header": "S",
|
|
114
|
+
"fields": {'test': {'bytes': 0, 'type': 'string'}}
|
|
115
|
+
},
|
|
116
|
+
'time': {
|
|
117
|
+
"header": "T",
|
|
118
|
+
"fields": {'test': {'bytes': 2, 'type': 'time'}}
|
|
119
|
+
},
|
|
120
|
+
'timestamp': {
|
|
121
|
+
"header": "TS",
|
|
122
|
+
"fields": {'test': {'bytes': 8, 'type': 'timestamp'}}
|
|
123
|
+
},
|
|
124
|
+
'unsigned': {
|
|
125
|
+
"header": "u",
|
|
126
|
+
"fields": {'test': {'bytes': 3, 'type': 'unsigned'}}
|
|
127
|
+
}
|
|
132
128
|
})
|
|
133
129
|
|
|
134
130
|
def test_array(self):
|
|
@@ -138,7 +134,7 @@ class BasicTest(unittest.TestCase):
|
|
|
138
134
|
{'test': 'otra más'}]
|
|
139
135
|
}
|
|
140
136
|
binary = self.protocol.encode(data, 'array')
|
|
141
|
-
recv = self.protocol.decode(binary
|
|
137
|
+
h, recv = self.protocol.decode(binary)
|
|
142
138
|
self.assertEqual(data, recv)
|
|
143
139
|
data = {'test': [
|
|
144
140
|
{'test': 'texto2 de prueba'},
|
|
@@ -147,93 +143,120 @@ class BasicTest(unittest.TestCase):
|
|
|
147
143
|
{'test': 'y una última'}]
|
|
148
144
|
}
|
|
149
145
|
binary = self.protocol.encode(data, 'array')
|
|
150
|
-
recv = self.protocol.decode(binary
|
|
146
|
+
h, recv = self.protocol.decode(binary)
|
|
151
147
|
self.assertEqual(data, recv)
|
|
152
148
|
|
|
153
149
|
def test_bits(self):
|
|
154
150
|
data = {'test': [True, False, True, False, False] * 3}
|
|
155
151
|
binary = self.protocol.encode(data, 'bits')
|
|
156
|
-
recv = self.protocol.decode(binary
|
|
152
|
+
h, recv = self.protocol.decode(binary)
|
|
157
153
|
self.assertEqual(data, recv)
|
|
158
154
|
data = {'test': [True, False, True, False, False] * 5}
|
|
159
155
|
binary = self.protocol.encode(data, 'bits')
|
|
160
|
-
recv = self.protocol.decode(binary
|
|
156
|
+
h, recv = self.protocol.decode(binary)
|
|
161
157
|
self.assertEqual(data, recv)
|
|
162
158
|
|
|
163
159
|
def test_bits_fixed(self):
|
|
164
160
|
data = {'test': [True, False, True, False, False, True, True]}
|
|
165
161
|
binary = self.protocol.encode(data, 'bits_fixed')
|
|
166
|
-
recv = self.protocol.decode(binary
|
|
162
|
+
h, recv = self.protocol.decode(binary)
|
|
167
163
|
self.assertEqual(data, recv)
|
|
168
164
|
|
|
169
165
|
def test_bool(self):
|
|
170
166
|
data = {'test': False}
|
|
171
167
|
binary = self.protocol.encode(data, 'bool')
|
|
172
|
-
recv = self.protocol.decode(binary
|
|
168
|
+
h, recv = self.protocol.decode(binary)
|
|
169
|
+
self.assertEqual(data, recv)
|
|
170
|
+
|
|
171
|
+
def test_bool_none(self):
|
|
172
|
+
data = {'test': None}
|
|
173
|
+
binary = self.protocol.encode(data, 'bool')
|
|
174
|
+
h, recv = self.protocol.decode(binary)
|
|
173
175
|
self.assertEqual(data, recv)
|
|
174
176
|
|
|
175
177
|
def test_char(self):
|
|
176
178
|
data = {'test': 'F'}
|
|
177
179
|
binary = self.protocol.encode(data, 'char')
|
|
178
|
-
recv = self.protocol.decode(binary
|
|
180
|
+
h, recv = self.protocol.decode(binary)
|
|
179
181
|
self.assertEqual(data, recv)
|
|
180
182
|
|
|
181
183
|
def test_date(self):
|
|
182
184
|
data = {'test': datetime.date(2024, 9, 13)}
|
|
183
185
|
binary = self.protocol.encode(data, 'date')
|
|
184
|
-
recv = self.protocol.decode(binary
|
|
186
|
+
h, recv = self.protocol.decode(binary)
|
|
185
187
|
self.assertEqual(data, recv)
|
|
186
188
|
|
|
187
189
|
def test_datetime(self):
|
|
188
190
|
data = {'test': datetime.datetime(2024, 9, 13, 15, 23, 51)}
|
|
189
191
|
binary = self.protocol.encode(data, 'datetime')
|
|
190
|
-
|
|
192
|
+
print('binary', binary)
|
|
193
|
+
h, recv = self.protocol.decode(binary)
|
|
194
|
+
print('recv', recv)
|
|
191
195
|
self.assertEqual(data, recv)
|
|
192
196
|
|
|
197
|
+
def test_datetime_error_type(self):
|
|
198
|
+
data = {'test': []}
|
|
199
|
+
with self.assertRaises(ValueError) as er:
|
|
200
|
+
self.protocol.encode(data, 'datetime')
|
|
201
|
+
|
|
202
|
+
def test_datetime_none(self):
|
|
203
|
+
data = {'test': None}
|
|
204
|
+
binary = self.protocol.encode(data, 'datetime')
|
|
205
|
+
print('binary', binary)
|
|
206
|
+
h, recv = self.protocol.decode(binary)
|
|
207
|
+
print('recv', recv)
|
|
208
|
+
self.assertEqual(datetime.datetime(2000, 1, 1), recv['test'])
|
|
209
|
+
|
|
193
210
|
def test_time(self):
|
|
194
211
|
data = {'test': datetime.time(15, 23)}
|
|
195
212
|
binary = self.protocol.encode(data, 'time')
|
|
196
|
-
recv = self.protocol.decode(binary
|
|
213
|
+
h, recv = self.protocol.decode(binary)
|
|
214
|
+
self.assertEqual(data, recv)
|
|
215
|
+
|
|
216
|
+
def test_time_none(self):
|
|
217
|
+
data = {'test': None}
|
|
218
|
+
binary = self.protocol.encode(data, 'time')
|
|
219
|
+
h, recv = self.protocol.decode(binary)
|
|
197
220
|
self.assertEqual(data, recv)
|
|
198
221
|
|
|
199
222
|
def test_flags(self):
|
|
200
223
|
data = {'f1': True, 'f2': False, 'f3': False, 'f4': True}
|
|
201
224
|
binary = self.protocol.encode(data, 'flags')
|
|
202
|
-
recv = self.protocol.decode(binary
|
|
225
|
+
h, recv = self.protocol.decode(binary)
|
|
203
226
|
self.assertEqual(data, recv)
|
|
204
227
|
|
|
205
228
|
def test_float(self):
|
|
206
229
|
data = {'test': -11.659812}
|
|
207
230
|
binary = self.protocol.encode(data, 'float')
|
|
208
|
-
recv = self.protocol.decode(binary
|
|
231
|
+
h, recv = self.protocol.decode(binary)
|
|
209
232
|
self.assertEqual(data, recv)
|
|
210
233
|
|
|
211
234
|
def test_signed(self):
|
|
212
235
|
data = {'test': -11812}
|
|
213
236
|
binary = self.protocol.encode(data, 'signed')
|
|
214
|
-
recv = self.protocol.decode(binary
|
|
237
|
+
h, recv = self.protocol.decode(binary)
|
|
215
238
|
self.assertEqual(data, recv)
|
|
216
239
|
|
|
217
240
|
def test_unsigned(self):
|
|
218
241
|
data = {'test': 9811812}
|
|
219
242
|
binary = self.protocol.encode(data, 'unsigned')
|
|
220
|
-
recv = self.protocol.decode(binary
|
|
243
|
+
h, recv = self.protocol.decode(binary)
|
|
221
244
|
self.assertEqual(data, recv)
|
|
222
245
|
|
|
223
246
|
def test_string(self):
|
|
224
247
|
data = {'test': 'texto de prueba'}
|
|
225
248
|
binary = self.protocol.encode(data, 'string')
|
|
226
|
-
recv = self.protocol.decode(binary
|
|
249
|
+
h, recv = self.protocol.decode(binary)
|
|
227
250
|
self.assertEqual(data, recv)
|
|
228
251
|
data = {'test': 'otro texto de prueba más largo'}
|
|
229
252
|
binary = self.protocol.encode(data, 'string')
|
|
230
|
-
recv = self.protocol.decode(binary
|
|
253
|
+
h, recv = self.protocol.decode(binary)
|
|
231
254
|
self.assertEqual(data, recv)
|
|
232
255
|
|
|
233
256
|
def test_timestamp(self):
|
|
234
257
|
data = {'test': datetime.datetime(2024, 9, 13, 15, 23, 51, 265981)}
|
|
235
258
|
binary = self.protocol.encode(data, 'timestamp')
|
|
236
|
-
recv = self.protocol.decode(binary
|
|
259
|
+
h, recv = self.protocol.decode(binary)
|
|
237
260
|
self.assertEqual(data, recv)
|
|
238
261
|
|
|
239
262
|
|
|
@@ -242,28 +265,31 @@ class AdvancedTest(unittest.TestCase):
|
|
|
242
265
|
def test_file_json(self):
|
|
243
266
|
protocol = Protocol(file='demo.json')
|
|
244
267
|
binary = protocol.encode(DATA, 'report')
|
|
245
|
-
recv = protocol.decode(binary
|
|
268
|
+
h, recv = protocol.decode(binary)
|
|
246
269
|
self.assertEqual(DATA, recv)
|
|
270
|
+
self.assertEqual(h, 'P')
|
|
247
271
|
|
|
248
|
-
def test_file_yaml(self):
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
272
|
+
# def test_file_yaml(self):
|
|
273
|
+
# protocol = Protocol(file='demo.yaml')
|
|
274
|
+
# binary = protocol.encode(DATA, 'report')
|
|
275
|
+
# h, recv = protocol.decode(binary)
|
|
276
|
+
# self.assertEqual(h, 'P')
|
|
253
277
|
|
|
254
278
|
def test_json(self):
|
|
255
|
-
protocol = Protocol(js={'medida':
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
279
|
+
protocol = Protocol(js={'medida':
|
|
280
|
+
{'header': 'M',
|
|
281
|
+
'fields': {
|
|
282
|
+
'id': {'bytes': 1, 'type': 'unsigned'},
|
|
283
|
+
'nombre': {'type': 'string'},
|
|
284
|
+
'valor': {'bytes': 2, 'type': 'signed'}
|
|
285
|
+
}}})
|
|
260
286
|
data = {'id': 2, 'nombre': 'Voltaje', 'valor': -20}
|
|
261
287
|
binary = protocol.encode(data, 'medida')
|
|
262
|
-
recv = protocol.decode(binary
|
|
288
|
+
h, recv = protocol.decode(binary)
|
|
263
289
|
self.assertEqual(data, recv)
|
|
264
290
|
data = {'id': 4, 'nombre': 'Corriente', 'valor': 240}
|
|
265
291
|
binary = protocol.encode(data, 'medida')
|
|
266
|
-
recv = protocol.decode(binary
|
|
292
|
+
h, recv = protocol.decode(binary)
|
|
267
293
|
self.assertEqual(data, recv)
|
|
268
294
|
|
|
269
295
|
def test_new_yaml(self):
|
|
@@ -319,8 +345,14 @@ class AdvancedTest(unittest.TestCase):
|
|
|
319
345
|
type: unsigned
|
|
320
346
|
""")
|
|
321
347
|
js = json.dumps(ym, indent=2)
|
|
322
|
-
print(js)
|
|
323
348
|
|
|
324
349
|
def test_convert_json_to_yaml(self):
|
|
325
350
|
protocol = Protocol(file='demo.json')
|
|
326
351
|
|
|
352
|
+
def test_login(self):
|
|
353
|
+
protocol = Protocol(file='demo.json')
|
|
354
|
+
data = {'serial': '15984316545'}
|
|
355
|
+
binary = protocol.encode(data, 'login')
|
|
356
|
+
header, recv = protocol.decode(binary)
|
|
357
|
+
self.assertEqual(data, recv)
|
|
358
|
+
self.assertEqual(header, 'T')
|
protobin-0.0.6/tests/demo.json
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"ask_schedule1": {
|
|
3
|
-
"id": [{"bytes": 4, "type": "unsigned"}],
|
|
4
|
-
"inicio": [{"bytes": 6, "type": "datetime"}]},
|
|
5
|
-
|
|
6
|
-
"fare": [
|
|
7
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
8
|
-
{"key": "color", "bytes": 7, "type": "string"},
|
|
9
|
-
{"key": "orden", "bytes": 1, "type": "unsigned"},
|
|
10
|
-
{"key": "nombre", "bytes": 13, "type": "string"},
|
|
11
|
-
{"keys": ["activo", "reintegro"], "bytes": 1, "type": "flags"},
|
|
12
|
-
{"keys": ["lunes", "martes", "miercoles", "jueves", "viernes", "sabado", "domingo", "feriado"], "bytes": 1, "type": "flags"},
|
|
13
|
-
{"key": "ruta", "bytes": 2, "type": "unsigned"},
|
|
14
|
-
{"key": "tarifa", "bytes": 2, "type": "float", "decimals": 2},
|
|
15
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
16
|
-
],
|
|
17
|
-
"command": [
|
|
18
|
-
{"key": "comando", "bytes": 1, "type": "char"},
|
|
19
|
-
{"key": "id", "bytes": 0, "type": "string"},
|
|
20
|
-
{"key": "value", "bytes": 0, "type": "string"}
|
|
21
|
-
],
|
|
22
|
-
"route_settings": [
|
|
23
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
24
|
-
{"key": "nombre", "bytes": 0, "type": "string"},
|
|
25
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
26
|
-
{"key": "tipo", "bytes": 0, "type": "string"},
|
|
27
|
-
{"key": "data", "bytes": 0, "type": "string"},
|
|
28
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
29
|
-
],
|
|
30
|
-
"forward_datero": [
|
|
31
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"},
|
|
32
|
-
{"key": "salida", "bytes": 4, "type": "unsigned"},
|
|
33
|
-
{"key": "hora", "bytes": 6, "type": "datetime"},
|
|
34
|
-
{"key": "dateros", "bytes": 0, "type": "array", "array": [
|
|
35
|
-
{"key": "padron", "bytes": 2, "type": "unsigned"},
|
|
36
|
-
{"key": "delta", "bytes": 1, "type": "unsigned"}
|
|
37
|
-
]}
|
|
38
|
-
],
|
|
39
|
-
"backward_datero": [
|
|
40
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"},
|
|
41
|
-
{"key": "i", "bytes": 1, "type": "unsigned"},
|
|
42
|
-
{"key": "delta", "bytes": 1, "type": "unsigned"},
|
|
43
|
-
{"key": "padron", "bytes": 2, "type": "unsigned"},
|
|
44
|
-
{"key": "id", "bytes": 0, "type": "string"}
|
|
45
|
-
],
|
|
46
|
-
"error": [
|
|
47
|
-
{"key": "error", "bytes": 0, "type": "string"}
|
|
48
|
-
],
|
|
49
|
-
"geocerca": [
|
|
50
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
51
|
-
{"key": "orden", "bytes": 1, "type": "unsigned"},
|
|
52
|
-
{"key": "longitud", "bytes": 4, "type": "float", "decimals": 6},
|
|
53
|
-
{"key": "latitud", "bytes": 4, "type": "float", "decimals": 6},
|
|
54
|
-
{"key": "radio", "bytes": 2, "type": "unsigned"},
|
|
55
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
56
|
-
{"keys": ["lado", "control", "datear", "activo"], "bytes": 1, "type": "flags"},
|
|
57
|
-
{"key": "nombre", "bytes": 15, "type": "string"},
|
|
58
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
59
|
-
],
|
|
60
|
-
"ask_trip": [
|
|
61
|
-
{"key": "salida", "bytes": 4, "type": "unsigned"}
|
|
62
|
-
],
|
|
63
|
-
"schedule": [
|
|
64
|
-
{"key": "salida", "bytes": 4, "type": "unsigned"},
|
|
65
|
-
{"key": "controles", "bytes": 0, "type": "array", "array": [
|
|
66
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"}
|
|
67
|
-
]}
|
|
68
|
-
],
|
|
69
|
-
"ask_schedule": [
|
|
70
|
-
{"key": "id", "bytes": 4, "type": "unsigned"},
|
|
71
|
-
{"key": "inicio", "bytes": 6, "type": "datetime"},
|
|
72
|
-
{"key": "controles", "bytes": 0, "type": "array", "array": [
|
|
73
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"},
|
|
74
|
-
{"key": "tiempo", "bytes": 1, "type": "signed"},
|
|
75
|
-
{"key": "volada", "bytes": 1, "type": "signed"}
|
|
76
|
-
]}
|
|
77
|
-
],
|
|
78
|
-
"login": [
|
|
79
|
-
{"key": "serial", "bytes": 0, "type": "string"}
|
|
80
|
-
],
|
|
81
|
-
"new_ip": [
|
|
82
|
-
{"key": "ip", "bytes": 0, "type": "string"}
|
|
83
|
-
],
|
|
84
|
-
"login_device": [
|
|
85
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
86
|
-
{"key": "padron", "bytes": 2, "type": "unsigned"},
|
|
87
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
88
|
-
{"key": "lado", "bytes": 1, "type": "bool"},
|
|
89
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"},
|
|
90
|
-
{"key": "estado", "bytes": 1, "type": "char"},
|
|
91
|
-
{"key": "salida", "bytes": 4, "type": "unsigned"},
|
|
92
|
-
{"key": "conductor", "bytes": 4, "type": "unsigned"},
|
|
93
|
-
{"key": "orden", "bytes": 1, "type": "unsigned"},
|
|
94
|
-
{"key": "logueado", "bytes": 1, "type": "bool"},
|
|
95
|
-
{"key": "data", "bytes": 6, "type": "datetime"},
|
|
96
|
-
{"key": "programada", "bytes": 2, "type": "time"}
|
|
97
|
-
],
|
|
98
|
-
"start_sales": [
|
|
99
|
-
{"key": "clave", "bytes": 0, "type": "string"},
|
|
100
|
-
{"key": "dni", "bytes": 0, "type": "string"},
|
|
101
|
-
{"key": "lado", "bytes": 1, "type": "bool"},
|
|
102
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
103
|
-
{"key": "unidad", "bytes": 2, "type": "unsigned"}
|
|
104
|
-
],
|
|
105
|
-
"start_sales_response": [
|
|
106
|
-
{"key": "error", "bytes": 1, "type": "bool"},
|
|
107
|
-
{"key": "title", "bytes": 0, "type": "string"},
|
|
108
|
-
{"key": "mensaje", "bytes": 0, "type": "string"},
|
|
109
|
-
{"key": "sesiones", "bytes": 0, "type": "array", "array": [
|
|
110
|
-
{"key": "id", "bytes": 4, "type": "unsigned"},
|
|
111
|
-
{"key": "conductor_id", "bytes": 2, "type": "unsigned"},
|
|
112
|
-
{"key": "conductor_codigo", "bytes": 0, "type": "string"},
|
|
113
|
-
{"keys": ["activo", "castigado", "conductor", "vencido"], "bytes": 1, "type": "flags"},
|
|
114
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
115
|
-
{"key": "lado", "bytes": 1, "type": "bool"},
|
|
116
|
-
{"key": "inicio", "bytes": 6, "type": "datetime"}
|
|
117
|
-
]}
|
|
118
|
-
],
|
|
119
|
-
"finalize_sales": [
|
|
120
|
-
{"key": "sesion", "bytes": 4, "type": "unsigned"},
|
|
121
|
-
{"key": "unidad", "bytes": 2, "type": "unsigned"},
|
|
122
|
-
{"key": "fin", "bytes": 6, "type": "datetime"},
|
|
123
|
-
{"key": "produccion", "bytes": 4, "type": "unsigned"},
|
|
124
|
-
{"key": "primero", "bytes": 4, "type": "unsigned"},
|
|
125
|
-
{"key": "ultimo", "bytes": 4, "type": "unsigned"}
|
|
126
|
-
],
|
|
127
|
-
"finalize_sales_response": [
|
|
128
|
-
{"key": "error", "bytes": 1, "type": "bool"},
|
|
129
|
-
{"key": "title", "bytes": 0, "type": "string"},
|
|
130
|
-
{"key": "mensaje", "bytes": 0, "type": "string"},
|
|
131
|
-
{"key": "id", "bytes": 4, "type": "unsigned"}
|
|
132
|
-
],
|
|
133
|
-
"message": [
|
|
134
|
-
{"key": "id", "bytes": 4, "type": "unsigned"},
|
|
135
|
-
{"key": "texto", "bytes": 0, "type": "string"}
|
|
136
|
-
],
|
|
137
|
-
"message_response": [
|
|
138
|
-
{"key": "id", "bytes": 4, "type": "unsigned"},
|
|
139
|
-
{"key": "read", "bytes": 1, "type": "bool"}
|
|
140
|
-
],
|
|
141
|
-
"operation": [
|
|
142
|
-
{"key": "id", "bytes": 0, "type": "string"},
|
|
143
|
-
{"key": "section", "bytes": 0, "type": "string"},
|
|
144
|
-
{"key": "key", "bytes": 0, "type": "string"},
|
|
145
|
-
{"key": "value", "bytes": 0, "type": "string"}
|
|
146
|
-
],
|
|
147
|
-
"operation_response": [
|
|
148
|
-
{"key": "id", "bytes": 0, "type": "string"}
|
|
149
|
-
],
|
|
150
|
-
"busstop": [
|
|
151
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
152
|
-
{"key": "orden", "bytes": 1, "type": "unsigned"},
|
|
153
|
-
{"key": "longitud", "bytes": 4, "type": "float", "decimals": 6},
|
|
154
|
-
{"key": "latitud", "bytes": 4, "type": "float", "decimals": 6},
|
|
155
|
-
{"key": "radio", "bytes": 2, "type": "unsigned"},
|
|
156
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
157
|
-
{"keys": ["liquidar", "lado", "terminal", "activo"], "bytes": 1, "type": "flags"},
|
|
158
|
-
{"key": "nombre", "bytes": 14, "type": "string"},
|
|
159
|
-
{"key": "velocidad", "bytes": 1, "type": "unsigned"},
|
|
160
|
-
{"key": "tarifas", "bytes": 0, "type": "array", "array": [
|
|
161
|
-
{"key": "boleto", "bytes": 2, "type": "unsigned"},
|
|
162
|
-
{"key": "fin", "bytes": 2, "type": "unsigned"}
|
|
163
|
-
]},
|
|
164
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
165
|
-
],
|
|
166
|
-
"parameter": [
|
|
167
|
-
{"key": "id", "bytes": 0, "type": "string"},
|
|
168
|
-
{"key": "nombre", "bytes": 0, "type": "string"},
|
|
169
|
-
{"key": "valor", "bytes": 0, "type": "string"}
|
|
170
|
-
],
|
|
171
|
-
"report": [
|
|
172
|
-
{"key": "positions", "bytes": 19, "type": "array", "array": [
|
|
173
|
-
{"key": "time", "bytes": 6, "type": "datetime"},
|
|
174
|
-
{"key": "lng", "bytes": 4, "type": "float", "decimals": 6},
|
|
175
|
-
{"key": "lat", "bytes": 4, "type": "float", "decimals": 6},
|
|
176
|
-
{"key": "speed", "bytes": 1, "type": "unsigned"},
|
|
177
|
-
{"key": "mark", "bytes": 2, "type": "unsigned"},
|
|
178
|
-
{"key": "busstop", "bytes": 2, "type": "unsigned"}
|
|
179
|
-
]},
|
|
180
|
-
{"key": "trip", "bytes": 4, "type": "unsigned"},
|
|
181
|
-
{"key": "route", "bytes": 1, "type": "unsigned"},
|
|
182
|
-
{"key": "direction", "bytes": 1, "type": "bool"},
|
|
183
|
-
{"key": "state", "bytes": 1, "type": "char"},
|
|
184
|
-
{"key": "sales", "bytes": 3, "type": "unsigned"},
|
|
185
|
-
{"key": "events", "bytes": 3, "type": "array", "array": [
|
|
186
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
187
|
-
{"key": "value", "bytes": 1, "type": "unsigned"}
|
|
188
|
-
]}
|
|
189
|
-
],
|
|
190
|
-
"report": {
|
|
191
|
-
"positions": {"bytes": 19,"type": "array",
|
|
192
|
-
"array": {
|
|
193
|
-
"time": {"bytes": 6,"type": "datetime"},
|
|
194
|
-
"lng": {"bytes": 4,"decimals": 6,"type": "float"},
|
|
195
|
-
"lat": {"bytes": 4,"decimals": 6,"type": "float"},
|
|
196
|
-
"speed": {"bytes": 1,"type": "unsigned"},
|
|
197
|
-
"mark": {"bytes": 2,"type": "unsigned"},
|
|
198
|
-
"busstop": {"bytes": 2,"type": "unsigned"}
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
"trip": {"bytes": 4,"type": "unsigned"},
|
|
202
|
-
"route": {"bytes": 1,"type": "unsigned"},
|
|
203
|
-
"direction": {"bytes": 1,"type": "bool"},
|
|
204
|
-
"state": {"bytes": 1,"type": "char"},
|
|
205
|
-
"sales": {"bytes": 3,"type": "unsigned"},
|
|
206
|
-
"events": {"bytes": 3,"type": "array",
|
|
207
|
-
"array": {
|
|
208
|
-
"id": {"bytes": 2,"type": "unsigned"},
|
|
209
|
-
"value": {"bytes": 1,"type": "unsigned"}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
"position_response": [
|
|
214
|
-
{"key": "reportes", "bytes": 1, "type": "unsigned"},
|
|
215
|
-
{"key": "ids", "bytes": 0, "type": "array", "array": [
|
|
216
|
-
{"key": "id", "bytes": 2, "type": "unsigned"}
|
|
217
|
-
]}
|
|
218
|
-
],
|
|
219
|
-
"route": [
|
|
220
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
221
|
-
{"key": "codigo", "bytes": 0, "type": "string"},
|
|
222
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
223
|
-
],
|
|
224
|
-
"trip": [
|
|
225
|
-
{"key": "id", "bytes": 4, "type": "unsigned"},
|
|
226
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
227
|
-
{"key": "lado", "bytes": 1, "type": "bool"},
|
|
228
|
-
{"key": "inicio", "bytes": 6, "type": "datetime"},
|
|
229
|
-
{"key": "estado", "bytes": 1, "type": "char"},
|
|
230
|
-
{"key": "frecuencia", "bytes": 1, "type": "unsigned"},
|
|
231
|
-
{"key": "conductor", "bytes": 4, "type": "unsigned"},
|
|
232
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"},
|
|
233
|
-
{"key": "controles", "bytes": 0, "type": "array", "array": [
|
|
234
|
-
{"key": "geocerca", "bytes": 2, "type": "unsigned"},
|
|
235
|
-
{"key": "tiempo", "bytes": 1, "type": "signed"},
|
|
236
|
-
{"key": "volada", "bytes": 1, "type": "signed"}
|
|
237
|
-
]},
|
|
238
|
-
{"key": "marcados", "bytes": 0, "type": "bits"}
|
|
239
|
-
],
|
|
240
|
-
"settings": [
|
|
241
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
242
|
-
{"key": "nombre", "bytes": 0, "type": "string"},
|
|
243
|
-
{"key": "tipo", "bytes": 0, "type": "string"},
|
|
244
|
-
{"key": "data", "bytes": 0, "type": "string"},
|
|
245
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
246
|
-
],
|
|
247
|
-
"tickets": [
|
|
248
|
-
{"key": "tickets", "bytes": 0, "type": "array", "array": [
|
|
249
|
-
{"key": "boleto", "bytes": 2, "type": "unsigned"},
|
|
250
|
-
{"key": "conductor", "bytes": 2, "type": "unsigned"},
|
|
251
|
-
{"key": "correlativo", "bytes": 4, "type": "unsigned"},
|
|
252
|
-
{"key": "dia", "bytes": 3, "type": "date"},
|
|
253
|
-
{"key": "fin", "bytes": 2, "type": "unsigned"},
|
|
254
|
-
{"key": "hora", "bytes": 6, "type": "datetime"},
|
|
255
|
-
{"key": "inicio", "bytes": 4, "type": "unsigned"},
|
|
256
|
-
{"key": "inspector", "bytes": 2, "type": "unsigned"},
|
|
257
|
-
{"key": "medio_pago", "bytes": 1, "type": "unsigned"},
|
|
258
|
-
{"key": "numero", "bytes": 4, "type": "unsigned"},
|
|
259
|
-
{"key": "precio", "bytes": 2, "type": "unsigned"},
|
|
260
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"},
|
|
261
|
-
{"key": "sesion", "bytes": 4, "type": "unsigned"},
|
|
262
|
-
{"key": "unidad", "bytes": 2, "type": "unsigned"},
|
|
263
|
-
{"key": "tarjeta", "bytes": 0, "type": "string"}
|
|
264
|
-
]}
|
|
265
|
-
],
|
|
266
|
-
"tickets_response": [
|
|
267
|
-
{"key": "tickets", "bytes": 0, "type": "array", "array": [
|
|
268
|
-
{"key": "correlativo", "bytes": 4, "type": "unsigned"},
|
|
269
|
-
{"key": "id", "bytes": 0, "type": "string"}
|
|
270
|
-
]}
|
|
271
|
-
],
|
|
272
|
-
"timestamp": [
|
|
273
|
-
{"key": "timestamp", "bytes": 6, "type": "timestamp"}
|
|
274
|
-
],
|
|
275
|
-
"timestamp_us": [
|
|
276
|
-
{"key": "timestamp", "bytes": 8, "type": "timestamp"}
|
|
277
|
-
],
|
|
278
|
-
"remaining_data": [
|
|
279
|
-
{"key": "faltantes", "bytes": 4, "type": "unsigned"},
|
|
280
|
-
{"key": "tabla", "bytes": 1, "type": "char"}
|
|
281
|
-
],
|
|
282
|
-
"user_route": [
|
|
283
|
-
{"key": "id", "bytes": 2, "type": "unsigned"},
|
|
284
|
-
{"key": "celular", "bytes": 9, "type": "string"},
|
|
285
|
-
{"key": "nombre", "bytes": 14, "type": "string"},
|
|
286
|
-
{"key": "rutas", "bytes": 1, "type": "array", "array": [
|
|
287
|
-
{"key": "ruta", "bytes": 1, "type": "unsigned"}
|
|
288
|
-
]},
|
|
289
|
-
{"key": "timestamp", "bytes": 6, "type": "datetime"}
|
|
290
|
-
]
|
|
291
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|