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
Ejemplo n.º 2
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
Ejemplo n.º 3
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])
    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])
    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)
Ejemplo n.º 6
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
Ejemplo n.º 7
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