/
walk.py
128 lines (104 loc) · 4.16 KB
/
walk.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
"""walk.py -- a pyownet implementation of owget
This implementation is for python 2.X
This programs parses an owserver URI, constructed in the obvious way:
'owserver://hostname:port/path' and prints all nodes reachable below it.
The URI scheme 'owserver:' is optional. For 'hostname:port' the default
is 'localhost:4304'
Usage examples:
python walk.py //localhost:14304/
python walk.py //localhost:14304/26.000026D90200/
python walk.py -K //localhost:14304/26.000026D90200/temperature
Caution:
'owget.py //localhost:14304/26.000026D90200' or
'owget.py //localhost:14304/26.000026D90200/temperature/' yield an error
"""
from __future__ import print_function
import sys
import argparse
if sys.version_info < (3, ):
from urlparse import urlsplit
else:
from urllib.parse import urlsplit
import collections
from pyownet import protocol
__all__ = ['main']
def main():
"""parse commandline arguments and print result"""
#
# setup command line parsing a la argpase
#
parser = argparse.ArgumentParser()
# positional args
parser.add_argument('uri', metavar='URI', nargs='?', default='/',
help='[owserver:]//server:port/entity')
# optional args for temperature scale
parser.set_defaults(t_flags=protocol.FLG_TEMP_C)
tempg = parser.add_mutually_exclusive_group()
tempg.add_argument('-C', '--Celsius', const=protocol.FLG_TEMP_C,
help='Celsius(default) temperature scale',
dest='t_flags', action='store_const', )
tempg.add_argument('-F', '--Fahrenheit', const=protocol.FLG_TEMP_F,
help='Fahrenheit temperature scale',
dest='t_flags', action='store_const', )
tempg.add_argument('-K', '--Kelvin', const=protocol.FLG_TEMP_K,
help='Kelvin temperature scale',
dest='t_flags', action='store_const', )
tempg.add_argument('-R', '--Rankine', const=protocol.FLG_TEMP_R,
help='Rankine temperature scale',
dest='t_flags', action='store_const', )
# optional arg for address format
fcodes = collections.OrderedDict((
('f.i', protocol.FLG_FORMAT_FDI),
('fi', protocol.FLG_FORMAT_FI),
('f.i.c', protocol.FLG_FORMAT_FDIDC),
('f.ic', protocol.FLG_FORMAT_FDIC),
('fi.c', protocol.FLG_FORMAT_FIDC),
('fic', protocol.FLG_FORMAT_FIC), ))
parser.set_defaults(format='f.i')
parser.add_argument('-f', '--format', choices=fcodes,
help='format for 1-wire unique serial IDs display')
parser.add_argument('--nosys', '--only-sensors',
action='store_false', dest='bus',
help='do not descend system directories')
#
# parse command line args
#
args = parser.parse_args()
#
# parse args.uri and substitute defaults
#
urlc = urlsplit(args.uri, scheme='owserver', allow_fragments=False)
if urlc.scheme != 'owserver':
parser.error("Invalid URI scheme '{}:'".format(urlc.scheme))
assert not urlc.fragment
if urlc.query:
parser.error(
"Invalid URI '{}', no query component allowed".format(args.uri))
host = urlc.hostname or 'localhost'
port = urlc.port or 4304
#
# create owserver proxy object
#
try:
proxy = protocol.proxy(
host, port, flags=args.t_flags | fcodes[args.format],
persistent=True)
except (protocol.ConnError, protocol.ProtocolError) as error:
parser.exit(status=1, message=str(error) + '\n')
def walk(path):
try:
if not path.endswith('/'):
val = proxy.read(path)
print("{:40} {!r}".format(path, val))
else:
for entity in proxy.dir(path, bus=args.bus):
walk(entity)
except protocol.OwnetError as error:
print('Unable to walk {}: server says {}'.format(path, error),
file=sys.stderr)
except protocol.ConnError as error:
print('Unable to walk {}: {}'.format(path, error), file=sys.stderr)
with proxy:
walk(urlc.path)
if __name__ == '__main__':
main()