-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathvalidate.py
129 lines (109 loc) · 4.18 KB
/
validate.py
1
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""validate.py
Verifies that ljm_constants.json is not obviously invalid.
"""
import sys
import ljmmm
import traceback
import os
def validate(json_file_path, raw_only=True):
"""Validates json_file_path as ljm constants JSON. Exits with non-zero on error."""
print ('Checking JSON file...')
try:
jsonFile = ljmmm.load_json_file(json_file_path, enable_comments=(not raw_only))
except Exception as e:
print('[ERROR] JSON file could not be parsed. (' + str(e) + ')')
traceback.print_exc()
exit(1)
if not raw_only:
return
print('Checking ljm_constants JSON file...')
try:
json_map = ljmmm.get_device_modbus_maps(
json_file_path,
expand_names=True,
inc_orig=True
)
except Exception as e:
print ('[ERROR] JSON file registers could not be parsed. (' + str(e) + ')')
exit(1)
try:
errors = ljmmm.get_errors(json_file_path)
except Exception as e:
print ('[ERROR] JSON file errors could not be parsed. (' + str(e) + ')')
exit(1)
err_msgs = []
print('Checking register map duplicates and streamable validity...')
# Track all register names so we do not throw the same error twice for a
# register (if the register is used with multiple devices)
all_names = []
for device in json_map:
previous_names = []
previous_addresses = {}
device_registers = json_map[device]
for register in device_registers:
unresolved = register[0]
resolved = register[1]
if \
'streamable' in unresolved and \
unresolved['streamable'] and \
not resolved['read']:
err_msgs.append(
"Register is streamable but not readable: %s" % (
resolved['name']
)
)
reg_name = resolved['name']
if reg_name in previous_names:
err_msgs.append('Duplicate entries for %s found.' % reg_name)
previous_names.append(reg_name)
reg_addr = resolved['address']
if reg_addr in previous_addresses and previous_addresses[reg_addr]['name'] != unresolved['name']:
err_msgs.append(
'Duplicate address for %s found:\n'
' %s\n'
' %s' % (
reg_addr,
str(previous_addresses[reg_addr]['name']),
str(resolved['name'])
)
)
previous_addresses[reg_addr] = unresolved
if 'description' in resolved and \
len(resolved['description']) == 0 and \
reg_name not in all_names:
err_msgs.append(
'No register description for: %s\n'
% str(reg_name)
)
elif not 'description' in resolved and \
reg_name not in all_names:
err_msgs.append(
'No register description field for: %s\n'
% str(reg_name)
)
all_names.append(reg_name)
print('Checking error duplicates...')
dup_ierrs = []
dup_jerrs = []
for i_it in range(0, len(errors)):
for j_it in range(i_it + 1, len(errors)):
ierr = errors[i_it]
jerr = errors[j_it]
if ierr['error'] == jerr['error'] and ierr['error'] not in dup_ierrs:
dup_ierrs.append(ierr)
dup_jerrs.append(jerr)
if dup_ierrs:
print ('Duplicate errors:')
for err in range(0, len(dup_ierrs)):
print (' ' + str(dup_ierrs[err]['error']))
err_msgs.append('Duplication errors were found (see above)')
for err in err_msgs:
print (err)
if len(err_msgs) != 0:
exit(1)
print (json_file_path + ' seems fine.')
if __name__ == '__main__':
if len(sys.argv) < 2:
print ('Usage: %s json_file_path' % sys.argv[0])
exit(1)
validate(sys.argv[1], raw_only=(os.path.basename(sys.argv[1]) == 'ljm_constants.json'))