def __is_sleep_mode_available(self):
        # Special case: if this is a ZB network we need to check if the
        # firmware version is less than 0x2x60.  If it is less than this,
        # then sleep mode is not supported on router modules (0x2260):
        xbee_dd_ddo_value = \
            AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_get_param(
                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                'DD',
                retries=DDO_RETRY_ATTEMPTS,
                use_cache=True)
        module_id, product_id = parse_dd(xbee_dd_ddo_value)

        if module_id not in (MOD_XB_ZNET25, MOD_XB_ZB, MOD_XB_S2C_ZB):
            # Sleep unsupported
            return False

        if module_id == MOD_XB_ZB or module_id == MOD_XB_S2C_ZB:
            xbee_vr_ddo_value = \
                AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_get_param(
                    AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                    'VR',
                    retries=DDO_RETRY_ATTEMPTS,
                    use_cache=True)
            fw_funcset, fw_version = parse_vr(xbee_vr_ddo_value)

            if (fw_funcset in UNSUPPORTED_ZB_FW_FUNCSETS and
                fw_version < UNSUPPORTED_ZB_LT_FW_VERSION):
                self.__tracer.warning("'%s' FW version is %s < %s, " + 
                                "sleep mode configuration unavailable.",
                                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                                hex(fw_version),
                                hex(UNSUPPORTED_ZB_LT_FW_VERSION))
                return False

        return True
Exemplo n.º 2
0
    def __prepare_network_update_param(self, ext_addr, param, override_map):
        '''
        Internal helper function used to update node parameters.

        Returns True if this node needs to be updated, otherwise False.
        '''

        minimum_sp_value = MINIMUM_ZB_RTR_SP_VALUE

        self.__tracer.debug("Fetching '%s' from '%s'", param, ext_addr)
        try:
            network_param = (AbstractXBeeConfigBlockDDO.configurator_get(
                self).ddo_get_param(ext_addr,
                                    param,
                                    retries=DDO_RETRY_ATTEMPTS,
                                    use_cache=True))
            # All params used here are 16-bit unsigned ints:
            network_param = struct.unpack('>H', network_param)[0]
        except Exception, e:
            self.__tracer.warning("Could not fetch param " \
                    "'%s' from '%s': %s", param, ext_addr, str(e))
            self.__tracer.debug("Removing '%s' from cache", ext_addr)
            (AbstractXBeeConfigBlockDDO.xbee_device_manager_get(
                self)._xbee_remove_node_from_list(ext_addr))
            raise e
Exemplo n.º 3
0
 def __init__(self, ext_addr):
     """\
     Create an XBeeConfigBlockWakeup object.
     
     See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.
     """
     AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)
 def __init__(self, ext_addr):
     """\
     Create an XBeeConfigBlockWakeup object.
     
     See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.
     """
     AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)
    def reset(self):
        """\
        Reset the state of this configuration block object.

        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.

        """      
        self.__pending_parameters = copy(self.__parameters)
        # Complete the state reset:
        AbstractXBeeConfigBlockDDO.reset(self)
Exemplo n.º 6
0
    def reset(self):
        '''
        Reset the state of this configuration block object.

        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.\
        XBeeConfigBlock`.
        '''
        self.__pending_parameters = copy(self.__parameters)
        # Complete the state reset:
        AbstractXBeeConfigBlockDDO.reset(self)
    def __init__(self, ext_addr):
        self.__parameters = { }
        self.__pending_parameters = { }
        self.__sleep_mode = SM_DISABLED
        self.__sleep_period_ms = 0

        from core.tracing import get_tracer
        self.__tracer = get_tracer('XBeeConfigBlockSleep')

        AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)
        AbstractXBeeConfigBlockDDO.apply_only_to_modules(self,
            (MOD_XB_ZNET25, MOD_XB_ZB, MOD_XB_S2C_ZB))
Exemplo n.º 8
0
    def __init__(self, ext_addr):
        self.__parameters = {}
        self.__pending_parameters = {}
        self.__sleep_mode = SM_DISABLED
        self.__sleep_period_ms = 0

        from core.tracing import get_tracer
        self.__tracer = get_tracer('XBeeConfigBlockSleep')

        AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)
        AbstractXBeeConfigBlockDDO.apply_only_to_modules(
            self, SLEEPABLE_MODULES)
Exemplo n.º 9
0
    def __is_sleep_mode_available(self, ext_addr=False):
        '''
        If ext_addr is False, uses the device referred to in this
        config block.
        '''
        # Special case: if this is a ZB network we need to check if the
        # firmware version is less than 0x2x60.  If it is less than this,
        # then sleep mode is not supported on router modules (0x2260):
        if ext_addr == False:
            ext_addr = AbstractXBeeConfigBlockDDO.ext_addr_get(self)

        module_id, _ = parse_dd(AbstractXBeeConfigBlockDDO.\
                                configurator_get(self)\
                                .ddo_get_param(ext_addr, 'DD',
                                               retries=DDO_RETRY_ATTEMPTS,
                                               use_cache=True))
        if module_id not in SLEEPABLE_MODULES:
            return False

        if module_id == MOD_XB_ZB or module_id == MOD_XB_S2C_ZB:
            fw_func, fw_v = parse_vr(AbstractXBeeConfigBlockDDO.\
                                     configurator_get(self).\
                                     ddo_get_param(ext_addr, 'VR',
                                                   retries=\
                                                   DDO_RETRY_ATTEMPTS,
                                                   use_cache=True))

            if (fw_func in UNSUPPORTED_ZB_FW_FUNCSETS
                    and fw_v < UNSUPPORTED_ZB_LT_FW_VERSION):
                self.__tracer.warning(
                    "'%s' FW version is %s < %s, "
                    "sleep mode configuration unavailable.", ext_addr,
                    hex(fw_v), hex(UNSUPPORTED_ZB_LT_FW_VERSION))
                return False
        return True
Exemplo n.º 10
0
    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the 
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.
        
        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.

        """

        try:
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)
        except Exception, e:
            # trace message will be printed by _is_applicable() or
            # apply_config() upon exception.
            return False
    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the 
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.
        
        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.

        """

        try:
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)
        except Exception, e:
            # trace message will be printed by _is_applicable() or
            # apply_config() upon exception.
            return False
Exemplo n.º 12
0
    def apply_config(self):
        """
        Apply the configuration actions to the node targeted by this object.

        After this method has been called the
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.

        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.
        """
        # This is called when all the settings have been successfully applied:
        return AbstractXBeeConfigBlockDDO.apply_config(self)
    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.

        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.

        """        
        # This is called when all the settings have been successfully applied:
        return AbstractXBeeConfigBlockDDO.apply_config(self)
    def __prepare_network_update_param(self, ext_addr, param):
        """Internal helper function used to update node parameters."""
        
        minimum_sp_value = MINIMUM_ZB_RTR_SP_VALUE

        self.__tracer.debug("Fetching '%s' from '%s'", param, ext_addr)
        try:
            network_param = (
                AbstractXBeeConfigBlockDDO.configurator_get(self)
                    .ddo_get_param(ext_addr, param,
                                   retries=DDO_RETRY_ATTEMPTS,
                                   use_cache=True))
            # All params used here are 16-bit unsigned ints:
            network_param = struct.unpack('H', network_param)[0]                        
        except Exception, e:
             self.__tracer.warning("Could not fetch param " +
                    "'%s' from '%s': %s", param, ext_addr, str(e))
             self.__tracer.debug("Removing '%s' from cache", ext_addr)
             (AbstractXBeeConfigBlockDDO
                .xbee_device_manager_get(self)
                ._xbee_remove_node_from_list(ext_addr))
             raise e
    def prepare_network(self):
        """\
        Setup the network to handle this node.
        
        It is important that all routers and the coordinator be
        prepared to reach a node with sleeping parameters.  Without
        preparing the network first, reaching the node to configure it
        (if it has been preconfigured, for instance) may leave the node
        unreachable!
        
        This method will be called as a special case from the
        XBeeDeviceManager at the appropriate time.
        
        Return type:
            * bool

        """

        if self.__sleep_mode == SM_DISABLED:
            return

        # Test local node for sleep fitness:
        if not self.__is_sleep_mode_available():
            return False
        
        # If we are setting up a node for cyclic sleep, we must set
        # appropriate values for SP and SN (if the values are not already
        # large enough) network wide so the network may buffer requests
        # long enough for our sleeping nodes:
        router_list = (AbstractXBeeConfigBlockDDO.xbee_device_manager_get(self)
                        .xbee_get_node_list(refresh=False))
        router_list = filter(lambda n: (n.type == 'router' or 
                            n.type == 'coordinator'), router_list)
        router_list = map(lambda n: n.addr_extended, router_list)
        write_list = [ ]
        
        xbee_dd_ddo_value = \
            AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_get_param(
                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                'DD',
                retries=DDO_RETRY_ATTEMPTS,
                use_cache=True)
        module_id, product_id = parse_dd(xbee_dd_ddo_value)
        
        applicable_params = None
        if module_id == MOD_XB_ZNET25:
            # Only SP is valid network wide:
            applicable_params = ( 'SP', )
        elif module_id == MOD_XB_ZB or module_id == MOD_XB_S2C_ZB:
            applicable_params = ( 'SP', 'SN' )
        for param in applicable_params:
            if param in self.__pending_parameters:
                network_param = None
                for network_node in router_list:
                    try:
                        if not self.__prepare_network_update_param(
                                  network_node, param):
                            # no update necessary, continue
                            continue
                    except Exception, e:
                        # signal to XBeeDeviceManager that network preparation
                        # needs to be retried:

                        # print "XDCBS: Error updating parameter: %s" % repr(e)
                        # print "-" * 60
                        # traceback.print_exc(file=sys.stdout)
                        # print "-" * 60
                        
                        return False
                    write_list.append(network_node)
Exemplo n.º 16
0
    def apply_config(self):
        '''
        Apply the configuration actions to the node targeted by this object.

        After this method has been called the
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.

        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.
        '''
        try:
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)

        except:
            # Trace messages handled by _is_applicable() and apply_config()
            return False

        # Special case:
        #
        # Check if sleep mode is unavailable on this module/firmware
        # combination:
        if not self.__is_sleep_mode_available():
            if self.__sleep_mode == SM_DISABLED:
                # This sleep block has been filled out with sleeping
                # disabled however sleep configuration is not available:
                # mark this block as complete.
                self.__tracer.debug('sleep mode unsupported and SM_DISABLED'
                                    ' given, block complete.')
                return AbstractXBeeConfigBlockDDO.apply_config(self)
            else:
                # We are unable to apply this block, mark it as a
                # block application failure:
                self.__tracer.warning('sleep mode unsupported'
                                      ' but sleep parameters given,'
                                      ' block FAILED. Please disable '
                                      'sleeping on this device.')
                return False

        # Configure the node:
        pending_mnemonics = self.__pending_parameters.keys()

        for mnemonic in pending_mnemonics:
            # NOTE: this message is duplicated in the XBeeConfigBlockDDO source
            self.__tracer.debug(
                "Apply_config: trying '%s' = '%s' to '%s'", mnemonic,
                format_hexrepr(self.__pending_parameters[mnemonic]),
                AbstractXBeeConfigBlockDDO.ext_addr_get(self))
            try:
                AbstractXBeeConfigBlockDDO.configurator_get(self).\
                    ddo_set_param(
                        AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                        mnemonic,
                        self.__pending_parameters[mnemonic],
                        retries=DDO_RETRY_ATTEMPTS)
            except Exception, e:
                self.__tracer.error(
                    "'%s' = '%s' to '%s' failed (%s)", mnemonic,
                    format_hexrepr(self.__pending_parameters[mnemonic]),
                    AbstractXBeeConfigBlockDDO.ext_addr_get(self), str(e))
                return False
            del (self.__pending_parameters[mnemonic])
Exemplo n.º 17
0
class XBeeConfigBlockFinalWrite(AbstractXBeeConfigBlockDDO):
    """\
    XBee DDO Configuration Block
    
    Implements an 
    :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block_ddo.AbstractXBeeConfigBlockDDO`
    for proper sequencing by the 
    :py:class:`~devices.xbee.xbee_device_manager.xbee_device_manager.XBeeDeviceManager`.

    This class will automatically be placed at the end of the chain of
    :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`
    objects by the
    :py:class:`~devices.xbee.xbee_device_manager.xbee_device_manager.XBeeDeviceManager`.

    It's purpose is to store the applied
    settings to non-volatile memory so nodes will reboot into a
    configured state in the event of a power loss.  It will also apply
    all changes performed by the chain, so that they take affect at
    the same time.

    """
    def __init__(self, ext_addr):
        """\
        Create an XBeeConfigBlockFinalWrite object.
        
        See: 
        :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`

        """
        AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)

    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the 
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.
        
        See 
        :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`

        """

        try:
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)
        except Exception, e:
            # trace message will be printed by _is_applicable() or
            # apply_config() upon exception.
            return False

        from core.tracing import get_tracer
        __tracer = get_tracer('XBeeConfigBlockFinalWrite')

        try:
            __tracer.debug("trying 'WR' to '%s'",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self))

            AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_set_param(
                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                'WR',
                retries=DDO_RETRY_ATTEMPTS,
                apply=True)
        except Exception, e:
            __tracer.error("Trying 'WR' to '%s' failed (%s)",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                           str(e))
            return False
                return AbstractXBeeConfigBlockDDO.apply_config(self)
        except Exception, e:
            # trace message will be printed by _is_applicable() or
            # apply_config() upon exception.
            return False

        from core.tracing import get_tracer
        __tracer = get_tracer('XBeeConfigBlockFinalWrite')

        try:
            __tracer.debug("trying 'WR' to '%s'",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self))
            
            AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_set_param(
                             AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                             'WR',
                             retries=DDO_RETRY_ATTEMPTS,
                             apply=True)
        except Exception, e:
            __tracer.error("Trying 'WR' to '%s' failed (%s)",
                            AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                            str(e))
            return False

        # This is called when all the settings have been successfully applied:
        return AbstractXBeeConfigBlockDDO.apply_config(self)


# internal functions & classes

Exemplo n.º 19
0
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)
        except Exception, e:
            # trace message will be printed by _is_applicable() or
            # apply_config() upon exception.
            return False

        from core.tracing import get_tracer
        __tracer = get_tracer('XBeeConfigBlockWakeup')

        try:
            __tracer.debug("Trying 'CB=1' to '%s'",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self))
            AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_set_param(
                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                'CB',
                1,
                retries=DDO_RETRY_ATTEMPTS)
        except Exception, e:
            __tracer.error("Trying 'CB=1' to '%s' failed (%s)",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                           str(e))
            return False

        # This is called when all the settings have been successfully applied:
        return AbstractXBeeConfigBlockDDO.apply_config(self)


# internal functions & classes
Exemplo n.º 20
0
class XBeeConfigBlockWakeup(AbstractXBeeConfigBlockDDO):
    """\
    XBee DDO Configuration Block
    
    Implements an 
    :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block_ddo.AbstractXBeeConfigBlockDDO`
    for proper sequencing by the 
    :py:class:`~devices.xbee.xbee_device_manager.xbee_device_manager.XBeeDeviceManager`.

    This class will automatically be placed at the beginning of the chain of
    :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`
    objects by the
    :py:class:`~devices.xbee.xbee_device_manager.xbee_device_manager.XBeeDeviceManager`.
    It's purpose is to perform a
    commissioning button press on a node that is about to be fully
    configured.  This should result in the node being awake for 30
    seconds.  If this is a sleeping node, this increased window of
    wake time increases the ability to fully configure nodes.
    """
    def __init__(self, ext_addr):
        """\
        Create an XBeeConfigBlockWakeup object.
        
        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.
        """
        AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)

    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the 
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.
        
        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.

        """

        try:
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)
        except Exception, e:
            # trace message will be printed by _is_applicable() or
            # apply_config() upon exception.
            return False

        from core.tracing import get_tracer
        __tracer = get_tracer('XBeeConfigBlockWakeup')

        try:
            __tracer.debug("Trying 'CB=1' to '%s'",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self))
            AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_set_param(
                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                'CB',
                1,
                retries=DDO_RETRY_ATTEMPTS)
        except Exception, e:
            __tracer.error("Trying 'CB=1' to '%s' failed (%s)",
                           AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                           str(e))
            return False
Exemplo n.º 21
0
class XBeeConfigBlockSleep(AbstractXBeeConfigBlockDDO):
    """
    XBee DDO Configuration Block

    Implements an
    :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block_ddo.AbstractXBeeConfigBlockDDO`
    for proper sequencing by the
    :py:class:`~devices.xbee.xbee_device_manager.xbee_device_manager.XBeeDeviceManager`.

    This class automatically configures the sleep cycle DDO parameters
    for XBee nodes via the :py:meth:`sleep_cycle_set` method.
    """
    def __init__(self, ext_addr):
        self.__parameters = {}
        self.__pending_parameters = {}
        self.__sleep_mode = SM_DISABLED
        self.__sleep_period_ms = 0

        from core.tracing import get_tracer
        self.__tracer = get_tracer('XBeeConfigBlockSleep')

        AbstractXBeeConfigBlockDDO.__init__(self, ext_addr)
        AbstractXBeeConfigBlockDDO.apply_only_to_modules(
            self, SLEEPABLE_MODULES)

    def _add_parameter(self, mnemonic, value):
        # zb_dev_manager needs to access
        if not isinstance(mnemonic, str) and len(mnemonic) == 2:
            raise AttributeError('mnemonic must be a string of length 2')
        self.__parameters[mnemonic] = value
        self.__pending_parameters[mnemonic] = value

    def __is_sleep_mode_available(self, ext_addr=False):
        '''
        If ext_addr is False, uses the device referred to in this
        config block.
        '''
        # Special case: if this is a ZB network we need to check if the
        # firmware version is less than 0x2x60.  If it is less than this,
        # then sleep mode is not supported on router modules (0x2260):
        if ext_addr == False:
            ext_addr = AbstractXBeeConfigBlockDDO.ext_addr_get(self)

        module_id, _ = parse_dd(AbstractXBeeConfigBlockDDO.\
                                configurator_get(self)\
                                .ddo_get_param(ext_addr, 'DD',
                                               retries=DDO_RETRY_ATTEMPTS,
                                               use_cache=True))
        if module_id not in SLEEPABLE_MODULES:
            return False

        if module_id == MOD_XB_ZB or module_id == MOD_XB_S2C_ZB:
            fw_func, fw_v = parse_vr(AbstractXBeeConfigBlockDDO.\
                                     configurator_get(self).\
                                     ddo_get_param(ext_addr, 'VR',
                                                   retries=\
                                                   DDO_RETRY_ATTEMPTS,
                                                   use_cache=True))

            if (fw_func in UNSUPPORTED_ZB_FW_FUNCSETS
                    and fw_v < UNSUPPORTED_ZB_LT_FW_VERSION):
                self.__tracer.warning(
                    "'%s' FW version is %s < %s, "
                    "sleep mode configuration unavailable.", ext_addr,
                    hex(fw_v), hex(UNSUPPORTED_ZB_LT_FW_VERSION))
                return False
        return True

    def reset(self):
        '''
        Reset the state of this configuration block object.

        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.\
        XBeeConfigBlock`.
        '''
        self.__pending_parameters = copy(self.__parameters)
        # Complete the state reset:
        AbstractXBeeConfigBlockDDO.reset(self)

    def __prepare_network_update_param(self, ext_addr, param, override_map):
        '''
        Internal helper function used to update node parameters.

        Returns True if this node needs to be updated, otherwise False.
        '''

        minimum_sp_value = MINIMUM_ZB_RTR_SP_VALUE

        self.__tracer.debug("Fetching '%s' from '%s'", param, ext_addr)
        try:
            network_param = (AbstractXBeeConfigBlockDDO.configurator_get(
                self).ddo_get_param(ext_addr,
                                    param,
                                    retries=DDO_RETRY_ATTEMPTS,
                                    use_cache=True))
            # All params used here are 16-bit unsigned ints:
            network_param = struct.unpack('>H', network_param)[0]
        except Exception, e:
            self.__tracer.warning("Could not fetch param " \
                    "'%s' from '%s': %s", param, ext_addr, str(e))
            self.__tracer.debug("Removing '%s' from cache", ext_addr)
            (AbstractXBeeConfigBlockDDO.xbee_device_manager_get(
                self)._xbee_remove_node_from_list(ext_addr))
            raise e

        # Do we have an SP/SN override?
        if override_map:
            pending_values = override_map
        else:
            pending_values = self.__pending_parameters

        value = None
        if (network_param < pending_values[param]):
            # Special-case SP to enforce minimum value:
            if param == 'SP':
                value = max(minimum_sp_value, pending_values[param])
            else:
                value = pending_values[param]

        if value is None:
            # signal nothing more to do
            return False

        self.__tracer.debug("Updating sleep param of node '%s', '%s' = %s",
                            ext_addr, param, format_hexrepr(value))
        try:
            (AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_set_param(
                ext_addr, param, value, apply=True))
        except Exception, e:
            self.__tracer.warning("Couldn't write param '%s' to '%s': %s",
                                  param, ext_addr, str(e))
            raise e
Exemplo n.º 22
0
                            # no update necessary, continue
                            continue
                    except Exception, e:
                        self.__tracer.warning('Could not prepare network for '
                                              'sleeping node %s... will '
                                              'try again later.' %
                                              self._ext_addr)
                        return False
                    write_list.append(network_node)

        for network_node in write_list:
            # Attempt to write parameter values to non-volatile memory
            # for the coordinator and router nodes so that parameter
            # modifications persist through subsequent resets.
            try:
                (AbstractXBeeConfigBlockDDO.configurator_get(
                    self).ddo_set_param(network_node, 'WR', ''))
            except Exception, e:
                self.__tracer.warning(
                    'couldn\'t write config '
                    'to \'%s\': %s', network_node, str(e))
                # Ignore this failure, it is non-fatal to network
                # performance
                continue
        # Signal to XBeeDeviceManager that network preparation was successful
        return True

    def apply_config(self):
        '''
        Apply the configuration actions to the node targeted by this object.

        After this method has been called the
                        # needs to be retried:

                        # print "XDCBS: Error updating parameter: %s" % repr(e)
                        # print "-" * 60
                        # traceback.print_exc(file=sys.stdout)
                        # print "-" * 60
                        
                        return False
                    write_list.append(network_node)

        for network_node in write_list:
            # Attempt to write parameter values to non-volatile memory for the
            # coordinator and router nodes so that parameter modifications
            # persist through subsequent resets.
            try:
                (AbstractXBeeConfigBlockDDO.configurator_get(self)
                    .ddo_set_param(network_node, 'WR',''))                
            except Exception, e:
                 self.__tracer.warning("couldn't write config " +
                                    "to '%s': %s", network_node, str(e))
                 # Ignore this failure, it is non-fatal to network performance
                 continue
             
        # Signal to XBeeDeviceManager that network preparation was successful
        return True                        
            

    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the
    def apply_config(self):
        """\
        Apply the configuration actions to the node targeted by this object.
        
        After this method has been called the
        :py:meth:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock.is_complete`
        method will return True.
        
        See :py:class:`~devices.xbee.xbee_config_blocks.xbee_config_block.XBeeConfigBlock`.

        """  
        try:
            if not AbstractXBeeConfigBlockDDO._is_applicable(self):
                # If the block is not applicable, mark this block as complete:
                return AbstractXBeeConfigBlockDDO.apply_config(self)
              
        except:
            # Trace messages handled by _is_applicable() and apply_config()            
            return False

        # Special case:
        #
        # Check if sleep mode is unavailable on this module/firmware
        # combination:
        if not self.__is_sleep_mode_available():
            if self.__sleep_mode == SM_DISABLED:
                # This sleep block has been filled out with sleeping
                # disabled however sleep configuration is not available:
                # mark this block as complete.
                self.__tracer.debug("sleep mode unsupported and SM_DISABLED" + 
                                    " given, block complete.")
                return AbstractXBeeConfigBlockDDO.apply_config(self)
            else:
                # We are unable to apply this block, mark it as a
                # block application failure:
                self.__tracer.warning("sleep mode unsupported" +
                                   " but sleep parameters given," + 
                                   " block FAILED. Please disable " +
                                   "sleeping on this" +
                                   " device.")
                return False

        # Configure the node:                
        pending_mnemonics = self.__pending_parameters.keys()
        for mnemonic in pending_mnemonics:
            # NOTE: this message is duplicated in the XBeeConfigBlockDDO source
            self.__tracer.debug("Apply_config: trying '%s' = '%s' to '%s'",
                             mnemonic,
                             format_hexrepr(
                                 self.__pending_parameters[mnemonic]),
                             AbstractXBeeConfigBlockDDO.ext_addr_get(self))
            try:
                AbstractXBeeConfigBlockDDO.configurator_get(self).ddo_set_param(
                    AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                    mnemonic,
                    self.__pending_parameters[mnemonic],
                    retries=DDO_RETRY_ATTEMPTS)
            except Exception, e:
                self.__tracer.error("'%s' = '%s' to '%s' failed (%s)",
                                mnemonic,
                                format_hexrepr(
                                    self.__pending_parameters[mnemonic]),
                                AbstractXBeeConfigBlockDDO.ext_addr_get(self),
                                str(e))
                return False
            del(self.__pending_parameters[mnemonic])