def local_shadow_connect(device_name, config_file, root_ca, certificate,
                         private_key, group_ca_dir):
    cfg = GroupConfigFile(config_file)
    ggd_name = cfg['devices'][device_name]['thing_name']
    iot_endpoint = cfg['misc']['iot_endpoint']

    dip = DiscoveryInfoProvider()
    dip.configureEndpoint(iot_endpoint)
    dip.configureCredentials(
        caPath=root_ca, certPath=certificate, keyPath=private_key
    )
    dip.configureTimeout(10)  # 10 sec
    logging.info(
        "[shadow_connect] Discovery using CA:{0} cert:{1} prv_key:{2}".format(
            root_ca, certificate, private_key
    ))
    gg_core, discovery_info = discover_configured_core(
        config_file=config_file, dip=dip, device_name=ggd_name,
    )
    if not gg_core:
        raise EnvironmentError("[core_connect] Couldn't find the Core")

    ca_list = discovery_info.getAllCas()
    core_list = discovery_info.getAllCores()
    group_id, ca = ca_list[0]
    core_info = core_list[0]
    logging.info("Discovered Greengrass Core:{0} from Group:{1}".format(
        core_info.coreThingArn, group_id)
    )
    group_ca_file = save_group_ca(ca, group_ca_dir, group_id)

    # local Greengrass Core discovered
    # get a shadow client to receive commands
    mqttsc = AWSIoTMQTTShadowClient(ggd_name)

    # now connect to Core from this Device
    logging.info("[core_connect] gca_file:{0} cert:{1}".format(
        group_ca_file, certificate))
    mqttsc.configureCredentials(group_ca_file, private_key, certificate)

    mqttc = mqttsc.getMQTTConnection()
    mqttc.configureOfflinePublishQueueing(10, DROP_OLDEST)
    if not mqtt_connect(mqttsc, gg_core):
        raise EnvironmentError("connection to Master Shadow failed.")

    # create and register the shadow handler on delta topics for commands
    # with a persistent connection to the Master shadow
    master_shadow = mqttsc.createShadowHandlerWithName(
        cfg['misc']['master_shadow_name'], True)

    return mqttc, mqttsc, master_shadow, ggd_name
Ejemplo n.º 2
0
class ThermoApp(App):
	DEVICE = '/dev/ttyAMA0'
	BAUD = 9600
	TIMEOUT = 5
	ipaddr=''
	lastGPUTempRead=0.0
	lastWeatherRead=0.0
	lastTempPressHumidRead=0.0
	lastShadowUpdate=0.0
	lastSetAlerts=0.0
	ui = ObjectProperty(None)
	zones = ObjectProperty(None)
	zonemap=['','17','27','22']
	zoneData={
		'1':ThermoZone(1,17),
		'2':ThermoZone(2,27),
		'3':ThermoZone(3,22)
	}
	furnace=Furnace()
	currentZone=1
	dataFeed = deque()
	
	deviceData={
		'AA':ThermoDevice('AA',2,'master'),
		'AB':ThermoDevice('AB',2,'tess'),
		'AC':ThermoDevice('AC',2,'kate'),
		'AD':ThermoDevice('AD',3,'girls'),
		'AE':ThermoDevice('AE',1,'snug'),
		'AF':ThermoDevice('AF',1,'living'),
		'AG':ThermoDevice('AG',0,'porch'),
		'AH':ThermoDevice('AH',1,'ground'),
		'BM':ThermoDevice('BM',0,'thermo'),
		'AW':ThermoDevice('AW',0,'weather'),
		'PI':ThermoDevice('PI',0,'GPU')}
	ser = serial.Serial(DEVICE, BAUD)
	
	voltage = 0.0
	tempvale = 0.0
	pressure = 0.0
	weather = []
	sensor = BME280(mode=BME280_OSAMPLE_8)
	host='a2pveb84akyryv.iot.us-east-1.amazonaws.com'
	rootCAPath='rootca.key'
	privateKeyPath='bdca28f300.private.key'
	certificatePath='bdca28f300.cert.pem'
	# -e a2pveb84akyryv.iot.us-east-1.amazonaws.com -r rootca.key -c bdca28f300.cert.pem -k bdca28f300.private.key

	def show_config(self):
		App.open_settings(self)
		Window.request_keyboard(self.keyboard_close, self)
	
	def keyboard_close(self):
		#print "close"
		return

	def build_config(self, config):
		config.setdefaults('startup', {
	    		'weatherText': 'foobar',
	    		'picSource': 'weather/1.jpg'
		})
		self.config=config

	def build_settings(self, settings):
		jsondata = """[
			{ "type": "title",
			"title": "Thermo application" },
			{ "type": "options",
			"title": "Initial Weather",
			"desc": "Weather Pic",
			"section": "startup",
			"key": "picSource",
			"options": ["weather/1.jpg", "weather/images.jpg", "weather/part_coudy.jpg"] },
			{ "type": "string",
			"title": "Weather Title",
			"desc": "Weather Text",
			"section": "startup",
			"key": "weatherText" }]"""
		settings.add_json_panel('Thermo application', self.config, data=jsondata)

	def build(self):
		self.ui=ThermoWidget()
		self.ui.weatherText='ThermoWidget'
		self.ui.picSource='weather/1.jpg'
		self.ui.tempDataText="temps"
		self.ui.setPointText="0.0"
		self.ui.ipAddressText="192.168.0.0"
		self.ui.averageTempText="0.0"
		self.ui.zoneAlertsText="Loading..."
		btn=self.ui.ids['increase']
		btn.bind(on_release=self.increaseSetPoint)
		btn=self.ui.ids['decrease']
		btn.bind(on_release=self.decreaseSetPoint)
		self.zones=self.ui.ids['zones']
		for z in range(0,4):
			btnstate='down' if self.currentZone==z else 'normal'
			btn = ToggleButton(
				allow_no_selection=False,
				text=str(z), 
				group='zonegroup', 
				size_hint=(None, None),
				halign='center',
				state=btnstate,
				background_normal='normal.png',
				background_down='down.png')
    			btn.bind(on_release=self.switch_zone)
    			self.zones.add_widget(btn)
		self.ui.weatherText=self.config.get('startup', 'weatherText')
		temp = subprocess.check_output(["ifconfig","wlan0"],universal_newlines=True)
		pos1=temp.find("inet addr:")
		pos2=temp.find(" Bcast:")
		self.ui.ipAddressText=temp[pos1+10:pos2]
		self.connectMQTT()
		Clock.schedule_interval(self.mainLoop, 10.0)
		return self.ui

	def switch_zone(self,toggle):
		self.currentZone=int(toggle.text)
		self.updateDisplay()
		pass

	def increaseSetPoint(self,instance):
		self.zoneData[str(self.currentZone)].setPoint+=5.0/9.0
		self.takeAction()
		self.updateDisplay()
		pass

	def decreaseSetPoint(self,instance):
		self.zoneData[str(self.currentZone)].setPoint-=5.0/9.0
		self.takeAction()
		self.updateDisplay()
		pass

	def loadConfig(self):
		# read config file into memory vars
		return

	def avgZone(self,zonenum):
		tot=0.0
		cnt=0
		for i in self.deviceData:
			device=self.deviceData[i]
			if(device.zone==zonenum):
				tot+=float(device.temp)
				if(device.temp>0.0):
					cnt+=1
		if cnt==0:
			cnt=1
		return tot/cnt
	
	def connectMQTT(self):
		self.myShadowClient = AWSIoTMQTTShadowClient("thermo")
    		#self.myAWSIoTMQTTClient = AWSIoTMQTTClient("thermo")

		self.myShadowClient.configureEndpoint(self.host, 8883)
		self.myShadowClient.configureCredentials(self.rootCAPath, self.privateKeyPath, self.certificatePath)

		# myShadowClient connection configuration
		self.myShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
		
		self.myShadowClient.connect()

		self.myAWSIoTMQTTClient = self.myShadowClient.getMQTTConnection()
		self.myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
		self.myAWSIoTMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
		self.myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
		self.myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)  # 5 sec
		

		# Connect and subscribe to AWS IoT
		#self.myAWSIoTMQTTClient.connect()
		# myAWSIoTMQTTClient.subscribe("thermo", 1, customCallback)
		# self.myAWSIoTMQTTClient.publish("thermo", "[[\'"+(strftime(DATE_FORMAT,localtime())+"\','TT','START','1']]", 1)
		# Create a device shadow instance using persistent subscription
		self.myDeviceShadow = self.myShadowClient.createShadowHandlerWithName("mythermo", True)
		return

	def updateDeviceShadow(self):
		if(time()-self.lastShadowUpdate > 300):
			thingState={
				"state" : {
					"reported" : {
						"sensors" : {
						},
						"zones" : {
						},
						"furnace" : {
						}
					}
				}
			}
			for i in self.deviceData:
				device=self.deviceData[i]
				thingState["state"]["reported"]["sensors"][device.id]={"temp":tformat(device.temp),"location":device.location,"batt":device.batt,"alert":device.alert,"lastupdate":device.lastupdate,"press":device.press,"humid":device.humid}
			for i in self.zoneData:
    				zone=self.zoneData[i]
				thingState["state"]["reported"]["zones"][zone.id]={"status":zone.status, "average":tformat(zone.average), "setPoint":tformat(zone.setPoint), "triggertemp":tformat(zone.triggertemp), "alert":zone.alert}
			thingState["state"]["reported"]["furnace"]={"onSeconds":self.furnace.onSeconds,"offSeconds":self.furnace.offSeconds,"maxBurnSeconds":self.furnace.maxBurnSeconds,"maxRestSeconds":self.furnace.maxRestSeconds,"status":self.furnace.status,"lastupdate":self.furnace.lastupdate}
			self.myDeviceShadow.shadowUpdate(json.dumps(thingState), None, 5)
			self.lastShadowUpdate=time()
		return	
		
	def updateDisplay(self):
		# draw everything
		# if click then show subpanel or change config
		self.ui.setPointText="{:2.0f}".format(self.zoneData[str(self.currentZone)].setPoint*9/5+32.0)
		self.ui.averageTempText=tformat(self.avgZone(self.currentZone))
		self.ui.tempDataText=''
		zonealerts='Alerts:'
		for i in self.deviceData:
			device=self.deviceData[i]
			thisDeviceText=tformat(device.temp)
			thisDeviceText+=" "+device.location+" "+device.alert
			self.ui.tempDataText+=thisDeviceText+'\n'
		for i in self.zoneData:
    			zone=self.zoneData[i]
			if(len(zone.alert)>0):
				zonealerts+=" Zone"+str(zone.id)+" "+zone.alert
		self.ui.zoneAlertsText=zonealerts
		return
	
	def readSensors(self):
		# get data from serial RF sensors
		# get data from remote PI
		# all data in memory only in this function
		# get temperature
		# messages are 12chars aIDTYPEVALUE aIDAWAKE---- or aIDSLEEPING-
		# returns -100 on error, or the temperature as a float
		
		fim = time()+ self.TIMEOUT
		
		voltage = 0
		tempvalue = -100
		deviceid = ''
		while (time()<fim) and (tempvalue == -100):
			n = self.ser.inWaiting()
			if n != 0:
				data = self.ser.read(n)
				nb_msg = len(data) / 12
				for i in range (0, nb_msg):
					msg = data[i*12:(i+1)*12]
		
					deviceid = msg[1:3]
					if self.deviceData.has_key(deviceid):
						device=self.deviceData[deviceid]
						device.lastupdate=strftime(DATE_FORMAT,localtime())
			
						if msg[3:7] == "TEMP":
							tempvalue = msg[7:]
							device.temp=tempvalue
							self.dataFeed.append((strftime(DATE_FORMAT,localtime()), deviceid, "TEMP", tempvalue))

						if msg[3:7] == "BATT":
							voltage = msg[7:11]
							if voltage == "LOW":
								voltage = 0.1
							device.batt=voltage
							self.dataFeed.append((strftime(DATE_FORMAT,localtime()), deviceid+'B', "BATT", voltage))

			else:
				sleep(5)
		return

	def getPiSensorData(self):
		if(time()-self.lastGPUTempRead > 60):
			temp = ""
			temp = subprocess.check_output(["/opt/vc/bin/vcgencmd","measure_temp"],universal_newlines=True)
			temp = temp[5 : -3]
			device=self.deviceData['PI']
			device.lastupdate=strftime(DATE_FORMAT,localtime())
			device.temp=temp
			self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "PI", "TEMP", temp))
			self.lastGPUTempRead = time()
		return

	def getConnectedSensorData(self):
		if(time()-self.lastTempPressHumidRead > 60):
			# get BME280 data
			temp=self.sensor.read_temperature()-1.0
			press=self.sensor.read_pressure()
			humid=self.sensor.read_humidity()
			self.pressure=press
			device=self.deviceData['BM']
			device.lastupdate=strftime(DATE_FORMAT,localtime())
			device.temp=temp
			device.press=press
			device.humid=humid
			self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "BM", "TEMP", temp))
			self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "BP", "PRESS", press))
			self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "BH", "HUMID", humid))
			self.lastTempPressHumidRead = time()

	def getWeather(self):
		if(time()-self.lastWeatherRead > 1800):
			# get and parse AccuWeather data
			cur = re.compile('Currently: (.*)<')
			link = "http://rss.accuweather.com/rss/liveweather_rss.asp?metric=0&locCode=US|44022"
			f = urllib.urlopen(link)
			myfile = f.read()
			tempvalue = cur.search(myfile).group(1)
			temp=tempvalue[-4:-1]
			pos=tempvalue.find(":")
			description=tempvalue[0:-5] if pos<0 else tempvalue[0:pos]
			description=description.replace(" ","_").lower()
			# print("description = [" + description +"]")
			device=self.deviceData['AW']
			device.lastupdate=strftime(DATE_FORMAT,localtime())
			device.temp=(float(temp)-32)*5/9
			if device.desc<>description :
				self.ui.picSource='weather/'+description+'.jpg' if 6 < localtime()[3] < 18 else 'weather/'+description+'_dark.jpg'
			device.desc=description
			self.ui.weatherText = tempvalue
			self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "AW", "NEWS", tempvalue))
						
			self.lastWeatherRead = time()
		return
	def setAlerts(self):
		# Reasons for alerts:
		# sensor battery level below 2.3
		# sensor not reporting ( sensor data age > 5x reporting )
		# temperature not under control = falling when attempting to raise
		#    alert if temp not correct direction for 10 minutes
		#    need control switch date time 
		if(time()-self.lastSetAlerts > 1800):
			for i in self.deviceData:
    				device=self.deviceData[i]
				device.alert=""
				if (not device.batt is None) & (device.batt<2.5):
    					device.alert="LOW"
					self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "ALERT", "LOW Battery in "+device.location, device.batt))
					self.lastSetAlerts = time()
				if (len(device.lastupdate)>0) & (device.id!='AW'): 
					age = datetime.datetime.strptime(strftime(DATE_FORMAT,localtime()),DATE_FORMAT) - datetime.datetime.strptime(device.lastupdate,DATE_FORMAT)
					#print "{} {}".format(device.location,age.seconds)
					if ( age.seconds > 600 ):
						device.alert="OLD"
						self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "ALERT", "NO Response in "+device.location, age.seconds))
						self.lastSetAlerts = time()
			for i in self.zoneData:
    				zone=self.zoneData[i]
				zone.alert=""
				if (zone.status):
					age = datetime.datetime.strptime(strftime(DATE_FORMAT,localtime()),DATE_FORMAT) - datetime.datetime.strptime(zone.lastupdate,DATE_FORMAT)
					if (age.seconds>600):
						zone.alert="OOC"
						self.dataFeed.append((strftime(DATE_FORMAT,localtime()), "ALERT", "OOC in zone "+str(zone.id), tformat(zone.average)))
						self.lastSetAlerts = time()
		return

	def uploadData(self):
		# put the data in the cloud or cache in a file until sucess
		# add it to the memory deque
		# if the deque > 10 try to upload it and any pending updates
		# else throw a flag for pending updates and write to a file
		if len(self.dataFeed)>10:
    			try:
				# write to a file
				#print "  write to file"
				with open("Output.txt", "a") as text_file:
					for record in self.dataFeed:
						text_file.write("{},{},{},{}\r\n".format(record[0],record[1],record[2],record[3]))
				# write to cloud
				#print "  write to cloud"

				self.myAWSIoTMQTTClient.publish("thermo", json.dumps(list(self.dataFeed)), 1)
				# clear the deque
				self.dataFeed.clear()
			except:
				print("Unexpected error in uploadData:", sys.exc_info()[0])
		return
		
	def downloadRequests(self):
		# get cloud data or web requests
		return
		
	def controlZone(self,zone,on,avg):
		zoneentry=self.zoneData[str(zone)]
		subprocess.call(["gpio", "-g", "write", str(zoneentry.port), "1" if on else "0"])
    		furnaceWasOn=False
		for i in self.zoneData:
			furnaceWasOn|=self.zoneData[i].status
		if(zoneentry.status != on):
			zoneentry.status=on
			furnaceIsOn=False
			for i in self.zoneData:
				furnaceIsOn|=self.zoneData[i].status
			if(furnaceIsOn!=furnaceWasOn):
				self.furnace.status=furnaceIsOn
				if (len(self.furnace.lastupdate)>0):
					age = datetime.datetime.strptime(strftime(DATE_FORMAT,localtime()),DATE_FORMAT) - datetime.datetime.strptime(self.furnace.lastupdate,DATE_FORMAT)
					# if it is now on  - age is how long it was off
					if(furnaceIsOn):
						self.furnace.offSeconds+=age.seconds
						if(age.seconds>self.furnace.maxRestSeconds):
							self.furnace.maxRestSeconds=age.seconds
					# if it is now off - age is how long it was on
					else:
						self.furnace.onSeconds+=age.seconds
						if(age.seconds>self.furnace.maxBurnSeconds):
							self.furnace.maxBurnSeconds=age.seconds
				self.furnace.lastupdate=strftime(DATE_FORMAT,localtime())
			zoneentry.lastupdate=strftime(DATE_FORMAT,localtime())
			zoneentry.triggertemp=avg
		return

	def takeAction(self):
		# contains all rules to make decisions based on data 
		for i in self.zoneData:
			zone=self.zoneData[i]
			zone.average=self.avgZone(zone.id)
			if(zone.average<10.0):
				self.controlZone(zone.id,False,zone.average)
				return
			#print "average in zone {} is {}".format(zone.id,zone.average)
    			if(zone.average<zone.setPoint-0.5):
    				self.controlZone(zone.id,True,zone.average)
    				#turn it on
			if(zone.average>zone.setPoint):
				self.controlZone(zone.id,False,zone.average)
    				#turn it off
		return
	
	def mainLoop(self,args):
		try:
			#print 'config'
			self.loadConfig()
			#print 'getWeather'
			self.getWeather()
			#print 'getPI'
			self.getPiSensorData()
			#print 'getBME'
			self.getConnectedSensorData()
			#print 'read'
			self.readSensors()
			#print 'alerts'
			self.setAlerts()
			#print 'update'
			self.updateDisplay()
			#print 'update shadow'
			self.updateDeviceShadow()
			#print 'upload'
			self.uploadData()
			#print 'download'
			self.downloadRequests()
			#print 'action'
			self.takeAction()
		except:
			type_, value_, traceback_ = sys.exc_info()
			print "EXCEPTION {}\r\n{}\r\n{}".format(type_, value_, traceback.format_tb(traceback_))
			self.dataFeed.append(value_)
		return
Ejemplo n.º 3
0
def initialize(device_name, config_file, root_ca, certificate, private_key,
               group_ca_path):
    global ggd_name

    cfg = GroupConfigFile(config_file)
    local = dict()
    remote = dict()

    # determine heartbeat device's thing name and endpoint for MQTT clients
    ggd_name = cfg['devices'][device_name]['thing_name']
    iot_endpoint = cfg['misc']['iot_endpoint']

    # Discover Greengrass Core
    dip = DiscoveryInfoProvider()
    dip.configureEndpoint(iot_endpoint)
    dip.configureCredentials(
        caPath=root_ca, certPath=certificate, keyPath=private_key
    )
    dip.configureTimeout(10)  # 10 sec
    log.info("Discovery using CA: {0} certificate: {1} prv_key: {2}".format(
        root_ca, certificate, private_key
    ))
    # Now discover the groups in which this device is a member.
    # The arm should only be in two groups. The local and master groups.
    discovered, discovery_info = utils.ggc_discovery(
        ggd_name, dip, retry_count=10, max_groups=2
    )

    # Each group returned has a groupId which can compare to the configured
    # groupId in the config file. If the IDs match, the 'local' Group has been
    # found and therefore local core.
    # If the groupId's do not match, the 'remote' or 'master' group has been
    # found.
    group_list = discovery_info.getAllGroups()
    for g in group_list:
        logging.info("[initialize] group_id:{0}".format(g.groupId))
        if g.groupId == cfg['group']['id']:
            local_cores = g.coreConnectivityInfoList
            local['core'] = local_cores[0]  # just grab first core as local
            local['ca'] = g.caList
        else:
            remote_cores = g.coreConnectivityInfoList
            remote['core'] = remote_cores[0]  # just grab first core as remote
            remote['ca'] = g.caList

    if len(local) > 1 and len(remote) > 1:
        logging.info("[initialize] local_core:{0} remote_core:{1}".format(
            local, remote
        ))
    else:
        raise EnvironmentError("Couldn't find the arm's Cores.")

    # just save one of the group's CAs to use as a CA file later
    local_core_ca_file = utils.save_group_ca(
        local['ca'][0], group_ca_path, local['core'].groupId
    )
    remote_core_ca_file = utils.save_group_ca(
        remote['ca'][0], group_ca_path, remote['core'].groupId
    )

    # Greengrass Cores discovered, now connect to Cores from this Device
    # get a client to send telemetry
    local_mqttc = AWSIoTMQTTClient(ggd_name)
    log.info("[initialize] local gca_file:{0} cert:{1}".format(
        local_core_ca_file, certificate))
    local_mqttc.configureCredentials(
        local_core_ca_file, private_key, certificate
    )
    local_mqttc.configureOfflinePublishQueueing(10, DROP_OLDEST)

    if not utils.mqtt_connect(mqtt_client=local_mqttc, core_info=local['core']):
        raise EnvironmentError("Connection to GG Core MQTT failed.")

    # get a shadow client to receive commands
    master_shadow_client = AWSIoTMQTTShadowClient(ggd_name)
    log.info("[initialize] remote ca_file:{0} cert:{1}".format(
        local_core_ca_file, certificate))
    remote_mqttc = master_shadow_client.getMQTTConnection()
    remote_mqttc.configureCredentials(
        remote_core_ca_file, private_key, certificate
    )

    if not utils.mqtt_connect(mqtt_client=master_shadow_client,
                              core_info=remote['core']):
        raise EnvironmentError("Connection to Master Shadow failed.")

    # create and register the shadow handler on delta topics for commands
    # with a persistent connection to the Master shadow
    master_shadow = master_shadow_client.createShadowHandlerWithName(
        cfg['misc']['master_shadow_name'], True)
    log.info("[initialize] created handler for shadow name: {0}".format(
        cfg['misc']['master_shadow_name']
    ))
    token = master_shadow.shadowGet(shadow_mgr, 5)
    log.info("[initialize] shadowGet() tk:{0}".format(token))

    return local_mqttc, remote_mqttc, master_shadow
Ejemplo n.º 4
0
class Robot:
    """
    Class Robot.

    Used to interact with the robot, it needs a cloud instance
    """

    command = None

    class Commands:
        """
        The robot mqtt command class.

        Used for the mqtt commands
        """

        start: None
        stop: None
        pause: None
        dock: None
        status: None
        find: None
        resume: None

        def __init__(self, robot):
            """
            Declare the partial functools.

            Used to gate what command are sent through mqtt
            """
            self.start = functools.partial(robot._cmd, 'start')
            self.stop = functools.partial(robot._cmd, 'stop')
            self.pause = functools.partial(robot._cmd, 'pause')
            self.dock = functools.partial(robot._cmd, 'dock')
            self.status = functools.partial(robot._cmd, 'status')
            self.find = functools.partial(robot._cmd, 'find')
            self.resume = functools.partial(robot._cmd, 'resume')

    def __init__(self, cloud=None, rid=None, output_raw=None):
        """
        Initialize the robot instance.

        Check if a cloud is provided and
        set the current map id.
        """
        self.command = Robot.Commands(self)
        # alias for hass
        self.send_command = self._cmd

        # if no cloud connexion is passed,create one using provided credentials
        if not cloud:
            raise Exception('You need to provide a cloud connection')
        else:
            self._cloud = cloud

        # use provided id or first robot available
        if rid:
            self._id = rid
        else:
            self._id = list(self._cloud.robots())[0]

        self._current_map_id = None
        self._current_user_pmapv_id = None
        self.maps()
        self.device = None
        self.output_raw = output_raw
        self.name = None
        self.shadow_client = None

    def connect(self):
        """
        Instantiate mqtt clients and delete them when exiting.

        We use AWSIoTMQTTShadowClient to create our MQTT connection.
        This manager will close the connection on exit
        """
        self.shadow_client = AWSIoTMQTTShadowClient(self._cloud.app_id +
                                                    str(os.urandom(6)),
                                                    useWebsocket=True)
        self.shadow_client.configureEndpoint(self._cloud.mqtt_endpoint, 443)
        setuppath = '/usr/local/etc/aws-root-ca1.cer'
        pippath = site.USER_SITE if path.exists(
            "%s/usr/local/etc/aws-root-ca1.cer" %
            site.USER_SITE) else get_python_lib()
        cerpath = setuppath if path.exists(
            setuppath) else "%s/usr/local/etc/aws-root-ca1.cer" % pippath
        self.shadow_client.configureCredentials(cerpath)
        self.shadow_client.configureIAMCredentials(self._cloud.access_key_id,
                                                   self._cloud.secret_key,
                                                   self._cloud.session_token)
        self.shadow_client.configureAutoReconnectBackoffTime(1, 128, 20)
        self.shadow_client.configureConnectDisconnectTimeout(10)
        self.shadow_client.configureMQTTOperationTimeout(5)
        # Set keepAlive interval to be 1 second and connect
        # Raise exception if there is an error in connecting to AWS IoT

        try:
            if not self.shadow_client.connect(5):
                raise Exception('AWSIoTMQTTShadowClientCouldNotConnect')
        except ValueError as e:
            logger.error(
                "shadow_client.connect returned '%s'"
                ', credentials are not authorized.', str(e))
            return -1
        self.device = self.shadow_client.createShadowHandlerWithName(
            self._id, True)
        self.connection = self.shadow_client.getMQTTConnection()
        logger.info('[+] mqtt connected')

    def disconnect(self):
        """Disconnect the mqtt stuff."""
        logger.info('[+] mqtt disconnected')
        self.connection.disconnect()

    # return maps and set active one
    def maps(self):
        """
        Return the map lists.

        Used to return a map lists and to set the active one in the instance
        only retrieve first map for now (fixme)
        """
        maps = []
        params = {'visible': 'true', 'activeDetails': '1'}
        maps = self._cloud.api.get(self._id, 'pmaps', params=params)
        if maps:
            path = ['active_pmapv_details', 'active_pmapv', 'pmap_id']
            self._current_map_id = maps[0][path[0]][path[1]][path[2]]
            self._current_user_pmapv_id = maps[0]['user_pmapv_id']
        return maps

    def rooms(self):
        """
        Return the room lists.

        Retrieve a correctly formated room list for humans
        """
        if self.maps():
            return (self.maps()[0]['active_pmapv_details']['regions'])
        else:
            return []

    def missions(self):
        """
        Return achieved mission list.

        return a json with the list of the finished missions and their statuses
        """
        params = {'filterType': 'omit_quickly_canceled_not_scheduled'}
        return self._cloud.api.get(self._id, 'missionhistory', params=params)

    def evac_history(self):
        """
        Return logs of evacuations.

        return a json with logs of evacuations
        """
        params = {'robotId': self._id, 'maxAge': 90}
        return self._cloud.api.get('evachistory', params=params)

    def timeline(self):
        """
        Return event timeline.

        return a json with the event timeline
        """
        params = {'event_type': 'HKC', 'details_type_filter': 'all'}
        return self._cloud.api.get('robots',
                                   self._id,
                                   'timeline',
                                   params=params)

    def vector_map(self, map_id=None, user_pmapv_id=None):
        """
        Return a map as json.

        Return a json with coordinates of the map
        and history of the mission if any.
        """
        if not map_id:
            map_id = self._current_map_id
        if not user_pmapv_id:
            user_pmapv_id = self._current_user_pmapv_id
        return self._cloud.api.get(self._id, 'pmaps', map_id, 'versions',
                                   user_pmapv_id, 'umf')

    def _make_payload(self, room_ids, cmd):
        payload = {
            'state': 'desired',
            'command': cmd,
            'initiator': 'rmtApp',
            'ordered': 0,
        }
        if cmd == 'start' and room_ids:
            logger.info('start cleaning of :')
            for room_id in room_ids.split(','):
                logger.info('  - %s (%s)', self.get_room_name(room_id),
                            room_id)
            regions = [{'type':'rid', 'region_id': room_id}
                       for room_id in room_ids.split(',')] \
                if ',' in room_ids else [{'region_id': room_ids, 'type': 'rid'}]
            payload.update({
                'pmap_id': self._current_map_id,
                'regions': regions,
                'user_pmapv_id': self._current_user_pmapv_id
            })
        return payload

    def _cmd(self, cmd, room_ids=None, print_output=_output_status):
        topic = '%s/things/%s/cmd' % (self._cloud.mqtt_topic, self._id)
        qos = 1

        payload = self._make_payload(room_ids, cmd)

        if cmd == 'status':
            try:
                self.device.shadowGet(print_output, 5)
            except Exception as e:
                logger.info('shadow get failed, exception: %s', e)
                logger.info('trying to refresh the connection (and the aws \
                             credentials)')
                self.disconnect()
                self.connect()
                self.device.shadowGet(print_output, 5)

            self.device.shadowRegisterDeltaCallback(print_output)
            return 0  # exit(0)
        logger.info('executing command %s on robot %s, payload : %s', cmd,
                    self._id, payload)

        if self.connection.publish(topic, json.dumps(payload), qos):
            try:
                self.device.shadowGet(print_output, 5)
            except Exception as e:
                logger.info('shadow get failed, exception: %s', e)
                logger.info('trying to refresh the connection (and the aws \
                             credentials)')
                self.disconnect()
                self.connect()
                self.device.shadowGet(print_output, 5)
            self.device.shadowRegisterDeltaCallback(print_output)
        else:
            raise Exception('MqttPublish%sError' % cmd)

    def current_state(self, state):
        """Return state as expected by the hass module."""
        # https://github.com/NickWaterton/Roomba980-Python/blob/master/roomba/roomba.py
        states = {
            'charge': 'Charging',
            'new': 'New Mission',
            'run': 'Running',
            'resume': 'Running',
            'hmMidMsn': 'Recharging',
            'recharge': 'Recharging',
            'stuck': 'Stuck',
            'hmUsrDock': 'User Docking',
            'dock': 'Docking',
            'dockend': 'Docking - End Mission',
            'cancelled': 'Cancelled',
            'stop': 'Stopped',
            'pause': 'Paused',
            'hmPostMsn': 'End Mission',
            '': None
        }
        return states[state]

    def set_preference(self, **kwargs):
        """Set preferences in robot (not implemented)."""
        logger.info('Set preference not implemented for %s', self._id)
        logger.info('-- Received keys --')
        if kwargs is not None:
            for key, value in kwargs.iteritems():
                logger.info('%s == %s' % (key, value))
        logger.info('-- End of Received keys --')

    def get_room_id(self, name):
        """Get room id from name."""
        for room in self.rooms():
            if name == room['name']:
                return room['id']

    def get_room_name(self, room_id):
        """Get room name from id."""
        for room in self.rooms():
            if room_id == room['id']:
                return room['name']
Ejemplo n.º 5
0
    myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(config.clientId,
                                                      useWebsocket=True)
    myAWSIoTMQTTShadowClient.configureEndpoint(config.host, config.port)
    myAWSIoTMQTTShadowClient.configureCredentials(config.rootCAPath)
else:
    myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(config.clientId)
    myAWSIoTMQTTShadowClient.configureEndpoint(config.host, config.port)
    myAWSIoTMQTTShadowClient.configureCredentials(config.rootCAPath,
                                                  config.privateKeyPath,
                                                  config.certificatePath)

# AWSIoTMQTTShadowClient configuration
myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10)  # 10 sec
myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5)  # 5 sec
MQTTClient = myAWSIoTMQTTShadowClient.getMQTTConnection()
MQTTClient.configureOfflinePublishQueueing(5, DROP_OLDEST)
# Connect to AWS IoT Shadow
myAWSIoTMQTTShadowClient.connect()

# Create a deviceShadow with persistent subscription
deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(
    config.thingName, True)

print('Connecting to MQTT server and setting up callbacks...')
jobsClient.connect()
jobExecutor = JobExecutor(config, deviceShadowHandler)
jobsMsgProc = JobsMessageProcessor(jobsClient, config.clientId, jobExecutor)

print('Starting to process jobs...')
while True:
Ejemplo n.º 6
0
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient

#for cert based connection
myShadowClient = AWSIoTMQTTShadowClient("raspberry-pi")

myShadowClient.configureEndpoint("a1xugslbalqdxo.iot.us-east-1.amazonaws.com", 8883)

myShadowClient.configureCredentials("/home/pi/python_mqtt/aws-iot-certs/rootCA.pem.crt",
                                    "/home/pi/python_mqtt/aws-iot-certs/c6417d9f55-private.pem.key",
                                    "/home/pi/python_mqtt/aws-iot-certs/c6417d9f55-certificate.pem.crt")

#myShadowClient.configureConnectionDisconnectTimeout(10)
myShadowClient.configureMQTTOperationTimeout(5)

myShadowClient.connect()
myDeviceShadow = myShadowClient.createShadowHandlerWithName("Bot", True)

payload = json.dumps({
    "state":{
        "reported": {
            "this_thing_is_alive": "I am Raspberry"
            }
        }
    })

#myDeviceShadow.shadowGet(customCallback, 5)
#myDeviceShadow.shadowUpdate(payload, shadowUpdate, 5)
myMQTTClient = myShadowClient.getMQTTConnection()
myMQTTClient.publish("topic/raspberry-pi/messages", "Payload message", 1)

Ejemplo n.º 7
0
def iot_setup():
    # imports variable to be configured and used in delta_handler f(x)
    global myDeviceShadow

    # Get device configuration details
    with open('config.json', 'r') as cfg:
        device = json.load(cfg)
    thing_uid = device['thing_uid']

    # Get keyfile paths
    key_dir = f'{os.getcwd()}/keys/'

    if os.path.exists(key_dir):
        try:
            with open(f'{key_dir}{thing_uid}.pem.crt', 'r') as r:
                root_file = f'{key_dir}RootCA.pem'
                key_file = f'{key_dir}{thing_uid}.private.key'
                crt_file = f'{key_dir}{thing_uid}.pem.crt'
        except FileNotFoundError as err:
            print(f'Issue with filenames in <{key_dir}>')
            print(str(err))
    else:
        print(f'Path <{key_dir} does not exist; verify working directory')

    # Certificate based connection
    myShadowClient = AWSIoTMQTTShadowClient(thing_uid)
    print(f'Shadow Client: {myShadowClient}')
    print(f'Shadow Client ID: {thing_uid}')

    # Configuration for TLS mutual authentication
    myShadowClient.configureEndpoint(device['endpt'], int(device['prt']))
    myShadowClient.configureCredentials(root_file, key_file, crt_file)

    myShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
    myShadowClient.configureConnectDisconnectTimeout(10)  # 10 sec
    myShadowClient.configureMQTTOperationTimeout(5)  # 5 sec

    print('shadow client configured')

    myShadowClient.connect()

    print('shadow client connected')

    # Create a device shadow instance using persistent subscriptions
    myDeviceShadow = myShadowClient.createShadowHandlerWithName(
        thing_uid, True)

    with open('default_payloads.json', 'r') as defaults:
        tmp = json.load(defaults)

    shadow_doc = tmp['default_shadow']
    payload = tmp['default_payload']

    # Shadow operations
    #init_shadow = myDeviceShadow.shadowGet(customShadowCallback, 5)

    shadow_doc['state']['reported']['property'] = 0
    shadow_doc['state']['reported']['state'] = 'initialized'
    shadow_doc['state']['reported']['time'] = f'{datetime.now()}'

    myDeviceShadow.shadowUpdate(json.dumps(shadow_doc),
                                customShadowCallback_Update, 5)
    #myDeviceShadow.shadowDelete(customShadowCallback_Delete, 5)
    myDeviceShadow.shadowRegisterDeltaCallback(customShadowCallback_Delta)
    #myDeviceShadow.shadowUnregisterDeltaCallback()

    print('shadow handler configured')

    # MQTT Client operations
    myMQTTClient = myShadowClient.getMQTTConnection()

    payload['mssg'] = 'MQTT live'
    payload['time'] = f'{datetime.now()}'
    payload['uid'] = thing_uid

    myMQTTClient.subscribe('myTopic', 1, customMssgCallback)
    sleep(0.1)
    myMQTTClient.publish("myTopic", json.dumps(payload), 0)

    print('mqtt client connection active')

    return (myDeviceShadow, myMQTTClient, payload)
Ejemplo n.º 8
0
    shadowClient = AWSIoTMQTTShadowClient(clientId)
    shadowClient.configureEndpoint(host, port)
    shadowClient.configureCredentials(rootCAPath, privateKeyPath,
                                      certificatePath)

# AWSIoTMQTTShadowClient configuration
# Configure the auto-reconnect backoff to start with 1 second and use 32 seconds as a maximum back off time.
# Connection over 20 seconds is considered stable and will reset the back off time back to its base.
shadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
# Used to configure the time in seconds to wait for a CONNACK or a disconnect to complete.
shadowClient.configureConnectDisconnectTimeout(10)  # 10 sec
# Used to configure the timeout in seconds for MQTT QoS 1 publish, subscribe and unsubscribe.
shadowClient.configureMQTTOperationTimeout(5)  # 5 sec

shadowClient.connect()
client = shadowClient.getMQTTConnection()
# Used to configure the queue size and drop behavior for the offline requests queueing.
client.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
time.sleep(1)

###################################
# Shadow of device
# Used to remotely set cycle time
###################################


class DeviceAnalyzerShadow:
    def shadowCallback_Update(self, payload, responseStatus, token):
        if responseStatus == "timeout":
            print("Update request " + token + " time out!")
            self.sendReportedState()
Ejemplo n.º 9
0
# For certificate based connection
myShadowClient = AWSIoTMQTTShadowClient("myClientID")

# Basic ops
myShadowClient.connect()

# Create a device shadow instance using persistent subscription
myDeviceShadow = myShadowClient.createShadowHandlerWithName("Bot", True)

# Shadow operations
myDeviceShadow.shadowGet(customCallback, 5)
myDeviceShadow.shadowUpdate(myJSONPayload, customCallback, 5)
myDeviceShadow.shadowDelete(customCallback, 5)
myDeviceShadow.shadowRegisterDeltaCallback(customCallback)
myDeviceShadow.shadowUnregisterDeltaCallback()

# To retrieve MQTTClient to perform plain MQTT ops along with shadow ops
myMQTTClient = myShadowClient.getMQTTConnection()
myMQTTClient.publish("plainMQTTTopic", "Payload", 1)

# Progressive Reconect Backoff
# When non-client-side disconnect occurs, SDK will auto-reconnect
AWSIoTPythonSDK.MQTTLib.AWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(
    baseReconnectQuietTimeSecond, maxReconnectQuietTimeSecond,
    stableConnectionTimeSecond)
# Defaults:
# baseReconnectQuietTimeSecond = 1;
# maxReconnectQuietTimeSecond = 32;
# stableConnectionTimeSecond = 20;
Ejemplo n.º 10
0
class AWSIoTMQTTShadowClientGenerator:
    def __init__(self,
                 host,
                 rootCAPath,
                 certificatePath,
                 privateKeyPath,
                 thingName,
                 clientId,
                 topic,
                 useWebsocket=False):
        self.host = host
        self.rootCAPath = rootCAPath
        self.certificatePath = certificatePath
        self.privateKeyPath = privateKeyPath
        self.useWebsocket = useWebsocket
        self.thingName = thingName
        self.clientId = clientId
        self.topic = topic

        if useWebsocket and certificatePath and privateKeyPath:
            print(
                "X.509 cert authentication and WebSocket are mutual exclusive. Please pick one."
            )
            exit(2)

        if not useWebsocket and (not certificatePath or not privateKeyPath):
            print("Missing credentials for authentication.")
            exit(2)

        # Configure logging
        logger = logging.getLogger("AWSIoTPythonSDK.core")
        logger.setLevel(logging.INFO)
        streamHandler = logging.StreamHandler()
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        streamHandler.setFormatter(formatter)
        logger.addHandler(streamHandler)

        # Init AWSIoTMQTTShadowClient
        self.myAWSIoTMQTTShadowClient = None
        self.myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId)
        # AWSIoTMQTTShadowClient configuration
        self.myAWSIoTMQTTShadowClient.configureEndpoint(host, 8883)
        self.myAWSIoTMQTTShadowClient.configureCredentials(
            rootCAPath, privateKeyPath, certificatePath)
        self.myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(
            1, 32, 20)
        self.myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(
            10)  # 10 sec
        self.myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5)  # 5 sec
        # Connect to AWS IoT
        self.myAWSIoTMQTTShadowClient.connect()
        time.sleep(2)

        # Init and configure AWSIoTMQTTClient. This is so I can publish to non-shadow topics
        self.myAWSIoTMQTTClient = self.myAWSIoTMQTTShadowClient.getMQTTConnection(
        )
        self.myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
        self.myAWSIoTMQTTClient.configureOfflinePublishQueueing(
            -1)  # Infinite offline Publish queueing
        self.myAWSIoTMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
        self.myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
        self.myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)  # 5 sec

        # Subscribe to MQTT topic
        self.myAWSIoTMQTTClient.subscribe(self.topic, 1,
                                          self.customMqttCallback)

        # Create a deviceShadow with persistent subscription
        self.deviceShadowHandler = self.myAWSIoTMQTTShadowClient.createShadowHandlerWithName(
            thingName, True)
        self.shadowCallbackContainer_Bot = ShadowCallbackContainer(self)

        # Listen on deltas
        self.deviceShadowHandler.shadowRegisterDeltaCallback(
            self.shadowCallbackContainer_Bot.customShadowCallbackDelta)

        # Create the initial State
        self._desired_state = {}
        self._reported_state = {}
        self._devices = []

    # This is how object will make calls to update its container object
    def setContainerCallback(self, callback):
        self.container_callback = callback

    def shadowUpdate(self, JSONPayload):
        self.deviceShadowHandler.shadowUpdate(JSONPayload,
                                              self.genericCallback, 5)

    def publish(self, JSONPayload):
        try:
            self.myAWSIoTMQTTClient.publish(self.topic, JSONPayload, 1)
        except:
            print("Publish error: ")

    def getState(self):
        _r = '"reported": {"ble_devices":' + json.dumps(
            self._reported_state.values()) + '}'
        _d = '"desired": {"ble_devices":' + json.dumps(
            self._desired_state.values()) + '}'
        return '{"state": {' + _r + ', ' + _d + '} }'

    def updateState(self, value):
        self._reported_state[value["MAC"]] = value
        for x in self._devices:
            self._desired_state[x]["color"] = value["color"]
        print(
            str(datetime.now()) + " Desired state values: " +
            json.dumps(self._desired_state.values()))
        print(
            str(datetime.now()) + " Reported state values: " +
            json.dumps(self._reported_state.values()))
        return self.getState()

    def registerDeviceAddress(self, address):
        print "AWSIoTMQTTShadowClientGenerator is registering device: " + address
        self._devices.append(address)
        # Initialize dictionary for this BLE device. Set color to off
        self._desired_state[address] = {
            "MAC": address,
            "color": "21430000009b"
        }

    def registerNotificationDelegate(self, notificationDelgate):
        self.shadowCallbackContainer_Bot.setNotificationDelegate(
            notificationDelgate)

    # Custom MQTT message callback
    def customMqttCallback(self, client, userdata, message):
        print("Received a new message from the lights topic: ")
        print(message.payload)
        print("from topic: ")
        print(message.topic)
        print("--------------\n\n")
        print("Setting PiHub global state with new value")
        #{"state": {"desired": {"property": "2142019b"}}}
        d = json.loads(message.payload)
        self.container_callback(d["state"]["desired"]["property"])

    def genericCallback(self, payload, responseStatus, token):
        # payload is a JSON string ready to be parsed using json.loads(...)
        # in both Py2.x and Py3.x
        if responseStatus == "timeout":
            print("Update request " + token + " time out!")
        if responseStatus == "accepted":
            payloadDict = json.loads(payload)
            print("~~~~~~~~~~~~~~~~~~~~~~~")
            print("Update request with token: " + token + " accepted!")
            print("property: " + json.dumps(payloadDict))
            print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")
        if responseStatus == "rejected":
            print("Update request " + token + " rejected!")
Ejemplo n.º 11
0
    shadow_client = AWSIoTMQTTShadowClient(clientId)
    shadow_client.configureEndpoint(ggcAddr, 8883)
    shadow_client.configureCredentials(rootCAPath, privateKeyPath,
                                       certificatePath)

    # Config AWSIoTMQTTShadowClient
    shadow_client.configureAutoReconnectBackoffTime(1, 32, 20)
    shadow_client.configureConnectDisconnectTimeout(10)  # 10 sec
    shadow_client.configureMQTTOperationTimeout(5)  # 5 sec

    # Connect to AWS IoT
    shadow_client.connect()

    # Create a deviceShadow with persistent subscription
    shadow_handler = shadow_client.createShadowHandlerWithName(thingName, True)
    shadow_mqttcli = shadow_client.getMQTTConnection()
    shadow_container = ShadowTelemetryContainer(shadow_handler, shadow_mqttcli,
                                                **deviceParams)

    # Create a deviceShadow doc
    JSONPayload = json.dumps({
        'state': {
            'reported': {
                'running': False
            }
        }
    }).encode()
    shadow_container.shadow_handler.shadowUpdate(
        JSONPayload, shadow_container.callback_update, 5)

    # Listen on deltas
Ejemplo n.º 12
0
        cfg = GroupConfigFile(args.config_file)

        web_name = cfg['devices']['GGD_web']['thing_name']
        # get a shadow client to receive commands
        mqttc_shadow_client = AWSIoTMQTTShadowClient(web_name)
        mqttc_shadow_client.configureEndpoint(ggd_config.master_core_ip,
                                              ggd_config.master_core_port)
        mqttc_shadow_client.configureCredentials(
            CAFilePath=dir_path + "/certs/master-server.crt",
            KeyPath=dir_path + "/certs/GGD_web.private.key",
            CertificatePath=dir_path + "/certs/GGD_web.certificate.pem.crt")

        if not mqtt_connect(mqttc_shadow_client):
            raise EnvironmentError("connection to Master Shadow failed.")

        mqttc = mqttc_shadow_client.getMQTTConnection()

        # create and register the shadow handler on delta topics for commands
        global master_shadow
        master_shadow = mqttc_shadow_client.createShadowHandlerWithName(
            "MasterBrain",
            True)  # persistent connection with Master Core shadow

        token = master_shadow.shadowGet(shadow_mgr, 5)
        log.debug("[initialize] shadowGet() tk:{0}".format(token))

        for t in ggd_config.convey_topics:
            mqttc.subscribe(t, 1, topic_update)
            log.info('[initialize] subscribed to topic:{0}'.format(t))

        for t in ggd_config.sort_bridge_topics:
Ejemplo n.º 13
0
    print("Discovery failed after %d retries. Exiting...\n" %
          (MAX_DISCOVERY_RETRIES))
    sys.exit(-1)

# Init AWSIoTMQTTShadowClient
myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId)
myAWSIoTMQTTShadowClient.configureEndpoint(host, port)
myAWSIoTMQTTShadowClient.configureCredentials(groupCA, privateKeyPath,
                                              certificatePath)
# myAWSIoTMQTTShadowClient.getMQTTConnection().onMessage = customOnMessage

# AWSIoTMQTTShadowClient configuration
myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10)  # 10 sec
myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5)  # 5 sec
myAWSIoTMQTTShadowClient.getMQTTConnection().configureOfflinePublishQueueing(
    10)  # Infinite offline Publish queueing
myAWSIoTMQTTShadowClient.getMQTTConnection().configureDrainingFrequency(
    2)  # Draining: 2 Hz

# Create a deviceShadow with persistent subscription
deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(
    topic, True)

# Delete shadow JSON doc
deviceShadowHandler.shadowDelete(customShadowCallback_Delete, 5)

# Listen on deltas
deviceShadowHandler.shadowRegisterDeltaCallback(customShadowCallback_Delta)

# Iterate through all connection options for the core and use the first successful one
connected = False