def __make_xml(self, channel_name, sample, type_info): ''' Version 1.1 xml (first versioned version, can be parsed by Device Cloud's initial "compact" version parser) ''' upload_type = SettingsBase.get_setting(self, 'upload_type') real = not SettingsBase.get_setting(self, 'legacy_time_format') if upload_type: frame = '<sample name="%s" value="%s" unit="%s" type="%s" '\ 'timestamp="%s" />' args = [_escape_entities(y) for y in \ [str(x) for x in (channel_name, sample.value, sample.unit, _type_str(type_info), iso_date(sample.timestamp, real_iso=real))]] else: frame = '<sample name="%s" value="%s" unit="%s" timestamp="%s" />' args = [_escape_entities(y) for y in \ [str(x) for x in (channel_name, sample.value, sample.unit, iso_date(sample.timestamp, real_iso=real))]] return frame % tuple(args)
def __repr__(self): if self.channel == None: return "<%s record=%s (no channel)>" % ( self.__class__.__name__, repr(self.record)) if getattr(self.channel, "perm_mask", None) == None: return "<%s record=%s channel=%s (no permissions mask)>" % ( self.__class__.__name__, repr(self.record), self.channel.name()) perm_denied = not (self.channel.perm_mask() & PERM_GET) if not perm_denied: try: return ("<%s record=%s channel=%s " "sample.value=%s timestamp=%s>") % ( self.__class__.__name__, repr(self.record), self.channel.name(), repr(self.channel.get().value), iso_date(t=self.channel.get().timestamp)) except: perm_denied = True if perm_denied: return "<%s record=%s channel=%s (get permission denied)>" % ( self.__class__.__name__, repr(self.record), self.channel.name())
def __repr__(self): try: return '<Sample: "%s" "%s" at "%s">' % (self.value, self.unit, iso_date(self.timestamp)) except: return '<Sample: "%s" "%s" at "%s">' % (self.value, self.unit, self.timestamp)
def __make_compact_xml(self, channel_name, sample, type_info=None): ''' second DIA upload format (parsed by Device Cloud) ''' data = "<sample name=\"%s\" value=\"%s\" unit=\"%s\"" \ " timestamp=\"%s\" />" return data % (channel_name, _escape_entities( sample.value), sample.unit, iso_date(sample.timestamp))
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)
def announce_device(self): message_list = [] message = "Device %s now online at %s" % (self.__deviceid, iso_date(time.time())) message_list.append(message) self.__transport_obj.send_message(message_list)
def _marshal_sample(self, sample): """ Marshal a :class:`Sample` object for XML-RPC representation. Returns a dictionary suitable for processing by the :class:`SimpleXMLRPCRequestHandler` class. This is an internal method which special-cases the attributes of the :class:`Sample` object. Attributes on :class:`Sample` objects are type-mapped for representation in the following manner: * The internal type :class:`Boolean` will be mapped to its string value. * All other values shall be mapped to their string representation by calling the Python built-in :func:`repr` function. """ return_dict = { } for member in filter(lambda m: not m.startswith('__'), dir(sample)): # print 'xmlrpc member:', member return_dict[member] = getattr(sample, member) # attempt to marshall complex instance types to their string reps: try: if isinstance(return_dict[member], Boolean): return_dict[member] = bool(return_dict[member]) elif type(return_dict[member]) == types.InstanceType: return_dict[member] = repr(return_dict[member]) elif member == 'timestamp': return_dict[member] = iso_date(sample.timestamp) except: return_dict[member] = "unrepresentable object" return return_dict
def __make_xml(self, channel_name, sample): """ Converts a sample to XML. Returns String Keyword arguments: channel_name -- the name of the channel sample -- the corresponding sample """ data = ["<sample>"] data.append("<name>%s</name>" % channel_name) data.append("<value>%s</value>" % \ self.__escape_entities(sample.value)) data.append("<unit>%s</unit>" % sample.unit) data.append("<timestamp>%s</timestamp>" % iso_date(sample.timestamp)) try: if isinstance(sample,AnnotatedSample): # then add any annotated fields if sample.errors: data.append("<errors>%s</errors>" % str(sample.errors)) if sample.other: data.append("<other>%s</other>" % str(sample.other)) except: traceback.print_exc() pass data.append("</sample>") return "".join(data)
def __repr__(self): if self.channel == None: return "<%s record=%s (no channel)>" % (self.__class__.__name__, repr(self.record)) if getattr(self.channel, "perm_mask", None) == None: return "<%s record=%s channel=%s (no permissions mask)>" % ( self.__class__.__name__, repr( self.record), self.channel.name()) perm_denied = not (self.channel.perm_mask() & PERM_GET) if not perm_denied: try: return ("<%s record=%s channel=%s " "sample.value=%s timestamp=%s>") % ( self.__class__.__name__, repr(self.record), self.channel.name(), repr( self.channel.get().value), iso_date(t=self.channel.get().timestamp)) except: perm_denied = True if perm_denied: return "<%s record=%s channel=%s (get permission denied)>" % ( self.__class__.__name__, repr( self.record), self.channel.name())
def post_process(self, rsp, delta_clock): """Change the value of the new channel with the linked channel one.""" self.__tracer.debug(pccc_util.show_bytes('pccc_rsp', rsp)) #if self.__tracer.debug(): # st = '> Poll(%s) rsp in %0.3f secs' % (self.get_name(), delta_clock) # print_bytes( st, rsp ) # self.req = self._parent.mbus.cli_response_parse( rsp, self.req) now = time.time() now_st = iso_date(now) data = pccc_util.getData_SlcProtectedTypesLogicalRead( rsp) for parse in self.parse_list: try: sam = parse.process_read( data, now ) # self.__tracer.info('chn(%s) = %s', parse.get_name(),sam) except: self.__tracer.error('parse %s failed', parse.get_name()) self.__tracer.error(traceback.format_exc()) continue self.__set_parse_channel( parse, sam) self.__tracer.info(' chan:%s', str(parse.show_value(now_st))) if self._stats_chan is not None: if( delta_clock != 0): # then delta_clock 0 means time.clock() roll-over # update the CYCLE TIME stats if( (self.attrib[ self.TIME_MIN] <= 0) or (self.attrib[ self.TIME_MIN] > delta_clock) ): # then a NEW min_time self.attrib.update({ self.TIME_MIN:delta_clock }) if( (self.attrib[ self.TIME_MAX] <= 0) or (self.attrib[ self.TIME_MAX] < delta_clock) ): # then a NEW max_time self.attrib.update({ self.TIME_MAX:delta_clock }) if( self.attrib[ self.TIME_AVG] <= 0): # then first update of average avg = delta_clock else: avg = self.attrib[ self.TIME_AVG] * self.TIME_AVG_RATIO avg += delta_clock * (1.0 - self.TIME_AVG_RATIO) self.attrib.update({ self.TIME_AVG:avg }) self.__tracer.info('poll(%s) reqs:%d rsp_min:%0.2f avg:%0.2f max:%0.2f (in secs)', \ self.attrib['name'], self.attrib[ self.REQ_CNT],\ self.attrib[ self.TIME_MIN], \ self.attrib[ self.TIME_AVG], self.attrib[ self.TIME_MAX] ) else: # some error occured self.__tracer.error('clock roll-over') return
def __show_records(self, records_list, results=None): """ Print or write into a file the record list. """ if results != None: results.write('-' * 89 + '\r\n') results.write('| Date' + 16 * ' ' + '| Event' + 10 * ' ' + '| Channel' + 14 * ' ' + '| Value' + 9 * ' ' + '| Units' + 3 * ' ' + '|\r\n') results.write('-' * 89 + '\r\n') for record in records_list: ch_id = record.get_channel_id() results.write('| ' + iso_date (record.get_timestamp()).ljust(20) [0:20] + '| ' + str(EVENT_TYPE [record.get_event_type()]).ljust(15) [0:15] + '| ' + str(self.__logger_cdb.get_channel_name (ch_id)).ljust(21) [0:21] + '| ' + str(record.get_value()).ljust(14) [0:14] + '| ' + str(self.__logger_cdb.get_channel_units (ch_id)).ljust(8) [0:8] + '|\r\n') results.write('-' * 89 + '\r\n') else: self.write('-' * 79 + '\r\n') self.write('| Date' + 16 * ' ' + '| Event' + 10 * ' ' + '| Channel' + 14 * ' ' + '| Value' + 9 * ' ' + '|\r\n') self.write('-' * 79 + '\r\n') for record in records_list: ch_id = record.get_channel_id() self.write ('| ' + iso_date(record.get_timestamp()).ljust(20) [0:20] + '| ' + str(EVENT_TYPE[record.get_event_type()]).ljust(15) [0:15] + '| ' + str(self.__logger_cdb.get_channel_name (ch_id)).ljust(21) [0:21] + '| ' + str(record.get_value()).ljust(14) [0:14] + '|\r\n') self.write('-' * 79 + '\r\n')
def __make_xml(self, channel_name, sample): data = "<sample>" data += "<name>%s</name>" data += "<value>%s</value>" data += "<unit>%s</unit>" data += "<timestamp>%s</timestamp>" data += "</sample>" return data % (channel_name, self.__escape_entities(sample.value), sample.unit, iso_date(sample.timestamp))
def __make_xml(self, channel_name, sample): data = "<sample>" data += "<name>%s</name>" data += "<value>%s</value>" data += "<unit>%s</unit>" data += "<timestamp>%s</timestamp>" data += "</sample>" return data % (channel_name, self.__escape_entities( sample.value), sample.unit, iso_date(sample.timestamp))
def __make_xml(self, channel_name, sample): data = "<sample>" data += "<name>%s</name>" data += "<value>%s</value>" data += "<unit>%s</unit>" data += "<timestamp>%s</timestamp>" data += "</sample>" return data % (channel_name, self.__escape_entities(sample.value), sample.unit, iso_date(sample.timestamp))
def __make_full_xml(self, channel_name, sample, type_info=None): ''' initial DIA upload format ''' data = "<sample>" data += "<name>%s</name>" data += "<value>%s</value>" data += "<unit>%s</unit>" data += "<timestamp>%s</timestamp>" data += "</sample>" return data % (channel_name, _escape_entities( sample.value), sample.unit, iso_date(sample.timestamp))
def __make_compact_xml(self, channel_name, sample): """ Converts a sample to compact XML (using attributes instead of tags). Returns String Keyword arguments: channel_name -- the name of the channel sample -- the corresponding sample """ data = "<sample name=\"%s\" value=\"%s\" unit=\"%s\" timestamp=\"%s\" />" return data % (channel_name, self.__escape_entities(sample.value), sample.unit, iso_date(sample.timestamp))
def __create_message(self, message_format, channel): # Run through the message format string, substituting # out any of the magic values, specifically: # %c, %v, %u, %t, and %h message = "" escape = False for i in message_format: if escape == True and i == 'c': message += channel.name() escape = False elif escape == True and i == 'v': message += str(channel.get().value) escape = False elif escape == True and i == 'u': message += str(channel.get().unit) escape = False elif escape == True and i == 't': message += str(channel.get().timestamp) escape = False elif escape == True and i == 'h': message += iso_date(channel.get().timestamp) escape = False elif i == '%': # If we are already in escaped mode, then the previous # escape was not used. # Reinsert the previous escape into the stream, and keep # ourselves in escape mode for the next character. if escape == True: message += '%' escape = True else: # If we are in escaped mode, and we get an escape # character that we don't recognize, make sure # we put back the escape character into our stream. if escape == True: escape = False message += '%' message += i # If user had the last character as an escape character, # then we should reinsert said escape character into the # stream, as it is unused for our parsing. if escape == True: message += '%' return message
def __make_xml(self, channel_name, sample): """ Converts a sample to XML. Returns String Keyword arguments: channel_name -- the name of the channel sample -- the corresponding sample """ data = "<sample>" data += "<name>%s</name>" data += "<value>%s</value>" data += "<unit>%s</unit>" data += "<timestamp>%s</timestamp>" data += "</sample>" return data % (channel_name, self.__escape_entities(sample.value), sample.unit, iso_date(sample.timestamp))
def __make_xml(self, channel_name, sample): """ Converts a sample to XML. Returns String Keyword arguments: channel_name -- the name of the channel sample -- the corresponding sample """ data = "<sample>" data += "<name>%s</name>" data += "<value>%s</value>" data += "<unit>%s</unit>" data += "<timestamp>%s</timestamp>" data += "</sample>" return data % (channel_name, self.__escape_entities(sample.value), sample.unit, iso_date(sample.timestamp))
def __upload_data(self): """ Builds XML string of the channel state and pushes to iDigi """ data = self.__cache.lock_cache() # print 'data = (%s)' % str(data) if data is None: # then was left unlocked print "idigi_db(%s): sample cache is empty" % self.__name # self.__cache.unlock_cache() return None print "idigi_db: Uploading to iDigi" xml = cStringIO.StringIO() xml.write("<?xml version=\"1.0\"?>") if SettingsBase.get_setting(self, "compact_xml"): xml.write("<idigi_data compact=\"True\">") else: xml.write("<idigi_data>") xml.write(data) xml.write("</idigi_data>") self.__last_upload_time = time.time() self.statistics['upload_tries'] += 1 success = self.__send_to_idigi(xml.getvalue()) if success: # if successful, delete upload list else try again next time # self.__cache_upload = [] self.statistics['upload_good'] += 1 self.statistics.update({'last_upload':iso_date()}) self.__cache.free_cache() else: # failed, try again next time self.__cache.unlock_cache() xml.close() self.save_statistics() return
def do_channel_get(self, arg): try: args = parse_line(arg) except: self.write("invalid syntax.\r\n") return 0 if len(args) != 1: self.write("invalid argument(s) specified.\r\n") self.do_help("channel_get") return 0 channel_name = args[0] 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) value = "(value unavailable)" unit = "(unit unavailable)" time_str = "(time unavailable)" try: sample = channel.get() value = str(sample.value) unit = sample.unit time_str = iso_date(sample.timestamp) except: pass if '\n' in value: value = value.replace('\n', '\r\n') value = '\r\n' + value self.write("\t%s: %s (%s) @ %s\r\n" % (channel_name, value, unit, time_str)) return 0
def do_channel_get(self, arg): try: args = parse_line(arg) except: self.write("invalid syntax.\r\n") return 0 if len(args) != 1: self.write("invalid argument(s) specified.\r\n") self.do_help("channel_get") return 0 channel_name = args[0] 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) value = "(value unavailable)" unit = "(unit unavailable)" time_str = "(time unavailable)" try: sample = channel.get() value = str(sample.value) unit = sample.unit time_str = iso_date(sample.timestamp) except: pass if '\n' in value: value = value.replace('\n','\r\n') value = '\r\n' + value self.write("\t%s: %s (%s) @ %s\r\n" % (channel_name, value, unit, time_str)) return 0
def __repr__(self): return '<AnnotatedSample: "%s" "%s" "%s" "%s" at "%s">' % \ (self.value, self.unit, self.errors, self.other, iso_date(self.timestamp))
self.write("unable to set: %s\r\n" % (str(e))) self.__tracer.error("unable to set: %s", str(e)) self.__tracer.debug(traceback.format_exc()) return 0 value = "(value unavailable)" unit = "(unit unavailable)" time_str = "(time unavailable)" try: sample = channel.get() value = str(sample.value) if '\n' in value: value = value.replace('\n', '\r\n') value = '\r\n' + value unit = sample.unit time_str = iso_date(sample.timestamp) except: pass self.write("\t%s: %s (%s) @ %s\r\n" % (channel_name, value, unit, time_str)) return 0 def complete_channel_set(self, text, line, begidx, endidx): matches = [] arg_num = 1 sio = StringIO(line) shlexer = shlex.shlex(sio) arg_num = 1 while 1:
def __make_compact_xml(self, channel_name, sample): data = "<sample name=\"%s\" value=\"%s\" unit=\"%s\" timestamp=\"%s\" />" return data % (channel_name, self.__escape_entities(sample.value), sample.unit, iso_date(sample.timestamp))
def sample_indication(self, buf, addr): self.upCount += 1 if self.upCount < 30: return else: self.upCount == 0 self.property_set("last_com", Sample(time.time(), value=iso_date(self.current_time_get()), unit="")) 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") 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="0", unit="")) print "failed to get signal and voltage" 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 format_logging_events_iterator(log_event_iterator): """ Format a plain ASCII table, given a logging event iterator. Such iterators can be seen in channels/channel_database_interface.py. In order to conserve memory, this formatter operates as an iterator and returns a single line of text at a time. """ log_event_type_map = { LoggingEventNewSample: "Sample", LoggingEventChannelNew: "Channel+", LoggingEventChannelRemove: "Channel-", LoggingEventMeta: "Meta", } headings = ( ("Record #", len(repr(sys.maxint))), ("Type", max(map(lambda s: len(s), log_event_type_map.values()))), ("Channel Name", 24), ("Sample Val.", len(repr(sys.maxint))), ("Timestamp", 19), ) # Table header header_top = "" header_bot = "" field_fmt = "" for field in headings: header_top += ' ' header_top += field[0].ljust(field[1])[:field[1]] header_bot += ' ' header_bot += '-' * field[1] field_fmt += ' ' field_fmt += '%-' + str(field[1]) + '.' + str(field[1]) + 's' yield header_top yield header_bot for log_event in log_event_iterator: line = "" if log_event.channel is None: if isinstance(log_event, LoggingEventMeta): line = field_fmt % ( "%d" % log_event.record, log_event_type_map[log_event.__class__], log_event.description, "N/A", "N/A") else: # unsupported LoggingEvent line = field_fmt % ( "-1", "Unknown", "N/A", "Unknown event type: %s" % log_event.__class__.__name__, "N/A") elif log_event.channel.perm_mask() & PERM_GET: line = field_fmt % ( "%d" % log_event.record, log_event_type_map[log_event.__class__], log_event.channel.name(), repr(log_event.channel.get().value), iso_date(log_event.channel.get().timestamp)) else: line = field_fmt % ( "%d" % log_event.record, log_event_type_map[log_event.__class__], log_event.channel.name(), "(N/A)", iso_date(log_event.channel.get().timestamp)) yield line
self.write("unable to set: %s\r\n" % (str(e))) self.__tracer.error("unable to set: %s", str(e)) self.__tracer.debug(traceback.format_exc()) return 0 value = "(value unavailable)" unit = "(unit unavailable)" time_str = "(time unavailable)" try: sample = channel.get() value = sample.value if '\n' in value: value = value.replace('\n','\r\n') value = '\r\n' + value unit = sample.unit time_str = iso_date(sample.timestamp) except: pass self.write("\t%s: %s (%s) @ %s\r\n" % (channel_name, value, unit, time_str)) return 0 def complete_channel_set(self, text, line, begidx, endidx): matches = [] arg_num = 1 sio = StringIO(line) shlexer = shlex.shlex(sio) arg_num = 1
def __make_compact_xml(self, channel_name, sample): data = "<sample name=\"%s\" value=\"%s\" unit=\"%s\" timestamp=\"%s\" />" return data % (channel_name, self.__escape_entities( sample.value), sample.unit, iso_date(sample.timestamp))
def run(self): """run when our device driver thread is started""" while 1: if self.__stopevent.isSet(): self.__stopevent.clear() break # confirm we have a valid EIP_ENCAP session if not self.eipc.isOpen(): self._tracer.info("Try to open EIP Encap Session to %s:%d", \ self.eipc.getIp(), self.eipc.getPort()) if( self.eipc.OpenSession({}) == 0): # then error, clean up garbage, sleep to retry self._tracer.warning("EIP RegSes failed! Retry in 1 minute.") gc.collect() time.sleep(60.0) continue if not self.eipc.ping(): self._tracer.warning("EIP Session closed - will retry to open.") time.sleep(5.0) continue self.time_start = time.time() self.attrib.update({ 'error':False }) # self.time_tup = time.localtime(self.time_start) self._tracer.debug('Cyclic Process at %s', iso_date(self.time_start)) # we only update occassionally - don't do for every poll item self.round_floats = SettingsBase.get_setting(self, self.FP_ROUND) for poll in self.poll_list: # issue each poll # poll.show_value( ' >>%s', True) self.send_poll( poll) # self._tracer.info('poll_stats', poll.attrib) # save end of cycle - how long the process took self.time_end = time.time() # handle the global detect error in at least 1 block self.__update_stats_channel() rate = SettingsBase.get_setting(self, self.POLL_MINUTE) if( rate == 0): # then use the older cycle design, not clean-minute design real_rate = SettingsBase.get_setting(self, self.POLL_RATE) else: # else we use the 'clean minutes' algorithm real_rate = sleep_aids.secs_until_next_minute_period( rate, time.gmtime(self.time_end)) if real_rate < self.POLL_MIN: real_rate = self.POLL_MIN time.sleep(real_rate) # stopping - clean up try: self.sock.close() except: pass self.sock = None for poll in self.poll_list: poll.clear_links() self.poll_list = None return