def test_set_value(self): value = "test_value" a = Attribute("test", Mock()) a.on_changed = Mock(a.on_changed) a.set_value(value) self.assertEquals("test_value", a.value) a.on_changed.assert_called_once_with([['value'], value])
def test_set_value(self): value = "test_value" a = Attribute(self.meta) a.on_changed = Mock(wrap=a.on_changed) a.set_value(value) self.assertEquals(a.value, value) a.on_changed.assert_called_once_with([['value'], value], True)
def test_put(self): func = Mock() value = "test_value" a = Attribute("test", Mock()) a.set_put_function(func) a.put(value) func.assert_called_once_with(value)
class TestAttribute(unittest.TestCase): def setUp(self): self.data = NTScalar(StringMeta()) self.data.set_notifier_path(Mock(), ["block", "attr"]) self.controller = Mock() self.context = Mock() self.o = Attribute(self.controller, self.context, self.data) def test_init(self): self.assertIsInstance(self.o, Attribute) assert hasattr(self.o, "meta") assert hasattr(self.o, "subscribe_meta") assert hasattr(self.o, "value") assert hasattr(self.o, "subscribe_value") def test_put(self): self.o.put_value(32) self.context.put.assert_called_once_with(["block", "attr", "value"], 32, timeout=None) def test_put_async(self): f = self.o.put_value_async(32) self.context.put_async.assert_called_once_with( ["block", "attr", "value"], 32) assert f == self.context.put_async.return_value def test_repr(self): self.controller.make_view.return_value = "foo" assert repr(self.o) == "<Attribute value='foo'>" self.controller.make_view.assert_called_once_with( self.context, self.o, "value")
def test_to_dict(self): meta = Mock() meta.to_dict = Mock(return_value={"test_meta": "dict"}) expected = OrderedDict() expected["value"] = "test_value" expected["meta"] = {"test_meta": "dict"} a = Attribute("test", meta) a.set_value("test_value") self.assertEquals(expected, a.to_dict())
def test_to_dict(self): meta = Mock() meta.to_dict = Mock(return_value = {"test_meta":"dict"}) expected = OrderedDict() expected["value"] = "test_value" expected["meta"] = {"test_meta":"dict"} a = Attribute("test", meta) a.set_value("test_value") self.assertEquals(expected, a.to_dict())
def create_process_block(self): self.process_block = Block() a = Attribute( StringArrayMeta(description="Blocks hosted by this Process")) self.process_block.add_attribute("blocks", a) a = Attribute( StringArrayMeta(description="Blocks reachable via ClientComms")) self.process_block.add_attribute("remoteBlocks", a) self.add_block(self.name, self.process_block)
def _create_default_attributes(self): self.state = Attribute(ChoiceMeta(description="State of Block", choices=self.stateMachine.possible_states)) self.state.set_parent(self.block,'state') self.state.set_value(self.stateMachine.DISABLED) yield ('state', self.state) self.status = Attribute(StringMeta(description="Status of Block")) self.status.set_value("Disabled") yield ('status', self.status) self.busy = Attribute(BooleanMeta( description="Whether Block busy or not")) self.busy.set_value(False) yield ('busy', self.busy)
def setUp(self): self.callback_result = 0 self.callback_value = '' meta = VMeta("meta for unit tests") self.block = MagicMock() self.proc = MagicMock(q=queue.Queue()) self.proc.create_queue = MagicMock(side_effect=queue.Queue) self.attr = Attribute(meta) self.attr.set_parent(self.block, "testAttr") self.attr2 = Attribute(meta) self.attr2.set_parent(self.block, "testAttr2") self.method = Method("method for unit tests") self.method.set_parent(self.block, "testFunc") self.method2 = Method("method for unit tests") self.method2.set_parent(self.block, "testFunc") self.bad_called_back = False
def test_from_dict(self, am_from_dict): meta = Mock() am_from_dict.return_value = meta d = {"value":"test_value", "meta":{"meta":"dict"}} a = Attribute.from_dict("test", d) self.assertEquals("test", a.name) self.assertEquals("test_value", a.value) self.assertIs(meta, a.meta)
def test_from_dict(self, am_from_dict): meta = Mock() am_from_dict.return_value = meta d = {"value": "test_value", "meta": {"meta": "dict"}} a = Attribute.from_dict("test", d) self.assertEquals("test", a.name) self.assertEquals("test_value", a.value) self.assertIs(meta, a.meta)
def test_compare_vtables(self): a = Attribute(VTable, "Positions") a.notify_listeners = MagicMock() t1 = [("x", VLong, numpy.arange(5, dtype=numpy.int64), ''), ("y", VLong, numpy.arange(5, dtype=numpy.int64) + 2, 'mm')] a.update(t1, None, 1.0) a.notify_listeners.assert_called_with( dict(value=t1, alarm=Alarm.ok(), timeStamp=1.0)) a.update(t1, None, 1.0) a.notify_listeners.assert_called_with(dict()) t2 = [("x", VLong, numpy.arange(5, dtype=numpy.int64) + 3, ''), ("y", VLong, numpy.arange(5, dtype=numpy.int64) + 2, '')] a.update(t2, None, 1.0) a.notify_listeners.assert_called_with(dict(value=t2))
def test_replace_children(self): b = Block() b.name = "blockname" b.methods["m1"] = 2 b.attributes["a1"] = 3 setattr(b, "m1", 2) setattr(b, "a1", 3) attr_meta = StringMeta(description="desc") attr = Attribute(attr_meta) b.add_attribute('attr', attr) method = Method(description="desc") b.add_method('method', method) b.on_changed = MagicMock(wrap=b.on_changed) b.replace_children({'attr': attr, 'method': method}) self.assertEqual(b.attributes, dict(attr=attr)) self.assertEqual(b.methods, dict(method=method)) b.on_changed.assert_called_once_with([[], b.to_dict()], True) self.assertFalse(hasattr(b, "m1")) self.assertFalse(hasattr(b, "a1"))
def _create_default_attributes(self): self.state = Attribute( ChoiceMeta(description="State of Block", choices=self.stateMachine.possible_states)) self.state.set_parent(self.block, 'state') self.state.set_value(self.stateMachine.DISABLED) yield ('state', self.state) self.status = Attribute(StringMeta(description="Status of Block")) self.status.set_value("Disabled") yield ('status', self.status) self.busy = Attribute( BooleanMeta(description="Whether Block busy or not")) self.busy.set_value(False) yield ('busy', self.busy)
def test_lists(self): a = Attribute(VStringArray, "List of strings") a.update(["c", "b"]) self.assertEqual(a.value, ["c", "b"]) self.assertRaises(AssertionError, a.update, "c")
class Controller(Loggable): """Implement the logic that takes a Block through its statemachine""" Resetting = Hook() def __init__(self, process, block, block_name): """ Args: process (Process): The process this should run under block (Block): Block instance to add Methods and Attributes to """ process.add_block(block_name, block) self.set_logger_name("%s.controller" % block_name) # dictionary of dictionaries # {state (str): {Method: writeable (bool)} self.methods_writeable = {} self.process = process self.parts = [] self.block = block for name, attribute in self._create_default_attributes(): block.add_attribute(name, attribute) for name, attribute in self.create_attributes(): block.add_attribute(name, attribute) for name, method in self.create_methods(): block.add_method(name, method) # Set if the method is writeable if method.only_in is None: states = [ state for state in self.stateMachine.possible_states if state != sm.DISABLED ] else: states = method.only_in for state in states: assert state in self.stateMachine.possible_states, \ "State %s is not one of the valid states %s" % \ (state, self.stateMachine.possible_states) self.set_method_writeable_in(method, states) def create_methods(self): """Abstract method that should provide Method instances for Block Yields: Method: Each one will be attached to the Block by calling block.add_method(method) """ for name, member in inspect.getmembers(self, inspect.ismethod): if hasattr(member, "Method"): member.Method.set_function(member) yield (name, member.Method) def create_attributes(self): """Abstract method that should provide Attribute instances for Block Yields: Attribute: Each one will be attached to the Block by calling block.add_attribute(attribute) """ return iter(()) def _create_default_attributes(self): self.state = Attribute( ChoiceMeta(description="State of Block", choices=self.stateMachine.possible_states)) self.state.set_parent(self.block, 'state') self.state.set_value(self.stateMachine.DISABLED) yield ('state', self.state) self.status = Attribute(StringMeta(description="Status of Block")) self.status.set_value("Disabled") yield ('status', self.status) self.busy = Attribute( BooleanMeta(description="Whether Block busy or not")) self.busy.set_value(False) yield ('busy', self.busy) @takes() @only_in(sm.DISABLED, sm.FAULT) def reset(self): try: self.transition(sm.RESETTING, "Resetting") self.Resetting.run(self) self.transition(sm.AFTER_RESETTING, "Done resetting") except Exception as e: self.log_exception("Fault occurred while Resetting") self.transition(sm.FAULT, str(e)) @takes() def disable(self): self.transition(sm.DISABLED, "Disabled") def add_parts(self, parts): self.parts.extend(parts) def transition(self, state, message): """ Change to a new state if the transition is allowed Args: state(str): State to transition to message(str): Status message """ if self.stateMachine.is_allowed(initial_state=self.state.value, target_state=state): self.state.set_value(state) if state in self.stateMachine.busy_states: self.busy.set_value(True) else: self.busy.set_value(False) self.status.set_value(message) for method in self.block.methods.values(): writeable = self.methods_writeable[state][method.name] method.set_writeable(writeable) self.block.notify_subscribers() else: raise TypeError("Cannot transition from %s to %s" % (self.state.value, state)) def set_method_writeable_in(self, method, states): """ Set the states that the given method can be called in Args: method(Method): Method that will be set writeable or not states(list[str]): List of states where method is writeable """ for state in self.stateMachine.possible_states: writeable_dict = self.methods_writeable.setdefault(state, {}) is_writeable = state in states writeable_dict[method.name] = is_writeable
class TestTask(unittest.TestCase): def setUp(self): self.callback_result = 0 self.callback_value = '' meta = VMeta("meta for unit tests") self.block = MagicMock() self.proc = MagicMock(q=queue.Queue()) self.proc.create_queue = MagicMock(side_effect=queue.Queue) self.attr = Attribute(meta) self.attr.set_parent(self.block, "testAttr") self.attr2 = Attribute(meta) self.attr2.set_parent(self.block, "testAttr2") self.method = Method("method for unit tests") self.method.set_parent(self.block, "testFunc") self.method2 = Method("method for unit tests") self.method2.set_parent(self.block, "testFunc") self.bad_called_back = False def test_init(self): t = Task("testTask", self.proc) self.assertIsInstance(t._logger, logging.Logger) self.assertIsInstance(t.q, queue.Queue) self.assertEqual(t.process, self.proc) def test_put_async(self): t = Task("testTask", self.proc) t.put_async(self.attr, "testValue") req = self.proc.q.get(timeout=0) self.assertIsInstance(req, Request) self.assertEqual(req.endpoint, [self.block.name, 'testAttr', 'value']) self.assertEqual(len(t._futures), 1) d = {self.attr: "testValue", self.attr2: "testValue2"} t.put_async(d) self.proc.q.get(timeout=0) req2 = self.proc.q.get(timeout=0) self.assertEqual(self.proc.q.qsize(), 0) self.assertIsInstance(req2, Request) self.assertEqual(len(t._futures), 3) def test_put(self): # single attribute t = Task("testTask", self.proc) resp = Return(0, None, None) resp.set_value('testVal') # cheat and add the response before the blocking call to put t.q.put(resp) t.stop() t.put(self.attr, "testValue") self.assertEqual(len(t._futures), 0) self.assertEqual(self.proc.q.qsize(), 1) def test_post(self): t = Task("testTask", self.proc) resp1 = Return(0, None, None) resp1.set_value('testVal') resp2 = Error(1, None, None) # cheat and add the responses before the blocking call to put t.q.put(resp1) t.q.put(resp2) t.stop() t.post(self.method, "testParm") t.post(self.method, "testParm2") self.assertEqual(len(t._futures), 0) self.assertEqual(self.proc.q.qsize(), 2) def test_wait_all(self): t = Task("testTask", self.proc) f1 = Future(t) f2 = Future(t) f3 = Future(t) f0 = Future(t) t._futures = {0: f0, 1: f1, 2: f2, 3: f3} f_wait1 = [f2, f0] self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0) resp0 = Return(0, None, None) resp0.set_value('testVal') resp2 = Error(2, None, None) t.q.put(resp0) t.q.put(resp2) t.wait_all( f_wait1, 0) self.assertEqual(t._futures, {1: f1, 3: f3}) self.assertEqual(f0.done(), True) self.assertEqual(f1.done(), False) self.assertEqual(f2.done(), True) self.assertEqual(f3.done(), False) self.assertEqual(self.proc.q.qsize(), 0) resp3 = Delta(3, None, None) t.q.put(resp3) f_wait1 = [f3] self.assertRaises(ValueError, t.wait_all, f_wait1, 0.01) t.stop() self.assertRaises(RuntimeWarning, t.wait_all, f_wait1, 0.01) resp1 = Return(1, None, None) resp1.set_value('testVal') t.q.put(resp1) self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0.01) self.assertEqual(t._futures, {}) t._futures = {0: f0, 1: f1, 2: f2} t.q.put(resp1) t.q.put(Task.TASK_STOP) self.assertEqual(f1.result(), 'testVal') def test_wait_all_missing_futures(self): # unsolicited response t = Task("testTask", self.proc) f1 = Future(t) resp10 = Return(10, None, None) t.q.put(resp10) t.q.put(Task.TASK_STOP) self.assertRaises(RuntimeWarning, t.wait_all, f1, 0) # same future twice f2 = Future(t) t._futures = {1: f2} resp1 = Return(1, None, None) t.q.put(resp1) t.q.put(Task.TASK_STOP) t.wait_all(f2,0) t.wait_all(f2,0) def _callback(self, value, a, b): self.callback_result = a+b self.callback_value = value def test_subscribe(self): t = Task("testTask", self.proc) resp = Update(0, None, None) resp.set_value('changedVal') t.q.put(resp) t.stop() new_id = t.subscribe(self.attr, self._callback, 3, 5) f1 = Future(t) t._futures = {1: f1} self.assertRaises(RuntimeWarning, t.wait_all, f1, 0) self.assertEqual(self.callback_value, 'changedVal') self.assertEqual(self.callback_result, 8) t.unsubscribe(new_id) def test_callback_error(self): t = Task("testTask", self.proc) resp = Error(0, None, None) resp.set_message('error') t.q.put(resp) t.stop() t.subscribe(self.attr, self._callback, 3, 5) f1 = Future(t) t._futures = {1: f1} self.assertRaises(RuntimeError, t.wait_all, f1, 0) def test_callback_unexpected(self): t = Task("testTask", self.proc) resp = Delta(0, None, None) t.q.put(resp) t.stop() t.subscribe(self.attr, self._callback, 3, 5) f1 = Future(t) t._futures = {1: f1} self.assertRaises(ValueError, t.wait_all, f1, 0) def _bad_callback(self, value): self.bad_called_back = True raise TestWarning() def test_callback_crash(self): t = Task("testTask", self.proc) resp = Update(0, None, None) resp.set_value('changedVal') t.q.put(resp) t.stop() t.subscribe(self.attr, self._bad_callback) f1 = Future(t) t._futures = {1: f1} self.assertRaises(RuntimeWarning, t.wait_all, f1, 0) self.assertEquals(self.bad_called_back, True) def test_when_matches(self): t = Task("testTask", self.proc) f = t.when_matches(self.attr, "matchTest") # match (response goes to the subscription at id 1, # not the future at id 0) resp = Update(1, None, None) resp.set_value('matchTest') t.q.put(resp) t.stop() self.assertEqual(f[0].result(0),'matchTest') def test_not_when_matches(self): t = Task("testTask", self.proc) f = t.when_matches(self.attr, "matchTest") # match (response goes to the subscription at id 1, # not the future at id 0) resp = Update(1, None, None) resp.set_value('NOTmatchTest') t.q.put(resp) t.stop() # this will abort the task because f[0] never gets filled self.assertRaises(RuntimeWarning, f[0].result)
class TestTask(unittest.TestCase): def setUp(self): self.callback_result = 0 self.callback_value = '' meta = VMeta("meta for unit tests") self.block = MagicMock() self.proc = MagicMock(q=queue.Queue()) self.proc.create_queue = MagicMock(side_effect=queue.Queue) self.attr = Attribute(meta) self.attr.set_parent(self.block, "testAttr") self.attr2 = Attribute(meta) self.attr2.set_parent(self.block, "testAttr2") self.method = Method("method for unit tests") self.method.set_parent(self.block, "testFunc") self.method2 = Method("method for unit tests") self.method2.set_parent(self.block, "testFunc") self.bad_called_back = False def test_init(self): t = Task("testTask", self.proc) self.assertIsInstance(t._logger, logging.Logger) self.assertIsInstance(t.q, queue.Queue) self.assertEqual(t.process, self.proc) def test_put_async(self): t = Task("testTask", self.proc) t.put_async(self.attr, "testValue") req = self.proc.q.get(timeout=0) self.assertIsInstance(req, Request) self.assertEqual(req.endpoint, [self.block.name, 'testAttr', 'value']) self.assertEqual(len(t._futures), 1) d = {self.attr: "testValue", self.attr2: "testValue2"} t.put_async(d) self.proc.q.get(timeout=0) req2 = self.proc.q.get(timeout=0) self.assertEqual(self.proc.q.qsize(), 0) self.assertIsInstance(req2, Request) self.assertEqual(len(t._futures), 3) def test_put(self): # single attribute t = Task("testTask", self.proc) resp = Return(0, None, None) resp.set_value('testVal') # cheat and add the response before the blocking call to put t.q.put(resp) t.stop() t.put(self.attr, "testValue") self.assertEqual(len(t._futures), 0) self.assertEqual(self.proc.q.qsize(), 1) def test_post(self): t = Task("testTask", self.proc) resp1 = Return(0, None, None) resp1.set_value('testVal') resp2 = Error(1, None, None) # cheat and add the responses before the blocking call to put t.q.put(resp1) t.q.put(resp2) t.stop() t.post(self.method, "testParm") t.post(self.method, "testParm2") self.assertEqual(len(t._futures), 0) self.assertEqual(self.proc.q.qsize(), 2) def test_wait_all(self): t = Task("testTask", self.proc) f1 = Future(t) f2 = Future(t) f3 = Future(t) f0 = Future(t) t._futures = {0: f0, 1: f1, 2: f2, 3: f3} f_wait1 = [f2, f0] self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0) resp0 = Return(0, None, None) resp0.set_value('testVal') resp2 = Error(2, None, None) t.q.put(resp0) t.q.put(resp2) t.wait_all(f_wait1, 0) self.assertEqual(t._futures, {1: f1, 3: f3}) self.assertEqual(f0.done(), True) self.assertEqual(f1.done(), False) self.assertEqual(f2.done(), True) self.assertEqual(f3.done(), False) self.assertEqual(self.proc.q.qsize(), 0) resp3 = Delta(3, None, None) t.q.put(resp3) f_wait1 = [f3] self.assertRaises(ValueError, t.wait_all, f_wait1, 0.01) t.stop() self.assertRaises(RuntimeWarning, t.wait_all, f_wait1, 0.01) resp1 = Return(1, None, None) resp1.set_value('testVal') t.q.put(resp1) self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0.01) self.assertEqual(t._futures, {}) t._futures = {0: f0, 1: f1, 2: f2} t.q.put(resp1) t.q.put(Task.TASK_STOP) self.assertEqual(f1.result(), 'testVal') def test_wait_all_missing_futures(self): # unsolicited response t = Task("testTask", self.proc) f1 = Future(t) resp10 = Return(10, None, None) t.q.put(resp10) t.q.put(Task.TASK_STOP) self.assertRaises(RuntimeWarning, t.wait_all, f1, 0) # same future twice f2 = Future(t) t._futures = {1: f2} resp1 = Return(1, None, None) t.q.put(resp1) t.q.put(Task.TASK_STOP) t.wait_all(f2, 0) t.wait_all(f2, 0) def _callback(self, value, a, b): self.callback_result = a + b self.callback_value = value def test_subscribe(self): t = Task("testTask", self.proc) resp = Update(0, None, None) resp.set_value('changedVal') t.q.put(resp) t.stop() new_id = t.subscribe(self.attr, self._callback, 3, 5) f1 = Future(t) t._futures = {1: f1} self.assertRaises(RuntimeWarning, t.wait_all, f1, 0) self.assertEqual(self.callback_value, 'changedVal') self.assertEqual(self.callback_result, 8) t.unsubscribe(new_id) def test_callback_error(self): t = Task("testTask", self.proc) resp = Error(0, None, None) resp.set_message('error') t.q.put(resp) t.stop() t.subscribe(self.attr, self._callback, 3, 5) f1 = Future(t) t._futures = {1: f1} self.assertRaises(RuntimeError, t.wait_all, f1, 0) def test_callback_unexpected(self): t = Task("testTask", self.proc) resp = Delta(0, None, None) t.q.put(resp) t.stop() t.subscribe(self.attr, self._callback, 3, 5) f1 = Future(t) t._futures = {1: f1} self.assertRaises(ValueError, t.wait_all, f1, 0) def _bad_callback(self, value): self.bad_called_back = True raise TestWarning() def test_callback_crash(self): t = Task("testTask", self.proc) resp = Update(0, None, None) resp.set_value('changedVal') t.q.put(resp) t.stop() t.subscribe(self.attr, self._bad_callback) f1 = Future(t) t._futures = {1: f1} self.assertRaises(RuntimeWarning, t.wait_all, f1, 0) self.assertEquals(self.bad_called_back, True) def test_when_matches(self): t = Task("testTask", self.proc) f = t.when_matches(self.attr, "matchTest") # match (response goes to the subscription at id 1, # not the future at id 0) resp = Update(1, None, None) resp.set_value('matchTest') t.q.put(resp) t.stop() self.assertEqual(f[0].result(0), 'matchTest') def test_not_when_matches(self): t = Task("testTask", self.proc) f = t.when_matches(self.attr, "matchTest") # match (response goes to the subscription at id 1, # not the future at id 0) resp = Update(1, None, None) resp.set_value('NOTmatchTest') t.q.put(resp) t.stop() # this will abort the task because f[0] never gets filled self.assertRaises(RuntimeWarning, f[0].result)
def test_init(self): a = Attribute(self.meta) self.assertIs(self.meta, a.meta) self.assertIs(self.meta.parent, a) self.assertIsNone(a.value) self.assertEquals("epics:nt/NTAttribute:1.0", a.typeid)
def setUp(self): self.data = NTScalar(StringMeta()) self.data.set_notifier_path(Mock(), ["block", "attr"]) self.controller = Mock() self.context = Mock() self.o = Attribute(self.controller, self.context, self.data)
def test_to_dict(self): a = Attribute(StringMeta("desc")) a.set_value("some string") self.assertEqual(a.to_dict(), self.serialized)
def test_init(self): meta = Mock() a = Attribute("test", meta) self.assertEquals("test", a.name) self.assertIs(meta, a.meta) self.assertIsNone(a.value)
def test_set_put_function(self): func = Mock() a = Attribute("test", Mock()) a.set_put_function(func) self.assertIs(func, a.put_func)
class Controller(Loggable): """Implement the logic that takes a Block through its statemachine""" Resetting = Hook() def __init__(self, process, block, block_name): """ Args: process (Process): The process this should run under block (Block): Block instance to add Methods and Attributes to """ process.add_block(block_name, block) self.set_logger_name("%s.controller" % block_name) # dictionary of dictionaries # {state (str): {Method: writeable (bool)} self.methods_writeable = {} self.process = process self.parts = [] self.block = block for name, attribute in self._create_default_attributes(): block.add_attribute(name, attribute) for name, attribute in self.create_attributes(): block.add_attribute(name, attribute) for name, method in self.create_methods(): block.add_method(name, method) # Set if the method is writeable if method.only_in is None: states = [state for state in self.stateMachine.possible_states if state != sm.DISABLED] else: states = method.only_in for state in states: assert state in self.stateMachine.possible_states, \ "State %s is not one of the valid states %s" % \ (state, self.stateMachine.possible_states) self.set_method_writeable_in(method, states) def create_methods(self): """Abstract method that should provide Method instances for Block Yields: Method: Each one will be attached to the Block by calling block.add_method(method) """ for name, member in inspect.getmembers(self, inspect.ismethod): if hasattr(member, "Method"): member.Method.set_function(member) yield (name, member.Method) def create_attributes(self): """Abstract method that should provide Attribute instances for Block Yields: Attribute: Each one will be attached to the Block by calling block.add_attribute(attribute) """ return iter(()) def _create_default_attributes(self): self.state = Attribute(ChoiceMeta(description="State of Block", choices=self.stateMachine.possible_states)) self.state.set_parent(self.block,'state') self.state.set_value(self.stateMachine.DISABLED) yield ('state', self.state) self.status = Attribute(StringMeta(description="Status of Block")) self.status.set_value("Disabled") yield ('status', self.status) self.busy = Attribute(BooleanMeta( description="Whether Block busy or not")) self.busy.set_value(False) yield ('busy', self.busy) @takes() @only_in(sm.DISABLED, sm.FAULT) def reset(self): try: self.transition(sm.RESETTING, "Resetting") self.Resetting.run(self) self.transition(sm.AFTER_RESETTING, "Done resetting") except Exception as e: self.log_exception("Fault occurred while Resetting") self.transition(sm.FAULT, str(e)) @takes() def disable(self): self.transition(sm.DISABLED, "Disabled") def add_parts(self, parts): self.parts.extend(parts) def transition(self, state, message): """ Change to a new state if the transition is allowed Args: state(str): State to transition to message(str): Status message """ if self.stateMachine.is_allowed(initial_state=self.state.value, target_state=state): self.state.set_value(state) if state in self.stateMachine.busy_states: self.busy.set_value(True) else: self.busy.set_value(False) self.status.set_value(message) for method in self.block.methods.values(): writeable = self.methods_writeable[state][method.name] method.set_writeable(writeable) self.block.notify_subscribers() else: raise TypeError("Cannot transition from %s to %s" % (self.state.value, state)) def set_method_writeable_in(self, method, states): """ Set the states that the given method can be called in Args: method(Method): Method that will be set writeable or not states(list[str]): List of states where method is writeable """ for state in self.stateMachine.possible_states: writeable_dict = self.methods_writeable.setdefault(state, {}) is_writeable = state in states writeable_dict[method.name] = is_writeable