Beispiel #1
0
    def sample_indication(self, buf, addr):
        # Parse the I/O sample:

        self._tracer.calls("XBeeXBIB.sample_indication()")

        io_sample = parse_is(buf)
        change = False
        now = None

        for i in range(4):
            # Refresh switch states, if different:
            val = bool(io_sample[self.DIO_NAME[i]])
            oldval = bool(self.property_get(self.SW_NAME[i]).value)
            if oldval != val:
                change = True
                self.property_set(self.SW_NAME[i], Sample(0, val))
                if val:
                    # then switch is NOT pressed
                    self._tracer.info('%s is NOT pressed (val=%s)',
                                        self.SW_NAME[i], val)
                else:
                    self._tracer.info('%s is PRESSED (val=%s)',
                                        self.SW_NAME[i], val)

        if not change:
            self._tracer.debug('Sample indication, but no change to switches')
Beispiel #2
0
    def sample_indication(self, buf, addr, force=False):
        #print "XBeeDIO: Got sample indication from: %s, buf is len %d." \
        #    % (str(addr), len(buf))
        extended_address = SettingsBase.get_setting(self, "extended_address")
        
        
        
        
        
        now = time.time() # we need all samples 'stamped' the same - no lag/jitter

        if self.trace: msg = "XBeeDIO(%s):" % (self.__name)
        
        io_sample = parse_is(buf)

        for io_pin in range(4):
            key = 'DIO%d' % INPUT_CHANNEL_TO_PIN[io_pin]
            if io_sample.has_key(key):
                val = bool(io_sample[key])
                name = "channel%d_input" % (io_pin+1)
                if self.trace: msg += ' Dio%d=' % (io_pin+1)
                try:
                    old = self.property_get(name)
                    if force or (old.timestamp == 0) or (old.value != val):
                        units1 = self.property_get(name).unit 
                        self.property_set(name,  Sample(now, val, units1))
                        if self.trace: # show value with '^' for change
                            msg += '%s^' % val
                    else:
                        if self.trace: # show value, no change
                            msg += '%s' % val
                except Exception, e:
                    print "XBeeDIO(%s): Exception generated: %s" %(self.__name, str(e))
Beispiel #3
0
    def sample_indication(self, buf, addr):
        #print "XBeeDIO: Got sample indication from: %s, buf is len %d." \
        #    % (str(addr), len(buf))

        now = time.time() # we need all samples 'stamped' the same - no lag/jitter
        msg = ""
        
        io_sample = parse_is(buf)

        for io_pin in range(4):
            key = 'DIO%d' % INPUT_CHANNEL_TO_PIN[io_pin]
            if io_sample.has_key(key):
                val = bool(io_sample[key])
                name = "channel%d_input" % (io_pin+1)
                msg += ' Dio%d=' % (io_pin+1)

                # Always update the channel with the new sample value, and
                # its timestamp, even if it is the same as the previous value.
                try:
                    # Make a copy of the old values.
                    old = self.property_get(name)
                    # Set the new value.
                    self.property_set(name,  Sample(now, val, "bool"))
                    # Print out some tracing about old versus new sample value.
                    if old.timestamp == 0 or old.value != val:
                        # show value with '^' for change
                        msg += '%s^' % val
                    else:
                        # show value, no change
                        msg += '%s' % val
                except Exception, e:
                    self.__tracer.error("Exception generated: %s", str(e))
Beispiel #4
0
    def sample_indication(self, buf, addr):
        # Parse the I/O sample:

        self._tracer.calls("XBeeXBIB.sample_indication()")

        io_sample = parse_is(buf)
        change = False
        now = None

        for i in range(4):
            # Refresh switch states, if different:
            val = bool(io_sample[self.DIO_NAME[i]])
            oldval = bool(self.property_get(self.SW_NAME[i]).value)
            if oldval != val:
                change = True
                self.property_set(self.SW_NAME[i], Sample(0, val))
                if val:
                    # then switch is NOT pressed
                    self._tracer.info('%s is NOT pressed (val=%s)',
                                      self.SW_NAME[i], val)
                else:
                    self._tracer.info('%s is PRESSED (val=%s)',
                                      self.SW_NAME[i], val)

        if not change:
            self._tracer.debug('Sample indication, but no change to switches')
    def sample_indication(self, buf, addr):
        self.__tracer.debug('Sample indication')
        # Parse the I/O sample:
        io_sample = parse_is(buf)

        for i in range(4):
            # Refresh switch states, if different:
            val = bool(io_sample["DIO%d" % i])
            oldval =  bool(self.property_get("sw%d" % (i+1)).value)
            if oldval != val:
                self.property_set("sw%d" % (i+1), Sample(0, val))
    def __decode_sample(self, buf):
        io_sample = parse_is(buf)

        for io_pin in range(4):
            key = 'DIO%d' % self.INPUT_CHANNEL_TO_PIN[io_pin]
            if io_sample.has_key(key):  
                val = bool(io_sample[key])
                name = "channel%d_input" % (io_pin+1)
                try:
                    self.property_set(name,  Sample(0, val, "bool"))
                except:
                    pass
Beispiel #7
0
    def __decode_sample(self, buf):
        io_sample = parse_is(buf)

        for io_pin in range(4):
            key = 'DIO%d' % self.INPUT_CHANNEL_TO_PIN[io_pin]
            if io_sample.has_key(key):
                val = bool(io_sample[key])
                name = "channel%d_input" % (io_pin + 1)
                try:
                    self.property_set(name, Sample(0, val, "bool"))
                except:
                    pass
Beispiel #8
0
    def sample_indication(self, buf, addr):


        # Parse the I/O sample:
        io_sample = parse_is(buf)
        
        # Calculate sensor channel values:
        if io_sample.has_key("AD3"):
            samp = Sample(0, value=int(io_sample["AD3"]), unit="V")
            self.property_set("battery", samp)
        
        
        return
    def sample_indication(self, buf, addr):
        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate channel values:
        light_mv, temperature_mv, current_mv = \
            map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2", "AD3"))
        light = round(light_mv,0)
        if light < 0:
            # clamp to be zero or higher
            light = 0

        power_state = self.property_get("power_on").value

        # TODO: CRA Max could you remove this offset code?  Change to clip at 0.
        if not power_state:
            self.offset = current_mv * (157.0 /47.0)
            if self.offset >= 600.0: ## Probably a current spike from flipping the power relay
                self.offset = 520.0

        current = round(
                    (current_mv * (157.0 / 47.0) - self.offset) / 180.0 * 0.7071,
                    3)

        pf_adj = self.get_power_factor()
        # compute powerfactor adjusted current
        if 1.0 >= pf_adj and 0.0 <= pf_adj:
            current *= pf_adj

        if current <= 0.05:
            # Clip the noise at the bottom of this sensor:
            current = 0.0
        temperature = (temperature_mv - 500.0) / 10.0
        # self-heating correction
        temperature = (temperature - 4.0) - (0.017*current**2 + 0.631*current)
        temperature = round(temperature, 2)

        # Update channels:
        self.property_set("light", Sample(0, light, "brightness"))
        self.property_set("temperature", Sample(0, temperature, "C"))
        self.property_set("current", Sample(0, current, "A"))

        # check the realtime clock and compare to the last power_on_time
        # turn off if the idle_off_setting has been met or exceeded
        idle_off_setting = SettingsBase.get_setting(self, "idle_off_seconds")
        if (power_state and idle_off_setting > 0):
            if ((time.time() - self.__power_on_time)  >= idle_off_setting):
                power_on_state_bool = self.property_get("power_on")
                power_on_state_bool.value = False
                self.prop_set_power_control(power_on_state_bool)
    def sample_indication(self, buf, addr):
        #print "XBeeWatchport: Got sample indication from: %s, buf is len %d." \
        #    % (str(addr), len(buf))

        io_sample = parse_is(buf)

        # Low battery check (attached to DIO11/P1):
        if SettingsBase.get_setting(self, "enable_low_battery"):
            # Invert the signal it is actually not_low_battery:
            low_battery = not bool(io_sample["DIO11"])
            self.property_set("low_battery", Sample(0, low_battery))

        # If we are in sleep mode, request a sample right now while we are awake!
        will_sleep = SettingsBase.get_setting(self, "sleep")
        if will_sleep == True:
            self.make_request()
    def sample_indication(self, buf, addr):
        #print "XBeeWatchport: Got sample indication from: %s, buf is len %d." \
        #    % (str(addr), len(buf))

        io_sample = parse_is(buf)

        # Low battery check (attached to DIO11/P1):
        if SettingsBase.get_setting(self, "enable_low_battery"):
            # Invert the signal it is actually not_low_battery:
            low_battery = not bool(io_sample["DIO11"])
            self.property_set("low_battery", Sample(0, low_battery))

        # If we are in sleep mode, request a sample right now while we are awake!
        will_sleep = SettingsBase.get_setting(self, "sleep")
        if will_sleep == True:
            self.make_request()
    def _sample_indication(self, buf, addr):
        """\
            Receive and parse an I/O sample

        """
        self.__tracer.debug('Sample indication')
        io_sample = parse_is(buf)

        # Calculate channel values:
        light_mv, temperature_mv = \
            map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2"))
        light = round(light_mv)
        temperature = round((temperature_mv - 500.0) / 10.0 - 4.0, 2)

        # Update channels:
        self.property_set("light", Sample(0, light, "brightness"))
        self.property_set("temperature", Sample(0, temperature, "C"))
    def __decode_sample(self, buf):
        """\
            Given raw sample data from our device, break it down, and send
            that result to each of our channels.
            Each channel will look at the sample, determine if any data in
            the sample is something it cares about, and if so, return back
            parsed data that is scaled for the type of channel it is.
        """
        io_sample = parse_is(buf)
        for ch in self.__aio_channel_structures:
            sample = ch.decode_sample(io_sample, self.__scale, self.__offset)
            if sample != None:
                self.__parent.property_set(ch.name() + "_value", sample)

        for ch in self.__dio_channel_structures:
            sample = ch.decode_sample(io_sample, self.__scale, self.__offset)
            if sample != None:
                self.__parent.property_set(ch.name() + "_input", sample)
Beispiel #14
0
    def sample_indication(self, buf, addr):
        
        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate channel values:
       # upbutton_mv, onbutton_mv, downbutton_mv = \
           # map(lambda cn: sample_to_mv(io_sample[cn]), ("AD0", "AD1", "AD2"))

            
 # Calculate sensor channel values:
        if io_sample.has_key("AD1") and io_sample.has_key("AD2") and io_sample.has_key("AD3"):
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2", "AD3"))
       
            up = round(light_mv, 2)
            on = round(temperature_mv, 2)
            down = round(humidity_mv, 2)
       
        power_state = self.property_get("power_on").value

        # Update channels:
        self.property_set("up", Sample(0, up, "mv"))
        self.property_set("on", Sample(0, on, "mv"))
        self.property_set("down", Sample(0, down, "mv")) 
        
                        # wire up any inputs
        input_source = SettingsBase.get_setting(self, 'input_source')
        cm = self.__core.get_service("channel_manager")
        cp = cm.channel_publisher_get()
        cdb = cm.channel_database_get()
 #       cp.subscribe(input_source, self.prop_set_input)
        

 #       try:
#        source_name = SettingsBase.get_setting(self, 'input_source')
        source_name = self.property_get("user_input_1").value
            
        if( source_name != None):
                source_chan = cdb.channel_get( source_name)
                # pre-load the starting value, which won't be published to us
                self.my_input = source_chan.get().value
   #             self.property_set("adder_reg2", Sample(0, my_input))
                self.property_set("utemp", Sample(0, self.my_input, "F"))               
Beispiel #15
0
    def sample_indication(self, buf, addr):

        self._tracer.calls("XBeeDIO.sample_indication()")

        # save time of last data, plus we want ALL of the samples to have
        # exact same timestamp (leaving 0 means some may be 1 second newer)
        self._last_timestamp = digitime.time()

        if self._tracer.info():
            # will be true for debug also
            msg = ""
            change = False
        else:
            msg = None

        io_sample = parse_is(buf)

        for io_pin in range(4):
            key = self.DIO_RAW_NAME[io_pin]
            if key in io_sample:
                val = bool(io_sample[key])
                name = self.CHN_INPUT_NAME[io_pin]
                if msg is not None:
                    msg += self.DIO_USER_NAME[io_pin]

                # Always update the channel with the new sample value, and
                # its timestamp, even if it is the same as the previous value.
                try:
                    # Make a copy of the old values.
                    old = self.property_get(name)
                    # Set the new value.
                    self.property_set(name,  Sample(self._last_timestamp, val, "bool"))
                    # Print out some tracing about old versus new sample value.
                    if msg is not None:
                        if old.timestamp == 0 or old.value != val:
                            # show value with '^' for change
                            msg += '=%s^ ' % val
                            change = True
                        else:
                            # show value, no change
                            msg += '=%s ' % val
                except Exception, e:
                    self._tracer.error("Exception generated: %s", str(e))
Beispiel #16
0
    def _sample_indication(self, buf, addr):
        """\
            Receive and parse an I/O sample

        """
        self._tracer.calls("XBeeXBR.sample_indication()")

        io_sample = parse_is(buf)
        #  print io_sample

        if io_sample["AD2"] <= self.BASE_RAW_TEMP_CUTOFF:
            # then assume has no valid inputs
            self._tracer.debug('sample_indication: lacks temperature/light hardware')
            return False

        # light is only a 'brightness', so we just return as mv
        light = round(self.raw_to_mv(io_sample["AD1"]))

        # temperature we'll convert from mv to degree C
        temperature = ((self.raw_to_mv(io_sample["AD2"]) - 500.0) / 10.0) + self.BASE_OFFSET_DEGC

        if SettingsBase.get_setting(self, "degf"):
            temperature = (temperature * 1.8) + 32.0
            units = 'F'
        else:
            units = 'C'

        # offset is a simple float value - we don't care if DegC or DegF
        temperature += SettingsBase.get_setting(self, "offset")

        # Update channels:
        now = digitime.time()
        self.property_set("light", Sample(now, light, "brightness"))
        self.property_set("temperature", Sample(now, temperature, units))
        self._tracer.debug('temperature:%0.1f%s light:%d ',
                temperature, units, light)

        return True
Beispiel #17
0
    def _sample_indication(self, buf, addr):
        """\
            Receive and parse an I/O sample

        """
        self._tracer.calls("XBeeXBR.sample_indication()")

        io_sample = parse_is(buf)
        #  print io_sample

        if io_sample["AD2"] <= self.BASE_RAW_TEMP_CUTOFF:
            # then assume has no valid inputs
            self._tracer.debug('sample_indication: lacks temperature/light hardware')
            return False

        # light is only a 'brightness', so we just return as mv
        light = round(self.raw_to_mv(io_sample["AD1"]))

        # temperature we'll convert from mv to degree C
        temperature = ((self.raw_to_mv(io_sample["AD2"]) - 500.0) / 10.0) + self.BASE_OFFSET_DEGC

        if SettingsBase.get_setting(self, "degf"):
            temperature = (temperature * 1.8) + 32.0
            units = 'F'
        else:
            units = 'C'

        # offset is a simple float value - we don't care if DegC or DegF
        temperature += SettingsBase.get_setting(self, "offset")

        # Update channels:
        now = digitime.time()
        self.property_set("light", Sample(now, light, "brightness"))
        self.property_set("temperature", Sample(now, temperature, units))
        self._tracer.debug('temperature:%0.1f%s light:%d ',
                temperature, units, light)

        return True
    def __decode_sample(self, buf):
        """\
            Given raw sample data from our device, break it down, and send
            that result to each of our channels.
            Each channel will look at the sample, determine if any data in
            the sample is something it cares about, and if so, return back
            parsed data that is scaled for the type of channel it is.
        """
        io_sample = parse_is(buf)
        for ch in self.__aio_channel_structures:
            sample = ch.decode_sample(io_sample, self.__scale, self.__offset)
            if sample != None:
                chn = ch.name() + "_value"
                self.__parent.property_set(chn, sample)
                if self.__tracer.debug():
                    self.__tracer.debug("%s = %s", chn, sample)

        for ch in self.__dio_channel_structures:
            sample = ch.decode_sample(io_sample, self.__scale, self.__offset)
            if sample != None:
                chn = ch.name() + "_input"
                self.__parent.property_set(chn, sample)
                if self.__tracer.debug():
                    self.__tracer.debug("%s = %s", chn, sample)
    def __decode_sample(self, buf):
        io_sample = parse_is(buf)

        for aio_num in range(4):
            aio_name = "AD%d" % (aio_num)
            channel_name = "channel%d_value" % (aio_num+1)
            channel_mode = SettingsBase.get_setting(self,
                                "channel%d_mode" % (aio_num+1))
            channel_mode = channel_mode.lower()
            channel_mode = self.LOCAL_AIO_MODE_MAP[channel_mode.lower()]

            if aio_name not in io_sample:
                continue

            raw_value = io_sample[aio_name]
            raw_value = raw_value * self.__scale

            # Don't reduce the raw_value by the offset if the raw_value is 1023.
            if self.__offset != 0.0 and raw_value < 1023:
                raw_value = raw_value - self.__offset

            raw_value = int(round(raw_value))

            if channel_mode == self.LOCAL_AIO_MODE_CURRENTLOOP:
                mV = raw_value * 1200.0 / 1023
                mA = mV / self.LOCAL_AIO_LOOP_R_OHMS

                # If we have gone negative by a tiny bit, which can happen
                # because of scaling, just set us back to 0.0.
                if mA < 0.0:
                    mA = 0.0

                self.property_set(channel_name, Sample(0, mA, "mA"))
            elif channel_mode == self.LOCAL_AIO_MODE_TENV:
                V = float(raw_value) * 1.2 / 1024.0 / self.LOCAL_AIO_TENV_SCALE
                self.property_set(channel_name, Sample(0, V, "V"))
    def __decode_sample(self, buf):
        io_sample = parse_is(buf)

        for aio_num in range(4):
            aio_name = "AD%d" % (aio_num)
            channel_name = "channel%d_value" % (aio_num + 1)
            channel_mode = SettingsBase.get_setting(
                self, "channel%d_mode" % (aio_num + 1))
            channel_mode = channel_mode.lower()
            channel_mode = self.LOCAL_AIO_MODE_MAP[channel_mode.lower()]

            if aio_name not in io_sample:
                continue

            raw_value = io_sample[aio_name]
            raw_value = raw_value * self.__scale

            # Don't reduce the raw_value by the offset if the raw_value is 1023.
            if self.__offset != 0.0 and raw_value < 1023:
                raw_value = raw_value - self.__offset

            raw_value = int(round(raw_value))

            if channel_mode == self.LOCAL_AIO_MODE_CURRENTLOOP:
                mV = raw_value * 1200.0 / 1023
                mA = mV / self.LOCAL_AIO_LOOP_R_OHMS

                # If we have gone negative by a tiny bit, which can happen
                # because of scaling, just set us back to 0.0.
                if mA < 0.0:
                    mA = 0.0

                self.property_set(channel_name, Sample(0, mA, "mA"))
            elif channel_mode == self.LOCAL_AIO_MODE_TENV:
                V = float(raw_value) * 1.2 / 1024.0 / self.LOCAL_AIO_TENV_SCALE
                self.property_set(channel_name, Sample(0, V, "V"))
Beispiel #21
0
    def sample_indication(self, buf, addr):
        # if we haven't gotten initial state yet, ask for it
        if self.property_get('power_on').value == UNKNOWN_POWER_STATE:
            if not self._set_initial_power_state():
                self.__tracer.warning('Power state unknown, ignoring '
                                      'sample indication.')
                return
        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate channel values:
        light_mv, temperature_mv, current_mv = \
            map(lambda cn: sample_to_mv(io_sample[cn]),
                ('AD1', 'AD2', 'AD3'))
        light = round(light_mv, 0)
        if light < 0:
            # clamp to be zero or higher
            light = 0

        power_state = Boolean(self.property_get("power_on").value)

        # TODO: CRA Max could you remove this offset code?  Change to
        # clip at 0.
        if not power_state:
            self.offset = current_mv * (157.0 / 47.0)
            if self.offset >= 600.0:
                # Probably a current spike from flipping the power relay
                self.offset = 520.0

        current = round((current_mv * (157.0 / 47.0) - self.offset) \
                        / 180.0 * 0.7071, 3)

        pf_adj = self.get_power_factor()
        # compute powerfactor adjusted current
        if 1.0 >= pf_adj and 0.0 <= pf_adj:
            current *= pf_adj

        if current <= 0.05:
            # Clip the noise at the bottom of this sensor:
            current = 0.0
        temperature = (temperature_mv - 500.0) / 10.0
        # self-heating correction
        temperature = (temperature - 4.0) - \
                      (0.017 * current ** 2 + 0.631 * current)
        temperature = round(temperature, 2)

        # Update channels:
        self.property_set("light", Sample(0, light, "brightness"))
        self.property_set("temperature", Sample(0, temperature, "C"))
        self.property_set("current", Sample(0, current, "A"))

        self.__tracer.debug('Power:%r light:%d %0.1fC %0.2fA',
                power_state, light, temperature, current)

        # check the realtime clock and compare to the last power_on_time
        # turn off if the idle_off_setting has been met or exceeded
        idle_off_setting = SettingsBase.get_setting(self, "idle_off_seconds")
        if (power_state and idle_off_setting > 0):
            if ((digitime.time() - self.__power_on_time) \
                >= idle_off_setting):
                power_on_state_bool = self.property_get("power_on")
                power_on_state_bool.value = False
                self.prop_set_power_control(power_on_state_bool)
                self.__tracer.debug('Idle Off True')
    def sample_indication(self, buf, addr):

        # check if we want to scroll a trace line or not
        do_trace = SettingsBase.get_setting(self, "trace")
        if do_trace:
            msg = ['XBeeSensor(%s): ' % self.__name]

        # Parse the I/O sample:
        io_sample = parse_is(buf)
        
        # Calculate sensor channel values:
        if io_sample.has_key("AD1") and io_sample.has_key("AD2") and io_sample.has_key("AD3"):
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2", "AD3"))

            #
            # handle temperature - first as celsius
            #
            scale = "F"
            temperature = temperature_mv
            if not SettingsBase.get_setting(self, "sleep"):
                # self-heating correction if running full-time - reduce 2 DegC
                temperature -= .001
            temperature = round(temperature, 2)
            
                
    
            #self.property_set("motion", Sample(0, temperature, scale))
            #if do_trace:
            #    msg.append( "%d %s" % (temperature, scale))
    
            #
            # handle the light value
            #
            light = round((light_mv / 10), 2)
            if light < 0:
                # clamp to be zero or higher
                light = 0
            self.property_set("temperature", Sample(0, light, "F"))
           # if do_trace:
            #    msg.append( ", %d brightness" % light)
    
            #
            # handle humidity - might be missing
            #
            if self.property_exists("humidity"):
                humidity = ((humidity_mv * 108.2 / 33.2) / 5000.0 - 0.16) / 0.0062
                if humidity < 0.0:
                    # clamp to min of 0%
                    humidity = 0.0
                elif humidity > 100.0:
                    # clamp to be max of 100%
                    humidity = 100.0
                self.property_set("humidity", Sample(0, humidity, "%"))
                if do_trace:
                    msg.append( ", %d RH%%" % humidity)
            else: # it remains the original default
                humidity = 0
        
        
        activate = self.property_get("power_on").value

        # Low battery check (attached to DIO11/P1):
        # Invert the signal it is actually not_low_battery:
        if io_sample.has_key("DIO2") and activate:
            low_battery = not bool(io_sample["DIO2"])
            if low_battery != bool(self.property_get("low_battery").value):
                self.property_set("low_battery", Sample(0, low_battery))
    
            if do_trace:
                if low_battery:
                    msg.append( ", low_battery")
                # try to keep memory use from dragging out
                msg = "".join( msg)
                print msg
                del msg

        temp = self.property_get("temperature").value
        SettingsBase.set_pending_setting(self, 'temp', temp)
        
        motion = self.property_get("low_battery").value
        
        
        if activate and motion:
            self.property_set("motion_event",
            Sample(0, Boolean(True, style=STYLE_ONOFF)))
        else:
            self.property_set("motion_event",
            Sample(0, Boolean(False, style=STYLE_ONOFF)))
            


        return
    def calibrate(self):
        """\
            Calibrate analog inputs on the XBee radio.
            Calculates scale and offset.
        """

        # Retrieve the radio type.
        # Calibration is different based on the XBee radio in the unit.
        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 voltages on channel 1
            for ch in self.__aio_channel_structures:
               if ch.channel() == 1:
                  ch.turn_on_calibration_series1()

            # Give it a moment to synch up.  Yes, this IS required!
            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)

            # Disable calibration voltages on channels 0 and 1
            for ch in self.__aio_channel_structures:
               if ch.channel() == 0 or ch.channel() == 1:
                  ch.turn_off_calibration_series2()

            # Give it a moment to synch up.  Yes, this IS required!
            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
            for ch in self.__aio_channel_structures:
               if ch.channel() == 0 or ch.channel() == 1:
                  ch.turn_on_calibration_series2()

            # Give it a moment to synch up.  Yes, this IS required!
            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])

            # Disable calibration voltages on channels 0 and 1
            for ch in self.__aio_channel_structures:
               if ch.channel() == 0 or ch.channel() == 1:
                  ch.turn_off_calibration_series2()

            # Give it a moment to synch up.  Yes, this IS required!
            digitime.sleep(0.010)

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

            scale1 = self.__CALIBRATION_06 / float(sample[1])
            scale2 = self.__CALIBRATION_10 / float(sample[0])

            self.__scale = (scale1 + scale2) / 2.0

            if self.__OLD_HARDWARE == True:
                self.__offset = (sample[1] *
                       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)
Beispiel #24
0
    def sample_indication(self, buf, addr):

        self._tracer.calls("XBeeRPM.sample_indication()")

        # save time of last data, plus we want ALL of the samples to have
        # exact same timestamp (leaving 0 means some may be 1 second newer)
        self._last_timestamp = digitime.time()

        # new method for mesh health monitoring
        self.set_time_of_last_data(self._last_timestamp)

        # if we haven't gotten initial state yet, ask for it
        if self.property_get('power_on').value == UNKNOWN_POWER_STATE:
            if not self._set_initial_power_state():
                self._tracer.warning('Power state unknown, ignoring '
                                     'sample indication.')
                return

        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate channel values:
        light_mv, temperature_mv, current_mv = \
            map(lambda cn: sample_to_mv(io_sample[cn]),
                ('AD1', 'AD2', 'AD3'))
        light = round(light_mv, 0)
        if light < 0:
            # clamp to be zero or higher
            light = 0

        power_state = Boolean(self.property_get("power_on").value,
                              style=STYLE_ONOFF)

        # TODO: CRA Max could you remove this offset code?  Change to
        # clip at 0.
        if not power_state:
            self.offset = current_mv * (157.0 / 47.0)
            if self.offset >= 600.0:
                # Probably a current spike from flipping the power relay
                self.offset = 520.0

        current = round((current_mv * (157.0 / 47.0) - self.offset) \
                        / 180.0 * 0.7071, 3)

        pf_adj = self.get_power_factor()
        # compute powerfactor adjusted current
        if 1.0 >= pf_adj and 0.0 <= pf_adj:
            current *= pf_adj

        if current <= 0.05:
            # Clip the noise at the bottom of this sensor:
            current = 0.0
        temperature = (temperature_mv - 500.0) / 10.0
        # self-heating correction
        temperature = (temperature - 4.0) - \
                      (0.017 * current ** 2 + 0.631 * current)

        if SettingsBase.get_setting(self, "degf"):
            temperature = (temperature * 1.8) + 32.0
            units = 'F'
        else:
            units = 'C'

        temperature = round(temperature, 2)

        # Update channels:
        self.property_set("light",
                          Sample(self._last_timestamp, light, "brightness"))
        self.property_set("temperature",
                          Sample(self._last_timestamp, temperature, units))
        self.property_set("current", Sample(self._last_timestamp, current,
                                            "A"))

        ## Check if sample has information about the power state
        if io_sample.has_key('AD4'):
            ## Define it as a boolean
            compare_state = Boolean(io_sample['AD4'], style=STYLE_ONOFF)

            ## compare to current power_state
            if not compare_state == power_state:
                ## It's different, set the power state to the new value
                self._tracer.warning("Power state was: %s, but now it is: %s" %
                                     (power_state, compare_state))
                self._tracer.warning("Returning power state to: %s" %
                                     (power_state))

                self.prop_set_power_control(Sample(0, str(power_state)))

        if self._tracer.info():
            self._tracer.info('Power:%r light:%d %0.1f%s %0.2fA', power_state,
                              light, temperature, units, current)

        # check the realtime clock and compare to the last power_on_time
        # turn off if the idle_off_setting has been met or exceeded
        idle_off_setting = SettingsBase.get_setting(self, "idle_off_seconds")
        if (power_state and idle_off_setting > 0):
            if ((digitime.time() - self.__power_on_time) \
                >= idle_off_setting):
                power_on_state_bool = self.property_get("power_on")
                power_on_state_bool.value = False
                self.prop_set_power_control(power_on_state_bool)
                self._tracer.debug('Idle Off True')
    def calibrate(self):
        """\
            Calibrate analog inputs on the XBee radio.
            Calculates scale and offset.
        """

        # Retrieve the radio type.
        # Calibration is different based on the XBee radio in the unit.
        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 voltages on channel 1
            for ch in self.__aio_channel_structures:
               if ch.channel() == 1:
                  ch.turn_on_calibration_series1()

            # Give it a moment to synch up.  Yes, this IS required!
            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)

            # Disable calibration voltages on channels 0 and 1
            for ch in self.__aio_channel_structures:
               if ch.channel() == 0 or ch.channel() == 1:
                  ch.turn_off_calibration_series2()

            # Give it a moment to synch up.  Yes, this IS required!
            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
            for ch in self.__aio_channel_structures:
               if ch.channel() == 0 or ch.channel() == 1:
                  ch.turn_on_calibration_series2()

            # Give it a moment to synch up.  Yes, this IS required!
            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])

            # Disable calibration voltages on channels 0 and 1
            for ch in self.__aio_channel_structures:
               if ch.channel() == 0 or ch.channel() == 1:
                  ch.turn_off_calibration_series2()

            # Give it a moment to synch up.  Yes, this IS required!
            digitime.sleep(0.010)

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

            scale1 = self.__CALIBRATION_06 / float(sample[1])
            scale2 = self.__CALIBRATION_10 / float(sample[0])

            self.__scale = (scale1 + scale2) / 2.0

            if self.__OLD_HARDWARE == True:
                self.__offset = (sample[1] *
                       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)
Beispiel #26
0
 def sample_indication(self, buf, addr):
     
     # Parse the I/O sample:
     io_sample = parse_is(buf)
    def sample_indication(self, buf, addr):

        # save time of last data, plus we want ALL of the samples to have
        # exact same timestamp (leaving 0 means some may be 1 second newer)
        self._last_timestamp = digitime.time()

        if self.__tracer.info():
            msg = []
        else:
            msg = None

        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate sensor channel values:
        if "AD1" in io_sample and "AD2" in io_sample and \
               "AD3" in io_sample:
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]),
                    ("AD1", "AD2", "AD3"))

            #
            # handle temperature - first as celsius
            #
            scale = "C"
            temperature = (temperature_mv - 500.0) / 10.0
            if not SettingsBase.get_setting(self, "sleep"):
                # self-heating correction if running full-time - reduce 2 DegC
                temperature -= 2.0
            temperature = round(temperature, 2)

            self.property_set("temperature",
                Sample(self._last_timestamp, temperature, scale))
            if msg is not None:
                msg.append("%d %s" % (temperature, scale))

            #
            # handle the light value
            #
            light = round(light_mv, 0)
            if light < 0:
                # clamp to be zero or higher
                light = 0
            self.property_set("light",
                Sample(self._last_timestamp, light, "brightness"))
            if msg is not None:
                msg.append(", %d brightness" % light)

            #
            # handle humidity - might be missing
            #
            if self.property_exists("humidity"):
                humidity = ((humidity_mv * 108.2 / 33.2) / 5000.0 - 0.16) / \
                           0.0062
                if humidity < 0.0:
                    # clamp to min of 0%
                    humidity = 0.0
                elif humidity > 100.0:
                    # clamp to be max of 100%
                    humidity = 100.0
                self.property_set("humidity",
                    Sample(self._last_timestamp, humidity, "%"))
                if msg is not None:
                    # cannot use %% in string, __tracer will misunderstand
                    msg.append(", %d RH" % humidity)

            else:  # it remains the original default
                humidity = 0

        # Low battery check (attached to DIO11/P1):
        # Invert the signal it is actually not_low_battery:
        if "DIO11" in io_sample:
            low_battery = not bool(io_sample["DIO11"])
            if low_battery != bool(self.property_get("low_battery").value):
                self.property_set("low_battery",
                    Sample(self._last_timestamp, low_battery))

            if low_battery and msg is not None:
                msg.append(", low_battery")
                # try to keep memory use from dragging out

        if msg is not None:
            self.__tracer.info("".join(msg))
            del msg

        return
Beispiel #28
0
    def sample_indication(self, buf, addr):

        self._tracer.calls("XBeeSensor.sample_indication()")

        # save time of last data, plus we want ALL of the samples to have
        # exact same timestamp (leaving 0 means some may be 1 second newer)
        self._last_timestamp = digitime.time()

        # new method for mesh health monitoring
        self.set_time_of_last_data(self._last_timestamp)

        if self._tracer.info():
            msg = []
        else:
            msg = None

        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate sensor channel values:
        if "AD1" in io_sample and "AD2" in io_sample and \
               "AD3" in io_sample:
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]),
                    ("AD1", "AD2", "AD3"))

            #
            # handle temperature - first as celsius
            #
            temperature = (temperature_mv - 500.0) / 10.0
            if not SettingsBase.get_setting(self, "sleep"):
                # self-heating correction if running full-time - reduce 2 DegC
                temperature -= 2.0

            if SettingsBase.get_setting(self, "degf"):
                temperature = (temperature * 1.8) + 32.0
                units = 'F'
            else:
                units = 'C'

            # offset is a simple float value - we don't care if DegC or DegF
            temperature += SettingsBase.get_setting(self, "offset")

            temperature = round(temperature, 2)

            self.property_set("temperature",
                              Sample(self._last_timestamp, temperature, units))
            if msg is not None:
                msg.append("%d %s" % (temperature, units))

            #
            # handle the light value
            #
            light = round(light_mv, 0)
            if light < 0:
                # clamp to be zero or higher
                light = 0
            self.property_set(
                "light", Sample(self._last_timestamp, light, "brightness"))
            if msg is not None:
                msg.append(", %d brightness" % light)

            #
            # handle humidity - might be missing
            #
            if self.property_exists("humidity"):
                humidity = ((humidity_mv * 108.2 / 33.2) / 5000.0 - 0.16) / \
                           0.0062
                if humidity < 0.0:
                    # clamp to min of 0%
                    humidity = 0.0
                elif humidity > 100.0:
                    # clamp to be max of 100%
                    humidity = 100.0
                self.property_set("humidity",
                                  Sample(self._last_timestamp, humidity, "%"))
                if msg is not None:
                    # cannot use %% in string, __tracer will misunderstand
                    msg.append(", %d RH" % humidity)

            else:  # it remains the original default
                humidity = 0

        # Low battery check (attached to DIO11/P1):
        # Invert the signal it is actually not_low_battery:
        if "DIO11" in io_sample:
            low_battery = not bool(io_sample["DIO11"])
            if low_battery != bool(self.property_get("low_battery").value):
                self.property_set("low_battery",
                                  Sample(self._last_timestamp, low_battery))

            if low_battery and msg is not None:
                msg.append(", low_battery")
                # try to keep memory use from dragging out

        if msg is not None:
            self._tracer.info("".join(msg))
            del msg

        return
    def sample_indication(self, buf, addr):
        zero_clamp = SettingsBase.get_setting(self, "zero_clamp")

        # check if we want to scroll a trace line or not
        
        
        msg = []

        raw_output = SettingsBase.get_setting(self, "raw_value")

        #print "XBeeAIO: Got sample indication from: %s, buf is len %d." \
        #    % (str(addr), len(buf))
        
        io_sample = parse_is(buf)

        for aio_num in range(4):
            aio_name = "AD%d" % (aio_num)
            channel_name = "channel%d_value" % (aio_num+1)
            channel2_name = "channel%d_value" % (aio_num+2)
            channel_mode = SettingsBase.get_setting(self,
                                "channel%d_mode" % (aio_num+1))
            channel_mode = channel_mode.lower()
            channel_mode = AIO_MODE_MAP[channel_mode.lower()]

            if aio_name not in io_sample:
                continue

            
            msg.append('%s=' % aio_name)

            raw_value = io_sample[aio_name]
            
            if( zero_clamp and (raw_value < zero_clamp)):
                # then user doesn't want to see low near-zero garbage
                raw_value = 0

            if channel_mode == AIO_MODE_OFF:
                # self.property_set(channel_name, Sample(0, 0, ""))
                msg.append('Off ')
                                  
            elif( raw_output):
                # then just put the raw binary in the sample
                self.property_set(channel_name, Sample(0, float(raw_value), "raw"))
                msg.append('%04d ' % raw_value)
                
            elif channel_mode == AIO_MODE_CURRENTLOOP:
                mV = raw_value * 1200.0 / 1023
                mA = mV / AIO_LOOP_R_OHMS
                self.property_set(channel_name, Sample(0, mA, "mA"))
                msg.append('%0.2fmA ' % mA)
                                  
            elif channel_mode == AIO_MODE_TENV:
                V = (float(raw_value) / 1024) * 10.25
                self.property_set(channel_name, Sample(0, V, "V"))

                # msg.append('(%04d) ' % raw_value)
                msg.append('%0.2fV ' % V)

            elif channel_mode == AIO_MODE_DIFFERENTIAL:
                # Only report the even AIO channels, ie, 0 and 2.
                # We will replicate and report these values for the
                # odd AIO channels as well.
                if aio_num % 2:
                    continue

                mid = AIO_DIFFERENTIAL_MIDPOINT_CHANNEL0
                if aio_num == 2:
                    mid = AIO_DIFFERENTIAL_MIDPOINT_CHANNEL2

                V = 0
                if raw_value >= mid:
                    V = ((raw_value - mid) / (1023.0 - mid)) * \
                            AIO_DIFFERENTIAL_MAX
                else:
                    V = ((mid - raw_value) / mid) * AIO_DIFFERENTIAL_MIN
                    
                self.property_set(channel_name, Sample(0, V, "V"))
                self.property_set(channel2_name, Sample(0, V, "V"))
                
                msg.append('%0.2fV ' % V)
                # msg.append('%s=%0,2fV ' % (aio_name+2, V))
                    
        # Low battery check (attached to DIO11/P1):
        if SettingsBase.get_setting(self, "enable_low_battery"):
            # Invert the signal it is actually not_low_battery:
            low_battery = not bool(io_sample["DIO11"])
            self.property_set("low_battery", Sample(0, low_battery))            
            if( low_battery):
                msg.append('bat=LOW!')

        self.__tracer.debug("".join( msg))
Beispiel #30
0
    def sample_indication(self, buf, addr):

        self._tracer.calls("XBeeAIO.sample_indication()")

        zero_clamp = SettingsBase.get_setting(self, "zero_clamp")

        # check if we want to scroll a trace line or not

        if self._tracer.info():
            # will be true for debug also
            msg = []
        else:
            msg = None

        raw_output = SettingsBase.get_setting(self, "raw_value")

        io_sample = parse_is(buf)
        if self._tracer.calls():
            self._tracer.calls('io_sample:%s', str(io_sample))

        for aio_num in range(4):
            aio_name = "AD%d" % (aio_num)
            channel_name = self.CHN_VALUE_NAME[aio_num]
            channel_mode = SettingsBase.get_setting(
                self, self.CHN_MODE_NAME[aio_num])
            channel_mode = channel_mode.lower()
            channel_mode = AIO_MODE_MAP[channel_mode.lower()]

            if aio_name not in io_sample:
                continue

            if msg is not None:
                msg.append('%s=' % aio_name)

            raw_value = io_sample[aio_name]

            if zero_clamp and (raw_value < zero_clamp):
                # then user doesn't want to see low near-zero garbage
                raw_value = 0

            if channel_mode == AIO_MODE_OFF:
                # self.property_set(channel_name, Sample(0, 0, ""))
                if msg is not None:
                    msg.append('Off ')

            elif raw_output:
                # then just put the raw binary in the sample
                self.property_set(channel_name,
                                  Sample(0, float(raw_value), "raw"))
                if msg is not None:
                    msg.append('%04d ' % raw_value)

            elif channel_mode == AIO_MODE_CURRENTLOOP:
                mV = raw_value * 1200.0 / 1023
                mA = mV / AIO_LOOP_R_OHMS
                self.property_set(channel_name, Sample(0, mA, "mA"))
                if msg is not None:
                    msg.append('%0.2fmA ' % mA)

            elif channel_mode == AIO_MODE_TENV:
                V = (float(raw_value) / 1024) * 10.25
                self.property_set(channel_name, Sample(0, V, "V"))

                # msg.append('(%04d) ' % raw_value)
                if msg is not None:
                    msg.append('%0.2fV ' % V)

            elif channel_mode == AIO_MODE_DIFFERENTIAL:
                # Only report the even AIO channels, ie, 0 and 2.
                # We will replicate and report these values for the
                # odd AIO channels as well.
                if aio_num % 2:
                    continue

                mid = AIO_DIFFERENTIAL_MIDPOINT_CHANNEL0
                if aio_num == 2:
                    mid = AIO_DIFFERENTIAL_MIDPOINT_CHANNEL2

                V = 0
                if raw_value >= mid:
                    V = ((raw_value - mid) / (1023.0 - mid)) * \
                            AIO_DIFFERENTIAL_MAX
                else:
                    V = ((mid - raw_value) / mid) * AIO_DIFFERENTIAL_MIN

                self.property_set(channel_name, Sample(0, V, "V"))
                channel2_name = "channel%d_value" % (aio_num + 2)
                self.property_set(channel2_name, Sample(0, V, "V"))

                if msg is not None:
                    msg.append('%0.2fV ' % V)
                # msg.append('%s=%0,2fV ' % (aio_name+2, V))

        # Low battery check (attached to DIO11/P1):
        if SettingsBase.get_setting(self, "enable_low_battery"):
            # Invert the signal it is actually not_low_battery:
            low_battery = not bool(io_sample["DIO11"])
            self.property_set("low_battery", Sample(0, low_battery))
            if low_battery and msg is not None:
                msg.append('bat=LOW!')

        if msg is not None:
            self._tracer.info("".join(msg))
    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)
Beispiel #32
0
    def sample_indication(self, buf, addr):
        
        excl = self.property_get("excl").value
        
        if excl:
            self.property_set("excl", Sample(0, value=Boolean(bool(0), style=STYLE_ONOFF)))
        # Parse the I/O sample:
        
        extended_address = SettingsBase.get_setting(self, "extended_address")
       
        if self.count > 20:
            try:
            
    	        db = self.__xbee_manager.xbee_device_ddo_get_param(extended_address,
    	                                                                  "DB", use_cache=True)
    	    #    sv = self.__xbee_manager.xbee_device_ddo_get_param(extended_address,
    	    #                                                             "%V", use_cache=True)
    	        
    	        
    	        
    	        try:
    	            dd = struct.unpack(">B", db)
    	            #print dd
    	        except:
    	        	self.property_set("signal", Sample(0, value="0", unit=""))
    	        	print "failed 4"     
    	        
    	      #  try:
    	      #  	sv = struct.unpack(">H", sv)
    	     #   except:
    	     #   	self.property_set("volts", Sample(0, value="failed", unit=""))
    	       # print sv
    	
    	        dd = str(dd)
    	        dd = dd[1:3]
    	        dd = "-" + dd + " dB"
    	      #  print "signal strength ="
    	      #  print dd
    	        self.property_set("signal", Sample(0, value=str(dd), unit=""))
    	        
    	        
    	        
    	      #  sv = str(sv)
    	      #  sv = sv[1:5]
    	      #  sv = int(sv)
    	      #  print sv
    	      #  volts = (sv * 1.1719) / 1000
    	     #   print "volts ="
    	     #   print volts
    	      #  self.property_set("volts", Sample(0, value=str(volts), unit=""))
    	    
    
            
            
            except:
            	self.property_set("signal", Sample(0, value="disconnected", unit=""))
            	print "failed to get signal and voltage"
            
        if self.count < 22:
            self.count += 1
        io_sample = parse_is(buf)

        # Calculate channel values:
        light_mv, temperature_mv = \
            map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2"))
        light = round(light_mv)
        temperature = round((((temperature_mv - 500.0) / 10.0 - 4.0)) * 1.8 + 32, 2) 

        # Update channels:
        self.property_set("light", Sample(0, light, "brightness"))
        self.property_set("temperature", Sample(0, temperature, self.include_unit))
    def sample_indication(self, buf, addr):

        # check if we want to scroll a trace line or not
        
        
        if self.count == 720:
                self.get_signal()
            
        
            
        if self.count == 720:
            self.count = 0
        
        
        if self.count < 722:
            self.count += 1
        
        
        do_trace = SettingsBase.get_setting(self, "trace")
        if do_trace:
            msg = ['XBeeSensor(%s): ' % self.__name]

        # Parse the I/O sample:
        io_sample = parse_is(buf)
        
        # Calculate sensor channel values:
        if io_sample.has_key("AD1") and io_sample.has_key("AD2") and io_sample.has_key("AD3"):
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2", "AD3"))

            #
            # handle temperature - first as celsius
            #
            scale = self.include_unit
            temperature = (((((temperature_mv - 500.0) / 10.0) * (1.8) ) + 32) + 2.6)
            if not SettingsBase.get_setting(self, "sleep"):
                # self-heating correction if running full-time - reduce 2 DegC
                temperature -= 2.0
            temperature = round(temperature, 2)
    
            self.property_set("temperature", Sample(0, temperature, scale))
            if do_trace:
                msg.append( "%d %s" % (temperature, scale))
    
            #
            # handle the light value
            #
            light = round(light_mv,0)
            if light < 0:
                # clamp to be zero or higher
                light = 0
            self.property_set("light", Sample(0, light, "brightness"))
            if do_trace:
                msg.append( ", %d brightness" % light)
    
            #
            # handle humidity - might be missing
            #
            if self.property_exists("humidity"):
                humidity = ((humidity_mv * 108.2 / 33.2) / 5000.0 - 0.16) / 0.0062
                if humidity < 0.0:
                    # clamp to min of 0%
                    humidity = 0.0
                elif humidity > 100.0:
                    # clamp to be max of 100%
                    humidity = 100.0
                self.property_set("humidity", Sample(0, humidity, "%"))
                if do_trace:
                    msg.append( ", %d RH%%" % humidity)
            else: # it remains the original default
                humidity = 0

        # Low battery check (attached to DIO11/P1):
        # Invert the signal it is actually not_low_battery:
        if io_sample.has_key("DIO11"):
            low_battery = not bool(io_sample["DIO11"])
            if low_battery != bool(self.property_get("low_battery").value):
                self.property_set("low_battery", Sample(0, low_battery))
    
            if do_trace:
                if low_battery:
                    msg.append( ", low_battery")
                # try to keep memory use from dragging out
                msg = "".join( msg)
                print msg
                del msg

        
        excl = self.property_get("excl").value
        
        if excl:
            self.property_set("excl", Sample(0, value=Boolean(bool(0), style=STYLE_ONOFF)))
        
        return
Beispiel #34
0
    def sample_indication(self, buf, addr):
        

        
                                # wire up any inputs
 #      input_source = SettingsBase.get_setting(self, 'input_source')
        cm = self.__core.get_service("channel_manager")
        cp = cm.channel_publisher_get()
        cdb = cm.channel_database_get()
 #       cp.subscribe(input_source, self.prop_set_input)
        
        

 #       try:
#        source_name = SettingsBase.get_setting(self, 'input_source')
        source_name = self.property_get("user_input_1").value
            
        if( source_name != None):
            source_chan = cdb.channel_get( source_name)
                # pre-load the starting value, which won't be published to us
            self.my_input = source_chan.get().value
   #             self.property_set("adder_reg2", Sample(0, my_input))
            self.property_set("driving_temp", Sample(0, self.my_input, "F"))              
#                self.property_set("input", Sample(0, self.my_input))      
         #       cp.subscribe(source_name, self.update_power_state1)
 #               cp.subscribe( source_name, self.prop_set_input )      

                #    self.property_set("2_high", Sample(0, 1.0))
                       
               
  
        
        
        
        # Parse the I/O sample:
        io_sample = parse_is(buf)

        # Calculate channel values:
       # upbutton_mv, onbutton_mv, downbutton_mv = \
           # map(lambda cn: sample_to_mv(io_sample[cn]), ("AD0", "AD1", "AD2"))

            

        
        
        if io_sample.has_key("AD0") and io_sample.has_key("AD1") and io_sample.has_key("AD2"):
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]), ("AD0", "AD1", "AD2"))
        
        
       
        up = (round(temperature_mv, 2)) / 10
        red_light = round(light_mv) 
           # on = round(temperature_mv, 2)
           # down = round(humidity_mv, 2)
       
 #       power_state = self.property_get("power_on").value

        # Update channels:
        self.property_set("temperature", Sample(0, up, "F"))
        self.property_set("red_light", Sample(0, red_light, "mv"))
 #       self.property_set("on", Sample(0, on, "mv"))
 #       self.property_set("down", Sample(0, down, "mv"))
        
        red = self.property_get("red_light").value
        heat = self.property_get("heat").value
        old = self.property_get("switch_to_old").value
        on = self.property_get("heat_ac_on").value
        old_on = self.property_get("old_thermostat_on").value
        
        if red_light < 100.0 and old_on:
            self.property_set("old_thermostat_on",
            Sample(0, Boolean(False, style=STYLE_ONOFF))) 
        
        if red_light > 100.0 and not old_on:
            self.old_thermostat(Sample(0, Boolean("on", STYLE_ONOFF)))        
                
            
#        if red_light > 100.0 and not old_on:
 #           self.old_thermostat(Sample(0, Boolean("on", STYLE_ONOFF)))
       #     self.property_set("2_low", Sample(0, 1.0)) 
            
 #       if red_light < 100 and old:
 #           self.property_set("switch_to_old", Sample(0, Boolean(False, style=STYLE_ONOFF)))
 #           self.property_set("old_thermostat_on", Sample(0, Boolean(False, style=STYLE_ONOFF)))
 #           
 #       if red_light < 100 and old_on:
 #           self.property_set("switch_to_old", Sample(0, Boolean(False, style=STYLE_ONOFF)))
 #           self.property_set("old_thermostat_on", Sample(0, Boolean(False, style=STYLE_ONOFF)))
        
        driving = self.property_get("driving_temp").value
        des_temp = self.property_get("desired_temp").value    
        ac = self.property_get("AC").value

        
    
        temp_plus = des_temp + 0.5
        temp_minus = des_temp - 0.5
            
        if heat and on and driving > temp_plus:
                    self.prop_set_power_control2_low(Sample(0, Boolean("on", STYLE_ONOFF)))
                    time.sleep(0.75)
                    self.prop_set_power_control2_low(Sample(0, Boolean("off", STYLE_ONOFF)))
       #     self.property_set("2_low", Sample(0, 1.0)) 
            
        if heat and not on and driving < temp_minus:
                    self.prop_set_power_control2_high(Sample(0, Boolean("on", STYLE_ONOFF)))
                    time.sleep(0.75)
                    self.prop_set_power_control2_high(Sample(0, Boolean("off", STYLE_ONOFF)))
                     
        if ac and not on and driving > temp_plus:
                     self.prop_set_power_control2_high(Sample(0, Boolean("on", STYLE_ONOFF)))
                     time.sleep(0.75)
                     self.prop_set_power_control2_high(Sample(0, Boolean("off", STYLE_ONOFF)))
        #    self.property_set("2_low", Sample(0, 1.0)) 
            
        if ac and on and driving < temp_minus:
                    self.prop_set_power_control2_low(Sample(0, Boolean("on", STYLE_ONOFF)))
                    time.sleep(0.75)
                    self.prop_set_power_control2_low(Sample(0, Boolean("off", STYLE_ONOFF)))
         #   self.property_set("2_high", Sample(0, 1.0))
         
        
        
         



                
        time.sleep(5.0)
Beispiel #35
0
    def sample_indication(self, buf, addr):
        msg = []

        # Parse the I/O sample:
        io_sample = parse_is(buf)
        
        # Calculate sensor channel values:
        if io_sample.has_key("AD1") and io_sample.has_key("AD2") and io_sample.has_key("AD3"):
            light_mv, temperature_mv, humidity_mv = \
                map(lambda cn: sample_to_mv(io_sample[cn]), ("AD1", "AD2", "AD3"))

            #
            # handle temperature - first as celsius
            #
            scale = "C"
            temperature = (temperature_mv - 500.0) / 10.0
            if not SettingsBase.get_setting(self, "sleep"):
                # self-heating correction if running full-time - reduce 2 DegC
                temperature -= 2.0
            temperature = round(temperature, 2)
    
            self.property_set("temperature", Sample(0, temperature, scale))
            msg.append( "%d %s" % (temperature, scale))
    
            #
            # handle the light value
            #
            light = round(light_mv,0)
            if light < 0:
                # clamp to be zero or higher
                light = 0
            self.property_set("light", Sample(0, light, "brightness"))            
            msg.append( ", %d brightness" % light)
    
            #
            # handle humidity - might be missing
            #
            if self.property_exists("humidity"):
                humidity = ((humidity_mv * 108.2 / 33.2) / 5000.0 - 0.16) / 0.0062
                if humidity < 0.0:
                    # clamp to min of 0%
                    humidity = 0.0
                elif humidity > 100.0:
                    # clamp to be max of 100%
                    humidity = 100.0
                self.property_set("humidity", Sample(0, humidity, "%"))               
                msg.append( ", %d RH%%" % humidity)
                
            else: # it remains the original default
                humidity = 0

        # Low battery check (attached to DIO11/P1):
        # Invert the signal it is actually not_low_battery:
        if io_sample.has_key("DIO11"):
            low_battery = not bool(io_sample["DIO11"])
            if low_battery != bool(self.property_get("low_battery").value):
                self.property_set("low_battery", Sample(0, low_battery))
    
            
            if low_battery:
                msg.append( ", low_battery")
                # try to keep memory use from dragging out
         
        self.__tracer.debug("".join(msg))
        del msg
        return
    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)