class CounterController(Controller):
    def create_attributes(self):
        self.counter = Attribute(NumberMeta(description="A counter"))
        self.counter.meta.set_dtype('uint32')
        self.counter.set_put_function(self.counter.set_value)
        self.counter.set_value(0)
        yield "counter", self.counter

    @Controller.Resetting
    def do_reset(self):
        self.counter.set_value(0, notify=False)
        # Transition will do the notify for us

    @takes()
    def increment(self):
        self.counter.set_value(self.counter.value + 1)
class CounterController(Controller):

    def create_attributes(self):
        self.counter = Attribute(NumberMeta(description="A counter"))
        self.counter.meta.set_dtype('uint32')
        self.counter.set_put_function(self.counter.set_value)
        self.counter.set_value(0)
        yield "counter", self.counter

    @Controller.Resetting
    def do_reset(self):
        self.counter.set_value(0, notify=False)
        # Transition will do the notify for us

    @takes()
    def increment(self):
        self.counter.set_value(self.counter.value + 1)
Exemple #3
0
class CAPart(Part):

    def create_attributes(self):
        params = self.params
        if params.pv is None and params.rbv is None:
            raise ValueError('must pass pv rbv')
        if params.rbv is None:
            if params.rbv_suff is None:
                params.rbv = params.pv
            else:
                params.rbv = params.pv + params.rbv_suff
        # Meta instance
        self.name = params.name
        self.meta = self.create_meta(params.description)
        # Pv strings
        self.pv = params.pv
        self.rbv = params.rbv
        # camonitor subscription
        self.monitor = None
        self.ca_format = catools.FORMAT_CTRL
        # This will be our attr
        self.attr = None
        # The attribute we will be publishing
        self.attr = Attribute(self.meta)
        self.attr.set_put_function(self.caput)
        yield self.name, self.attr

    def create_meta(self, description):
        raise NotImplementedError

    def get_datatype(self):
        raise NotImplementedError

    @Controller.Resetting
    def connect_pvs(self):
        # release old monitor
        self.close_monitor()
        # make the connection in cothread's thread, use caget for initial value
        pvs = [self.rbv]
        if self.pv:
            pvs.append(self.pv)
        ca_values = cothread.CallbackResult(
            catools.caget, pvs,
            format=self.ca_format, datatype=self.get_datatype())
        # check connection is ok
        for i, v in enumerate(ca_values):
            assert v.ok, "CA connect failed with %s" % v.state_strings[v.state]
        self.update_value(ca_values[0])
        # now setup monitor on rbv
        self.monitor = catools.camonitor(
            self.rbv, self.on_update, notify_disconnect=True,
            format=self.ca_format, datatype=self.get_datatype())

    def close_monitor(self):
        if self.monitor is not None:
            cothread.CallbackResult(self.monitor.close)
            self.monitor = None

    def caput(self, value):
        cothread.CallbackResult(
            catools.caput, self.pv, value, wait=True, timeout=None,
            datatype=self.get_datatype())
        # now do a caget
        value = cothread.CallbackResult(
            catools.caget, self.rbv,
            format=self.ca_format, datatype=self.get_datatype())
        self.update_value(value)

    def on_update(self, value):
        # Called on cothread's queue, so don't block
        self.process.spawn(self.update_value, value)

    def update_value(self, value):
        self.log_debug("Camonitor update %r", value)
        # TODO: make Alarm from value.status and value.severity
        # TODO: make Timestamp from value.timestamp
        if not value.ok:
            # TODO: set disconnect
            self.attr.set_value(None)
        else:
            # update value
            self.attr.set_value(value)