Example #1
0
    def substep( self, value, data, listeners ):
        '''
        This function is wraps step function.  It counts usage, errors then sends the data to next function.

        :param value: The number to convert to volts.
        :type value: int, float, string, etc
        :param data: a dictionary containing more information about the
                value. Data can be added to this as needed.  Here is a list
                of values that will be in the data dictionary:

              |  1 **date:** time received: time when value was received.
              |  2. **units:** units of the number
              |  3. **name:** name assigned to the value
              |  4. **device** name of the device the data is from.
              |  5. **port** name of the port the data is from.
        :param listeners: a list of the pubsub routines to send the data to
        :returns: value, data, listeners
        :rtype: value, dict, listeners
        :Raises: None

        '''
        # Trap any exceptions from getting to pubsub
        try:
            value, data, listeners = self.step( value, data, listeners )
            self.counter += 1
            self.last_count_time = datetime.utcnow()
            self.logger.debug( 'value {} listeners {}'.format( value, listeners ) )
            Common.send( value, data, listeners )
        except Exception as ex:
            self.logger.exception( "{}: {}".format( __name__, ex ) )
            self.errors += 1
            self.last_error_time = datetime.utcnow()
    def process( self, env ):
        '''
        Process a envelope received from the XBee.  This involves the following:
        1.  get the addresses from the header
        2.  get the data out of the packet
        3.  get information about the source of the data
        4.  send each packet using the pub/sub system

        Args:
        :param envelope: a packet received from the XBee radio and decomposed by the ZigBee module
        :type DataEnvelope:
        Return: None
        :Raises: None
        '''
        self.logger.debug( 'processing command {}'.format( env ) )
        try:
            value = env[Constants.EnvelopeContents.VALUE]
            steps = copy.copy( env[Constants.EnvelopeContents.STEPS] )

            Common.send( value, env.args, steps )
            self.logger.debug( "Successfully sent command to XBee" )
        except KeyError as ex:
            self.logger.exception( 'value or steps missing from env {}'.
                                   format( env ) )
        except ListenerSpecIncomplete as lsi:
            self.logger.error( 'Invalid topic: {}'.format( lsi ) )
Example #3
0
    def getUseCount(self, value, data, listeners):
        ''' 
        Report the number of times that step has been called.
        
        :param value: Not used.
        :type value: int
        :param data: a dictionary containing more information about the value.
        :param listeners: a list of the subscribed routines to send the to.
        :returns: int, dict, listeners

        >>> from steps.zigbee2volts import ZigbeeCountToVolts
        >>> zig = ZigbeeCountToVolts()
        >>> zig.getUseCount(100, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        (0, {'device': 'xyz', 'units': 'V', 'port': 'abc'}, ['a', 'b'])
        >>> zig.step(1, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        >>> zig.getUseCount(100, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        (1, {'device': 'xyz', 'units': 'V', 'port': 'abc'}, ['a', 'b'])

        '''
        if (self.counter != 0):
            self.logger.debug('getUseCount = {}'.format(self.counter))
            data[Constants.DataPacket.device] = 'HouseMonitor.' + self.whoami
            data[Constants.DataPacket.port] = data[
                Constants.DataPacket.name] = 'Count'
            data[Constants.DataPacket.arrival_time] = self.last_count_time
            try:
                Common.send(self.counter, data, copy.copy(listeners))
            except Exception as ex:
                self.logger.exception('Common.send error {}'.format(ex))
Example #4
0
    def getErrorCount(self, value, data, listeners):
        ''' Report the number of errors that has occurred in this step.

        :param value: Not used.
        :type value: int
        :param data: a dictionary containing more information about the
                value. Data can be added to this as needed.  Here is a list
                of values that will be in the data dictionary:

              |  1. **date:** time received: time when value was received.
              |  2. **units:** units of the number
              |  3. **name:** name assigned to the value
        :param listeners: a list of the subscribed routines to send the data to
        :returns: count, data, listeners
        :rtype: float, dict, listeners
        :Raises: None

        >>> from steps.zigbee2volts import ZigbeeCountToVolts
        >>> zig = ZigbeeCountToVolts()
        >>> zig.getErrorCount(100, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        '''
        if (self.errors != 0):
            self.logger.debug('getErrorCount = {}'.format(self.errors))
            data[Constants.DataPacket.device] = 'HouseMonitor.' + self.whoami
            data[Constants.DataPacket.port] = data[
                Constants.DataPacket.name] = 'Error Count'
            data[Constants.DataPacket.arrival_time] = self.last_error_time
            try:
                Common.send(self.errors, data, copy.copy(listeners))
            except Exception as ex:
                self.logger.exception('Common.send error {}'.format(ex))
Example #5
0
    def getUseCount( self, value, data, listeners ):
        ''' 
        Report the number of times that step has been called.
        
        :param value: Not used.
        :type value: int
        :param data: a dictionary containing more information about the value.
        :param listeners: a list of the subscribed routines to send the to.
        :returns: int, dict, listeners

        >>> from steps.zigbee2volts import ZigbeeCountToVolts
        >>> zig = ZigbeeCountToVolts()
        >>> zig.getUseCount(100, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        (0, {'device': 'xyz', 'units': 'V', 'port': 'abc'}, ['a', 'b'])
        >>> zig.step(1, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        >>> zig.getUseCount(100, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        (1, {'device': 'xyz', 'units': 'V', 'port': 'abc'}, ['a', 'b'])

        '''
        if ( self.counter != 0 ):
            self.logger.debug( 'getUseCount = {}'.format( self.counter ) )
            data[Constants.DataPacket.device] = 'HouseMonitor.' + self.whoami
            data[Constants.DataPacket.port] = data[Constants.DataPacket.name] = 'Count'
            data[Constants.DataPacket.arrival_time] = self.last_count_time
            try:
                Common.send( self.counter, data, copy.copy( listeners ) )
            except Exception as ex:
                self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #6
0
    def substep(self, value, data, listeners):
        '''
        This function is wraps step function.  It counts usage, errors then sends the data to next function.

        :param value: The number to convert to volts.
        :type value: int, float, string, etc
        :param data: a dictionary containing more information about the
                value. Data can be added to this as needed.  Here is a list
                of values that will be in the data dictionary:

              |  1 **date:** time received: time when value was received.
              |  2. **units:** units of the number
              |  3. **name:** name assigned to the value
              |  4. **device** name of the device the data is from.
              |  5. **port** name of the port the data is from.
        :param listeners: a list of the pubsub routines to send the data to
        :returns: value, data, listeners
        :rtype: value, dict, listeners
        :Raises: None

        '''
        # Trap any exceptions from getting to pubsub
        try:
            value, data, listeners = self.step(value, data, listeners)
            self.counter += 1
            self.last_count_time = datetime.utcnow()
            self.logger.debug('value {} listeners {}'.format(value, listeners))
            Common.send(value, data, listeners)
        except Exception as ex:
            self.logger.exception("{}: {}".format(__name__, ex))
            self.errors += 1
            self.last_error_time = datetime.utcnow()
Example #7
0
    def process(self, env):
        '''
        Process a envelope received from the XBee.  This involves the following:
        1.  get the addresses from the header
        2.  get the data out of the packet
        3.  get information about the source of the data
        4.  send each packet using the pub/sub system

        Args:
        :param envelope: a packet received from the XBee radio and decomposed by the ZigBee module
        :type DataEnvelope:
        Return: None
        :Raises: None
        '''
        self.logger.debug('processing command {}'.format(env))
        try:
            value = env[Constants.EnvelopeContents.VALUE]
            steps = copy.copy(env[Constants.EnvelopeContents.STEPS])

            Common.send(value, env.args, steps)
            self.logger.debug("Successfully sent command to XBee")
        except KeyError as ex:
            self.logger.exception(
                'value or steps missing from env {}'.format(env))
        except ListenerSpecIncomplete as lsi:
            self.logger.error('Invalid topic: {}'.format(lsi))
Example #8
0
    def getErrorCount( self, value, data, listeners ):
        ''' Report the number of errors that has occurred in this step.

        :param value: Not used.
        :type value: int
        :param data: a dictionary containing more information about the
                value. Data can be added to this as needed.  Here is a list
                of values that will be in the data dictionary:

              |  1. **date:** time received: time when value was received.
              |  2. **units:** units of the number
              |  3. **name:** name assigned to the value
        :param listeners: a list of the subscribed routines to send the data to
        :returns: count, data, listeners
        :rtype: float, dict, listeners
        :Raises: None

        >>> from steps.zigbee2volts import ZigbeeCountToVolts
        >>> zig = ZigbeeCountToVolts()
        >>> zig.getErrorCount(100, {'device': 'xyz', 'port': 'abc'}, ['a', 'b'])
        '''
        if ( self.errors != 0 ):
            self.logger.debug( 'getErrorCount = {}'.format( self.errors ) )
            data[Constants.DataPacket.device] = 'HouseMonitor.' + self.whoami
            data[Constants.DataPacket.port] = data[Constants.DataPacket.name] = 'Error Count'
            data[Constants.DataPacket.arrival_time] = self.last_error_time
            try:
                Common.send( self.errors, data, copy.copy( listeners ) )
            except Exception as ex:
                self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #9
0
    def output( self, value, data, listeners ):
        '''
        This routine will output a log of data that it receives

        Args:
            value: the value for the data
            data: more information about the value
            listeners:  the various listeners for this object

        Return:
            the string that is printed

        Execptions:
            None
        '''
        name = data['Name']
        date = data['date time received']

        line = "{:25.25s} {} {}{}".format( name, date, value, os.linesep )

        self.os.write( line )

        try:
            Common.send( value=value, data=data, listeners=listeners )
        except Exception as ex:
            self.logger.exception( 'Common.send error {}'.format( ex ) )

        return line
Example #10
0
    def output(self, value, data, listeners):
        '''
        This routine will output a log of data that it receives

        Args:
            value: the value for the data
            data: more information about the value
            listeners:  the various listeners for this object

        Return:
            the string that is printed

        Execptions:
            None
        '''
        name = data['Name']
        date = data['date time received']

        line = "{:25.25s} {} {}{}".format(name, date, value, os.linesep)

        self.os.write(line)

        try:
            Common.send(value=value, data=data, listeners=listeners)
        except Exception as ex:
            self.logger.exception('Common.send error {}'.format(ex))

        return line
Example #11
0
 def test_send_with_split( self, sendMessage ):
     value = 1
     data = {'device': {'port': {'a': 'b'}}}
     listeners = [['x', 'y', 'z'], 'a', 'b', 'c']
     Common.send( value, data, listeners )
     expected_call_list = [call( 'x', listeners=['y', 'z'], data={'device': {'port': {'a': 'b'}}}, value=1 ),
                          call( 'a', listeners=['b', 'c'], data={'device': {'port': {'a': 'b'}}}, value=1 )]
     self.assertEqual( sendMessage.mock_calls, expected_call_list )
Example #12
0
    def process( self, packet ):
        '''
        Process a envelope received from the XBee.  This involves the following:
        1.  get the addresses from the header
        2.  get the data out of the packet
        3.  get information about the source of the data
        4.  send each packet using the pub/sub system

        Args:
        :param envelope: a packet received from the XBee radio and decomposed by the ZigBee module
        :type DataEnvelope:
        Return: None
        :Raises: None
        '''
        self.logger.debug( 'processing data from zigbee {}'.format( packet ) )
        try:
            if packet[Constants.XBee.id] == Constants.XBee.api_responses.rx_io_data_long_addr:
                source_addr_long = "{:#x}".format( unpack( '!Q', packet[Constants.XBee.source_addr_long] )[0] )
                source_addr = "{:#x}".format( unpack( '!H', packet[Constants.XBee.source_addr] )[0] )
                if Constants.XBee.samples in packet:
                    samples = packet[Constants.XBee.samples]
                    for port in samples[0]:
                        package = {}
                        try:
                            if ( self.devices.valid_device( source_addr_long ) ):
                                package[Constants.DataPacket.device] = source_addr_long
                                package[Constants.DataPacket.name] = self.devices.get_port_name( source_addr_long, port )
                                package[Constants.DataPacket.port] = port
                                package[Constants.DataPacket.arrival_time] = datetime.utcnow()
                                package[Constants.DataPacket.units] = self.devices.get_port_units( source_addr_long, port )
                                package[Constants.DataPacket.steps] = copy.copy( self.devices.get_steps( source_addr_long, port ) )
                                data = samples[0][port]

                                Common.send( data, package, package[Constants.DataPacket.steps] )
                        except InvalidDeviceError as ie:
                                self.logger.exception( str( ie ) )
                        except InvalidPortError as ie:
                                self.logger.exception( str( ie ) )
                        except InvalidConfigurationOptionError as ie:
                                self.logger.exception( str( ie ) )
                        except Exception as ex:
                            self.logger.exception( 'Common.send error {}'.format( ex ) )
            else:
                self.logger.info( 'None processed ZigBee response {}'.format( pprint.pformat( packet ) ) )
        except KeyError:
            self.logger.exception( "error extracting data from {}".format( pprint.pformat( packet ) ) )
        except ListenerSpecIncomplete as lsi:
            self.logger.error( 'Invalid topic: {}'.format( lsi ) )
Example #13
0
 def changeDisableButtonWarningLight(self, value):
     ''' Turn on or off the LED that indicates that the garage door is open. 
     
     :param value: determines if the light will be on or off.
     :type value: Boolean
     :returns: none
     
     '''
     steps = [Constants.TopicNames.ZigBeeOutput]
     data = {}
     data[Constants.DataPacket.device] = self.panel_address
     data[Constants.DataPacket.port] = self.panel_disable_button_led
     try:
         Common.send(value, data, steps)
     except Exception as ex:
         self.logger.exception('Common.send error {}'.format(ex))
Example #14
0
 def changeDisableButtonWarningLight( self, value ):
     ''' Turn on or off the LED that indicates that the garage door is open. 
     
     :param value: determines if the light will be on or off.
     :type value: Boolean
     :returns: none
     
     '''
     steps = [Constants.TopicNames.ZigBeeOutput]
     data = {}
     data[Constants.DataPacket.device] = self.panel_address
     data[Constants.DataPacket.port] = self.panel_disable_button_led
     try:
         Common.send( value, data, steps )
     except Exception as ex:
         self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #15
0
 def changeGarageDoorWarningLight( self, value ):
     ''' Turn on or off the LED that indicates that the disable alarm has been pressed. 
     
     :param value: determines if the light will be on or off.
     :type value: Boolean
     :returns: none
     
     '''
     steps = [Constants.TopicNames.ZigBeeOutput]
     data = {}
     data[Constants.DataPacket.device] = self.panel_address
     data[Constants.DataPacket.port] = self.panel_garage_door_led
     light = not value
     try:
         Common.send( light, data, steps )
     except Exception as ex:
         self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #16
0
 def changeGarageDoorWarningLight(self, value):
     ''' Turn on or off the LED that indicates that the disable alarm has been pressed. 
     
     :param value: determines if the light will be on or off.
     :type value: Boolean
     :returns: none
     
     '''
     steps = [Constants.TopicNames.ZigBeeOutput]
     data = {}
     data[Constants.DataPacket.device] = self.panel_address
     data[Constants.DataPacket.port] = self.panel_garage_door_led
     light = not value
     try:
         Common.send(light, data, steps)
     except Exception as ex:
         self.logger.exception('Common.send error {}'.format(ex))
Example #17
0
    def changeAlarm( self, value ):
        ''' Turn on or off the alarm that indicates that the garage door is open.         

        :param value: determines if the alarm will be on or off.
        :type value: Boolean
        :returns: none

        '''
        self.alarm = value
        steps = [Constants.TopicNames.ZigBeeOutput]
        data = {}
        data[Constants.DataPacket.device] = self.panel_address
        data[Constants.DataPacket.port] = self.panel_alarm
        self.logger.debug( "changeAlarm with {} {} {}".format( value, data, steps ) )
        try:
            Common.send( value, data, steps )
        except Exception as ex:
            self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #18
0
    def process( self, envelope ):
        '''
        Process a packet received from the XBee.  This involves the following:
        #.  get the addresses from the header
        #.  get the data out of the packet
        #.  get information about the source of the data
        #.  send each packet using the pub/sub system

        :param packet: a packet recived from the XBee radio and decomposed by the ZigBee module
        :return: None
        :Raises: None
        '''
        try:
            value = envelope[Constants.EnvelopeContents.VALUE] if Constants.EnvelopeContents.VALUE in envelope else 1
            listeners = envelope[Constants.EnvelopeContents.STEPS]
            Common.send( value, envelope.args, listeners )
        except Exception as ex:
            self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #19
0
    def changeAlarm(self, value):
        ''' Turn on or off the alarm that indicates that the garage door is open.         

        :param value: determines if the alarm will be on or off.
        :type value: Boolean
        :returns: none

        '''
        self.alarm = value
        steps = [Constants.TopicNames.ZigBeeOutput]
        data = {}
        data[Constants.DataPacket.device] = self.panel_address
        data[Constants.DataPacket.port] = self.panel_alarm
        self.logger.debug("changeAlarm with {} {} {}".format(
            value, data, steps))
        try:
            Common.send(value, data, steps)
        except Exception as ex:
            self.logger.exception('Common.send error {}'.format(ex))
Example #20
0
    def process(self, envelope):
        '''
        Process a packet received from the XBee.  This involves the following:
        #.  get the addresses from the header
        #.  get the data out of the packet
        #.  get information about the source of the data
        #.  send each packet using the pub/sub system

        :param packet: a packet recived from the XBee radio and decomposed by the ZigBee module
        :return: None
        :Raises: None
        '''
        try:
            value = envelope[
                Constants.EnvelopeContents.
                VALUE] if Constants.EnvelopeContents.VALUE in envelope else 1
            listeners = envelope[Constants.EnvelopeContents.STEPS]
            Common.send(value, envelope.args, listeners)
        except Exception as ex:
            self.logger.exception('Common.send error {}'.format(ex))
Example #21
0
 def send_old_values( self, value, data, listeners ):
     new_data = copy( data )
     new_listeners = copy( listeners )
     if ( value == False ):
         new_data[Constants.DataPacket.units] = "closed"
         new_data[Constants.DataPacket.arrival_time] = new_data[Constants.DataPacket.arrival_time] - self.smuggen_before
         new_value = "1"
     elif( value == True ):
         new_data[Constants.DataPacket.units] = "open"
         new_data[Constants.DataPacket.arrival_time] = new_data[Constants.DataPacket.arrival_time] - self.smuggen_before
         new_value = "0"
     else:
         new_value = -1
         new_data[Constants.DataPacket.units] = 'invalid'
         self.logger.warn( "invalid state %d", value )
     self.logger.info( "prior door state was {} {} {}".format( new_value, new_data[Constants.DataPacket.units], listeners ) )
     try:
         Common.send( new_value, new_data, new_listeners )
     except Exception as ex:
         self.logger.exception( 'Common.send error {}'.format( ex ) )
Example #22
0
 def send_old_values(self, value, data, listeners):
     new_data = copy(data)
     new_listeners = copy(listeners)
     if (value == False):
         new_data[Constants.DataPacket.units] = "closed"
         new_data[Constants.DataPacket.arrival_time] = new_data[
             Constants.DataPacket.arrival_time] - self.smuggen_before
         new_value = "1"
     elif (value == True):
         new_data[Constants.DataPacket.units] = "open"
         new_data[Constants.DataPacket.arrival_time] = new_data[
             Constants.DataPacket.arrival_time] - self.smuggen_before
         new_value = "0"
     else:
         new_value = -1
         new_data[Constants.DataPacket.units] = 'invalid'
         self.logger.warn("invalid state %d", value)
     self.logger.info("prior door state was {} {} {}".format(
         new_value, new_data[Constants.DataPacket.units], listeners))
     try:
         Common.send(new_value, new_data, new_listeners)
     except Exception as ex:
         self.logger.exception('Common.send error {}'.format(ex))
Example #23
0
    def process(self, packet):
        '''
        Process a envelope received from the XBee.  This involves the following:
        1.  get the addresses from the header
        2.  get the data out of the packet
        3.  get information about the source of the data
        4.  send each packet using the pub/sub system

        Args:
        :param envelope: a packet received from the XBee radio and decomposed by the ZigBee module
        :type DataEnvelope:
        Return: None
        :Raises: None
        '''
        self.logger.debug('processing data from zigbee {}'.format(packet))
        try:
            if packet[Constants.XBee.
                      id] == Constants.XBee.api_responses.rx_io_data_long_addr:
                source_addr_long = "{:#x}".format(
                    unpack('!Q', packet[Constants.XBee.source_addr_long])[0])
                source_addr = "{:#x}".format(
                    unpack('!H', packet[Constants.XBee.source_addr])[0])
                if Constants.XBee.samples in packet:
                    samples = packet[Constants.XBee.samples]
                    for port in samples[0]:
                        package = {}
                        try:
                            if (self.devices.valid_device(source_addr_long)):
                                package[Constants.DataPacket.
                                        device] = source_addr_long
                                package[Constants.DataPacket.
                                        name] = self.devices.get_port_name(
                                            source_addr_long, port)
                                package[Constants.DataPacket.port] = port
                                package[Constants.DataPacket.
                                        arrival_time] = datetime.utcnow()
                                package[Constants.DataPacket.
                                        units] = self.devices.get_port_units(
                                            source_addr_long, port)
                                package[
                                    Constants.DataPacket.steps] = copy.copy(
                                        self.devices.get_steps(
                                            source_addr_long, port))
                                data = samples[0][port]

                                Common.send(
                                    data, package,
                                    package[Constants.DataPacket.steps])
                        except InvalidDeviceError as ie:
                            self.logger.exception(str(ie))
                        except InvalidPortError as ie:
                            self.logger.exception(str(ie))
                        except InvalidConfigurationOptionError as ie:
                            self.logger.exception(str(ie))
                        except Exception as ex:
                            self.logger.exception(
                                'Common.send error {}'.format(ex))
            else:
                self.logger.info('None processed ZigBee response {}'.format(
                    pprint.pformat(packet)))
        except KeyError:
            self.logger.exception("error extracting data from {}".format(
                pprint.pformat(packet)))
        except ListenerSpecIncomplete as lsi:
            self.logger.error('Invalid topic: {}'.format(lsi))
Example #24
0
 def test_send( self, sendMessage ):
     value = 1
     data = {'device': {'port': {'a': 'b'}}}
     listeners = ['a', 'b', 'c']
     Common.send( value, data, listeners )
     sendMessage.assert_called_once_with( 'a', value=value, data=data, listeners=['b', 'c'] )