Files
ha-core/app/StateMachine.py
2013-09-18 00:07:39 -07:00

57 lines
1.6 KiB
Python

from collections import defaultdict, namedtuple
from threading import RLock
from datetime import datetime
from app.EventBus import Event
from app.util import ensure_list, matcher
EVENT_STATE_CHANGED = "state_changed"
state = namedtuple("State", ['state','last_changed'])
class StateMachine:
def __init__(self, eventBus):
self.states = dict()
self.eventBus = eventBus
self.lock = RLock()
def add_category(self, category, initialState):
self.states[category] = state(initialState, datetime.now())
def set_state(self, category, newState):
self.lock.acquire()
assert category in self.states, "Category does not exist: {}".format(category)
oldState = self.states[category]
if oldState.state != newState:
self.states[category] = state(newState, datetime.now())
self.eventBus.fire(Event(EVENT_STATE_CHANGED, {'category':category, 'oldState':oldState, 'newState':self.states[category]}))
self.lock.release()
def get_state(self, category):
assert category in self.states, "Category does not exist: {}".format(category)
return self.states[category]
def track_state_change(eventBus, category, fromState, toState, action):
fromState = ensure_list(fromState)
toState = ensure_list(toState)
def listener(event):
assert isinstance(event, Event), "event needs to be of Event type"
if category == event.data['category'] and \
matcher(event.data['oldState'].state, fromState) and \
matcher(event.data['newState'].state, toState):
action(event.data['category'], event.data['oldState'], event.data['newState'])
eventBus.listen(EVENT_STATE_CHANGED, listener)