コード例 #1
0
    def _upload_old_data(self):
        '''
        Upload (up to MAX_RECOVER) saved files from failed uploads.
        '''
        count = 0
        todo = self._stats_file.files_list
        while count < MAX_RECOVER:
            if len(todo) == 0:
                break
            fname = todo[0]
            if not os.path.exists(create_full_path(fname)):
                TRACER.warning('When trying to upload old data, discovered ' \
                               '%s no longer exists on the filesystem. ' \
                               'Skipping...' % (fname))
                todo = todo[1:]
                continue
            fin = None
            try:
                fin = open(create_full_path(fname), 'r')
                data = fin.read()
                fin.close()
            except Exception:
                TRACER.warning('When trying to upload old data, could not ' \
                               'open %s for reading. Removing...' % (fname))
                if fin:
                    fin.close()
                try:
                    os.remove(create_full_path(fname))
                except Exception:
                    # we give up here
                    TRACER.debug('Could not remove bad file %s. It will be ' \
                                 'ignored in the future.' % (fname))
                todo = todo[1:]
                continue

            # trying to upload now...
            self._stats_file.upload_attempts += 1
            self._tracer.debug("starting upload of old data to Device Cloud")

            success = self.__send_to_idigi(fname, data)
            if success:
                self._tracer.debug(
                    "finished upload of old data to Device Cloud")
                self._stats_file.last_success = digitime.time()
                self._stats_file.successful_uploads += 1
                todo = todo[1:]
                try:
                    os.remove(create_full_path(fname))
                except Exception:
                    # we give up here...
                    _delete_fail(fname)
                count += 1
            else:
                self._tracer.debug("upload of old data to Device Cloud failed")
                self._stats_file.last_failure = digitime.time()
                break

        self._stats_file.files_list = todo
        self._stats_file.save()
コード例 #2
0
 def set_gpio(self,gpio,sample):
     
     self.setting_gpio = True
     #Update the channel and the module GPIO
     if sample.value==True:            
         self.property_set(gpio,Sample(digitime.time(), True))
         digihw.gpio_set_value(self.gpios_ind[gpio], 1)
     else:
         self.property_set(gpio,Sample(digitime.time(), False))
         digihw.gpio_set_value(self.gpios_ind[gpio], 0)
     self.setting_gpio = False
コード例 #3
0
    def set_gpio(self, gpio, sample):

        self.setting_gpio = True
        #Update the channel and the module GPIO
        if sample.value == True:
            self.property_set(gpio, Sample(digitime.time(), True))
            digihw.gpio_set_value(self.gpios_ind[gpio], 1)
        else:
            self.property_set(gpio, Sample(digitime.time(), False))
            digihw.gpio_set_value(self.gpios_ind[gpio], 0)
        self.setting_gpio = False
コード例 #4
0
    def get_GPIOs(self):

        for gpio in self.input_gpios:
            val = digihw.gpio_get_value(gpio)
            #If the GPIO value has changed, update its channel
            if self.gpios["GPIO_" + str(gpio)] != val:
                self.gpios["GPIO_" + str(gpio)] = val
                if val == 0:
                    self.property_set("GPIO_" + str(gpio),
                                      Sample(digitime.time(), False))
                else:
                    self.property_set("GPIO_" + str(gpio),
                                      Sample(digitime.time(), True))
コード例 #5
0
 def get_GPIOs(self):
     
     for gpio in self.input_gpios:
         val = digihw.gpio_get_value(gpio)
         #If the GPIO value has changed, update its channel
         if self.gpios["GPIO_"+str(gpio)]!=val:
             self.gpios["GPIO_"+str(gpio)]=val            
             if val==0 :
                 self.property_set("GPIO_"+str(gpio),
                     Sample(digitime.time(), False))
             else:
                 self.property_set("GPIO_"+str(gpio),
                     Sample(digitime.time(), True))
コード例 #6
0
    def do_channel_set(self, arg):
        try:
            args = parse_line(arg)
        except:
            self.write("invalid syntax.\r\n")
            return 0
        channel_name = ""
        value = None
        unit = ""
        if len(args) < 2 or len(args) > 3:
            self.write("invalid argument(s) specified.\r\n")
            return 0
        if len(args) > 1:
            channel_name = args[0]
            value = args[1]
        if len(args) > 2:
            unit = args[2]
            self.__tracer.info("have unit: %s", unit)

        if not self.__cdb.channel_exists(channel_name):
            self.write("unknown channel '%s'\r\n" % (channel_name))
            return 0

        channel = self.__cdb.channel_get(channel_name)

        sample = None
        try:
            sample = Sample(digitime.time(), channel.type()(value), unit)
        except Exception, e:
            self.write("unable to parse '%s': %s\r\n" % (value, str(e)))
            self.write("type expected: %s\r\n" % (channel.type()))
            return 0
コード例 #7
0
    def do_channel_set(self, arg):
        try:
            args = parse_line(arg)
        except:
            self.write("invalid syntax.\r\n")
            return 0
        channel_name = ""
        value = None
        unit = ""
        if len(args) < 2 or len(args) > 3:
            self.write("invalid argument(s) specified.\r\n")
            return 0
        if len(args) > 1:
            channel_name = args[0]
            value = args[1]
        if len(args) > 2:
            unit = args[2]
            self.__tracer.info("have unit: %s", unit)


        if not self.__cdb.channel_exists(channel_name):
            self.write("unknown channel '%s'\r\n" % (channel_name))
            return 0

        channel = self.__cdb.channel_get(channel_name)

        sample = None
        try:
            sample = Sample(digitime.time(), channel.type()(value), unit)
        except Exception, e:
            self.write("unable to parse '%s': %s\r\n" % (value, str(e)))
            self.write("type expected: %s\r\n" % (channel.type()))
            return 0
コード例 #8
0
    def _set_targets(self):

        # Set targets to produce samples
        self.time_now = time.time()

        for tgt in channel_map.keys():
            self.targets[tgt] = self.time_now + channel_map[tgt]
コード例 #9
0
    def _sync_to_disk(self):
        '''
        Dumps the samples currently in memory to disk.

        As a side-effect, clears the current memory cache and
        resets the self.__sample_sync timer.

        If this method fails, it will have cleared the in-memory cache,
        but *may have thrown away data*.

        Must be called with __entry_lock!
        '''
        try:
            # swap out data store
            output_list = self.__upload_queue
            self.__upload_queue = dict()
            self.__sample_sync = digitime.time()

            mem_samples = self._samples_in_queue(output_list)
            append = not (self.__sample_count == mem_samples)

            temp_string = cStringIO.StringIO()
            self.__write_dict_to_xml_output(output_list, temp_string)

            # flush to disk
            self._save_failed_data(BUFFER_NAME,
                                   temp_string.getvalue(),
                                   write_stats=False,
                                   append=append)
            temp_string.close()
        except Exception, e:
            TRACER.warning('Error while syncing to disk: data may have ' \
                           'been lost. (%s)' % (str(e)))
            return
コード例 #10
0
ファイル: xbee_rpm.py プロジェクト: bernhara/DigiGateway4Raph
    def _set_initial_power_state(self):
        '''
        set the initial power state (if set as "same")

        This needs to be outside of the start method, because
        it requires active communication with the device.

        Returns True on success, False on failure.
        '''
        # Retrieve current state from device for channel
        d4 = self._xbee_manager.xbee_device_ddo_get_param(
            self._extended_address, 'd4')

        d4 = struct.unpack('B', d4)[0]

        if d4 == POWER_ON:
            state = True

            # Treat as having just been turned on for shut-off
            self.__power_on_time = digitime.time()
        elif d4 == POWER_OFF:
            state = False
        else:
            self._tracer.warning('Unrecognized initial power_on state '
                                 '<%s>!\nNot touching "power_on" property.' %
                                 d4)
            return False

        self.property_set("power_on",
                          Sample(0, str(Boolean(state, style=STYLE_ONOFF))))
        return True
コード例 #11
0
ファイル: xbee_rpm.py プロジェクト: Lewiswight/4CT-GW--master
    def _set_initial_power_state(self):
        '''
        set the initial power state (if set as "same")

        This needs to be outside of the start method, because
        it requires active communication with the device.

        Returns True on success, False on failure.
        '''
        # Retrieve current state from device for channel
        d4 = self.__xbee_manager.xbee_device_ddo_get_param(
            SettingsBase.get_setting(self, 'extended_address'), 'd4')

        d4 = struct.unpack('B', d4)[0]

        if d4 == POWER_ON:
            state = True

            # Treat as having just been turned on for shut-off
            self.__power_on_time = digitime.time()
        elif d4 == POWER_OFF:
            state = False
        else:
            self.__tracer.warning('Unrecognized initial power_on state '
                                  '<%s>!\nNot touching "power_on" property.'
                                  % d4)
            return False

        self.property_set("power_on",
                          Sample(0, str(Boolean(state, style=STYLE_ONOFF))))
        return True
コード例 #12
0
    def _set_targets(self):

        # Set targets to produce samples
        self.time_now = time.time()

        for tgt in channel_map.keys():
            self.targets[tgt] = self.time_now + channel_map[tgt]
コード例 #13
0
ファイル: xbee_cb.py プロジェクト: Lewiswight/4CT-GW--master
    def button_press(self, buf, addr):

        now = digitime.time()

        self._tracer.info('Commissioning Button from %s at %s', addr[0],
            digitime.strftime("%Y-%m-%d %H:%M:%S", digitime.localtime(now)) )

        dct = parse_node_identification(buf)

        if dct is not None:
            x = dct['event']
            if x == 'pushbutton':
                msg = 'CB ' + dct['addr64']
                if self.property_get("cb_trigger").value == True:
                    self.property_set("cb_trigger", Sample(now, False))
                self.property_set("cb_trigger", Sample(now, True))
                self.property_set("cb_trigger", Sample(now, False))
            elif x == 'join':
                msg = 'JN ' + dct['addr64']
            elif x == 'power_cycle':
                msg = 'PWR ' + dct['addr64']
            else:
                self._tracer.warning('Unknown Source Event:0x%02X', x)
                return None

            if dct.has_key('dev_dd'):
                # append the lower device DD value
                msg += ' DD:0x%04X' % dct['dev_dd']

            self.property_set("button", Sample(now, msg))
            self._tracer.debug('channel=\"%s\"', msg)

        return
コード例 #14
0
    def button_press(self, buf, addr):

        now = digitime.time()

        self._tracer.info(
            'Commissioning Button from %s at %s', addr[0],
            digitime.strftime("%Y-%m-%d %H:%M:%S", digitime.localtime(now)))

        dct = parse_node_identification(buf)

        if dct is not None:
            x = dct['event']
            if x == 'pushbutton':
                msg = 'CB ' + dct['addr64']
                if self.property_get("cb_trigger").value == True:
                    self.property_set("cb_trigger", Sample(now, False))
                self.property_set("cb_trigger", Sample(now, True))
                self.property_set("cb_trigger", Sample(now, False))
            elif x == 'join':
                msg = 'JN ' + dct['addr64']
            elif x == 'power_cycle':
                msg = 'PWR ' + dct['addr64']
            else:
                self._tracer.warning('Unknown Source Event:0x%02X', x)
                return None

            if dct.has_key('dev_dd'):
                # append the lower device DD value
                msg += ' DD:0x%04X' % dct['dev_dd']

            self.property_set("button", Sample(now, msg))
            self._tracer.debug('channel=\"%s\"', msg)

        return
コード例 #15
0
    def _trigger(self, rate):
        want_print = SettingsBase.get_setting(self, PROP_PRINTF)

        new_time = time.time()

        if abs(new_time - self.time_now) > rate + 10:
            # If time has jumped considerably between polls, the
            # wall time has jumped.  Best thing to do is just
            # re-target based on the new time
            self.__tracer.warning("System time jump, resetting")
            self._set_targets()

        self.time_now = new_time
        self.time_tup = time.localtime(self.time_now)
        self.sample = (self.time_now, tuple(self.time_tup))

        # Check target channels
        for tgt in channel_map.keys():
            if self.time_now >= self.targets[tgt]:
                if want_print == tgt:
                    self.print_time_is_now()
                self.property_set(tgt,
                                  Sample(self.time_now, self.sample,
                                         'time'))
                self.targets[tgt] = self.time_now + channel_map[tgt]
コード例 #16
0
    def announce_device(self):

        message_list = []
        message = "Device %s now online at %s" % (self.__deviceid,
                                                  iso_date(digitime.time()))
        message_list.append(message)
        self.__transport_obj.send_message(message_list)
コード例 #17
0
ファイル: enduser.py プロジェクト: Lewiswight/4CT-GW--master
    def announce_device(self):
 
        message_list = []
        message = "Device %s now online at %s" % (self.__deviceid,
                                                  iso_date(digitime.time()))
        message_list.append(message)
        self.__transport_obj.send_message(message_list)
コード例 #18
0
    def __init__(self, name, core_services):
        self.__name = name
        self.__core = core_services
        
        self._logger = init_module_logger(name)        

        ## Local State Variables:
        self.__lora_manager = None
        
        self._extended_address_setting = None
        
        # Settings
        #
        # xbee_device_manager: must be set to the name of an XBeeDeviceManager
        #                      instance.
        # extended_address: the extended address of the XBee Sensor device you
        #                   would like to monitor.
        #
        # Advanced settings:
        #
        # None

        settings_list = [
                         
            Setting(
                name='lora_device_manager', type=str, required=True),
            Setting(
                name='extended_address', type=str, required=True),                         
                  
            Setting(
                name='log_level', type=str, required=False, default_value='DEBUG', verify_function=check_debug_level_setting),                  
          
            ]

        ## Channel Properties Definition:
        property_list = [
            # getable properties
            ChannelSourceDeviceProperty(name='software_version', type=str,
                initial=Sample(timestamp=digitime.time(), value=VERSION_NUMBER),
                perms_mask= DPROP_PERM_GET,
                options=DPROP_OPT_AUTOTIMESTAMP),
                         
            # setable properties
            ChannelSourceDeviceProperty(name='simulate_xbee_frame', type=str,
                initial=Sample(timestamp=0, value=''),
                perms_mask= DPROP_PERM_SET,
                options=DPROP_OPT_AUTOTIMESTAMP,
                set_cb=self._simulate_xbee_frame_cb),
            ChannelSourceDeviceProperty(name='command', type=str,
                initial=Sample(timestamp=0, value=''),
                perms_mask= DPROP_PERM_SET,
                options=DPROP_OPT_AUTOTIMESTAMP,
                set_cb=self._send_command_to_sensor_cb),                         
                         
         ]
        
        ## Initialize the DeviceBase interface:
        DeviceBase.__init__(self, self.__name, self.__core,
                                        settings_list, property_list)
コード例 #19
0
 def __print_statistics(self, channel, filter):
     """\
         Print SMS, Satellite and Iridium Statistics.
     """
     self.__tracer.info(
         "STAT: Channel %s (%s) SM %s (Total %d Last: %.0f Now: %.0f Next: %.0f)",
         channel, filter['filter'],
         filter['type'], filter['total_sent'], filter['last_sent'],
         digitime.time(), filter['last_sent'] + filter['interval'] * 60)
コード例 #20
0
 def __print_statistics(self, channel, filter):
     """\
         Print SMS, Satellite and Iridium Statistics.
     """
     self.__tracer.info("STAT: Channel %s (%s) SM %s (Total %d Last: %.0f Now: %.0f Next: %.0f)",
         channel, filter['filter'], filter['type'],
            filter['total_sent'], filter['last_sent'],
            digitime.time(),
            filter['last_sent'] + filter['interval'] * 60)
コード例 #21
0
ファイル: web.py プロジェクト: Lewiswight/4CT-GW--master
    def iso_date(self, t=None):

        # Optional argument 't' is a string with the date in seconds,
        # which defaults to the current time if not specified.

        if t is None:
            t = digitime.time()
        time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t))

        return time_str
コード例 #22
0
    def iso_date(self, t=None):

        # Optional argument 't' is a string with the date in seconds,
        # which defaults to the current time if not specified.

        if t is None:
            t = digitime.time()
        time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t))

        return time_str
コード例 #23
0
ファイル: xmlrpc.py プロジェクト: Lewiswight/4CT-GW--master
    def channel_set(self, channel_name,
                    timestamp, value, unit = "", autotimestamp = False):

        if autotimestamp:
            timestamp = digitime.time()
        channel = self.__cdb.channel_get(channel_name)
        try:
            sample = Sample(timestamp, channel.type()(value), unit)
        except Exception, e:
            raise Exception, "unable to coerce value '%s' to type '%s'" % \
                (value, repr(channel.type()))
コード例 #24
0
    def receive(self, channel):
        '''
        Store a sample from a given channel and possibly trigger upload.

        The channel argument is ignored (but is required by the
        notification mechanism).
        '''

        if not self.__enabled.isSet():
            TRACER.debug('self.__enabled.isSet is NOT set')
            return

        sam = channel.get()
        if not SettingsBase.get_setting(self, "upload_time_zero"):
            if sam.timestamp == 0:
                TRACER.debug('discard sample with null time')
                return

        # save the sample
        try:
            self.__entry_lock.acquire()
            self.__sample_count += 1
            prev = self.__upload_queue.get(channel.name(),
                                           (channel.type(), list()))
            prev[1].append(sam)
            self.__upload_queue[channel.name()] = prev

            mem_samples = self._samples_in_queue()
            # sync to disk?
            if mem_samples * SAMPLE_SIZE > MAX_SIZE:
                TRACER.info('flushing samples to disk due to memory ' \
                            'constraint')
                self._sync_to_disk()
            elif digitime.time() - self.__sample_sync > DISK_FLUSH:
                TRACER.info('flushing samples to disk due to time')
                self._sync_to_disk()
        finally:
            self.__entry_lock.release()

        sample_threshold = SettingsBase.get_setting(self, "sample_threshold")
        if sample_threshold > 0 and self.__sample_count >= sample_threshold:
            # It really doesn't matter that we set sample count to zero
            # here... self.__upload sets self.__sample_count back to zero.
            # We just don't want to repeatedly bang on the threshold event.
            try:
                self.__entry_lock.acquire()
                self.__sample_count = 0
            finally:
                self.__entry_lock.release()
            self.__threshold_event.set()
            self._tracer.debug("Reached threshold of %i, setting event flag",
                               sample_threshold)
コード例 #25
0
ファイル: web.py プロジェクト: Lewiswight/4CT-GW--master
 def set_channel(self, channel_name, value):
     try:
         cm = self.__core.get_service("channel_manager")
         cdb = cm.channel_database_get()
         channel = cdb.channel_get(channel_name)
         try:
             typing_value = channel.type()(value)
         except Exception:
             self.__tracer.debug(traceback.format_exc())
             return
         channel.consumer_set(Sample(digitime.time(), typing_value))
     except Exception:
         self.__tracer.debug(traceback.format_exc())
コード例 #26
0
 def set_channel(self, channel_name, value):
     try:
         cm = self.__core.get_service("channel_manager")
         cdb = cm.channel_database_get()
         channel = cdb.channel_get(channel_name)
         try:
             typing_value = channel.type()(value)
         except Exception:
             self.__tracer.debug(traceback.format_exc())
             return
         channel.consumer_set(Sample(digitime.time(), typing_value))
     except Exception:
         self.__tracer.debug(traceback.format_exc())
コード例 #27
0
    def message_indication(self, sensor, buf, addr=None):
        if SHOW_COMM:
            print "M300: message indication, len=%d, " % len(buf),
            for by in buf:
                print '%02X ' % ord(by),
            print

        self.__response_buffer += buf

        if len(self.__response_buffer) < 6:
            # We may need to just give the network a bit more time
            # but just in case, reschedule the retry event now:
            self.__reschedule_retry_watchdog()
            return

        bus_id = sensor.get_id_tag()
        dct = sensor.ind_status_3(buf)

        if dct.has_key('error'):
            # then we failed
            # Ick!  The RS-485 reply packets may not been packetized
            # in the proper sequence.  Flush the buffer.
            self.__response_buffer = ""
            print 'bad checksum'

        else:
            # Update our channels:
            now = digitime.time()

            if dct['target_detected']:
                # then perhaps no error

                self._tracer.info('ID:%d rng:%0.1fin, str:%d%% tmp:%0.1fC', \
                    bus_id, dct['range'], dct['strength'], dct['temperature'])

                self.property_set(self.make_chn_name_error(bus_id), \
                                  Sample(now, False))
                self.property_set(self.make_chn_name_strength(bus_id), \
                                  Sample(now, float(dct['strength']), "prc"))
                self.property_set(self.make_chn_name_error_flag(bus_id), \
                                  Sample(now, False))
                self.property_set(self.make_chn_name_range(bus_id), \
                                  Sample(now, dct['range'], "in"))
                self.property_set(self.make_chn_name_temperature(bus_id), \
                                  Sample(now, dct['temperature'], "C"))

            else:
                self._tracer.warning('ID:%d - no target detected', bus_id)

        return
コード例 #28
0
    def __init__(self, name, core_services):
        ## Initialize and declare class variables
        self.__name = name
        self.__core = core_services

        self.__logger = init_module_logger(name)

        ## Settings Table Definition:
        settings_list = [
            Setting(name='baudrate',
                    type=int,
                    required=False,
                    default_value=38400,
                    verify_function=lambda x: x > 0),
            Setting(name='port', type=str, required=False, default_value='11'),
            Setting(name='mainloop_serial_read_timeout',
                    type=int,
                    required=False,
                    default_value=30),
            Setting(name='log_level',
                    type=str,
                    required=False,
                    default_value='DEBUG',
                    verify_function=check_debug_level_setting),
        ]

        ## Channel Properties Definition:
        property_list = [
            ChannelSourceDeviceProperty(name='software_version',
                                        type=str,
                                        initial=Sample(
                                            timestamp=digitime.time(),
                                            value=VERSION_NUMBER),
                                        perms_mask=DPROP_PERM_GET,
                                        options=DPROP_OPT_AUTOTIMESTAMP),
            ChannelSourceDeviceProperty(name="LoRaPlugAndSenseFrame",
                                        type=str,
                                        initial=Sample(timestamp=0, value=''),
                                        perms_mask=DPROP_PERM_GET,
                                        options=DPROP_OPT_AUTOTIMESTAMP),
        ]

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

        ## Thread initialization:
        self.__stopevent = threading.Event()
        threading.Thread.__init__(self, name=name)
        threading.Thread.setDaemon(self, True)
コード例 #29
0
 def producer_set(self, sample):
     """
     Update the current sample object.
     
     This function should only be called by a DeviceProperties object.
     """
     sample = ChannelSource._type_remap_and_check(self, self.type, sample)
     self.__rlock.acquire()
     try:
         if sample.timestamp == 0 and self.options & DPROP_OPT_AUTOTIMESTAMP:
             sample.timestamp = digitime.time()
         self.__sample = copy(sample)
     finally:
         self.__rlock.release()
コード例 #30
0
    def _send_data_to_dia_channel(self, frame, addr):
              
        self._last_timestamp = digitime.time()
        io_sample=parser(decode_waspmote_frame(frame))
        
        self._logger.debug ('Found following information: %s' % str(io_sample))
          
        # route each information to its corresponding channel
        for key in io_sample.keys():
            
            if libelium_to_dia_map.has_key(key):
                channel_name, type_name, channel_unit = libelium_to_dia_map[key]
            else:
                # add this key to existing map for next loop
                                # use default values =>
                # ... the new channel has the information name
                channel_name = libelium_key_to_dia_channel_name (key)
                # ... type will be default
                type_name = str
                # ... unit will be none
                channel_unit = ''

                # extend the map (initialized in utils) with this new key                
                libelium_to_dia_map[key] = (channel_name, type_name, channel_unit)
                

            #verify the type of the value
            if type_name=='float':
                    sample_value=Convert_Str_Float(io_sample[key])
            elif type_name=='int':
                    sample_value=Convert_Str_Integer(io_sample[key])
            else:
                    sample_value=io_sample[key]
                    
            sample = Sample(self._last_timestamp, sample_value, channel_unit)
            
            #verify if the channel already exists. I not, create it. 
            if not self.property_exists(channel_name):
                # create the new channel
                self.add_property(
                   ChannelSourceDeviceProperty(channel_name,
                                               type=type(sample_value),
                                               initial=sample,
                                               perms_mask=DPROP_PERM_GET,
                                               options=DPROP_OPT_AUTOTIMESTAMP))
                self._logger.info ("Created channel \"%s\" for key \"%s\"" % (channel_name, key))
                
            # send the new sample
            self._logger.debug ('Put %s data to dia channel: %s' % (key, channel_name))
            self.property_set(channel_name, sample)                
コード例 #31
0
    def message_indication(self, sensor, buf, addr=None):
        if SHOW_COMM:
            print "M300: message indication, len=%d, " % len(buf),
            for by in buf:
                print '%02X ' % ord(by),
            print

        self.__response_buffer += buf

        if len(self.__response_buffer) < 6:
            # We may need to just give the network a bit more time
            # but just in case, reschedule the retry event now:
            self.__reschedule_retry_watchdog()
            return

        bus_id = sensor.get_id_tag()
        dct = sensor.ind_status_3(buf)

        if dct.has_key('error'):
            # then we failed
            # Ick!  The RS-485 reply packets may not been packetized
            # in the proper sequence.  Flush the buffer.
            self.__response_buffer = ""
            print 'bad checksum'

        else:
            # Update our channels:
            now = digitime.time()

            if dct['target_detected']:
                # then perhaps no error

                self._tracer.info('ID:%d rng:%0.1fin, str:%d%% tmp:%0.1fC', \
                    bus_id, dct['range'], dct['strength'], dct['temperature'])

                self.property_set(self.make_chn_name_error(bus_id), \
                                  Sample(now, False))
                self.property_set(self.make_chn_name_strength(bus_id), \
                                  Sample(now, float(dct['strength']), "prc"))
                self.property_set(self.make_chn_name_error_flag(bus_id), \
                                  Sample(now, False))
                self.property_set(self.make_chn_name_range(bus_id), \
                                  Sample(now, dct['range'], "in"))
                self.property_set(self.make_chn_name_temperature(bus_id), \
                                  Sample(now, dct['temperature'], "C"))

            else:
                self._tracer.warning('ID:%d - no target detected', bus_id)

        return
コード例 #32
0
 def producer_set(self, sample):
     """
     Update the current sample object.
     
     This function should only be called by a DeviceProperties object.
     """
     sample = ChannelSource._type_remap_and_check(self, self.type, sample)
     self.__rlock.acquire()
     try:
         if sample.timestamp == 0 and self.options & DPROP_OPT_AUTOTIMESTAMP:
             sample.timestamp = digitime.time()
         self.__sample = copy(sample)
     finally:
         self.__rlock.release()
コード例 #33
0
    def channel_set(self,
                    channel_name,
                    timestamp,
                    value,
                    unit="",
                    autotimestamp=False):

        if autotimestamp:
            timestamp = digitime.time()
        channel = self.__cdb.channel_get(channel_name)
        try:
            sample = Sample(timestamp, channel.type()(value), unit)
        except Exception, e:
            raise Exception, "unable to coerce value '%s' to type '%s'" % \
                (value, repr(channel.type()))
コード例 #34
0
    def send_message(self, client, message):
        """\
            Send a message from a Client out using Iridium.
        """
        current_time = digitime.time()
        count = 0

        # Walk the saved message queue, and remove any/all
        # messages that have gone past our expiry time/date.
        while self.__message_queue:
            item_time, item_data = self.__message_queue[0]
            if item_time + self.__message_queue_interval < current_time:
                item = heapq.heappop(self.__message_queue)
                iridium_manager_tracer.info("Removing old item! %s", item)
                del item
            else:
                break

        # Whenever we want to send a message, we need to verify that we don't
        # go past what the user specified as their maximum they are willing to
        # send in a given interval time frame.
        if len(self.__message_queue) >= self.__message_queue_max:
            iridium_manager_tracer.warning("Maximum messages per interval have been met.  " \
                  "Not sending: %s", message)
            return 0

        if isinstance(client, IridiumTransportClient):
            iridium_manager_tracer.info("Sending Digi Iridium message: %s",
                                        message)
            digi_iridium.send(message)
        elif isinstance(client, iDigiIridiumTransportClient):
            iridium_manager_tracer.info("Sending iDigi Iridium message: %s",
                                        message[0])
            count, handle = idigi_iridium.send_dia(message[0])

        # Store the packet we just sent.
        # We do this for 2 reasons.
        # 1) Keep track of how many we sent per interval.
        # 2) To ensure we got our packet ACK'ed.
        if isinstance(client, IridiumTransportClient):
            d = dict(packet=message, acked=False)
        elif isinstance(client, iDigiIridiumTransportClient):
            d = dict(packet=message[0], acked=False)

        item = [current_time, d]
        heapq.heappush(self.__message_queue, item)

        return count
コード例 #35
0
    def message_indication(self, buf):
        self._tracer.calls("message indication.")

        self.__response_buffer += buf

        if len(self.__response_buffer) < 6:
            # Response may have been fragmented, so wait for more pieces
            self._tracer.debug("Received incomplete data")
            return

        # we have our response, move state to IDLE
        self.__mode = self.MODE_IDLE

        dct = self.__sensor.ind_status_3(buf)
        if self._tracer.debug:
            self._tracer.debug('parsed ind: %s', str(dct))

        now = digitime.time()
        if dct.has_key('error'):
            # then the indication failed
            self.__response_buffer = ""

        else:
            # Update our channels:
            self.__rsp_cnt += 1
            self.property_set("strength", Sample(now, dct['strength'], "%"))
            self.property_set(
                "target_detected",
                Sample(now, Boolean(dct['target_detected'], STYLE_YESNO)))
            self.property_set(
                "error_flag",
                Sample(now, Boolean(dct['sensor_error'], STYLE_YESNO)))
            self.property_set("range", Sample(now, dct['range'], "in"))
            self.property_set("temperature",
                              Sample(now, dct['temperature'], "C"))

            if self._tracer.info:
                self._tracer.info("temp=%0.1fC range=%0.1fin strength=%d%%",
                                  dct['temperature'], dct['range'],
                                  dct['strength'])

        self.update_availability(now)
        return
コード例 #36
0
ファイル: xbee_dio.py プロジェクト: bernhara/DigiGateway4Raph
    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))
コード例 #37
0
def set(request):
    """auto-generated from set.pyhtml"""
    import sys, string, cStringIO
    py_code = cStringIO.StringIO()
    py_code.write("<script>\n")
    import digitime
    from samples.sample import Sample
    from common.types.boolean import Boolean
    import channels.channel_source_device_property as dev_props
    try:
        e = request["args"]['own']
        chan = request["cm"].channel_get(e[3:])
        val_type = chan.type()
        value = request["args"]["val"]
        if isinstance(value, Boolean) and not value:
            value = ""
        chan.consumer_set(Sample(digitime.time(), val_type(value)))
        if chan.perm_mask() & dev_props.DPROP_PERM_GET and not (
                chan.options_mask() & dev_props.DPROP_OPT_DONOTDUMPDATA):
            py_code.write("		$(\"")
            py_code.write(str(e))
            py_code.write("\").value = \"")
            py_code.write(str(chan.get().value))
            py_code.write("\";\n")
            py_code.write("		$(\"")
            py_code.write(str(e))
            py_code.write(".debug\").innerHTML = \"\";\n")
        else:
            py_code.write("		$(\"")
            py_code.write(str(e))
            py_code.write("\").value = \"\";\n")
    except Exception, detail:
        py_code.write("	$(\"")
        py_code.write(str(e))
        py_code.write("\").value = \"\";\n")
        if request["args"].has_key(
                "val") and not request["args"]["val"].split() == "":
            py_code.write("	   $(\"")
            py_code.write(str(e))
            py_code.write(".debug\").innerHTML = \"")
            py_code.write(str(detail))
            py_code.write("\";\n")
コード例 #38
0
    def message_indication(self, buf):
        self._tracer.calls("message indication.")

        self.__response_buffer += buf

        if len(self.__response_buffer) < 6:
            # Response may have been fragmented, so wait for more pieces
            self._tracer.debug("Received incomplete data")
            return

        # we have our response, move state to IDLE
        self.__mode = self.MODE_IDLE

        dct = self.__sensor.ind_status_3(buf)
        if self._tracer.debug:
            self._tracer.debug('parsed ind: %s', str(dct))
            
        now = digitime.time()
        if dct.has_key('error'):
            # then the indication failed
            self.__response_buffer = ""
            
        else:
            # Update our channels:
            self.__rsp_cnt += 1
            self.property_set("strength", 
                Sample(now, dct['strength'], "%"))
            self.property_set("target_detected",
                Sample(now, Boolean(dct['target_detected'], STYLE_YESNO)))
            self.property_set("error_flag",
                Sample(now, Boolean(dct['sensor_error'], STYLE_YESNO)))
            self.property_set("range", 
                Sample(now, dct['range'], "in"))
            self.property_set("temperature", 
                Sample(now, dct['temperature'], "C"))

            if self._tracer.info:
                self._tracer.info("temp=%0.1fC range=%0.1fin strength=%d%%",
                    dct['temperature'], dct['range'], dct['strength'])

        self.update_availability(now)
        return
コード例 #39
0
ファイル: xbee_rpm.py プロジェクト: bernhara/DigiGateway4Raph
    def prop_set_power_control(self, bool_sample):
        '''
        Set the power on the device and the power_on property.
        '''
        power_on = Boolean(bool_sample.value, style=STYLE_ONOFF)
        if power_on:
            ddo_io_value = POWER_ON
            self.__power_on_time = digitime.time()
        else:
            ddo_io_value = POWER_OFF

        try:
            self._xbee_manager.xbee_device_ddo_set_param(
                self._extended_address, 'D4', ddo_io_value, apply=True)
            self.property_set("power_on", Sample(0, str(power_on)))
            if self._tracer.info():
                self._tracer.info('Power going %r at %s', power_on,
                                  digitime.asctime())
        except:
            self._tracer.debug(traceback.format_exc())
コード例 #40
0
    def __init__(self, name=STATS_FILE):
        '''
        Create/load the backing file and load current values.
        '''

        self.file_name = create_full_path(name)
        self.creation_time = 0
        self.upload_attempts = 0
        self.successful_uploads = 0
        self.last_failure = 0
        self.last_success = 0
        self.file_number = 0
        self.files_list = []  # files that need to be pushed
        if os.path.exists(self.file_name):
            old_vals = open(self.file_name, 'r')
            self.load(old_vals)
            old_vals.close()

        # if this file is new, or the old creation time was corrupted...
        if self.creation_time == 0:
            self.creation_time = digitime.time()
コード例 #41
0
    def prop_set_led(self, led_name, sample):

        self._tracer.calls("XBeeXBIB.prop_set_led(%s, %s)", led_name, sample)

        now = digitime.time()

        ddo_io_value = 0  # I/O high impedance
        if sample.value:
            ddo_io_value = 4  # I/O sinking

        led_io = LED_IO_MAP[led_name]

        self._extended_address = SettingsBase.get_setting(self, "extended_address")

        # we want to allow the exception to propogate to the caller
        self._xbee_manager.xbee_device_ddo_set_param(
                                    self._extended_address, led_io, ddo_io_value,
                                    apply=True)
        val = Boolean(sample.value, style=STYLE_ONOFF)
        self.property_set(led_name, Sample(now, val))
        self._tracer.info('%s is now %r', led_name, val)
コード例 #42
0
ファイル: pyhtml.py プロジェクト: Lewiswight/4CT-GW--master
def set(request):
    """auto-generated from set.pyhtml"""
    import sys,string,cStringIO
    py_code=cStringIO.StringIO()
    py_code.write("<script>\n")
    import digitime
    from samples.sample import Sample
    from common.types.boolean import Boolean
    import channels.channel_source_device_property as dev_props
    try:
        e = request["args"]['own']
        chan = request["cm"].channel_get(e[3:])
        val_type = chan.type()
        value = request["args"]["val"]
        if isinstance(value,Boolean) and not value:
            value = ""
        chan.consumer_set(Sample(digitime.time(), val_type(value) ))
        if chan.perm_mask() & dev_props.DPROP_PERM_GET and not (chan.options_mask() & dev_props.DPROP_OPT_DONOTDUMPDATA):
            py_code.write("		$(\"")
            py_code.write(str(e))
            py_code.write("\").value = \"")
            py_code.write(str(chan.get().value))
            py_code.write("\";\n")
            py_code.write("		$(\"")
            py_code.write(str(e))
            py_code.write(".debug\").innerHTML = \"\";\n")
        else:
            py_code.write("		$(\"")
            py_code.write(str(e))
            py_code.write("\").value = \"\";\n")
    except Exception, detail:
        py_code.write("	$(\"")
        py_code.write(str(e))
        py_code.write("\").value = \"\";\n")
        if request["args"].has_key("val") and not request["args"]["val"].split()=="":
            py_code.write("	   $(\"")
            py_code.write(str(e))
            py_code.write(".debug\").innerHTML = \"")
            py_code.write(str(detail))
            py_code.write("\";\n")
コード例 #43
0
ファイル: xbee_rpm.py プロジェクト: Lewiswight/4CT-GW--master
    def prop_set_power_control(self, bool_sample):
        '''
        Set the power on the device and the power_on property.
        '''
        power_on = Boolean(bool_sample.value, style=STYLE_ONOFF)
        if power_on:
            ddo_io_value = POWER_ON
            self.__power_on_time = digitime.time()
        else:
            ddo_io_value = POWER_OFF

        extended_address = SettingsBase.get_setting(self, "extended_address")
        try:
            self.__xbee_manager.xbee_device_ddo_set_param(
                                    extended_address, 'D4', ddo_io_value,
                                    apply=True)
            self.property_set("power_on", Sample(0, str(power_on)))
            if self.__tracer.info():
                self.__tracer.info('Power going %r at %s', power_on,
                                    digitime.asctime())
        except:
            self.__tracer.debug(traceback.format_exc())
コード例 #44
0
    def start(self):
        """
        Starts the driver.
        Subscribes the driver to the channel_pattern.
        """
        self._tracer.calls("InfoDevice.start()")

        self._sched = self._core.get_service("scheduler")

        # this will be a singleton, perhaps None
        self.__nvstash = nvStash.get_instance_singleton()
        if self.__nvstash is None:
            self._tracer.debug("no NVRAM STASH active - all data is volatile.")
        else:
            self.__nvstash.load()

        self._last_timestamp = digitime.time()
        for tag in ("name", "version", "sitename", "comment", "tags"):
            x = str(SettingsBase.get_setting(self, tag))
            if tag in ("comment", "tags") and self.__nvstash is not None:
                # for these, over-write from NVSTASH is anything there
                nv = self.__nvstash.get('%s.%s' % (self._name, tag))
                if nv is not None:
                    x = nv

            if x is None or len(x) == 0:
                # then delete this channel
                self._tracer.debug("delete tag %s", tag)
                self.remove_one_property(tag)
            else:
                sam = Sample(self._last_timestamp, x, "")
                self._tracer.debug("initialize tag %s, val = %s", tag, x)
                self.property_set(tag, sam)
                self._tag_list.append(tag)

        # restart timer is appropriate, static refreshed above
        self.refresh_cb(refresh_static=False)

        return True
コード例 #45
0
ファイル: xbee_xbr.py プロジェクト: Lewiswight/4CT-GW--master
    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
コード例 #46
0
ファイル: xbee_xbr.py プロジェクト: bernhara/DigiGateway4Raph
    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
コード例 #47
0
    def _merge_cache(self, num_samples_in_memory):
        '''
        Returns an xml fragment consisting of <sample> elements.

        Must be called with __entry_lock!

        This also removes the cache file.
        '''
        mem_size = num_samples_in_memory * SAMPLE_SIZE
        max_sample_bytes_to_collect = MAX_UPLOAD_SIZE - mem_size
        try:
            self.__sample_sync = digitime.time()
            if not os.path.exists(BUFFER_NAME):
                return ''
            f = open(BUFFER_NAME)
            op_string = f.readline()

            # braindead check for good data
            if op_string.startswith('<sample'):
                retval = _read_last_bytes(f, max_sample_bytes_to_collect)
            else:
                TRACER.debug('Removed stale non-cache data file %s.' \
                             % BUFFER_NAME)
                retval = ''
            f.close()
            os.remove(BUFFER_NAME)
            return retval
        except Exception, e:
            TRACER.debug('problem merging cache... data may be lost\n' \
                         '(%s)' % (str(e)))
            try:
                f.close()
                os.remove(BUFFER_NAME)
                return ''
            except Exception, e2:
                TRACER.debug('problem with merge_cache cleanup: %s' \
                             % (str(e2)))
                return ''
コード例 #48
0
    def prop_set_led(self, led_name, sample):

        self._tracer.calls("XBeeXBIB.prop_set_led(%s, %s)", led_name, sample)

        now = digitime.time()

        ddo_io_value = 0  # I/O high impedance
        if sample.value:
            ddo_io_value = 4  # I/O sinking

        led_io = LED_IO_MAP[led_name]

        self._extended_address = SettingsBase.get_setting(
            self, "extended_address")

        # we want to allow the exception to propogate to the caller
        self._xbee_manager.xbee_device_ddo_set_param(self._extended_address,
                                                     led_io,
                                                     ddo_io_value,
                                                     apply=True)
        val = Boolean(sample.value, style=STYLE_ONOFF)
        self.property_set(led_name, Sample(now, val))
        self._tracer.info('%s is now %r', led_name, val)
コード例 #49
0
    def _trigger(self, rate):
        want_print = SettingsBase.get_setting(self, PROP_PRINTF)

        new_time = time.time()

        if abs(new_time - self.time_now) > rate + 10:
            # If time has jumped considerably between polls, the
            # wall time has jumped.  Best thing to do is just
            # re-target based on the new time
            self.__tracer.warning("System time jump, resetting")
            self._set_targets()

        self.time_now = new_time
        self.time_tup = time.localtime(self.time_now)
        self.sample = (self.time_now, tuple(self.time_tup))

        # Check target channels
        for tgt in channel_map.keys():
            if self.time_now >= self.targets[tgt]:
                if want_print == tgt:
                    self.print_time_is_now()
                self.property_set(tgt,
                                  Sample(self.time_now, self.sample, 'time'))
                self.targets[tgt] = self.time_now + channel_map[tgt]
コード例 #50
0
    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
コード例 #51
0
    def import_binary(self, buf):
        if self._trace: print "import_binary"

        # confirm the basic form of the packet
        if self._mbtcp:
            # confirm basic Modbus/TCP
            if len(buf) < 8:
                return { 'error':
                    'Error: Bad MB/TCP length, too short, was only %d bytes, need 8 or more' % \
                    len(buf) }
                    
            # check the sequence number
            if self.__last_seq != buf[:2]:
                return { 'error':
                    'Error: Bad MB/TCP seq no' }

            if buf[2:5] != '\x00\x00\x00':
                return { 'error':
                    'Error: Bad MB/TCP header zeros' }

            x = ord(buf[5])
            if x != (len(buf) - 6):
                return { 'error':
                    'Error: Bad MB/TCP header - len=%d does not match buffer len()=%d' % \
                        (x, (len(buf) - 6))}

            buf = buf[6:] # normalize to PDU only, remove header

        else:
            # confirm basic Modbus/RTU
            if len(buf) < 5:
                return { 'error':
                    'Error: Bad MB/RTU length, too short, was only %d bytes' % \
                    len(buf) }

            crcCalc = crc16.calcString(buf[:-2])
            crcRecv = ord(buf[-2]) + (ord(buf[-1]) * 256)

            if crcCalc != crcRecv:
                return { 'error':
                    'Error: Bad MB/RTU CRC16' }

            buf = buf[:-2] # normalize to PDU only, remove CRC16

        # we now have the response, which will be:
        # - an error/exception
        # - slave_id response
        # - reg response of 3 floats
        # - reg response of 26 floats

        x = ord(buf[0])
        if x != self._addr:
            return { 'error': 'Error: Bad Modbus Unit Id/Slave Address' }

        fnc = ord(buf[1])
        if fnc & 0x80:
            x = ord(buf[2])
            return { 'error': 'Error: Exception Response, code:%d' % x}

        # all of our good responses have byte-count in 3rd byte
        x = ord(buf[2])
        if x != (len(buf) - 3):
            return { 'error': 'Error: byte count of %d incorrect' % x}

        if fnc == 0x11:
            # then slave id response
            return self.import_slave_id(buf)

        elif fnc == 0x03:
            # then reg response
            self._last_timestamp = digitime.time()
            if self.__8035:
                return self.import_8035(buf)
            else:
                return self.import_8036(buf)

        else:
            return { 'error': 'Error: unexpected function code %d in response' % fnc }
コード例 #52
0
ファイル: idigi.py プロジェクト: Lewiswight/4CT-GW--master
    def __command_set_channel_data(self, data):
        """\
            Given a channel name, sets the specified data value on the channel.
            Returns the current information about the channel.
        """
        channel_name = ""
        for i in data:
            if i == '\0':
                break
            channel_name += i
        else:
            self.__tracer.warning("Ill-formed iDigi Set Channel Command." \
                                 "  Channel name not sent correctly.")
            return None

        data = data[len(channel_name) + 1:]
        self.__tracer.info("Set Channel name: %s", channel_name)

        value_type = struct.unpack("!c", data[0])[0]
        data = data[1:]
        self.__tracer.info("Set value type: %s", value_type)

        if value_type == '?':
            value = struct.unpack("!B", data[0:1])[0]
            value = bool(value)
            data = data[1:]
        elif value_type == 'i':
            value = struct.unpack("!i", data[0:4])[0]
            data = data[4:]
        elif value_type == 'f':
            value = struct.unpack("!f", data[0:4])[0]
            data = data[4:]
        elif value_type == 's':
            value = ""
            for i in data:
                if i == '\0':
                    break
                value += i
            else:
                self.__tracer.warning("Ill-formed iDigi Set Channel Command." \
                                     "  String value type not sent correctly.")
                return None
            data = data[len(value) + 1:]
        else:
            self.__tracer.warning("Ill-formed iDigi Set Channel Command." \
                                 "  Unknown value type.")
            return None

        self.__tracer.info("Set Value: %s", value)

        cm = self.__core.get_service("channel_manager")
        cdb = cm.channel_database_get()
        channel = cdb.channel_get(channel_name)

        sample = None
        try:
            sample = Sample(digitime.time(), channel.type()(value), "")
        except Exception, e:
            self.__tracer.error("iDigi Set Channel Command." \
                                 "  Unable to create sample.")
            return None
コード例 #53
0
ファイル: xbee_rpm.py プロジェクト: Lewiswight/4CT-GW--master
    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')
コード例 #54
0
    def run(self):
        """\
            The Run method.
        """
        # Create a shorthand list of our stored clients, along with any
        # stored messages we want to send to each client.
        client_message_list = []
        for client in self.client_list:
            e = dict(name = client.name(), client = client, message_list = [])
            client_message_list.append(e)

        wait_time = SHUTDOWN_WAIT
        while not self.__stopevent.isSet():
            try:

                #self.__tracer.info("ShortMessaging: Before sleeping of %d seconds", \
                #       wait_time)
                digitime.sleep(wait_time)
                #self.__tracer.info("ShortMessaging: After sleeping of %d seconds", \
                #       wait_time)

                current_time = digitime.time()

                # Walk through the queued up channels that have updates
                # waiting to be sent.

                #self.__tracer.info("ShortMessaging: Len of Watched List: %d", \
                #       len(self.__channels_being_watched))
                #for entry in self.__channels_being_watched:
                #    for filter in entry['filters']:
                #        self.__print_statistics(entry['channel'], filter)

                #self.__tracer. "ShortMessaging: Len of Coalesce List: %d", \
                #       len(self.__coalesce_list))
                #for entry in self.__coalesce_list:
                #    self.__print_statistics(entry['channel'], entry['filter'])

                for entry in copy.copy(self.__coalesce_list):
                    filter = entry['filter']
                    messages = entry['messages']
                    interval = filter['interval'] * 60
                    last = filter['last_sent']

                    # See if the time is up, and that we need to send
                    # a new update.
                    if (last + interval) < current_time:

                        self.__tracer.info("Past Time, Should Send!")

                        for message in messages:

                            # Find the correct client entry.
                            for client in client_message_list:
                                if message['client'] == client['name']:
                                    break
                            else:
                                self.__tracer.warning("Run: Unable to find " \
                                      "Client in Client List")
                                continue

                            # Add message to the list of messages we should
                            # send to this client.
                            client['message_list'].append(message['message'])

                            # Bump our filter's total sent value.
                            filter['total_sent'] += 1

                        # Bump our filter's last sent value to the current time
                        filter['last_sent'] = current_time

                        # Finally, remove entry from our list.
                        self.__coalesce_list.remove(entry)

                # Walk each client in our message list cache
                for client in client_message_list:

                    # Check to see if the client has any data that needs
                    # to be sent.
                    if len(client['message_list']) > 0:
                        ret = client['client'].send_message(client['message_list'])
                        if ret == False:
                            self.__tracer.error("Unable to send message!")

                        client['message_list'] = []

            except Exception, e:
                self.__tracer.error("exception while uploading: %s", str(e))
コード例 #55
0
    def __match_filter(self, channel):
        """\
            Given a full channel name, determine whether any of our
            patterns/filters matches against it.
            Returns the list of matched filters.
        """
        current_time = digitime.time()

        filters = []
        for update_type in [ "updates", "alarms" ]:

            # Get our updates and alarms list.
            #
            # Because of the way Dia requires defining a list in its
            # configuration file, the get_setting() call below will first
            # return this value in a dictionary with the actual updates and
            # alarms list stored under the key name of 'instance_list'.
            entry_list = SettingsBase.get_setting(self, update_type)

            # It's possible the user doesn't have any of the given type set up.
            # This is fine, and we should just continue to the next type.
            if len(entry_list) == 0:
                continue

            try:
                entry_list = entry_list['instance_list']
            except Exception, e:
                self.__tracer.error("Exception trying to get instance_list: %s", \
                       str(e))
                continue

            for entry in entry_list:

                if 'settings' not in entry or entry['settings'] == None:
                    continue

                settings = entry['settings']
                if 'filter' in settings:

                    # If this filter matches something we care about,
                    # add it to our list.
                    if wild_match(settings['filter'], channel) == True:
                        self.__tracer.info("Match (%s) Filter of %s and Dia channel name of %s", \
                                    update_type, settings['filter'], channel)
                        if update_type == "updates":
                            data = dict(type           = update_type,
                                        filter         = settings['filter'],
                                        clients        = settings['clients'],
                                        interval       = settings['interval'],
                                        condition      = None,
                                        synched        = False,
                                        total_sent     = 0,
                                        last_sent      = current_time)
                        else:
                            data = dict(type           = update_type,
                                        filter         = settings['filter'],
                                        clients        = settings['clients'],
                                        interval       = 0,
                                        condition      = settings['condition'],
                                        synched        = False,
                                        total_sent     = 0,
                                        last_sent       = 0.0)

                        filters.append(data)
コード例 #56
0
                                    str(e))

  



        xml2 = xml.getvalue()
        xml2 = xml2[:-1]
        xml2 = xml2 + "] }" 

        if new_sample_count > 0:
            self.__tracer.debug("Starting upload to iDigi")
            # Due to an NDS issue, clock may roll over, we'll just
            # keep track modulo 32-bit to allow for that.
            self.__last_upload_clock = int(digitime.real_clock()) & 0xffffffff
            self.__last_upload_time = digitime.time()

            success = self.__send_to_idigi(xml2)
            if success == True:
                self.__tracer.debug("Finished upload to iDigi")
            else:
                self.__tracer.debug("Upload failed to iDigi")
        else:
            self.__tracer.debug("No new Sample data to send to iDigi")

        xml.close()

    def __make_xml(self, channel_name, sample):
        
        
        data = "{"