State machine categories don't have to be initialized anymore

This commit is contained in:
Paulus Schoutsen 2013-09-29 16:02:58 -07:00
parent c7e36e4fc1
commit f04e9b07a9
3 changed files with 20 additions and 21 deletions

View File

@ -115,22 +115,23 @@ class StateMachine(object):
self.eventbus = eventbus
self.lock = RLock()
def add_category(self, category, initial_state):
""" Add a category which state we will keep track off. """
self.states[category] = State(initial_state, datetime.now())
def set_state(self, category, new_state):
""" Set the state of a category. """
self._validate_category(category)
""" Set the state of a category, add category is it does not exist. """
self.lock.acquire()
old_state = self.states[category]
if old_state.state != new_state:
# Add category is it does not exist
if category not in self.states:
self.states[category] = State(new_state, datetime.now())
self.eventbus.fire(Event(EVENT_STATE_CHANGED, {'category':category, 'old_state':old_state, 'new_state':self.states[category]}))
# Change state and fire listeners
else:
old_state = self.states[category]
if old_state.state != new_state:
self.states[category] = State(new_state, datetime.now())
self.eventbus.fire(Event(EVENT_STATE_CHANGED, {'category':category, 'old_state':old_state, 'new_state':self.states[category]}))
self.lock.release()
@ -151,6 +152,7 @@ class StateMachine(object):
return [(category, self.states[category].state, self.states[category].last_changed) for category in sorted(self.states.keys())]
def _validate_category(self, category):
""" Helper function to throw an exception when the category does not exist. """
if category not in self.states:
raise CategoryDoesNotExistException("Category {} does not exist.".format(category))

View File

@ -122,7 +122,7 @@ class WeatherWatcher(object):
self.sun = ephem.Sun()
self._update_sun_state(create_state=True)
self._update_sun_state()
def next_sun_rising(self, observer=None):
@ -143,7 +143,7 @@ class WeatherWatcher(object):
return ephem.localtime(observer.next_setting(self.sun))
def _update_sun_state(self, now=None, create_state=False):
def _update_sun_state(self, now=None):
""" Updates the state of the sun and schedules when to check next. """
observer = self._get_observer()
@ -161,11 +161,7 @@ class WeatherWatcher(object):
self.logger.info("Sun:{}. Next change: {}".format(new_state, next_change.strftime("%H:%M")))
if create_state:
self.statemachine.add_category(STATE_CATEGORY_SUN, new_state)
else:
self.statemachine.set_state(STATE_CATEGORY_SUN, new_state)
self.statemachine.set_state(STATE_CATEGORY_SUN, new_state)
# +10 seconds to be sure that the change has occured
track_time_change(self.eventbus, self._update_sun_state, point_in_time=next_change + timedelta(seconds=10))
@ -206,10 +202,10 @@ class DeviceTracker(object):
new_last_seen = default_last_seen
self.devices_to_track[device]['last_seen'] = new_last_seen
self.statemachine.add_category(self.devices_to_track[device]['category'], new_state)
self.statemachine.set_state(self.devices_to_track[device]['category'], new_state)
# Update all devices state
statemachine.add_category(STATE_CATEGORY_ALL_DEVICES, DEVICE_STATE_HOME if len(initial_search) > 0 else DEVICE_STATE_NOT_HOME)
statemachine.set_state(STATE_CATEGORY_ALL_DEVICES, DEVICE_STATE_HOME if len(initial_search) > 0 else DEVICE_STATE_NOT_HOME)
track_time_change(eventbus, lambda time: self.update_devices(device_scanner.get_active_devices()))

View File

@ -48,7 +48,7 @@ class TestHTTPInterface(HomeAssistantTestCase):
HTTPInterface(self.eventbus, self.statemachine, API_PASSWORD)
self.statemachine.add_category("test", "INIT_STATE")
self.statemachine.set_state("test", "INIT_STATE")
self.eventbus.fire(Event(EVENT_START))
@ -96,7 +96,8 @@ class TestHTTPInterface(HomeAssistantTestCase):
"new_state":"debug_state_change",
"api_password":API_PASSWORD})
self.assertEqual(req.status_code, 400)
self.assertEqual(req.status_code, 200)
self.assertEqual(self.statemachine.get_state("test_category_that_does_not_exist").state, "debug_state_change")
def test_api_fire_event_with_no_data(self):
""" Test if the API allows us to fire an event. """