def pre_start(self): """\ Do initial base class set up required before start, such as initialize self._xbee_manager and self._extended_address """ if self._xbee_manager is None: # then initialize things self._tracer.calls("XBeeBase.pre_start()") # Fetch the XBee Manager name from the Settings Manager: dm = self._core.get_service("device_driver_manager") self._xbee_manager = dm.instance_get( SettingsBase.get_setting(self, "xbee_device_manager")) # Register ourselves with the XBee Device Manager instance: self._xbee_manager.xbee_device_register(self) # Get the extended address of the device: self._extended_address = SettingsBase.get_setting(self, "extended_address") # Create a callback specification that calls back this driver when # our device has left the configuring state and has transitioned # to the running state: xbdm_running_event_spec = XBeeDeviceManagerRunningEventSpec() xbdm_running_event_spec.cb_set(self.running_indication) self._xbee_manager.xbee_device_event_spec_add(self, xbdm_running_event_spec) # else do nothing return
def make_request(self): success = True self._tracer.debug("make_request") extended_address = SettingsBase.get_setting(self, "extended_address") try: sample = self.__xbee_manager.xbee_device_ddo_get_param(extended_address, '1S') self.__decode_sample(sample) self._tracer.debug("Successfully retrieved and decoded sample.") except TypeError: success = False self._tracer.error("Device driver does not match with connected hardware.") pass except: success = False self._tracer.warning("Xmission failure, will retry.") pass # Schedule another heart beat poll, but only if we aren't in sleep mode. will_sleep = SettingsBase.get_setting(self, "sleep") if will_sleep != True: self.__schedule_request() self.__reschedule_retry_watchdog() return success
def apply_settings(self): SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): # There were problems with settings, terminate early: print "idigi_db (%s): Settings rejected/not found: %s %s" % \ (self.__name, rejected, not_found) return (accepted, rejected, not_found) # Verify that if we are on the Digi ConnectPort X3, that the user # doesn't have the secure option set to True. # If they do, we MUST bail here and also warn the user that the # Digi ConnectPort X3 cannot do secure/encrypted idigi connections. if accepted['secure'] == True and get_platform_name() == 'digix3': print "idigi_db (%s): The Digi ConnectPort X3 product cannot " \ "do secure/encrypted connections to the iDigi Server. " \ "Please set the 'secure' option to False!" % \ (self.__name) rejected['secure'] = accepted['secure'] del accepted['secure'] return (accepted, rejected, not_found) SettingsBase.commit_settings(self, accepted) # xbee_manager_name = SettingsBase.get_setting(self, "xbee_device_manager") dm = self.__core.get_service("device_driver_manager") self.__xbee_manager = dm.instance_get("xbee_device_manager") self.__last_upload_time = 0 self.repeat() return (accepted, rejected, not_found)
def run(self): #Get the device properties time_sleep = SettingsBase.get_setting(self,"update_rate") self.input_gpios = SettingsBase.get_setting(self,"input_gpios") self.output_gpios = SettingsBase.get_setting(self,"output_gpios") #Call the GPIOs initializer method self.initialize_gpios() #Start the refresh thread while 1: if self.__stopevent.isSet(): self.__stopevent.clear() break try: while self.setting_gpio: pass self.get_GPIOs() except Exception, e: self.__tracer.error("Unable to update values: %s", str(e)) #Sleep the time configured in settings (in seconds) digitime.sleep(time_sleep)
def run(self): while self.started_flag: msg = self.queue.get() if not self.started_flag: return host = SettingsBase.get_setting(self, 'server_address') port = SettingsBase.get_setting(self, 'port') frm = SettingsBase.get_setting(self, 'from_address') to = SettingsBase.get_setting(self, 'to_address') try: s = smtplib.SMTP(host, port) except Exception, e: self.__tracer.error("Failed to connect to SMTP server") self.__tracer.warning("If using a DNS name, " + \ "make sure the Digi device is configured" + \ " to use the correct DNS server") try: error_list = s.sendmail(frm, to, msg) except: self.__tracer.error("Failed to send messages, please double check server/port") else: for err in error_list: self.__tracer.error("Failed to send message to %s address", err) s.quit()
def apply_settings(self): SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): # there were problems with settings, terminate early: self.__tracer.error("Settings rejected/not found: %s %s", rejected, not_found) return (accepted, rejected, not_found) # Verify that the sample predelay time when added to the awake time # is not over 0xffff. if accepted['sample_predelay'] + accepted['awake_time_ms'] > 0xffff: self.__tracer.error("The awake_time_ms value (%d) " + "and sample_predelay value (%d) " + "when added together cannot exceed 65535.", self.__name, accepted['sample_predelay'], accepted['awake_time_ms']) rejected['awake_time_ms'] = accepted['awake_time_ms'] del accepted['awake_time_ms'] rejected['sample_predelay'] = accepted['sample_predelay'] del accepted['sample_predelay'] return (accepted, rejected, not_found) SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def conditional_settings_serializer_load(self, settings_filename="", suffix=""): """ Infer which serializer should be loaded and used. Parameters: * `settings_filename` - Filename to use to determine serializer * `suffix` - Suffix of filename used to determine serializer Only one of `settings_filename` or `suffix` need be specified """ if len(settings_filename): suffix = os.path.splitext(settings_filename)[1][1:] elif not len(suffix): raise CoreSettingsInvalidSerializer if suffix in [ 'yml', 'yaml' ]: from settings.settings_serializer_yaml import SettingsSerializerYaml SettingsBase.register_serializer(self, "yaml", SettingsSerializerYaml()) self.__serializer_ext_map["yaml"] = "yml" return 'yaml' if suffix == 'pyr': from settings.settings_serializer_py import SettingsSerializerPy SettingsBase.register_serializer(self, 'pyr', SettingsSerializerPy()) self.__serializer_ext_map['pyr'] = 'pyr' return 'pyr' else: raise CoreSettingsInvalidSerializer( "unsupported serializer '%s'" % suffix )
def start(self): # If the use_default_httpserver setting is specified, # the presentation will start own http server on the specified port. isDefault = SettingsBase.get_setting(self, 'use_default_httpserver') if not globals().has_key('Callback'): isDefault = False if isDefault: self._cb_handle = Callback(self.cb) self.__tracer.info("using web page %s and" " using digiweb", self.get_page()) else: self._cb_handle = self.get_channels try: port = SettingsBase.get_setting(self, 'port') self.__tracer.info("using port %d and BaseHTTPServer", port) HTTPServer.__init__(self, ('', port), WebRequestHandler) except Exception: self.__tracer.debug(traceback.format_exc()) self.socket.close() # Only start a thread if the Python web-server is # used: threading.Thread.start(self)
def running_indication(self): # request initial status here. self.__tracer.info("Running indication") extended_address = SettingsBase.get_setting(self, "extended_address") humidity_present = SettingsBase.get_setting(self, "humidity_present") # this is a flawed design - if the gateway has just rebooted, # and the Xbee sensor sleeps (which it should), then an actual # GET_DDO will be issued, which causes Dia to freeze here and # almost certainly throw exception and put the device off line. try: dd_value = self.__xbee_manager.xbee_device_ddo_get_param( extended_address, 'DD', use_cache=True) except: self.__tracer.warning('Using default DD') dd_value = 0x0003000E module_id, product_id = parse_dd(dd_value) self.__tracer.info('DD info (module_id, product_id) = ' + '(0x%04x, 0x%04x)"', module_id, product_id) if product_id == PROD_DIGI_XB_SENSOR_LTH or humidity_present == True: self.__tracer.info("Sensor is a '%s' adding humidity channel", product_name(product_id)) self.add_property( ChannelSourceDeviceProperty(name="humidity", type=float, initial=Sample(timestamp=0, value=0.0, unit="%"), perms_mask=DPROP_PERM_GET, options=DPROP_OPT_AUTOTIMESTAMP)) else: self.__tracer.info("Sensor is a '%s' no humidity capability.", product_name(product_id))
def apply_settings(self): SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): # there were problems with settings, terminate early: self.__tracer.error("Settings rejected/not found: %s %s", rejected, not_found) return (accepted, rejected, not_found) # Walk each setting, and verify the physical channel type # is the same type the user specified in their config. for setting in accepted.copy(): if setting[0:7] == "channel": try: channel = setting[7] operation = setting[9:] type = digihw.get_channel_type(int(channel) - 1) if type == self.IO_TYPE_ANALOG: if operation != "mode": raise ValueError, "Channel mode is not correct" elif type == self.IO_TYPE_DIGITAL: if operation != "dir" and operation != "source": raise ValueError, "Channel mode is not correct" else: raise ValueError, "Channel mode is not correct" except Exception, e: self.__tracer.error("Unable to parse settings: %s", e) rejected[setting] = accepted[setting] del accepted[setting]
def run(self): """run when our device driver thread is started""" ip = SettingsBase.get_setting(self, "server_ip") port = int(SettingsBase.get_setting(self, "server_port")) server = 'wsgiref' run_itty(server, ip, port)
def run(self): type = SettingsBase.get_setting(self, "type") if type == "serial": from presentations.console.console_serial_server import \ ConsoleSerialServer server = ConsoleSerialServer( SettingsBase.get_setting(self, "device"), SettingsBase.get_setting(self, "baudrate"), self.__core, self.__stopevent ) else: server = ConsoleTcpServer(('', SettingsBase.get_setting(self, "port")), ConsoleTcpRequestHandler, self.__core, self.__stopevent) while 1: if self.__stopevent.isSet(): break if isinstance(server, ConsoleTcpServer): r, w, e = select([server.socket], [], [], 1.0) else: r = True # Serial ports are always ready if r: # Spawns a thread for TCP, blocks for Serial server.handle_request() while hasattr(server, "handlers") and len(server.handlers): # Wait for handlers to exit time.sleep(1.0)
def apply_settings(self): """\ Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ try: if not threading.Thread.isAlive(self): return except: return if 'update_rate' in accepted and \ accepted['update_rate'] > SHUTDOWN_WAIT: self.__tracer.warning('Long update_rate setting may ' + 'interfere with shutdown of Dia.') SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def start_post(self): self._tracer.debug("RobustXBee:Start_Post") hb = SettingsBase.get_setting(self, "heart_beat_sec") if (hb is not None) and (hb > 0): # then enable the periodic intake of data productions self.__xbee_manager.register_sample_listener(self, self.get_extended_address(), self._heart_beat_indication) hb = SettingsBase.get_setting(self, "heart_beat_io") if (hb is not None) and (len(hb) > 0): # then set a dummy IO to input, but only if HeartBeat active cfg = self.get_ddo_block() cfg.add_parameter(hb, 3) self.get_xbee_manager().xbee_device_config_block_add( self, cfg) else: # no heart_beat try: # remove the availability channel self.remove_one_property(self.RXBEE_DEF_AVAIL_CHAN) # remove the online channel self.remove_one_property(self.HB_STATUS_CHAN) except: pass # Indicate that we have no more configuration to add: self.get_xbee_manager().xbee_device_configure(self) return RobustBase.start_post(self)
def start(self): """Start the device driver. Returns bool.""" cm = self.__core.get_service("channel_manager") cp = cm.channel_publisher_get() cdb = cm.channel_database_get() left_channel_name = SettingsBase.get_setting(self, LEFT_VOLUME_CHANNEL) left_channel = cdb.channel_get(left_channel_name) right_channel_name = SettingsBase.get_setting(self, RIGHT_VOLUME_CHANNEL) right_channel = cdb.channel_get(right_channel_name) # Determine initial state: if left_channel.get().value >= right_channel.get().value: print "INIT LEFT: volume is %f" % (left_channel.get().value) self.__state = STATE_PUMP_OUT_LEFT self.property_set("left_pump_on", Sample(0, Boolean(True, STYLE_ONOFF))) else: print "INIT RIGHT: volume is %f" % (right_channel.get().value) self.__state = STATE_PUMP_OUT_RIGHT self.property_set("right_pump_on", Sample(0, Boolean(True, STYLE_ONOFF))) # Perform channel subscriptions: cp.subscribe(left_channel_name, lambda chan: self.tank_volume_update(chan, LEFT_VOLUME_CHANNEL)) cp.subscribe(right_channel_name, lambda chan: self.tank_volume_update(chan, RIGHT_VOLUME_CHANNEL)) return True
def __init__(self, name, core_services, settings, properties): self._name = name self._core = core_services self._tracer = get_tracer(name) # Initialize settings: ## Settings Table Definition: settings_list = [ Setting( name='trace', type=str, required=False, default_value=self.DEF_TRACE), ] # Add our settings_list entries into the settings passed to us. settings = self.merge_settings(settings, settings_list) self.__settings = settings SettingsBase.__init__(self, binding=("devices", (name,), "settings"), setting_defs=settings) # Initialize properties: self.__properties = { } for property in properties: self.add_property(property) # pre_start - check if special trace level requested trace = SettingsBase.get_setting(self, "trace") try: self._tracer.set_level(trace) except: self._tracer.warning("Ignoring bad trace level \'%s\' for this device", trace) self._tracer.calls("DeviceBase.__init__()")
def start(self): """Start the device driver. Returns bool.""" RobustBase.start_pre(self) # copy the Modbus Unit ID (slave id) to our Veris H8036 object x = SettingsBase.get_setting(self, "unit_id") self._my_tracer.debug("Setting Modbus Unit-ID:%d ", x) self._H8036.set_ModbusAddress(x) # create the Dia channels x = SettingsBase.get_setting(self, "channels") self._my_tracer.debug("Setting H8036 Mode:%s ", x) self._H8036.enable_channels(x) nam_list = self._H8036.get_channel_name_list() for nam in nam_list: self._my_tracer.debug("Adding Channel:%s ", nam) self.add_property( ChannelSourceDeviceProperty(name=nam, type=float, initial=Sample(0, 0.0, 'not init'), perms_mask=DPROP_PERM_GET, options=DPROP_OPT_AUTOTIMESTAMP)) RobustBase.start_post(self) return True
def __init__(self, settings_flo, settings_filename): # Provides self.settings and serialization: settings_list = [ Setting( name='devices', type=list, required=False, default_value=[]), Setting( name='loggers', type=list, required=False, default_value=[]), Setting( name='presentations', type=list, required=False, default_value=[]), Setting( name='services', type=list, required=False, default_value=[]), Setting( name='tracing', type=list, required=False, default_value=[]), ] SettingsBase.__init__(self, binding=(), setting_defs=settings_list) self.__settings_filename = settings_filename self.__service_map = {} self.__serializer_ext_map = {} self.__sleep_req = None # STUB: seconds to wait before power-off self.__shutdown_event = threading.Event() # TODO: core may become a thread so we can monitor services and # attempt to restart them when they fail. try: self.epoch(settings_flo) except KeyboardInterrupt: # pragma: no cover raise KeyboardInterrupt except CoreSettingsException: print "Core: Initial settings invalid, aborting start up..." sys.exit() except: print "Core: Fatal exception caught! Halting execution." self.request_shutdown()
def start(self): # Fetch the XBee Manager name from the Settings Manager: xbee_manager_name = SettingsBase.get_setting(self, "xbee_device_manager") dm = self.__core.get_service("device_driver_manager") self.__xbee_manager = dm.instance_get(xbee_manager_name) # Register ourselves with the XBee Device Manager instance: self.__xbee_manager.xbee_device_register(self) # Get the extended address of the device: extended_address = SettingsBase.get_setting(self, "extended_address") #register a callback for when the config is done xb_rdy_state_spec = XBeeDeviceManagerRunningEventSpec() xb_rdy_state_spec.cb_set(self._config_done_cb) self.__xbee_manager.xbee_device_event_spec_add(self, xb_rdy_state_spec) # Create a DDO configuration block for this device: xbee_ddo_cfg = XBeeConfigBlockDDO(extended_address) # Call the XBeeSerial function to add the initial set up of our device. # This will set up the destination address of the devidce, and also set # the default baud rate, parity, stop bits and flow control. XBeeSerial.initialize_xbee_serial(self, xbee_ddo_cfg) # Register this configuration block with the XBee Device Manager: self.__xbee_manager.xbee_device_config_block_add(self, xbee_ddo_cfg) # Indicate that we have no more configuration to add: self.__xbee_manager.xbee_device_configure(self) return True
def __send_to_idigi(self, data): """ Sends data to iDigi Keyword arguments: data - the XML string to send """ filename = SettingsBase.get_setting(self, "filename") filename_format = SettingsBase.get_setting(self, "filename_format") filename = filename_format % (filename, self.__current_file_number) collection = SettingsBase.get_setting(self, "collection") secure = SettingsBase.get_setting(self, "secure") print "idigi_upload: Uploading %s to iDigi" % filename success, err, errmsg = idigi_data.send_idigi_data(data, filename, collection, secure) if not success: # if successful, delete upload list else try again next time print "idigi_db: Uploading ERROR %s (%s)" % (err,errmsg) self.__current_file_number += 1 max_files = SettingsBase.get_setting(self, "file_count") if self.__current_file_number >= max_files + 1: self.__current_file_number = 1 return success
def receive(self, channel): """ Called whenever there is a new sample Keyword arguments: channel -- the channel with the new sample """ # we always cache if SettingsBase.get_setting(self, "compact_xml"): sam = self.__make_compact_xml(channel.name(),channel.get()) else: sam = self.__make_xml(channel.name(),channel.get()) self.__cache.append(sam) self.__sample_count += 1 print '%s:%d cache:%s' % (self.__name, self.__sample_count, sam) # If we have exceeded the sample threshold, notify the thread # responsible for pushing up data if self.__sample_count >= SettingsBase.get_setting(self, "sample_threshold"): # print "idigi_db: Reached threshold of %i, setting event flag" % sample_threshold self.__threshold_event.set() return
def load_settings(self, settings_filename, settings_flo=None): """ Load settings from `settings_filename`. If the optional parameter `setting_flo` is specified, that file-like object will be used as the source of settings data. `settings_filename` is always used in order to infer the settings serializer used to interpret the settings as given by a extension-to-type mapping table defined as a constant in the core service. """ serializer_name = self.conditional_settings_serializer_load( settings_filename=settings_filename) if not settings_flo: if not os.path.exists(settings_filename): raise CoreSettingsFileNotFound try: settings_flo = open(settings_filename, 'r') except: raise CoreSettingsFileNotFound try: SettingsBase.load(self, settings_flo, serializer_name) except Exception, e: try: print "Core: Unable to load settings: %s" % (str(e)) except: print "Core: Unable to load settings: reason unavailable" raise CoreSettingsException
def run(self): """Worker thread for the TCPCSV client.""" state = STATE_NOTCONNECTED sd = None while not self.__stopevent.isSet(): if state == STATE_NOTCONNECTED: server = SettingsBase.get_setting(self, "server") port = SettingsBase.get_setting(self, "port") sd = socket(AF_INET, SOCK_STREAM) try: sd.connect((server, port)) except Exception, e: print "TCPCSV(%s): error connecting to %s:%d: %s" % \ (self.__name, server, port, str(e)) time.sleep(RECONNECT_DELAY) continue state = STATE_CONNECTED if state == STATE_CONNECTED: sio = StringIO() self._write_channels(sio) try: sd.sendall(sio.getvalue()) except: try: sd.close() except: pass state = STATE_NOTCONNECTED continue del(sio) time.sleep(SettingsBase.get_setting(self, "interval"))
def start(self): """Start the device driver. Returns bool.""" ECM1240_Xbee.start(self) if self._import_settings(): self.apply_settings() logger_id = SettingsBase.get_setting(self, 'sunspec_lid') if (logger_id is None) or (logger_id.lower == 'none'): self._ecm._lid = None self._lid_ns = None #elif logger_id.lower is in ['mac', 'auto']: # self._ecm._lid = None # self._lid_ns = 'mac' else: self._ecm._lid = logger_id self._lid_ns = 'mac' format = SettingsBase.get_setting(self, 'sunspec_format').lower() if format in ECM1240_SunSpec.XML_FORM_LIST: self._ecm._xml_form = format self.__tracer.debug('%s: Selecting XML format "%s".', self.__showname, format) else: self.__tracer.error('%s: Unknown XML format "%s".', self.__showname, format) self._ecm._single_channel = SettingsBase.get_setting(self, 'single_channel') if self._ecm._single_channel: self.__tracer.debug('%s: Forcing Single Channel Mode', self.__showname) return True
def start(self): """Start the device driver. Returns bool.""" self.__tracer.info("Starting device") # force desired fixed parameters into our base/parent devices RobustXSerial.start_pre(self) # match our private tracer to Robust_Base's family one self.__tracer.level = self._tracer.level ## Remove the statistic channels if NOT desired # why add, then remove? Otherwise they don't exist at # start-up for subscription by other devices/presentations if not SettingsBase.get_setting(self, "add_statistics"): self.__tracer.info("Statistic Channels are disabled.") self.remove_list_of_properties( ["co2_stats", "hum_stats", "tmp_stats"]) self.__co2_stats = None self.__hum_stats = None self.__tmp_stats = None ## Force a default IA Modbus config if none # 'enabling' really only enables this config check if SettingsBase.get_setting(self, "enable_modbus"): try: if rci_modbus.rci_test_for_ia_table(): self.__tracer.info("Detected existing Modbus IA Config.") else: if rci_modbus.rci_create_ia_table_mbdia(): self.__tracer.info("Created new Modbus IA Config.") else: self.__tracer.error("Modbus IA Config creation FAILED.") except: self.__tracer.debug(traceback.format_exc()) self.__tracer.error('Modbus IA Config creation FAILED!') self.__three_command = SettingsBase.get_setting(self, "three_commands") # Create a DDO configuration block for this device: xbee_ddo_cfg = self.get_ddo_block() # enable/disable the LED statistics channels if SettingsBase.get_setting(self, "disable_led"): # disable by setting DIO-10 (p0) to 5/dig-out high xbee_ddo_cfg.add_parameter('P0', 5) else: # enable by setting DIO-10 (p0) to 1/RSSI/PWM xbee_ddo_cfg.add_parameter('P0', 1) # Register configuration blocks with the XBee Device Manager: self.get_xbee_manager().xbee_device_config_block_add(self, xbee_ddo_cfg) RobustXSerial.start_post(self) # force garbage collection in case we deleted big things gc.collect() return True
def apply_settings(self): """\ Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): print "TimingService(%s) Settings rejected/not found: %s %s" % ( self.__name, rejected, not_found) SettingsBase.commit_settings(self, accepted) # Tear down and rebuild annotation system, this does mean that # reconfiguration will cause a window where stale data will # not be reported at the time where it technically becomes # stale under either configuration necessarily. self._destroy_timers() self._create_timers() self._enroll_channel_sources() return (accepted, rejected, not_found)
def repeat(self): if self.started == False: time.sleep(60) interval = SettingsBase.get_setting(self, "interval") if self.__event_timer is not None: try: self.__xbee_manager.xbee_device_schedule_cancel( self.__event_timer) except: pass self.__event_timer = self.__xbee_manager.xbee_device_schedule_after( SettingsBase.get_setting(self, "interval"), self.repeat) try: self.__upload_data() self.connected = 0 except: self.connected += 1 print "error in sending from repeat function"
def apply_settings(self): SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) # verify exclusive issues if(accepted['poll_clean_minutes'] > 0): # then we have exclusive issues to settle if(accepted['sleep']): # cannot sleep with clean_minutes active print "XBeeWatchport: 'sleep' cannot be True if poll_clean_minutes is used." rejected['sleep'] = accepted['sleep'] del accepted['sleep'] # over-ride / force sample_rate to match clean_minutes accepted['sample_rate_ms'] = \ accepted['poll_clean_minutes'] * 60000 if len(rejected) or len(not_found): # there were problems with settings, terminate early: print "Settings rejected/not found: %s %s" % (rejected, not_found) return (accepted, rejected, not_found) SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def start_pre(self): """\ Start the device driver. """ self._tracer.debug("RobustXBee:Start_Pre") # suppress the Robust_Device start of polling until XBee config is done self._start_polling = False RobustBase.start_pre(self) # Fetch the XBee Manager name from the Settings Manager: xbee_manager_name = SettingsBase.get_setting(self, "xbee_device_manager") dm = self.get_core().get_service("device_driver_manager") self.__xbee_manager = dm.instance_get(xbee_manager_name) # Register ourselves with the XBee Device Manager instance: self.__xbee_manager.xbee_device_register(self) # Get the extended address of the device: self.__extended_address = SettingsBase.get_setting(self, "extended_address") # Create a callback to tell this driver when our device has left the # configuring state, transitioning to the running state x = XBeeDeviceManagerRunningEventSpec() x.cb_set(self.running_indication) self.__xbee_manager.xbee_device_event_spec_add(self, x) self.initialize_robust_xbee() return True
def run(self): """run when our device driver thread is started""" self.sd = None '''/ import serial self.sd = serial.Serial( 0, #port number baudrate=115200, #baudrate bytesize=serial.EIGHTBITS, #number of databits parity=serial.PARITY_NONE, #enable parity checking stopbits=serial.STOPBITS_ONE, #number of stopbits timeout=3, #set a timeout value xonxoff=0, #enable software flow control rtscts=0, #enable RTS/CTS flow control ) ''' try: fd = None fd = open(path + 'id_secret_token.txt', 'r+') id = fd.readline() secret = fd.readline() token = fd.readline() fd.close() self.hvconn = HealthVaultConn(path, id, secret, token) except: traceback.print_exc() if fd != None: fd.close() self.hvconn = None ip = SettingsBase.get_setting(self, "server_ip") port = int(SettingsBase.get_setting(self, "server_port")) server = 'wsgiref' run_itty(server, ip, port)
def apply_settings(self): """ Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): self._tracer.error("Settings rejected/not found: %s %s", rejected, not_found) SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def __init__(self, core, settings_binding, additional_settings=None): """ Creates a new :class:`AbstractServiceManager` instance. `core` must be a reference to the core service manager (see :mod:`~src.core.core_services`). `settings_binding` must be a valid settings binding tuple. This determines at what point in the settings registry the service will locate and receive its settings. If we wished to create a service manager which received its settings in a binding off the registry root called "devices" the `settings_binding` would be given as a one element tuple ('devices',). `additional_settings` is a list of :class:`Setting` objects which define additional settings, aside from the implied instance list that all :class:`AbstractServiceManager` instances have. """ if additional_settings == None: additional_settings = [] # Core reference: self._core = core # Maps instance name (str) -> service instance (object) self._name_instance_map = {} # Maps service name (str) -> service instance (object) self._loaded_services = {} from core.tracing import get_tracer self.__tracer = get_tracer('AbstractServiceManager') # Initialize settings infrastructure: settings_list = [ Setting(name='instance_list', type=list, required=False, default_value=[]), ] settings_list.extend(additional_settings) SettingsBase.__init__(self, binding=settings_binding, setting_defs=settings_list)
def apply_settings(self): """ Apply new settings on this abstract service manager instance. This function is called by the settings sub-system when there are new settings available. This method may be overridden. The default implementation accepts all settings and then calls the local private function self._reenumerate_services() in order to start new services. Changes in settings are then committed to the settings running registry. """ SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) self._reenumerate_services() SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def create_filter_channel(self, source_channel, filter_channel): """\ Required override of the base channel's call of the same name. This allows us create/build a custom class to control the filter. Keyword arguments: source_channel -- the channel we are shadowing filter_channel -- the shadow/filter channel """ threshold = SettingsBase.get_setting(self, "threshold") readings = SettingsBase.get_setting(self, "readings") continuous = SettingsBase.get_setting(self, "continuous") return ThresholdBoolAlarm(self._name, self._core, source_channel, filter_channel, threshold, readings, continuous)
def log_page(self, type, path, headers, args): """Prepares the HTML log page. """ refresh_rate = SettingsBase.get_setting(self, 'refresh_rate') log = self.format_log() my_html = """<HTML><HEAD><TITLE>Gateway Log File</TITLE><META http-equiv="refresh" content="%d"> <STYLE TYPE="text/css">div.DEBUG{color:C0C0C0}div.INFO{color:0000FF}div.WARNING{color:FFFF00} div.ERROR{color:FFA500}div.CRITICAL{color:FF0000}</STYLE></HEAD> <BODY><H1>Log Info</H1><P>%s</P></BODY></HTML>""" % (refresh_rate, log) return (digiweb.TextHtml, my_html)
def get_eoln(self): eoln = SettingsBase.get_setting(self, "eoln") if eoln is None: return None if eoln != self.__eoln_save: # cache result to avoid repeat processing of escapes self.__eoln_save = eoln self._eoln = strip_escapes(eoln) return self._eoln
def next_poll_cycle(self): self.__poll_event = None manual = SettingsBase.get_setting(self, "manual_trigger") for sensor in self.__sensor_list: # repeat for each ID tag (or node) id = sensor.get_id_tag() self._tracer.debug("%s: poll sensor ID tag %d", self.showname, id) if manual: # then issue the manual software poll req = sensor.req_software_trigger_1() try: self.write(req) if SHOW_COMM: print "M300: send MANUAL READ, len=%d, " % len(req), for by in req: print '%02X ' % ord(by), print # there is NO response to this poll, # but we need to wait some delay time.sleep(self.MANUAL_DELAY_SEC) except: traceback.print_exc() self._tracer.error("manual poll xmission failure, abort cycle.") break # poll the status req = sensor.req_status_3() if SHOW_COMM: print "M300: send STATUS, len=%d, " % len(req), for by in req: print '%02X ' % ord(by), print try: self.write(req) data = self.read(self.READ_SIZE) self.flushInput() self.message_indication(sensor, data) except: traceback.print_exc() self._tracer.error("status xmission failure, will retry.") break self.__schedule_poll_cycle() # self.__reschedule_retry_watchdog() return
def make_request(self): self._tracer.calls("XBeeAIO.make_request()") will_sleep = SettingsBase.get_setting(self, "sleep") sample_rate_ms = SettingsBase.get_setting(self, "sample_rate_ms") if not will_sleep: try: io_sample = self.ddo_get_param('IS') self.sample_indication(io_sample, self._extended_address) except: self._tracer.warning("Xmission failure, will retry.") pass # Scheduling first request and watchdog heart beat poll, # but only if we aren't in sleep mode and . if will_sleep != True and sample_rate_ms > 0xffff: self.__schedule_request() self.__reschedule_retry_watchdog()
def __write_dict_to_xml_output(self, data_dict, output_object): ''' Write all the samples in the data_dict to the output_object. ''' compat = SettingsBase.get_setting(self, 'compatibility') for name, vals in data_dict.iteritems(): sample_type = vals[0] for sample in vals[1]: output_object.write(self.methods[compat](name, sample, sample_type)) output_object.write('\n')
def start(self): transforms = SettingsBase.get_setting(self, "instance_list") for t in transforms: try: self.tlist.append(Transform(self, self.__core, **t)) except: self.__tracer.error("%s", sys.exc_info()[1]) self.__tracer.error("Transform was %s", pformat(t)) return True
def apply_settings(self): """\ Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ self._tracer.calls("DeviceBase.apply_settings()") SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): # there were problems with settings, terminate early: return (accepted, rejected, not_found) SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def subscribe_write_channels(self): # 'sio' is a file-like object which reads/writes to a string # buffer, as seen in StringIO.py. cm = self.__core.get_service("channel_manager") cp = cm.channel_publisher_get() channel0 = SettingsBase.get_setting(self, "channel0") cp.subscribe(channel0, self.cb_data_available) return
def request_info(self): """Request cluster info: single byte of 0x00""" self.send_to_cluster('\x00', XBEE_GPIO_CLUST_INFO) self.__tracer.info("XBeeGPIOClient: Discovery request sent: %s", digitime.time()) # Schedule a timeout self.info_timer = self.schedule_after( self.request_info, self.timeout * self.info_timeout_scale) if self.info_timeout_scale < 8: self.info_timeout_scale = self.info_timeout_scale * 2 self.poll_secs = SettingsBase.get_setting(self, "poll_rate")
def stop(self): """Stop listening for messages""" if not RCI_NONBLOCKING: target_name = SettingsBase.get_setting(self, 'target_name') rci.stop_rci_callback(target_name) else: if self._handle: del self._handle self._handle = None return True
def running_indication(self): self._tracer.calls("XBeeDIO.running_indication()") if not SettingsBase.get_setting(self, "sleep"): # Our device is now running, load our initial state. # It is okay if we take an Exception here, as the device # might have already gone to sleep. try: io_sample = self.ddo_get_param('IS') self.sample_indication(io_sample, self._extended_address) except: pass
def apply_settings(self): """\ Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): # there were problems with settings, terminate early: self.__tracer.warning("There was an error with the settings. " + "Attempting to continue.") SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def apply_settings(self): """\ Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) #if len(rejected) or len(not_found): if len(not_found): # Ignore extra settings, but reject if required settings are # not found return (accepted, rejected, not_found) SettingsBase.commit_settings(self, accepted) return (accepted, rejected, not_found)
def _add_filter_channel(self, channel_name, retry=3): cm = self._core.get_service("channel_manager") cdb = cm.channel_database_get() channel = cdb.channel_get(channel_name) cm = self._core.get_service("channel_manager") cdb = cm.channel_database_get() dm = self._core.get_service("device_driver_manager") target_device_name = channel.name().split('.')[0] # If the user has specified an override name for the channel name # that we will make, use it by adding an underscore in front of it. channel_name_override = SettingsBase.get_setting( self, "channel_name_override") if channel_name_override != None and self._name != "": filter_channel_name = "_%s" % (channel_name_override) # Otherwise, append the name to the filter channel name with an underscore else: filter_channel_name = "_%s_%s" % (channel.name().split('.')[1], self._name) #check if we already added filter channel if cdb.channel_exists("%s.%s" % (target_device_name, filter_channel_name)): self._tracer.error("Trying to add duplicate filter channel") return #find the target device driver try: target_device = dm.instance_get(target_device_name) except ASMInstanceNotFound: if retry > 0: self._tracer.error( "%s not started, rescheduling filter channel creation, retry %d", target_device_name, retry) self._scheduler.schedule_after(30, self._add_filter_channel, channel_name, retry - 1) else: self._tracer.error( "%s is not starting, filter channel creation giving up", target_device_name) return #create the filter property we are going to add filter_channel = self.physically_create_filter_channel( channel, filter_channel_name) target_device.add_property(filter_channel) #create the filter channel object and hook up to target channel filter_channel_object = self.create_filter_channel( channel, filter_channel) self._filter_objects.append(filter_channel_object)
def _match_filter(self, channel_name): filter_string = SettingsBase.get_setting(self, "target_channel_filter") device_filter = '*' property_filter = '*' if filter_string.find('.') != -1: (device_filter, property_filter) = filter_string.split('.') (device_name, property_name) = channel_name.split('.') if (self._match_substrings(device_name, device_filter) and self._match_substrings(property_name, property_filter, True)): return True return False
def apply_settings(self): """Called when new configuration settings are available. Must return tuple of three dictionaries: a dictionary of accepted settings, a dictionary of rejected settings, and a dictionary of required settings that were not found. """ SettingsBase.merge_settings(self) accepted, rejected, not_found = SettingsBase.verify_settings(self) if len(rejected) or len(not_found): self.logger.warn( "%s(%s): settings rejected/not found: %s/%s" % (self.__class__.__name__, self.__name, rejected, not_found)) SettingsBase.commit_settings(self, accepted) new_level_string = SettingsBase.get_setting(self, 'log_level') try: # The syntax of the setting has already been verified new_level = eval('logging.' + new_level_string) self.logger.setLevel(new_level) except Exception: # new_level_string is not an attribube of the logging package self.logger.error( 'Setting change error for log_level: should be DEBUG, ERROR, ...' ) return (accepted, rejected, not_found)
def start(self): # Verify that the user has a reasonable Device Cloud host set on their device. if hasattr(idigi_data, 'get_idigi_values'): host, token, path, port, secureport = idigi_data.get_idigi_values() if host == None or host == "" or host == " ": self.__tracer.error( "Host '%s' is not a valid value. " + "Please check your device and set the Host value " + "appropriately", host) raise ValueError("name must be a non-empty string") # Start by appending 1 to filename of pushed data self.__current_file_number = 1 # Event to use for notification of meeting the sample threshold self.__threshold_event = threading.Event() # Count of samples since last data push self.__sample_count = 0 # Here we grab the channel publisher channels = SettingsBase.get_setting(self, "channels") cm = self.__core.get_service("channel_manager") cp = cm.channel_publisher_get() # And subscribe to receive notification about new samples # as long as sample_threshold is not 0 sample_threshold = SettingsBase.get_setting(self, "sample_threshold") if sample_threshold: if len(channels) > 0: for channel in channels: cp.subscribe(channel, self.receive) else: cp.subscribe_to_all(self.receive) threading.Thread.start(self) self.apply_settings() return True
def run(self): cm = self.__core.get_service("channel_manager") cp = cm.channel_publisher_get() channel_src = [ 'channel1_source', 'channel2_source', 'channel3_source', 'channel4_source' ] src_path = [ SettingsBase.get_setting(self, channel) for channel in channel_src ] pos_index = 0 for ch_name in src_path: if ch_name != None: channel_to = "channel%d_output" % (pos_index + 1) cp.subscribe(ch_name, lambda src_ch, dest_name=channel_to: self.sub_cb( src_ch, dest_name)) pos_index += 1 while 1: if self.__stopevent.isSet(): self.__stopevent.clear() break current_channel1_input_status = bool(digihw.get_din(IN_PORT)) # current_temperature = digihw.temperature() # current_voltage = digihw.voltage_monitor() #While thread is running, set those channels' value concurrently # self.property_set("temperature", # Sample(0, int(current_temperature))) # self.property_set("voltage", Sample(0, current_voltage)) self.property_set("channel1_input", Sample(0, current_channel1_input_status)) digitime.sleep( SettingsBase.get_setting(self, "sample_rate_ms") / 1000)
def schedule_request(self): """\ Schedule a request to acquire samples for all our channels. """ # Cancel any/all pending requests. self.cancel_all_pending_requests() # Request a new event at our poll rate in the future. sample_rate_ms = SettingsBase.get_setting(self.__parent, "sample_rate_ms") event = self.__xbee_manager.xbee_device_schedule_after( sample_rate_ms / 1000, self.make_request) if event != None: self.__request_events.append(event)
def start(self): self._logger.info('Start') while 1: interface = SettingsBase.get_setting(self, 'interface') if self.__stopevent.isSet(): self.__stopevent.clear() break if on_digi_board() and (not SettingsBase.get_setting( self, "no_digicli")): current_ip_address = self._get_ip_address_with_digicli() else: current_ip_address = self._get_ip_address_with_socket() if current_ip_address: # we got a valid address if current_ip_address != self._published_ip_address: # address has changed => update it self._logger.debug('Got new IP address for interface: %s' % interface) if self._update_dtdns(): self._published_ip_address = current_ip_address else: self._logger.debug('IP address unchanged') # wait and check for new address change digitime.sleep( SettingsBase.get_setting(self, 'address_update_rate')) else: self._logger.debug('No valid IP address for interface: %s' % interface) # wait and check for new address availability digitime.sleep( SettingsBase.get_setting(self, 'check_for_valid_address_rate')) self._logger.info('Terminating') return True
def __reschedule_retry_watchdog(self): self.__tracer.debug("__reschedule_retry_watchdog") sample_rate_ms = SettingsBase.get_setting(self, "sample_rate_ms") try: if self.__retry_event: self.__xbee_manager.xbee_device_schedule_cancel( self.__retry_event) except: pass self.__retry_event = \ self.__xbee_manager.xbee_device_schedule_after( sample_rate_ms * 1000 * 1.5, self.retry_request)
def start(self): cm = self.__core.get_service("channel_manager") # subscribe to all the channels that drive our logic cp = cm.channel_publisher_get() channel_name = SettingsBase.get_setting(self, 'command_channel') self.__logger.info("Subscribing to command channel: %s" % channel_name) cp.subscribe(channel_name, self.__new_ecocity_command) threading.Thread.start(self) return True
def run(self): cm = self.__core.get_service("channel_manager") cp = cm.channel_publisher_get() cdb = cm.channel_database_get() #threshold = SettingsBase.get_setting(self, 'acc_threshold') sample_rate_ms = SettingsBase.get_setting(self, 'sample_rate_ms') #self._tracer.info("Threshold set to %.3fG" %threshold) if digihw.NB_GPIO != len(channel_type): self._tracer.info('Invalid number of channels') while 1: if self.__stopevent.isSet(): self.__stopevent.clear() break # acceleration_value = self.update_accelerometer_info() # self.property_set("acceleration", Sample(0, acceleration_value)) for index, ch_type in enumerate(channel_type): if ch_type == 'in': current_status = bool(digihw.gpio_get_value(index)) digihw.gpio_set_input(index) self.property_set('channel%d_input' %(index+1), \ Sample(0, current_status)) elif ch_type == 'out': status = self.property_get('channel%d_output' %(index+1)).value digihw.gpio_set_value(index, status) try: self._tracer.info("Reading GPS data.....") gps_data = digihw.gps_location() #Retrieve information from gps_location name = ['latitude', 'longitude', 'altitude', 'current_time'] for index in range(len(name)): self.property_set(name[index], Sample(0, value = gps_data[index])) except: import traceback traceback.print_exc() self._tracer.info("Unable to get a GPS signal.") self._tracer.info("Please place the GPS antenna in another place.") status = digihw.ignition_sense() self.property_set("ignition_status", Sample(0, status)) digitime.sleep(sample_rate_ms / 1000)
def run(self): state = STATE_NOTCONNECTED sd = None last_write = 0 while not self.__stopevent.isSet(): if state == STATE_NOTCONNECTED: server = SettingsBase.get_setting(self, "server") port = SettingsBase.get_setting(self, "port") sd = socket(AF_INET, SOCK_STREAM) try: sd.connect((server, port)) except Exception, e: self.__tracer.error("error connecting to %s:%d: %s", \ server, port, str(e)) digitime.sleep(RECONNECT_DELAY) continue state = STATE_CONNECTED interval = SettingsBase.get_setting(self, "interval") if state == STATE_CONNECTED \ and digitime.real_clock() > last_write + interval: sio = StringIO() self._write_channels(sio) try: sd.sendall(sio.getvalue()) last_write = digitime.real_clock() except: try: sd.close() except: pass state = STATE_NOTCONNECTED continue del (sio) digitime.sleep(min(SHUTDOWN_WAIT, interval))
def __adjust_sample_rate_sec(self, val=None): if val is None: # then use existing setting, which shall be string val = SettingsBase.get_setting(self, "sample_rate_sec") elif isinstance(val, types.IntType): # else make int as seconds into string val = str(val) # else assume is string # Parse out the sample rate string, set self.__rate to seconds self.__rate = int(parse_time_duration( val, in_type='sec', out_type='sec')) #if self.trace_debug_events(): # print '%s: import sample rate (%s) as %d sec' % \ # (self.showname, val, self.__rate) val = SettingsBase.get_setting(self, "sample_rate_sec") if val != str(self.__rate): # then we changed the value try: SettingsBase.set_pending_setting(self, \ "sample_rate_sec", str(self.__rate)) # push the new settings into running system self.apply_settings() except: traceback.print_exc() if (self.__rate % 60) == 0: # then we'll do the 'clean minutes' function self.__clean_minutes = 0 else: self.__clean_minutes = None return
def run(self): """run when our device driver thread is started""" self.apply_settings() addr = SettingsBase.get_setting(self, 'extended_address') xbee_manager = SettingsBase.get_setting(self, 'xbee_device_manager') dm = self.__core.get_service("device_driver_manager") xbee_manager = dm.instance_get(xbee_manager) self.__autotap = AutoTapStreamer(xbee_manager, addr) while 1: if self.__stopevent.isSet(): self.__stopevent.clear() break if self.property_get("ready_for_communication").value == 0: if self.__autotap.readyForCommunication(): vin = self.__autotap.getVIN() supported_parameters = [] for pid in self.__autotap.getSupportedParameters(): supported_parameters.append( AutoTapStreamer.PID_NAME_MAP[pid]) self.property_set("ready_for_communication", Sample(0, 1)) self.property_set("vin", Sample(0, vin)) self.property_set("supported_parameters", Sample(0, str(supported_parameters))) if self.property_get("ready_for_communication").value == 1: for pid in self.__autotap.getSupportedParameters(): val = self.__autotap.getParameterValues([pid]) pidValue = self.__autotap.\ convertValueToReadableFormat(pid, val[pid]) self.property_set(PID_NAME_MAP[pid], Sample(0, PID_TYPE_MAP[pid](pidValue))) time.sleep(SettingsBase.get_setting(self, "update_rate"))