MSP device support complete. NOT TESTED YET! Preliminary python host lib
[cerebrum.git] / pylibcerebrum / pylibcerebrum.py
blobc548d02eec982098e8f9b0b2b95c9ad5baf24c09
2 import serial
3 import json
4 import struct
6 class Ganglion
7 def __init__(self, config=None, configfile=None, proxies=None):
8 if isInstance(config, dict):
9 self.config = config
10 self.proxies = proxies
11 return
12 if configfile is not None:
13 cf = open(configfile, 'r')
14 config = cf.readlines()
15 cf.close()
16 self.config = json.JSONDecoder().decode('\n'.join(config))
17 #FIXME add sanity check(s) here or just let it fail?
18 self.proxies = {}
19 for dname, dconf in self.config["dev"].items():
20 self.proxies[dname] = SerialProxy(dname, dconf)
22 def __getattr__(self, name):
23 if name in self.config:
24 node = self.config[name]
25 if isInstance(node, str):
26 [dname, endpoint] = node.split('.')
27 return proxies[dname].__getattr__(endpoint)
28 else:
29 return Ganglion(config=node, proxies=self.proxies)
31 def __setattr__(self, name, value):
32 if name in self.config:
33 [dname, endpoint] = self.config[name].split('.')
34 proxies[dname].set_value(endpoint, value)
35 else:
36 self.__dict__[name] = value
38 class SerialProxy:
39 # NOTE: the device config is *not* the stuff from the config "dev" section but
40 #read from the device. It can also be found in that [devicename].config.json
41 #file created by the code generator
42 def __init__(self, device_config):
43 self.ser = serial.Serial(device_config["serial"], device_config["baudrate"]))
44 self.config = read_config()
46 def read_config(self):
47 ser.write("\\#\0\0\0")
48 clen = stuct.unpack("h", ser.read(2))
49 cbytes = ser.read(clen)
50 self.config = json.JSONDecoder().decode(cbytes)
52 def __setattr__(self, name, value):
53 if name in self.config["properties"]:
54 var = self.config["properties"][name]
55 cmd="\\#" + struct.pack("hh", var["id"]+1, struct.calcsize(var["fmt"])) + struct.pack(var["fmt"], value)
56 ser.write(cmd)
57 clen = stuct.unpack("h", ser.read(2))
58 cbytes = ser.read(clen)
59 if not clen == 0:
60 #FIXME error handling
61 pass
62 else:
63 self.__dict__[name] = value
65 def __getattr__(self, name):
66 if name in self.config["properties"]:
67 var = self.config["properties"][name]
68 cmd="\\#" + struct.pack("hh", var["id"], 0)
69 ser.write(cmd)
70 clen = stuct.unpack("h", ser.read(2))
71 cbytes = ser.read(clen)
72 if not clen == struct.calcsize(var["fmt"])):
73 #FIXME error handling
74 return None
75 return struct.unpack(var["fmt"], cbytes)
76 elif name in self.config["functions"]:
77 fun = self.config["functions"][name]
79 def proxy(args):
80 cmd="\\#" + struct.pack("hh", fun["id"], struct.calcsize(fun["args"])) + struct.pack(fun["args"], args)
81 ser.write(cmd)
82 clen = stuct.unpack("h", ser.read(2))
83 cbytes = ser.read(clen)
84 if not clen == struct.calcsize(fun["returns"])):
85 #FIXME error handling
86 return None
87 return struct.unpack(fun["returns"], cbytes)
89 return proxy
90 else:
91 self.__dict__[name] = value