コード例 #1
0
 def testEmptyNotAllowed(self):
     try:
         enum = Enum()
     except AssertionError:
         pass
     else:
         fail("Expected assertion - empty enums not allowed")
コード例 #2
0
class Messenger():
    '''Messenger provides an abstraction layer for a pub/sub message bus.  Clients work with messenger directly, and
    plumberjack wires the appropriate implementation in to the system.  This class is an abstract base class and
    requires a concrete implementation to operate.'''
    __metaclass__ = ABCMeta
    TOPIC_SYSTEM = 'system'
    TOPIC_SYSTEM_CONTROL = 'system.control'
    TOPIC_COMPONENT_STATUS = 'component.status'
    TOPIC_COMPONENT_HEARTBEAT = 'component.heartbeat'
    TOPIC_SENSOR_DATA = 'component.sensor.data'

    MESSAGE_CATEGORY = Enum('Panic', 'Alert', 'Update', 'Command')

    @classmethod
    def buildPacket(self,
                    msgtopic=TOPIC_SENSOR_DATA,
                    msgcategory=MESSAGE_CATEGORY.Update,
                    msgbus=None,
                    msgdevice=None,
                    msgvalue=None,
                    msgdata=None):
        return MessagePacket(topic=msgtopic,
                             category=msgcategory,
                             bus=msgbus,
                             device=msgdevice,
                             value=msgvalue,
                             data=msgdata,
                             timestamp=time.time())

    @abstractmethod
    def publish(self, sender, topic, message):
        '''Publish a message to the specified topic.  The specified topic MUST have been previously registered via
        registerTopic or an exception will be thrown.'''
        pass

    @abstractmethod
    def subscribe(self, subscriber, topic, callback=None):
        '''Subscribe to the specified topic.  Messages sent to a given topic will be sent to all subscribers.
        The specified topic MUST have been previously registered via registerTopic or an exception will be thrown.'''
        pass

    @abstractmethod
    def registerTopic(self, topic):
        '''Register topic to make it available for publish and/or subscribe.'''
        pass

    @abstractmethod
    def getTopics(self):
        '''Retrieve a list of known/registered topics'''
        pass

    @abstractmethod
    def unsubscribe(self, subscriber, topic):
        '''Remove a subscriber from a topic'''
        pass

    @abstractmethod
    def removeSubscriber(self, subscriber):
        '''Remove a subscriber from all topics'''
        pass
コード例 #3
0
class BaseSphereEntity():
    '''Base class for entities within Sphere'''
    DATA_TYPES = Enum('String','Integer','Float','Boolean','Date','Binary')
    UNKNOWN = '(Unknown)'
    def __init__(self, name = BaseSphereEntity.UNKNOWN, description = BaseSphereEntity.UNKNOWN):
        self._name = name
        self._description = description

    name = property(lambda self: self._name)
    description = property(lambda self: self._description)
コード例 #4
0
class EnumTests(unittest.TestCase):
    def setUp(self):
        self.enum = Enum('Dog','Cat','Fish')


    def testEmptyNotAllowed(self):
        try:
            enum = Enum()
        except AssertionError:
            pass
        else:
            fail("Expected assertion - empty enums not allowed")

    def testInclusion(self):
        assert self.enum.Cat

    def testInclusion_case(self):
        try:
            items = self.enum.cat
        except:
            pass
        else:
            fail("Expected assertion - enums are case sensitive")

    def testExclusion(self):
        try:
            items = self.enum.Frog
        except:
            pass
        else:
            fail("Expected assertion - item not in set")

    def testEquals(self):
        cat = self.enum.Cat
        anotherCat = self.enum.Cat

        assert (cat == anotherCat)

    def testLength(self):
        assert(self.enum.__len__() == 3)
コード例 #5
0
class Device(BaseSphereEntity):
    '''Represents a single Device within Sphere.  A Device can represent nearly anything, from a physical item like a
    switch or a light to a virtual state machine.  Devices within Sphere are typically contained within a Device Bus.
    Devices can be represented as nested items - devices can contain other devices.  For example, a single device
    representing a relay board may contain several nested sensor and actuator devices, each representing a single
    controllable or readable resource.'''
    DEVICE_STATUS = Enum('Unknown', 'New', 'Available', 'Missing', 'Error')
    def __init__(self):
        BaseSphereEntity.__init__(self)
        self._address = None
        self._configuration = dict()
        self._status = Device.DEVICE_STATUS.Unknown
        self._lastUpdate = time.time()
        self._devices = list()
        self._deviceType = None

    address = property(lambda self: self._address)
    configuration = property(lambda self: self._configuration)
    status = property(lambda self: self._status)
    lastUpdate = property(lambda self: self._lastUpdate)
    devices = property(lambda self: self._devices)
    deviceType = property(lambda self: self._deviceType)
コード例 #6
0
class EnumTests(unittest.TestCase):
    def setUp(self):
        self.enum = Enum('Dog', 'Cat', 'Fish')

    def testEmptyNotAllowed(self):
        try:
            enum = Enum()
        except AssertionError:
            pass
        else:
            fail("Expected assertion - empty enums not allowed")

    def testInclusion(self):
        assert self.enum.Cat

    def testInclusion_case(self):
        try:
            items = self.enum.cat
        except:
            pass
        else:
            fail("Expected assertion - enums are case sensitive")

    def testExclusion(self):
        try:
            items = self.enum.Frog
        except:
            pass
        else:
            fail("Expected assertion - item not in set")

    def testEquals(self):
        cat = self.enum.Cat
        anotherCat = self.enum.Cat

        assert (cat == anotherCat)

    def testLength(self):
        assert (self.enum.__len__() == 3)
コード例 #7
0
class Controllable:
    '''ABC for controllable components (components with start/stop functionality)
    Adds basic features common to these components - lifecycle management,
    logging, and messenger.'''

    __metaclass__ = ABCMeta

    STATUS = Enum('Unknown', 'Starting', 'Started', 'Stopping', 'Stopped',
                  'Error')

    def __init__(self, name):
        self._name = name
        self._description = None
        self._status = Controllable.STATUS.Unknown
        self._messenger = messengerFactory.getMessenger(self)
        self._log = logFactory.getLogger(self)
        self._stop = threading.Event()

    name = property(lambda self: self._name)
    description = property(lambda self: self._description)
    status = property(lambda self: self._status)

    @abstractmethod
    def _doStart(self):
        '''Start the component's processing.  Should perform actual startup.
          Base class takes care of logging, messaging, and state change.
          Must return boolean indicating success of operation.
          Implementing classes should throw ControllableException on error.'''
        pass

    def start(self):
        '''Perform actual startup, wraps call to _doStart.  This method takes care of clearing the self._stop event.
        There is little benefit to overriding this method.'''
        if self._status in (Controllable.STATUS.Unknown,
                            Controllable.STATUS.Stopped,
                            Controllable.STATUS.Error):
            self._setStatus(Controllable.STATUS.Starting)
            try:
                self._log.debug("Starting component [%s]...", self._name)
                self._stop.clear()
                stat = self._doStart()
                if stat:
                    self._log.debug("Component [%s] started.", self._name)
                else:
                    self._log.warning("Unable to start component [%s]!",
                                      self._name)
                # TODO: subscribe to messenger if started successfully
                newStatus = Controllable.STATUS.Started if stat else Controllable.STATUS.Stopped
                self._setStatus(newStatus)
            except Exception as ex:
                # TODO: should this exception be surfaced?
                self._setStatus(Controllable.STATUS.Error)
                self._log.error("Exception at startup: %s", ex)

    @abstractmethod
    def _doStop(self):
        '''Stop the component's processing.  Should perform actual shutdown.
          Base class takes care of logging, messaging, and state change.
          Must return boolean indicating success of operation.
          Implementing classes should throw ControllableException on error.'''
        pass

    @abstractmethod
    def _doRefresh(self):
        '''Perform component interval-based processing (if applicable)'''
        pass

    def stop(self):
        '''Perform actual stop, wraps call to _doStop.  This method takes care of setting the self._stop event.
        There is little benefit to overriding this method.'''
        if self._status == Controllable.STATUS.Started:
            self._setStatus(Controllable.STATUS.Stopping)
            try:
                self._log.debug("Stopping component [%s]...", self._name)
                self._stop.set()
                stat = self._doStop()
                if stat:
                    self._log.debug("Component [%s] stopped.", self._name)
                else:
                    self._log.warning("Unable to stop component [%s]",
                                      self._name)
                # TODO: unsubscribe all if stopped
                newStatus = Controllable.STATUS.Stopped if stat else Controllable.STATUS.Started
                self._setStatus(newStatus)
            except Exception as ex:
                # TODO: should this exception be surfaced?
                # TODO: this could leave background thread in inconsistent state
                self._setStatus(Controllable.STATUS.Error)
                self._log.error("Exception at stop: %s", ex)

    def refresh(self):
        if self._status == Controllable.STATUS.Started:
            self._log.debug("[%s] Executing refresh loop", self._name)
            self._doRefresh()

    def _setStatus(self, status):
        if status <> self._status:
            self._status = status
            self._messenger.publish(self, Messenger.TOPIC_COMPONENT_STATUS,
                                    status)
コード例 #8
0
 def setUp(self):
     self.enum = Enum('Dog','Cat','Fish')
コード例 #9
0
 def setUp(self):
     self.enum = Enum('Dog', 'Cat', 'Fish')