def initialize(self):
        self.vibration = self.args['vibration_sensor']
        self.door = self.args['open_sensor']

        machine = Machine(self, States)

        machine.add_transitions(IDLE,
                                StateOn(self.vibration),
                                CLEANING,
                                on_transition=self.cleaning)
        machine.add_transition(CLEANING,
                               StateOff(self.vibration),
                               CLEAN,
                               on_transition=self.clean)
        machine.add_transition(CLEAN,
                               Timeout(86400),
                               MUSTY,
                               on_transition=self.musty)
        machine.add_transition(CLEAN,
                               StateOn(self.door),
                               IDLE,
                               on_transition=self.idle)
        machine.add_transition(MUSTY,
                               StateOn(self.door),
                               IDLE,
                               on_transition=self.idle)

        machine.log_graph_link()
  def test_trigger_list(self):
    trigger1 = StateOn('sensor.s')
    trigger2 = StateOn('sensor.t')
    with patch.object(self.machine, 'add_transition') as add_transition:
      self.machine.add_transitions(A, [trigger1, trigger2], B)

    add_transition.assert_any_call(A, trigger1, B, None)
    add_transition.assert_any_call(A, trigger2, B, None)
    self.assertEqual(add_transition.call_count, 2)
  def test_any_transition_callback(self):
    self.machine.add_transition(A, StateOn('sensor.s'), B)
    callback = Mock()
    self.machine.on_transition(callback)

    self.hass.set_state('sensor.s', 'on')
    callback.assert_called_once_with(A, B)
  def test_immediate_transition(self):
    """If a trigger condition is already met when entering a new state,
    immediately perform the transition."""
    self.machine.add_transition(A, StateOn('sensor.s'), B)
    self.machine.add_transition(B, StateEq('sensor.t', 'value1'), C)

    self.hass.set_state('sensor.s', 'on')
    self.assertEqual(self.machine.current_state, C)
  def test_transitions_cancels_timeout(self):
    self.machine.add_transition(A, StateOn('sensor.s'), B)
    self.machine.add_transitions(A, Timeout(10), C)

    self.hass.set_state('sensor.s', 'on')
    self.assertEqual(self.machine.current_state, B)

    self.hass.advance_time(10)
    self.assertEqual(self.machine.current_state, B)
  def test_boolean_entity_triggers(self):
    self.machine.add_transition(A, StateOn('sensor.s'), B)
    self.machine.add_transition(B, StateOff('sensor.s'), A)
    self.assertEqual(self.machine.current_state, A)

    self.hass.set_state('sensor.s', 'on')
    self.assertEqual(self.machine.current_state, B)

    self.hass.set_state('sensor.s', 'off')
    self.assertEqual(self.machine.current_state, A)
  def test_transition_to_self_restarts_timer(self):
    self.machine.add_transition(A, StateOn('sensor.s'), A)
    self.machine.add_transitions(A, Timeout(10), B)

    self.hass.advance_time(5)
    self.hass.set_state('sensor.s', 'on')
    self.assertEqual(self.machine.current_state, A)
    self.hass.advance_time(5)
    self.assertEqual(self.machine.current_state, A)
    self.hass.advance_time(5)
    self.assertEqual(self.machine.current_state, B)
  def test_from_any_transition(self):
    self.machine.add_transitions(ANY, StateOn('sensor.s'), B)

    self.hass.set_state('sensor.s', 'on')
    self.assertEqual(self.machine.current_state, B)