def ParseConfigFile(configFilePath): parms = configparser.ConfigParser({ "domain": "internetofthings.ibmcloud.com", "clean-session": "true" }) sectionHeader = "device" try: with open(configFilePath) as f: try: parms.read_file(f) except AttributeError: # Python 2.7 support # https://docs.python.org/3/library/configparser.html#configparser.ConfigParser.read_file parms.readfp(f) domain = parms.get(sectionHeader, "domain") organization = parms.get(sectionHeader, "org") deviceType = parms.get(sectionHeader, "type") deviceId = parms.get(sectionHeader, "id") authMethod = parms.get(sectionHeader, "auth-method") authToken = parms.get(sectionHeader, "auth-token") cleanSession = parms.get(sectionHeader, "clean-session") except IOError as e: reason = "Error reading device configuration file '%s' (%s)" % ( configFilePath, e[1]) raise ConfigurationException(reason) return { 'domain': domain, 'org': organization, 'type': deviceType, 'id': deviceId, 'auth-method': authMethod, 'auth-token': authToken, 'clean-session': cleanSession }
def __init__(self, options, logHandlers=None): self._options = options ### DEFAULTS ### if "domain" not in self._options: # Default to the domain for the public cloud offering self._options['domain'] = "internetofthings.ibmcloud.com" if "clean-session" not in self._options: self._options['clean-session'] = "true" if "org" not in self._options: # Default to the quickstart self._options['org'] = "quickstart" if "port" not in self._options and self._options["org"] != "quickstart": self._options["port"] = 8883 if self._options["org"] == "quickstart": self._options["port"] = 1883 ### REQUIRED ### if self._options['org'] == None: raise ConfigurationException("Missing required property: org") if self._options['type'] == None: raise ConfigurationException("Missing required property: type") if self._options['id'] == None: raise ConfigurationException("Missing required property: id") if self._options['org'] != "quickstart": if self._options['auth-method'] == None: raise ConfigurationException( "Missing required property: auth-method") if (self._options['auth-method'] == "token"): if self._options['auth-token'] == None: raise ConfigurationException( "Missing required property for token based authentication: auth-token" ) else: raise UnsupportedAuthenticationMethod(options['auth-method']) AbstractClient.__init__( self, domain=self._options['domain'], organization=self._options['org'], clientId="d:" + self._options['org'] + ":" + self._options['type'] + ":" + self._options['id'], username="******" if (self._options['auth-method'] == "token") else None, password=self._options['auth-token'], logHandlers=logHandlers, cleanSession=self._options['clean-session'], port=self._options['port']) # Add handler for commands if not connected to QuickStart if self._options['org'] != "quickstart": self.client.message_callback_add("iot-2/cmd/+/fmt/+", self.__onCommand) self.subscriptionsAcknowledged = threading.Event() # Initialize user supplied callback self.commandCallback = None self.client.on_connect = self.on_connect self.setMessageEncoderModule('json', jsonCodec) self.setMessageEncoderModule('json-iotf', jsonIotfCodec) self.setMessageEncoderModule('xml', xmlCodec)
def __init__(self, options, logHandlers=None): self._options = options #Defaults if "domain" not in self._options: # Default to the domain for the public cloud offering self._options['domain'] = "internetofthings.ibmcloud.com" if "org" not in self._options: # Default to the quickstart ode self._options['org'] = "quickstart" if "clean-session" not in self._options: self._options['clean-session'] = "true" if "port" not in self._options and self._options["org"] != "quickstart": self._options["port"] = 8883 if self._options["org"] == "quickstart": self._options["port"] = 1883 #Check for any missing required properties if self._options['org'] == None: raise ConfigurationException("Missing required property: org") if self._options['type'] == None: raise ConfigurationException("Missing required property: type") if self._options['id'] == None: raise ConfigurationException("Missing required property: id") if self._options['org'] != "quickstart": if self._options['auth-method'] == None: raise ConfigurationException( "Missing required property: auth-method") if (self._options['auth-method'] == "token"): if self._options['auth-token'] == None: raise ConfigurationException( "Missing required property for token based authentication: auth-token" ) else: raise UnsupportedAuthenticationMethod(options['authMethod']) self._options['subscriptionList'] = {} self.COMMAND_TOPIC = "iot-2/type/" + self._options[ 'type'] + "/id/" + self._options['id'] + "/cmd/+/fmt/+" AbstractClient.__init__( self, domain=self._options['domain'], organization=self._options['org'], clientId="g:" + self._options['org'] + ":" + self._options['type'] + ":" + self._options['id'], username="******" if (self._options['auth-method'] == "token") else None, password=self._options['auth-token'], logHandlers=logHandlers, port=self._options['port']) # Add handler for commands if not connected to QuickStart if self._options['org'] != "quickstart": gatewayCommandTopic = "iot-2/type/" + options[ 'type'] + "/id/" + options['id'] + "/cmd/+/fmt/json" messageNotificationTopic = "iot-2/type/" + options[ 'type'] + "/id/" + options['id'] + "/notify" #localTopic = "iot-2/type/iotsample-raspberrypi2/id/89898889/cmd/greeting/fmt/json" self.client.message_callback_add(gatewayCommandTopic, self.__onCommand) self.client.message_callback_add("iot-2/type/+/id/+/cmd/+/fmt/+", self.__onDeviceCommand) self.client.message_callback_add(messageNotificationTopic, self.__onMessageNotification) self.subscriptionsAcknowledged = threading.Event() # Initialize user supplied callback self.commandCallback = None self.deviceCommandCallback = None self.notificationCallback = None self.client.on_connect = self.on_connect self.setMessageEncoderModule('json', jsonCodec) self.setMessageEncoderModule('json-iotf', jsonIotfCodec) self.setMessageEncoderModule('xml', xmlCodec) # Create api key for gateway authentication self.gatewayApiKey = "g/" + self._options['org'] + '/' + self._options[ 'type'] + '/' + self._options['id'] self.logger = logging.getLogger(self.__module__ + "." + self.__class__.__name__) self.logger.setLevel(logging.INFO) self.api = api.ApiClient( { "org": self._options['org'], "auth-token": self._options['auth-token'], "auth-key": self.gatewayApiKey }, self.logger)
def __init__(self, config, logHandlers=None, deviceInfo=None): """ Override the constructor """ if config['identity']['orgId'] == "quickstart": raise ConfigurationException( "QuickStart does not support device management") self._config = GatewayClientConfig(**config) AbstractClient.__init__(self, domain=self._config.domain, organization=self._config.orgId, clientId=self._config.clientId, username=self._config.username, password=self._config.password, port=self._config.port, transport=self._config.transport, cleanStart=self._config.cleanStart, sessionExpiry=self._config.sessionExpiry, keepAlive=self._config.keepAlive, caFile=self._config.caFile, logLevel=self._config.logLevel, logHandlers=logHandlers) self.COMMAND_TOPIC = "iot-2/type/" + self._config.typeId + "/id/" + self._config.deviceId + "/cmd/+/fmt/+" gatewayCommandTopic = "iot-2/type/" + self._config.typeId + "/id/" + self._config.deviceId + "/cmd/+/fmt/json" deviceCommandTopic = "iot-2/type/+/id/+/cmd/+/fmt/+" messageNotificationTopic = "iot-2/type/" + self._config.typeId + "/id/" + self._config.deviceId + "/notify" self.client.message_callback_add(gatewayCommandTopic, self._onCommand) self.client.message_callback_add(deviceCommandTopic, self._onDeviceCommand) self.client.message_callback_add(messageNotificationTopic, self._onMessageNotification) # Initialize user supplied callback self.deviceCommandCallback = None self.notificationCallback = None # --------------------------------------------------------------------- # Device Management Specific code starts here # --------------------------------------------------------------------- self.readyForDeviceMgmt = threading.Event() # Add handler for supported device management commands self.client.message_callback_add("iotdm-1/#", self.__onDeviceMgmtResponse) # List of DM requests that have not received a response yet self._deviceMgmtRequestsPendingLock = threading.Lock() self._deviceMgmtRequestsPending = {} # List of DM notify hook self._deviceMgmtObservationsLock = threading.Lock() self._deviceMgmtObservations = [] # Initialize local device data model self.metadata = {} if deviceInfo is not None: self._deviceInfo = deviceInfo else: self._deviceInfo = DeviceInfo() self._location = None self._errorCode = None # Initialize subscription list self._subscriptions[self.DM_RESPONSE_TOPIC_TEMPLATE % (self._config.typeId, self._config.deviceId)] = 1 self._subscriptions[self.DM_OBSERVE_TOPIC_TEMPLATE % (self._config.typeId, self._config.deviceId)] = 1 self._subscriptions[self.COMMAND_TOPIC] = 1
def __init__(self, config, logHandlers=None, deviceInfo=None): if config['identity']['orgId'] == "quickstart": raise ConfigurationException( "QuickStart does not support device management") DeviceClient.__init__(self, config, logHandlers) # Initialize user supplied callback self.deviceActionCallback = None self.firmwereActionCallback = None self.dmeActionCallback = None messages_callbacks = ( ("iotdm-1/#", self.__onDeviceMgmtResponse), (ManagedDeviceClient.DM_REBOOT_TOPIC, self.__onRebootRequest), (ManagedDeviceClient.DM_FACTORY_REESET, self.__onFactoryResetRequest), (ManagedDeviceClient.DM_FIRMWARE_UPDATE_TOPIC, self.__onFirmwereUpdate), (ManagedDeviceClient.DM_OBSERVE_TOPIC, self.__onFirmwereObserve), (ManagedDeviceClient.DM_FIRMWARE_DOWNLOAD_TOPIC, self.__onFirmwereDownload), (ManagedDeviceClient.DM_UPDATE_TOPIC, self.__onUpdatedDevice), (ManagedDeviceClient.DM_CANCEL_OBSERVE_TOPIC, self.__onFirmwereCancel), (ManagedDeviceClient.DME_ACTION_TOPIC, self.__onDMEActionRequest), ) # Add handler for supported device management commands for message, callback in messages_callbacks: self.client.message_callback_add(message, callback) # Initialize user supplied callback self.client.on_subscribe = self._onSubscribe self.client.on_disconnect = self._onDisconnect self.readyForDeviceMgmt = threading.Event() # List of DM requests that have not received a response yet self._deviceMgmtRequestsPendingLock = threading.Lock() self._deviceMgmtRequestsPending = {} # List of DM notify hook self._deviceMgmtObservationsLock = threading.Lock() self._deviceMgmtObservations = [] # Initialize local device data model self.metadata = {} if deviceInfo is not None: self._deviceInfo = deviceInfo else: self._deviceInfo = DeviceInfo() self._location = None self._errorCode = None self.__firmwareUpdate = None self.manageTimer = None # Register startup subscription list self._subscriptions[self.DM_RESPONSE_TOPIC] = 1 self._subscriptions[self.DM_OBSERVE_TOPIC] = 1 self._subscriptions[self.DM_REBOOT_TOPIC] = 1 self._subscriptions[self.DM_FACTORY_REESET] = 1 self._subscriptions[self.DM_UPDATE_TOPIC] = 1 self._subscriptions[self.DM_FIRMWARE_UPDATE_TOPIC] = 1 self._subscriptions[self.DM_FIRMWARE_DOWNLOAD_TOPIC] = 1 self._subscriptions[self.DM_CANCEL_OBSERVE_TOPIC] = 1 self._subscriptions[self._COMMAND_TOPIC] = 1 self._subscriptions[self.DME_ACTION_TOPIC] = 1
def __init__(self, **kwargs): # Validate the arguments if 'identity' not in kwargs: raise ConfigurationException("Missing identity from configuration") if 'orgId' not in kwargs['identity'] or kwargs['identity']['orgId'] is None: raise ConfigurationException("Missing identity.orgId from configuration") if 'typeId' not in kwargs['identity'] or kwargs['identity']['typeId'] is None: raise ConfigurationException("Missing identity.typeId from configuration") if 'deviceId' not in kwargs['identity'] or kwargs['identity']['deviceId'] is None: raise ConfigurationException("Missing identity.deviceId from configuration") # Authentication is not supported for quickstart if kwargs['identity']['orgId'] is "quickstart": if 'auth' in kwargs: raise ConfigurationException("Quickstart service does not support device authentication") else: if 'auth' not in kwargs: raise ConfigurationException("Missing auth from configuration") if 'token' not in kwargs['auth'] or kwargs['auth']['token'] is None: raise ConfigurationException("Missing auth.token from configuration") if 'options' in kwargs and 'mqtt' in kwargs['options']: # validate port if 'port' in kwargs['options']['mqtt'] and kwargs['options']['mqtt']['port'] is not None: if not isinstance(kwargs['options']['mqtt']['port'], int): raise ConfigurationException("Optional setting options.mqtt.port must be a number if provided") # Validate cleanStart if 'cleanStart' in kwargs['options']['mqtt'] and not isinstance(kwargs['options']['mqtt']['cleanStart'], bool): raise ConfigurationException("Optional setting options.mqtt.cleanStart must be a boolean if provided") # Set defaults for optional configuration if 'options' not in kwargs: kwargs['options'] = {} if "domain" not in kwargs['options']: kwargs['options']['domain'] = "internetofthings.ibmcloud.com" if "logLevel" not in kwargs['options']: kwargs['options']['logLevel'] = logging.INFO if 'mqtt' not in kwargs['options']: kwargs['options']['mqtt'] = {} if "port" not in kwargs['options']['mqtt']: kwargs['options']['mqtt']['port'] = None if "transport" not in kwargs['options']['mqtt']: kwargs['options']['mqtt']['transport'] = 'tcp' if "cleanStart" not in kwargs['options']['mqtt']: kwargs['options']['mqtt']['cleanStart'] = False if "sessionExpiry" not in kwargs['options']['mqtt']: kwargs['options']['mqtt']['sessionExpiry'] = 3600 if "keepAlive" not in kwargs['options']['mqtt']: kwargs['options']['mqtt']['keepAlive'] = 60 if "caFile" not in kwargs['options']['mqtt']: kwargs['options']['mqtt']['caFile'] = None dict.__init__(self, **kwargs)
def ParseEnvVars(): """ Parse environment variables into a Python dictionary suitable for passing to the device client constructor as the `options` parameter - `WIOTP_IDENTITY_ORGID` - `WIOTP_IDENTITY_TYPEID` - `WIOTP_IDENTITY_DEVICEID` - `WIOTP_AUTH_TOKEN` - `WIOTP_DOMAIN` (optional) - `WIOTP_LOGLEVEL` (optional) - `WIOTP_OPTIONS_MQTT_PORT` (optional) - `WIOTP_OPTIONS_MQTT_TRANSPORT` (optional) - `WIOTP_OPTIONS_MQTT_CAFILE` (optional) - `WIOTP_OPTIONS_MQTT_CLEANSTART` (optional) - `WIOTP_OPTIONS_MQTT_SESSIONEXPIRY` (optional) - `WIOTP_OPTIONS_MQTT_KEEPALIVE` (optional) """ # Identify orgId = os.getenv("WIOTP_IDENTITY_ORGID", None) typeId = os.getenv("WIOTP_IDENTITY_TYPEID", None) deviceId = os.getenv("WIOTP_IDENTITY_DEVICEID", None) # Auth authToken = os.getenv("WIOTP_AUTH_TOKEN", None) # Options domain = os.getenv("WIOTP_OPTIONS_DOMAIN", None) logLevel = os.getenv("WIOTP_OPTIONS_LOGLEVEL", "info") port = os.getenv("WIOTP_OPTIONS_MQTT_PORT", None) transport = os.getenv("WIOTP_OPTIONS_MQTT_TRANSPORT", None) caFile = os.getenv("WIOTP_OPTIONS_MQTT_CAFILE", None) cleanStart = os.getenv("WIOTP_OPTIONS_MQTT_CLEANSTART", "False") sessionExpiry = os.getenv("WIOTP_OPTIONS_MQTT_SESSIONEXPIRY", "3600") keepAlive = os.getenv("WIOTP_OPTIONS_MQTT_KEEPALIVE", "60") caFile = os.getenv("WIOTP_OPTIONS_MQTT_CAFILE", None) if orgId is None: raise ConfigurationException("Missing WIOTP_IDENTITY_ORGID environment variable") if typeId is None: raise ConfigurationException("Missing WIOTP_IDENTITY_TYPEID environment variable") if deviceId is None: raise ConfigurationException("Missing WIOTP_IDENTITY_DEVICEID environment variable") if orgId is not "quickstart" and authToken is None: raise ConfigurationException("Missing WIOTP_AUTH_TOKEN environment variable") if port is not None: try: port = int(port) except ValueError as e: raise ConfigurationException("WIOTP_OPTIONS_MQTT_PORT must be a number") try: sessionExpiry = int(sessionExpiry) except ValueError as e: raise ConfigurationException("WIOTP_OPTIONS_MQTT_SESSIONEXPIRY must be a number") try: keepAlive = int(keepAlive) except ValueError as e: raise ConfigurationException("WIOTP_OPTIONS_MQTT_KEEPAIVE must be a number") if logLevel not in ["error", "warning", "info", "debug"]: raise ConfigurationException("WIOTP_OPTIONS_LOGLEVEL must be one of error, warning, info, debug") else: # Convert log levels from string to int (we need to upper case our strings from the config) logLevel = logging.getLevelName(logLevel.upper()) cfg = { 'identity': { 'orgId': orgId, 'typeId': typeId, 'deviceId': deviceId }, 'options': { 'domain': domain, 'logLevel': logLevel, 'mqtt': { 'port': port, 'transport': transport, 'caFile': caFile, 'cleanStart': cleanStart in ["True", "true", "1"], 'sessionExpiry': sessionExpiry, 'keepAlive': keepAlive } } } # Quickstart doesn't support auth, so ensure we only add this if it's defined if authToken is not None: cfg['auth'] = { 'token': authToken } return cfg
def __init__(self, options, logHandlers=None): self._options = options if self._options['org'] == None: raise ConfigurationException("Missing required property: org") if self._options['type'] == None: raise ConfigurationException("Missing required property: type") if self._options['id'] == None: raise ConfigurationException("Missing required property: id") if self._options['org'] != "quickstart": if self._options['auth-method'] == None: raise ConfigurationException( "Missing required property: auth-method") if (self._options['auth-method'] == "token"): if self._options['auth-token'] == None: raise ConfigurationException( "Missing required property for token based authentication: auth-token" ) else: raise UnsupportedAuthenticationMethod(options['authMethod']) self._options['subscriptionList'] = {} # Include staging self._options[ 'staging'] = options['staging'] if 'staging' in options else None AbstractClient.__init__(self, organization=options['org'], clientId="g:" + options['org'] + ":" + options['type'] + ":" + options['id'], username="******" if (options['auth-method'] == "token") else None, password=options['auth-token'], logHandlers=logHandlers, staging=options['staging']) # Add handler for commands if not connected to QuickStart if self._options['org'] != "quickstart": gatewayCommandTopic = "iot-2/type/" + options[ 'type'] + "/id/" + options['id'] + "/cmd/+/fmt/json" messageNotificationTopic = "iot-2/type/" + options[ 'type'] + "/id/" + options['id'] + "/notify" #localTopic = "iot-2/type/iotsample-raspberrypi2/id/89898889/cmd/greeting/fmt/json" self.client.message_callback_add(gatewayCommandTopic, self.__onCommand) self.client.message_callback_add("iot-2/type/+/id/+/cmd/+/fmt/+", self.__onDeviceCommand) self.client.message_callback_add(messageNotificationTopic, self.__onMessageNotification) self.subscriptionsAcknowledged = threading.Event() # Initialize user supplied callback self.commandCallback = None self.deviceCommandCallback = None self.notificationCallback = None self.client.on_connect = self.on_connect self.setMessageEncoderModule('json', jsonCodec) self.setMessageEncoderModule('json-iotf', jsonIotfCodec)