def setup_sensors(self): sensor = Sensor(int, "sensor1", "Test sensor 1", "count", [0, 10]) sensor.set_value(sensor.value(), status=Sensor.UNKNOWN, timestamp=1) self.add_sensor(sensor) sensor2 = Sensor(int, "sensor2", "Test sensor 2", "count", [0, 10]) sensor2.set_value(sensor.value(), status=Sensor.UNKNOWN, timestamp=0) self.add_sensor(sensor2)
class MyServer(DeviceServer): VERSION_INFO = ("dummy-server", 1, 0) BUILD_INFO = ("hipsr-dummy-server", 0, 1, "") def setup_sensors(self): """Setup some server sensors.""" self._time_result = Sensor(Sensor.TIMESTAMP, "time.result", "Last ?time result.", "") self._read_result = Sensor(Sensor.STRING, "read.result", "Last ?read result.", "") self._write_result = Sensor(Sensor.STRING, "write.result", "Last ?write result.", "") self.add_sensor(self._time_result) self.add_sensor(self._read_result) self.add_sensor(self._write_result) @request() @return_reply(Timestamp()) def request_time(self, sock): """Return the current time in ms since the Unix Epoch.""" r = time.time() self._time_result.set_value(r) return ("ok", r) @request(Str(),Int(),Int()) @return_reply(Str()) def request_read(self, sock, device_name, bytes, offset=0): """Dummy implementation of kactp ?read command Opens a pickled data file stored in /snap directory, and returns a packed struct of the data. Notes ----- * The pickle should already be packed as a struct. * Currently ignoring the bytes and offset arguments. """ # Attempt to load pickled data try: filename='%s/registers/%s.pkl'%(os.getcwd(),device_name) data = pkl.load(open(filename,'r')) except: return ("fail", "Could not load %s."%filename) # Return data self._read_result.set_value(data) return ("ok", data) @request(Str(),Int(),Str()) @return_reply(Str()) def request_write(self, sock, device_name, offset, data): """Dummy implementation of kactp ?write command Opens a pickled data file stored in /register directory, and writes a value to it. Notes ----- * katcp_wrapper passes us already serialzed data, so no need to use struct """ # Attempt to dump pickled data try: filename='%s/registers/%s.pkl'%(os.getcwd(),device_name) pkl.dump(data, open(filename,'w')) except: return ("fail", "Could not dump %s."%filename) return ("ok", data)
class FakeSensor(object): """Fake sensor.""" def __init__(self, name, sensor_type, description, units='', params=None, clock=time): self.name = name sensor_type = Sensor.parse_type(sensor_type) params = str(params).split(' ') if params else None self._sensor = Sensor(sensor_type, name, description, units, params) self.__doc__ = self.description = description self._clock = clock self._listeners = set() self._last_update = SensorUpdate(0.0, 0.0, 'unknown', None) self._strategy = None self._next_period = None self.set_strategy('none') @property def value(self): return self._last_update.value @property def status(self): return self._last_update.status @property def strategy(self): return SampleStrategy.SAMPLING_LOOKUP[self._strategy.get_sampling()] def get_value(self): # XXX Check whether this also triggers a sensor update a la strategy return self._sensor.value() def _set_value(self, value, status=Sensor.NOMINAL): self._sensor.set_value(value, status, self._clock.time()) def _update_value(self, timestamp, status_str, value_str): update_seconds = self._clock.time() value = self._sensor.parse_value(value_str) self._last_update = SensorUpdate(update_seconds, timestamp, status_str, value) for listener in set(self._listeners): listener(update_seconds, timestamp, status_str, value_str) def set_strategy(self, strategy, params=None): """Set sensor strategy.""" def inform_callback(sensor_name, timestamp_str, status_str, value_str): """Inform callback for sensor strategy.""" self._update_value(float(timestamp_str), status_str, value_str) print sensor_name, timestamp_str, status_str, value_str if self._strategy: self._strategy.detach() params = normalize_strategy_parameters(params) self._strategy = SampleStrategy.get_strategy(strategy, inform_callback, self._sensor, *params) self._strategy.attach() self._next_period = self._strategy.periodic(self._clock.time()) def update(self, timestamp): while self._next_period and timestamp >= self._next_period: self._next_period = self._strategy.periodic(self._next_period) def register_listener(self, listener, min_wait=-1.0): """Add a callback function that is called when sensor value is updated. Parameters ---------- listener : function Callback signature: listener(update_seconds, value_seconds, status, value) min_wait : float, optional Minimum waiting period before listener can be called again, used to limit the callback rate (zero or negative for no rate limit) *This is ignored* as the same effect can be achieved with an event-rate strategy on the sensor. """ self._listeners.add(listener) def unregister_listener(self, listener): """Remove a listener callback added with register_listener(). Parameters ---------- listener : function Reference to the callback function that should be removed """ self._listeners.discard(listener)
class MyServer(DeviceServer): VERSION_INFO = ("dummy-server", 1, 0) BUILD_INFO = ("hipsr-dummy-server", 0, 1, "") FRUIT = [ "apple", "banana", "pear", "kiwi", ] BANDS = [ "autolux", "nirvana", "acdc", "tool", ] def setup_sensors(self): """Setup some server sensors.""" self._add_result = Sensor(Sensor.FLOAT, "add.result", "Last ?add result.", "", [-10000, 10000]) self._time_result = Sensor(Sensor.TIMESTAMP, "time.result", "Last ?time result.", "") self._eval_result = Sensor(Sensor.STRING, "eval.result", "Last ?eval result.", "") self._fruit_result = Sensor(Sensor.DISCRETE, "fruit.result", "Last ?pick-fruit result.", "", self.FRUIT) self._band_result = Sensor(Sensor.DISCRETE, "band.result", "Last ?pick-band result.", "", self.BAND) self.add_sensor(self._add_result) self.add_sensor(self._time_result) self.add_sensor(self._eval_result) self.add_sensor(self._fruit_result) self.add_sensor(self._band_result) @request(Float(), Float()) @return_reply(Float()) def request_add(self, sock, x, y): """Add two numbers""" r = x + y self._add_result.set_value(r) return ("ok", r) @request() @return_reply(Timestamp()) def request_time(self, sock): """Return the current time in ms since the Unix Epoch.""" r = time.time() self._time_result.set_value(r) return ("ok", r) @request(Str()) @return_reply(Str()) def request_eval(self, sock, expression): """Evaluate a Python expression.""" r = str(eval(expression)) self._eval_result.set_value(r) return ("ok", r) @request() @return_reply(Discrete(FRUIT)) def request_pick_fruit(self, sock): """Pick a random fruit.""" r = random.choice(self.FRUIT + [None]) if r is None: return ("fail", "No fruit.") self._fruit_result.set_value(r) return ("ok", r) @request() @return_reply(Discrete(BAND)) def request_pick_band(self, sock): """Pick a random fruit.""" r = random.choice(self.BAND + [None]) if r is None: return ("fail", "No band.") self._fruit_result.set_value(r) return ("ok", r)