def apply_settings(self):
        
        SettingsBase.merge_settings(self)
        accepted, rejected, not_found = SettingsBase.verify_settings(self)

        if len(rejected) or len(not_found):
            # There were problems with settings, terminate early:
            print "idigi_db (%s): Settings rejected/not found: %s %s" % \
                (self.__name, rejected, not_found)
            return (accepted, rejected, not_found)

        # Verify that if we are on the Digi ConnectPort X3, that the user
        # doesn't have the secure option set to True.
        # If they do, we MUST bail here and also warn the user that the
        # Digi ConnectPort X3 cannot do secure/encrypted idigi connections.
        if accepted['secure'] == True and get_platform_name() == 'digix3':
            print "idigi_db (%s): The Digi ConnectPort X3 product cannot " \
                  "do secure/encrypted connections to the iDigi Server.  " \
                  "Please set the 'secure' option to False!" % \
                                (self.__name)

            rejected['secure'] = accepted['secure']
            del accepted['secure']
            return (accepted, rejected, not_found)

        SettingsBase.commit_settings(self, accepted)
        
       # xbee_manager_name = SettingsBase.get_setting(self, "xbee_device_manager")
        dm = self.__core.get_service("device_driver_manager")
        self.__xbee_manager = dm.instance_get("xbee_device_manager")
        
        self.__last_upload_time = 0
        
        self.repeat()
        return (accepted, rejected, not_found)
    def stop(self):

        if get_platform_name() == "digix3":
            self.__tracer.info("May take up to %02f seconds", SettingsBase.get_setting(self, "sample_rate_sec"))

        self.__stopevent.set()
        return True
예제 #3
0
    def stop(self):

        if get_platform_name() == 'digix3':
            self.__tracer.info(
                "May take up to %02f seconds",
                SettingsBase.get_setting(self, "sample_rate_sec"))

        self.__stopevent.set()
        return True
예제 #4
0
    def run(self):

        serial_device = SettingsBase.get_setting(self, "serial_device")
        baud_rate = SettingsBase.get_setting(self, "serial_baud")

        # The way we read the NMEA-0183 data stream is different between
        # the nds-based products and the X3 products.
        #
        # The nds-based product has the data stream coming in over
        # a serial port, so we need to be able to set the baud rate.
        #
        # The X3-based product has the data stream coming in over I2C,
        # which does not require setting any sort of baud rate.
        # Also, the X3 platform is slower than the nds based platforms,
        # so we offer a way to delay reading the stream, so that parsing
        # the stream doesn't monopolize the cpu.

        if get_platform_name() == 'digix3':
            sample_rate_sec = SettingsBase.get_setting(self, "sample_rate_sec")
        else:
            sample_rate_sec = 0

        _serial = serial.Serial(port=serial_device,
                                baudrate=baud_rate,
                                timeout=SHUTDOWN_WAIT)

        nmea_obj = nmea.NMEA()

        while 1:
            if self.__stopevent.isSet():
                self.__stopevent.clear()
                _serial.close()
                break

            # 16384 is a MAGIC NUMBER that came into existence
            # before my time...  my (extremely limited) testing
            # has shown that this number makes for clean cut-offs
            # in talker strings (as defined by the NMEA 0183
            # Protocol definition (v3))
            #
            # In other words, you always get the full last line
            # up to and including the line-terminating '\r\n'.
            #
            # This makes the nmea parser joyful.

            # this returns '' on a timeout
            data = _serial.read(size=16384)

            # Read in the NMEA-0183 stream data, and parse it
            if data and len(data) > 0:

                self.__tracer.debug(data)
                nmea_obj.feed(data, self.property_setter)

                digitime.sleep(sample_rate_sec)
예제 #5
0
    def run(self):
       
        serial_device = SettingsBase.get_setting(self, "serial_device")
        baud_rate = SettingsBase.get_setting(self, "serial_baud")

        # The way we read the NMEA-0183 data stream is different between
        # the nds-based products and the X3 products.
        #
        # The nds-based product has the data stream coming in over
        # a serial port, so we need to be able to set the baud rate.
        #
        # The X3-based product has the data stream coming in over I2C,
        # which does not require setting any sort of baud rate.
        # Also, the X3 platform is slower than the nds based platforms,
        # so we offer a way to delay reading the stream, so that parsing
        # the stream doesn't monopolize the cpu.

        if get_platform_name() == 'digix3':
            sample_rate_sec = SettingsBase.get_setting(self, "sample_rate_sec")
        else:
            sample_rate_sec = 0

        _serial = serial.Serial(port=serial_device,
                                baudrate=baud_rate,
                                timeout=SHUTDOWN_WAIT)

        nmea_obj = nmea.NMEA()
        
        while 1:
            if self.__stopevent.isSet():
                self.__stopevent.clear()
                _serial.close()
                break

            # 16384 is a MAGIC NUMBER that came into existence
            # before my time...  my (extremely limited) testing
            # has shown that this number makes for clean cut-offs
            # in talker strings (as defined by the NMEA 0183
            # Protocol definition (v3))
            #
            # In other words, you always get the full last line
            # up to and including the line-terminating '\r\n'.
            #
            # This makes the nmea parser joyful.

            # this returns '' on a timeout
            data = _serial.read(size=16384)
            
            # Read in the NMEA-0183 stream data, and parse it
            if data and len(data) > 0:
                
                self.__tracer.debug(data)
                nmea_obj.feed(data, self.property_setter)

                digitime.sleep(sample_rate_sec)
    def turn_on_calibration_series2(self):
        """
        Turn on calibration mode for the channel when using a
        XBee Series 2 Radio (ZNet 2.5, ZB).

        On all supported products, the channel must be changed
        to either TenV or CurrentLoop mode first.
        Since Dia requires all the AIO channels to be defined to a mode
        during configuration, we can assume here that the channel
        has been configured to either TenV or CurrentLoop already,
        and so we do NOT need to set a channel mode here.

        Then based on the product, to have the unit read the known
        "calibrated" values of .6V and 1V respectively, you must do:

            On X3-based products, the GPIO pin 0 must be set to 0.

            On nds-based products, the device uses 2 GPIO pins on
            the XBee radio for switching to and from the calibrated values.
            Thus, we need to issue 2 XBee DDO commands that will tell
            the XBee radio to swap its reads for that channel.
            Channel 0: DDO P2 -> 4
            Channel 1: DDO D4 -> 4

        """

        # X3-based product calibration
        # Set GPIO 0 = 0
        if get_platform_name() == 'digix3':
            digihw.gpio_set_value(0, 0)

        # nds-based product calibration
        # Issue the special XBee DDO commands to swap inputs to known values
        elif get_platform_name() == 'digiconnect':
            if self.__channel == 0:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'P2', 4,
                                    apply = True)
            elif self.__channel == 1:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 4, 
                                    apply = True)
예제 #7
0
    def turn_on_calibration_series2(self):
        """
        Turn on calibration mode for the channel when using a
        XBee Series 2 Radio (ZNet 2.5, ZB).

        On all supported products, the channel must be changed
        to either TenV or CurrentLoop mode first.
        Since DIA requires all the AIO channels to be defined to a mode
        during configuration, we can assume here that the channel
        has been configured to either TenV or CurrentLoop already,
        and so we do NOT need to set a channel mode here.

        Then based on the product, to have the unit read the known
        "calibrated" values of .6V and 1V respectively, you must do:

            On X3-based products, the GPIO pin 0 must be set to 0.

            On nds-based products, the device uses 2 GPIO pins on
            the XBee radio for switching to and from the calibrated values.
            Thus, we need to issue 2 XBee DDO commands that will tell
            the XBee radio to swap its reads for that channel.
            Channel 0: DDO P2 -> 4
            Channel 1: DDO D4 -> 4

        """

        # X3-based product calibration
        # Set GPIO 0 = 0
        if get_platform_name() == 'digix3':
            digihw.gpio_set_value(0, 0)

        # nds-based product calibration
        # Issue the special XBee DDO commands to swap inputs to known values
        elif get_platform_name() == 'digiconnect':
            if self.__channel == 0:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'P2', 4,
                                    apply = True)
            elif self.__channel == 1:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 4,
                                    apply = True)
예제 #8
0
    def turn_off_calibration_series2(self):
        """
        Turn off calibration mode for the channel when using a
        XBee Series 2 Radio (ZNet 2.5, ZB).

        This function reverses the process of what the function
        'turn_off_calibration_series2' did, and sets us back into
        normal operating mode.

        To do this:

            On X3-based products, the GPIO pin 0 must be set to 1.

            On nds-based products, the device uses 2 GPIO pins on
            the XBee radio for switching to and from the calibrated values.
            Thus, we need to issue 2 XBee DDO commands that will tell
            the XBee radio to swap its reads back for that channel.
            Channel 0: DDO P2 -> 5
            Channel 1: DDO D4 -> 5
        """

        # X3-based product calibration
        #
        # Set GPIO 0 = 1
        if get_platform_name() == 'digix3':
            digihw.gpio_set_value(0, 1)

        # nds-based product calibration
        #
        # Issue the special XBee DDO commands to swap inputs to known values
        elif get_platform_name() == 'digiconnect':
            if self.__channel == 0:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'P2', 5,
                                    apply = True)
            elif self.__channel == 1:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 5,
                                    apply = True)
    def turn_off_calibration_series2(self):
        """
        Turn off calibration mode for the channel when using a
        XBee Series 2 Radio (ZNet 2.5, ZB).

        This function reverses the process of what the function
        'turn_off_calibration_series2' did, and sets us back into
        normal operating mode.

        To do this:

            On X3-based products, the GPIO pin 0 must be set to 1.

            On nds-based products, the device uses 2 GPIO pins on
            the XBee radio for switching to and from the calibrated values.
            Thus, we need to issue 2 XBee DDO commands that will tell
            the XBee radio to swap its reads back for that channel.
            Channel 0: DDO P2 -> 5
            Channel 1: DDO D4 -> 5
        """

        # X3-based product calibration
        #
        # Set GPIO 0 = 1
        if get_platform_name() == 'digix3':
            digihw.gpio_set_value(0, 1)

        # nds-based product calibration
        #
        # Issue the special XBee DDO commands to swap inputs to known values
        elif get_platform_name() == 'digiconnect':
            if self.__channel == 0:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'P2', 5,
                                    apply = True)
            elif self.__channel == 1:
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 5, 
                                    apply = True)
예제 #10
0
    def __verify_power_setting(self, power):
        # The power option is ONLY supported on the X3 product.
        # So assume power is always on, and is intended to be always on.
        # Only do real checking for the False case.
        if power == Boolean(True, style = STYLE_ONOFF):
            return True
        elif power == Boolean(False, style=STYLE_ONOFF):
            if get_platform_name() == 'digix3':
                return True
            else:
                self.__tracer.error("Turning IO power off " +
                                    "on this device is not supported!")
                return False

        return False
    def __verify_power_setting(self, power):
        # The power option is ONLY supported on the X3 product.
        # So assume power is always on, and is intended to be always on.
        # Only do real checking for the False case.
        if power == Boolean(True, style = STYLE_ONOFF):
            return True
        elif power == Boolean(False, style=STYLE_ONOFF):
            if get_platform_name() == 'digix3':
                return True
            else:
                self.__tracer.error("Turning IO power off " +
                                    "on this device is not supported!")
                return False

        return False
예제 #12
0
    def start(self):
        """Start the device driver.  Returns bool."""

        # Attempt to detect if we are on older units that require a different
        # algorithm for determine calibration.
        try:
            device_info = query_state("device_info")
            for item in device_info:
                hardware_strapping = item.find('hardwarestrapping')
                if hardware_strapping != None:
                    hardware_strapping = hardware_strapping.text
                    break
            else:
                hardware_strapping = ''

            if hardware_strapping == self.OLD_HARDWARE_STRAPPING_A or hardware_strapping == self.OLD_HARDWARE_STRAPPING_B:
                self.__tracer.info("Old hardware detected. " +
                                   "Turning on old support flag.")
                self.__OLD_HARDWARE = True
        except:
            pass

        # Grab the calibration rate setting, and store it
        self.__calibration_interval = SettingsBase.get_setting(self.__parent,
                                                   "calibration_rate_ms")

        self.__calibration_interval /= 1000.0

        # Force a calibration the first time getting samples.
        self.__calibration_time = -self.__calibration_interval

        # Fetch the XBee Manager name from the Settings Manager:
        xbee_manager_name = SettingsBase.get_setting(self.__parent, "xbee_device_manager")
        dm = self.__core.get_service("device_driver_manager")
        self.__xbee_manager = dm.instance_get(xbee_manager_name)

        # Walk through the channels, allocating required channel types
        # and creating each channels respective channel properties.
        for channel in self.__aio_channels:
            channel_name = "channel%d" % (channel + 1)
            mode = SettingsBase.get_setting(self.__parent, 'channel%d_mode' % (channel + 1))
            aio_chan = XBeeLocalAIO(channel_name, self, channel, mode.lower())
            self.__aio_channel_structures.append(aio_chan)

        for channel in self.__dio_channels:
            channel_name = "channel%d" % (channel + 1)
            direction = SettingsBase.get_setting(self.__parent, 'channel%d_dir' % (channel + 1))
            direction = direction.lower()
            source = SettingsBase.get_setting(self.__parent, 'channel%d_source' % (channel + 1))
            source = source.lower()
            dio_chan = XBeeLocalDIO(channel_name, self, channel, direction.lower(), source)
            self.__dio_channel_structures.append(dio_chan)

        # Register ourselves with the XBee Device Manager instance:
        self.__xbee_manager.xbee_device_register(self)

        # Create a callback specification that calls back this driver when
        # our device has left the configuring state and has transitioned
        # to the running state:
        xbdm_running_event_spec = XBeeDeviceManagerRunningEventSpec()
        xbdm_running_event_spec.cb_set(self.running_indication)
        self.__xbee_manager.xbee_device_event_spec_add(self,
                                                        xbdm_running_event_spec)

        # Create a callback specification for our device address, endpoint
        # Digi XBee profile and sample cluster id:
        xbdm_rx_event_spec = XBeeDeviceManagerRxEventSpec()
        xbdm_rx_event_spec.cb_set(self.sample_indication)
        # xbdm_rx_event_spec.match_spec_set((None,
        xbdm_rx_event_spec.match_spec_set((gw_extended_address(),
                0xe8, 0xc105, 0x92), (True, True, True, True))
        self.__xbee_manager.xbee_device_event_spec_add(self, xbdm_rx_event_spec)


        # Create a DDO configuration block for this device.
        # None indicates that we will be using the local radio.
        xbee_ddo_cfg = XBeeConfigBlockDDO(None)

        # Get the gateway's extended address:
        gw_xbee_sh, gw_xbee_sl = gw_extended_address_tuple()

        # Set the destination for I/O samples to be the gateway:
        xbee_ddo_cfg.add_parameter('DH', gw_xbee_sh)
        xbee_ddo_cfg.add_parameter('DL', gw_xbee_sl)

        # For the X3, aux power can be turned on/off.
        # For all other platforms, it is always on, and cannot be turned off.
        if get_platform_name() == 'digix3':
            power = SettingsBase.get_setting(self.__parent, "power")
            if power == Boolean(True, style = STYLE_ONOFF):
                xbee_ddo_cfg.add_parameter('d4', 5)
            elif power == Boolean(False, style=STYLE_ONOFF):
                xbee_ddo_cfg.add_parameter('d4', 4)

        # Call each channels start function to configure itself and start.
        # It will append any needed DDO commands to the 'xbee_ddo_cfg' block
        # we pass in.
        for channel in self.__aio_channel_structures:
            channel.start(xbee_ddo_cfg)

        for channel in self.__dio_channel_structures:
            channel.start(xbee_ddo_cfg)

        # Walk the digital channels again, if any are set to input,
        # we need to have the pin monitored.
        ic = 0
        for channel in self.__dio_channel_structures:
            if channel.mode() == "in":
                ic |= 1 << channel.channel()

        # Enable I/O line monitoring on pins DIO0 .. DIO3 &
        # enable change detection on DIO11:
        #
        # 0x   8    0    0
        #   1000 0000 0000 (b)
        #   DDDD DDDD DDDD
        #   IIII IIII IIII
        #   OOOO OOOO OOOO
        #   1198 7654 3210
        #   10
        #
        xbee_ddo_cfg.add_parameter('IC', ic)

        # Disable any periodic I/O sampling:
        xbee_ddo_cfg.add_parameter('IR', 0)

        # Register this configuration block with the XBee Device Manager:
        self.__xbee_manager.xbee_device_config_block_add(self, xbee_ddo_cfg)

        # Indicate that we have no more configuration to add:
        self.__xbee_manager.xbee_device_configure(self)

        return True
예제 #13
0
    def start(self):
        """Start the device driver.  Returns bool."""

        # Attempt to detect if we are on older units that require a different
        # algorithm for determine calibration.
        try:
            device_info = query_state("device_info")
            for item in device_info:
                hardware_strapping = item.find('hardwarestrapping')
                if hardware_strapping != None:
                    hardware_strapping = hardware_strapping.text
                    break
            else:
                hardware_strapping = ''

            if hardware_strapping == self.OLD_HARDWARE_STRAPPING_A or hardware_strapping == self.OLD_HARDWARE_STRAPPING_B:
                self.__tracer.info("Old hardware detected. " +
                                   "Turning on old support flag.")
                self.__OLD_HARDWARE = True
        except:
            pass

        # Grab the calibration rate setting, and store it
        self.__calibration_interval = SettingsBase.get_setting(self.__parent,
                                                   "calibration_rate_ms")

        self.__calibration_interval /= 1000.0

        # Force a calibration the first time getting samples.
        self.__calibration_time = -self.__calibration_interval

        # Fetch the XBee Manager name from the Settings Manager:
        xbee_manager_name = SettingsBase.get_setting(self.__parent, "xbee_device_manager")
        dm = self.__core.get_service("device_driver_manager")
        self.__xbee_manager = dm.instance_get(xbee_manager_name)

        # Walk through the channels, allocating required channel types
        # and creating each channels respective channel properties.
        for channel in self.__aio_channels:
            channel_name = "channel%d" % (channel + 1)
            mode = SettingsBase.get_setting(self.__parent, 'channel%d_mode' % (channel + 1))
            aio_chan = XBeeLocalAIO(channel_name, self, channel, mode.lower())
            self.__aio_channel_structures.append(aio_chan)

        for channel in self.__dio_channels:
            channel_name = "channel%d" % (channel + 1)
            direction = SettingsBase.get_setting(self.__parent, 'channel%d_dir' % (channel + 1))
            direction = direction.lower()
            source = SettingsBase.get_setting(self.__parent, 'channel%d_source' % (channel + 1))
            source = source.lower()
            dio_chan = XBeeLocalDIO(channel_name, self, channel, direction.lower(), source)
            self.__dio_channel_structures.append(dio_chan)

        # Register ourselves with the XBee Device Manager instance:
        self.__xbee_manager.xbee_device_register(self)

        # Create a callback specification that calls back this driver when
        # our device has left the configuring state and has transitioned
        # to the running state:
        xbdm_running_event_spec = XBeeDeviceManagerRunningEventSpec()
        xbdm_running_event_spec.cb_set(self.running_indication)
        self.__xbee_manager.xbee_device_event_spec_add(self,
                                                        xbdm_running_event_spec)

        # Create a callback specification for our device address, endpoint
        # Digi XBee profile and sample cluster id:
        xbdm_rx_event_spec = XBeeDeviceManagerRxEventSpec()
        xbdm_rx_event_spec.cb_set(self.sample_indication)
        # xbdm_rx_event_spec.match_spec_set((None,
        xbdm_rx_event_spec.match_spec_set((gw_extended_address(),
                0xe8, 0xc105, 0x92), (True, True, True, True))
        self.__xbee_manager.xbee_device_event_spec_add(self, xbdm_rx_event_spec)


        # Create a DDO configuration block for this device.
        # None indicates that we will be using the local radio.
        xbee_ddo_cfg = XBeeConfigBlockDDO(None)

        # Get the gateway's extended address:
        gw_xbee_sh, gw_xbee_sl = gw_extended_address_tuple()

        # Set the destination for I/O samples to be the gateway:
        xbee_ddo_cfg.add_parameter('DH', gw_xbee_sh)
        xbee_ddo_cfg.add_parameter('DL', gw_xbee_sl)

        # For the X3, aux power can be turned on/off.
        # For all other platforms, it is always on, and cannot be turned off.
        if get_platform_name() == 'digix3':
            power = SettingsBase.get_setting(self.__parent, "power")
            if power == Boolean(True, style = STYLE_ONOFF):
                xbee_ddo_cfg.add_parameter('d4', 5)
            elif power == Boolean(False, style=STYLE_ONOFF):
                xbee_ddo_cfg.add_parameter('d4', 4)

        # Call each channels start function to configure itself and start.
        # It will append any needed DDO commands to the 'xbee_ddo_cfg' block
        # we pass in.
        for channel in self.__aio_channel_structures:
            channel.start(xbee_ddo_cfg)

        for channel in self.__dio_channel_structures:
            channel.start(xbee_ddo_cfg)

        # Walk the digital channels again, if any are set to input,
        # we need to have the pin monitored.
        ic = 0
        for channel in self.__dio_channel_structures:
            if channel.mode() == "in":
                ic |= 1 << channel.channel()

        # Enable I/O line monitoring on pins DIO0 .. DIO3 &
        # enable change detection on DIO11:
        #
        # 0x   8    0    0
        #   1000 0000 0000 (b)
        #   DDDD DDDD DDDD
        #   IIII IIII IIII
        #   OOOO OOOO OOOO
        #   1198 7654 3210
        #   10
        #
        xbee_ddo_cfg.add_parameter('IC', ic)

        # Disable any periodic I/O sampling:
        xbee_ddo_cfg.add_parameter('IR', 0)

        # Register this configuration block with the XBee Device Manager:
        self.__xbee_manager.xbee_device_config_block_add(self, xbee_ddo_cfg)

        # Indicate that we have no more configuration to add:
        self.__xbee_manager.xbee_device_configure(self)

        return True
예제 #14
0
    def __calibrate(self):
        """__calibrate()
        Calibrate analog inputs. Calculates scale and offset."""

        xbee_dd_ddo_value = self.__xbee_manager.xbee_device_ddo_get_param(None,
                            'DD', use_cache=True)
        module_id, product_id = parse_dd(xbee_dd_ddo_value)

        # XBee series 1 uses one calibration voltage on AN2
        if module_id == MOD_XB_802154:

            # Enable calibration voltage on channel 1
            self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 4,
                                apply=True)
            digitime.sleep(0.010)

            # Read calibration sample
            result = self.__xbee_manager.xbee_device_ddo_get_param(None, 'IS')
            sample = parse_is(result)["AD1"]
            self.__tracer.debug("Calibration sample is %d", sample)

            # Return channel to operating mode
            self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 5,
                                apply=True)
            digitime.sleep(0.010) 

            if sample == 0:
                raise ValueError, "Calibration error: bad sample"

            # Calulate linear scale and offset.
            # These apply to all analog channels.
            self.__scale = 1.25 / sample
            self.__offset = 0

        # XBee series 2 uses two calibration voltages on AN1 and AN2
        elif module_id == MOD_XB_ZNET25 or module_id == MOD_XB_ZB or module_id == MOD_XB_S2C_ZB:

            # Enable calibration voltages on channels 0 and 1
            if get_platform_name() == 'digix3':
                self.__xbee_manager.xbee_device_ddo_set_param(None, 
                            self.LOCAL_AIO_CONTROL_LINES[0], 2, apply=True)
                self.__xbee_manager.xbee_device_ddo_set_param(None,
                            self.LOCAL_AIO_CONTROL_LINES[1], 2, apply=True)
                digihw.gpio_set_value(0, 0)
            elif get_platform_name() == 'digiconnect':
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'P2', 4,
                                    apply=True)
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 4, 
                                    apply=True)

            digitime.sleep(0.010)

            # Read calibration samples
            result = self.__xbee_manager.xbee_device_ddo_get_param(None, 'IS')
            data = parse_is(result)
            sample = [ data["AD0"], data["AD1"] ]

            self.__tracer.debug("Calibration samples are %d, %d", 
                               sample[0], sample[1])

            # Return channels to operating mode
            if get_platform_name() == 'digix3':
                digihw.gpio_set_value(0, 1)
            elif get_platform_name() == 'digiconnect':
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'P2', 5,
                                    apply=True)
                self.__xbee_manager.xbee_device_ddo_set_param(None, 'D4', 5,
                                    apply=True)

            digitime.sleep(0.010)

            for io_pin in range(2):
                mode = SettingsBase.get_setting(self, 'channel%d_mode' % (io_pin+1) )
                mode = self.LOCAL_AIO_MODE_MAP[mode.lower()]

                if mode == self.LOCAL_AIO_MODE_CURRENTLOOP:
                    self.__xbee_manager.xbee_device_ddo_set_param(None,
                           self.LOCAL_AIO_CONTROL_LINES[io_pin], 2, apply=True)
                elif mode == self.LOCAL_AIO_MODE_TENV:
                    self.__xbee_manager.xbee_device_ddo_set_param(None,
                           self.LOCAL_AIO_CONTROL_LINES[io_pin], 2, apply=True)

            if sample[0] == sample[1]:
                raise ValueError, "Calibration error: equal samples"

            self.__sample1 = sample[1]
            self.__sample2 = sample[0]

            scale1 = self.LOCAL_AIO_CALIBRATION_06 / float(sample[1])
            scale2 = self.LOCAL_AIO_CALIBRATION_10 / float(sample[0])

            self.__scale = (scale1 + scale2) / 2.0

            if self.__OLD_HARDWARE == True:
                self.__offset = (self.__sample1 *
                       self.__scale - self.LOCAL_AIO_CALIBRATION_06) * 2.4
            else:
                self.__offset = 0.0

        else:
            raise ValueError, "XBee does not support analog inputs"

        self.__calibration_time = digitime.real_clock()

        self.__tracer.debug("Scale is %f, offset is %f", 
                            self.__scale, self.__offset)
예제 #15
0
    def __calibrate(self):
        """__calibrate()
        Calibrate analog inputs. Calculates scale and offset."""

        xbee_dd_ddo_value = self.__xbee_manager.xbee_device_ddo_get_param(
            None, 'DD', use_cache=True)
        module_id, product_id = parse_dd(xbee_dd_ddo_value)

        # XBee series 1 uses one calibration voltage on AN2
        if module_id == MOD_XB_802154:

            # Enable calibration voltage on channel 1
            self.__xbee_manager.xbee_device_ddo_set_param(None,
                                                          'D4',
                                                          4,
                                                          apply=True)
            digitime.sleep(0.010)

            # Read calibration sample
            result = self.__xbee_manager.xbee_device_ddo_get_param(None, 'IS')
            sample = parse_is(result)["AD1"]
            self.__tracer.debug("Calibration sample is %d", sample)

            # Return channel to operating mode
            self.__xbee_manager.xbee_device_ddo_set_param(None,
                                                          'D4',
                                                          5,
                                                          apply=True)
            digitime.sleep(0.010)

            if sample == 0:
                raise ValueError, "Calibration error: bad sample"

            # Calulate linear scale and offset.
            # These apply to all analog channels.
            self.__scale = 1.25 / sample
            self.__offset = 0

        # XBee series 2 uses two calibration voltages on AN1 and AN2
        elif module_id == MOD_XB_ZNET25 or module_id == MOD_XB_ZB or module_id == MOD_XB_S2C_ZB:

            # Enable calibration voltages on channels 0 and 1
            if get_platform_name() == 'digix3':
                self.__xbee_manager.xbee_device_ddo_set_param(
                    None, self.LOCAL_AIO_CONTROL_LINES[0], 2, apply=True)
                self.__xbee_manager.xbee_device_ddo_set_param(
                    None, self.LOCAL_AIO_CONTROL_LINES[1], 2, apply=True)
                digihw.gpio_set_value(0, 0)
            elif get_platform_name() == 'digiconnect':
                self.__xbee_manager.xbee_device_ddo_set_param(None,
                                                              'P2',
                                                              4,
                                                              apply=True)
                self.__xbee_manager.xbee_device_ddo_set_param(None,
                                                              'D4',
                                                              4,
                                                              apply=True)

            digitime.sleep(0.010)

            # Read calibration samples
            result = self.__xbee_manager.xbee_device_ddo_get_param(None, 'IS')
            data = parse_is(result)
            sample = [data["AD0"], data["AD1"]]

            self.__tracer.debug("Calibration samples are %d, %d", sample[0],
                                sample[1])

            # Return channels to operating mode
            if get_platform_name() == 'digix3':
                digihw.gpio_set_value(0, 1)
            elif get_platform_name() == 'digiconnect':
                self.__xbee_manager.xbee_device_ddo_set_param(None,
                                                              'P2',
                                                              5,
                                                              apply=True)
                self.__xbee_manager.xbee_device_ddo_set_param(None,
                                                              'D4',
                                                              5,
                                                              apply=True)

            digitime.sleep(0.010)

            for io_pin in range(2):
                mode = SettingsBase.get_setting(
                    self, 'channel%d_mode' % (io_pin + 1))
                mode = self.LOCAL_AIO_MODE_MAP[mode.lower()]

                if mode == self.LOCAL_AIO_MODE_CURRENTLOOP:
                    self.__xbee_manager.xbee_device_ddo_set_param(
                        None,
                        self.LOCAL_AIO_CONTROL_LINES[io_pin],
                        2,
                        apply=True)
                elif mode == self.LOCAL_AIO_MODE_TENV:
                    self.__xbee_manager.xbee_device_ddo_set_param(
                        None,
                        self.LOCAL_AIO_CONTROL_LINES[io_pin],
                        2,
                        apply=True)

            if sample[0] == sample[1]:
                raise ValueError, "Calibration error: equal samples"

            self.__sample1 = sample[1]
            self.__sample2 = sample[0]

            scale1 = self.LOCAL_AIO_CALIBRATION_06 / float(sample[1])
            scale2 = self.LOCAL_AIO_CALIBRATION_10 / float(sample[0])

            self.__scale = (scale1 + scale2) / 2.0

            if self.__OLD_HARDWARE == True:
                self.__offset = (self.__sample1 * self.__scale -
                                 self.LOCAL_AIO_CALIBRATION_06) * 2.4
            else:
                self.__offset = 0.0

        else:
            raise ValueError, "XBee does not support analog inputs"

        self.__calibration_time = digitime.real_clock()

        self.__tracer.debug("Scale is %f, offset is %f", self.__scale,
                            self.__offset)
예제 #16
0
    def __init__(self, name, core_services):
        self.__name = name
        self.__core = core_services

        ## Local State Variables:
        self.__xbee_aio_driver = None
        self.__xbee_dio_driver = None

        self.__analog_channels = []
        self.__digital_channels = []

        from core.tracing import get_tracer
        self.__tracer = get_tracer(name)

        ## Settings Table Definition:

        settings_list = [
            Setting(name = 'power', type = Boolean, required = False,
                    default_value = Boolean("On", STYLE_ONOFF),
                    verify_function = self.__verify_power_setting),
            Setting(name = 'sample_rate_ms', type = int, required = False,
                   default_value = 60000,
                   verify_function = lambda x: x >= 100 and x <= 6000000),
            Setting(name = 'calibration_rate_ms', type = int, required = False,
                   default_value = 900000,
                   verify_function = lambda x: x >= 0),
        ]

        ## Channel Properties Definition:
        property_list = []

        # Dynamically create the rest of our settings based on what the device supports.
        for ch in range(0, self.IO_MAX_CHANNELS):

            # Attempt to get the channel type.
            # If we try to go beyond the amount of supported channels,
            # we will get a ValueError exception.  If we do, stop our loop.
            try:
                type = digihw.get_channel_type(ch)
                
            except ValueError:
                # we'll hit this once we go past valid count since we support 10
                # channels, but likely device like X4H only has 4
                # traceback.print_exc()
                break
                
            except:
                traceback.print_exc()

            if type == self.IO_TYPE_ANALOG:
                self.__tracer.info("Detected IO channel %d is Analog", 
                                        ch + 1)
                self.__analog_channels.append(ch)

                settings_list.append(Setting(
                    name = 'channel%d_mode' % (ch + 1), 
                    type=str, required=False,
                    verify_function = _verify_aio_channel_mode,
                    default_value = self.LOCAL_AIO_MODE_TENV))

            elif type == self.IO_TYPE_DIGITAL:
                self.__tracer.info("Detected IO channel %d is Digital", 
                                        ch + 1)
                self.__digital_channels.append(ch)

                settings_list.append(Setting(
                    name = 'channel%d_dir' % (ch + 1), type = str,
                    required=False,
                    default_value='in'))
                settings_list.append(Setting(
                    name = 'channel%d_source' % (ch + 1), type = str,
                    required = False,
                    default_value=''))
                    
            else:
                raise "Unknown IO hardware type channel %d, is %d" % \
                            ((ch + 1), type)

        # Finally, on some platforms, the AIO and DIO support is done by
        # the XBee radio inside the unit.
        #
        # If this is the case, we will need to also have the
        # 'xbee_device_manager' setting provided to us as well.
        if get_platform_name() == 'digix3':
            settings_list.append(Setting(name='xbee_device_manager',
                                         type = str, required = True))
            self.__xbee_aio_driver = self.__xbee_dio_driver = \
                                     XBeeLocalIO(self, core_services,
                                         self.__analog_channels,
                                         self.__digital_channels)
        elif get_platform_name() == 'digiconnect':
            settings_list.append(Setting(name='xbee_device_manager',
                                         type = str, required = True))
            self.__xbee_aio_driver = self.__xbee_dio_driver = \
                                     XBeeLocalIO(self, core_services,
                                         self.__analog_channels,
                                         self.__digital_channels)

        ## Initialize the DeviceBase interface:
        DeviceBase.__init__(self, self.__name, self.__core,
                                settings_list, property_list)
    def __init__(self, name, core_services):
        self.__name = name
        self.__core = core_services

        ## Local State Variables:
        self.__xbee_aio_driver = None
        self.__xbee_dio_driver = None

        self.__analog_channels = []
        self.__digital_channels = []

        from core.tracing import get_tracer
        self.__tracer = get_tracer(name)

        ## Settings Table Definition:

        settings_list = [
            Setting(name = 'power', type = Boolean, required = False,
                    default_value = Boolean("On", STYLE_ONOFF),
                    verify_function = self.__verify_power_setting),
            Setting(name = 'sample_rate_ms', type = int, required = False,
                   default_value = 60000,
                   verify_function = lambda x: x >= 100 and x <= 6000000),
            Setting(name = 'calibration_rate_ms', type = int, required = False,
                   default_value = 900000,
                   verify_function = lambda x: x >= 0),
        ]

        ## Channel Properties Definition:
        property_list = []

        # Dynamically create the rest of our settings based on what the device supports.
        for ch in range(0, self.IO_MAX_CHANNELS):

            # Attempt to get the channel type.
            # If we try to go beyond the amount of supported channels,
            # we will get a ValueError exception.  If we do, stop our loop.
            try:
                type = digihw.get_channel_type(ch)
            except ValueError:
                break

            if type == self.IO_TYPE_ANALOG:
                self.__tracer.info("Detected IO channel %d is " +
                                   "an Analog Channel", ch + 1)
                self.__analog_channels.append(ch)

                settings_list.append(Setting(
                    name = 'channel%d_mode' % (ch + 1), 
                    type=str, required=False,
                    verify_function = _verify_aio_channel_mode,
                    default_value = self.LOCAL_AIO_MODE_TENV))

            elif type == self.IO_TYPE_DIGITAL:
                self.__tracer.info("Detected IO channel %d is" + 
                                   "a Digital Channel",  ch + 1)
                self.__digital_channels.append(ch)

                settings_list.append(Setting(
                    name = 'channel%d_dir' % (ch + 1), type = str,
                    required=False,
                    default_value='in'))
                settings_list.append(Setting(
                    name = 'channel%d_source' % (ch + 1), type = str,
                    required = False,
                    default_value=''))

        # Finally, on some platforms, the AIO and DIO support is done by
        # the XBee radio inside the unit.
        #
        # If this is the case, we will need to also have the
        # 'xbee_device_manager' setting provided to us as well.
        if get_platform_name() == 'digix3':
            settings_list.append(Setting(name='xbee_device_manager',
                                         type = str, required = True))
            self.__xbee_aio_driver = self.__xbee_dio_driver = \
                                     XBeeLocalIO(self, core_services,
                                         self.__analog_channels,
                                         self.__digital_channels)
        elif get_platform_name() == 'digiconnect':
            settings_list.append(Setting(name='xbee_device_manager',
                                         type = str, required = True))
            self.__xbee_aio_driver = self.__xbee_dio_driver = \
                                     XBeeLocalIO(self, core_services,
                                         self.__analog_channels,
                                         self.__digital_channels)

        ## Initialize the DeviceBase interface:
        DeviceBase.__init__(self, self.__name, self.__core,
                                settings_list, property_list)