def setup_aws_shadow_client(host, rootCAPath, privateKeyPath, certificatePath, device_name): # 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 shadow = AWSIoTMQTTShadowClient(device_name + "-client") shadow.configureEndpoint(host, 8883) shadow.configureCredentials(rootCAPath, privateKeyPath, certificatePath) # AWSIoTMQTTShadowClient configuration shadow.configureAutoReconnectBackoffTime(1, 32, 20) shadow.configureConnectDisconnectTimeout(10) # 10 sec shadow.configureMQTTOperationTimeout(5) # 5 sec #Last Will shadow.configureLastWill('my/things/' + device_name + '/update', '{"state":{"reported":{"connected":"false"}}}', 1) # Connect to AWS IoT shadow.connect() # Create a deviceShadow with persistent subscription client = shadow.createShadowHandlerWithName(device_name, True) return shadow, client
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
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
newPayload = '{"state":{"reported":' + deltaMessage + '}}' self.deviceShadowInstance.shadowUpdate(newPayload, None, 5) LEDPIN = 14 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # Ignore warning for now GPIO.setup(LEDPIN, GPIO.OUT, initial=GPIO.LOW) clientId = "mypythoncodeled" thingName = "LED" myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId) myAWSIoTMQTTShadowClient.configureEndpoint( "a2c6vtfn7g8m57-ats.iot.us-east-1.amazonaws.com", 8883) myAWSIoTMQTTShadowClient.configureCredentials("root-CA.pem", "LED-private.pem.key", "LED.pem.crt") # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName( thingName, True) shadowCallbackContainer_Bot = shadowCallbackContainer(deviceShadowHandler) # Listen on deltas deviceShadowHandler.shadowRegisterDeltaCallback( shadowCallbackContainer_Bot.customShadowCallback_Delta) # Loop forever while True:
SHADOW_HANDLER = "ColorPiRpi" # Automatically called whenever the shadow is updated. def myShadowUpdateCallback(payload, responseStatus, token): print() print('UPDATE: $aws/things/' + SHADOW_HANDLER + '/shadow/update/#') print("payload = " + payload) print("responseStatus = " + responseStatus) print("token = " + token) # Create, configure, and connect a shadow client. myShadowClient = AWSIoTMQTTShadowClient(SHADOW_CLIENT) myShadowClient.configureEndpoint(HOST_NAME, 8883) myShadowClient.configureCredentials(ROOT_CA, PRIVATE_KEY, CERT_FILE) myShadowClient.configureConnectDisconnectTimeout(10) myShadowClient.configureMQTTOperationTimeout(5) myShadowClient.connect() # Create a programmatic representation of the shadow. myDeviceShadow = myShadowClient.createShadowHandlerWithName( SHADOW_HANDLER, True) # Keep generating random test data until this script # stops running. # To stop running this script, press Ctrl+C. while True: # Generate random True or False test data to represent # okay or low moisture levels, respectively. moisture = random.choice([True, False])
# Configure logging logger = logging.getLogger("AWSIoTPythonSDK.core") logger.setLevel(logging.DEBUG) streamHandler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') streamHandler.setFormatter(formatter) logger.addHandler(streamHandler) # Init AWSIoTMQTTShadowClient myAWSIoTMQTTShadowClient = None if useWebsocket: myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId, useWebsocket=True) myAWSIoTMQTTShadowClient.configureEndpoint(host, 443) myAWSIoTMQTTShadowClient.configureCredentials(rootCAPath) else: myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId) myAWSIoTMQTTShadowClient.configureEndpoint(host, 8883) myAWSIoTMQTTShadowClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath) # AWSIoTMQTTShadowClient configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() #myAWSIoTMQTTShadowClient.shadowGet(customShadowCallback_Delta, 5)
print("Error in discovery!") print("Type: %s" % str(type(e))) print("Error message: %s" % e.message) retryCount -= 1 print("\n%d/%d retries left\n" % (retryCount, MAX_DISCOVERY_RETRIES)) print("Backing off...\n") backOffCore.backOff() if not discovered: print("Discovery failed after %d retries. Exiting...\n" % (MAX_DISCOVERY_RETRIES)) sys.exit(-1) # Iterate through all connection options for the core and use the first successful one myAWSIoTShadowClient = AWSIoTMQTTShadowClient(clientId) myAWSIoTShadowClient.configureCredentials(groupCA, privateKeyPath, certificatePath) myAWSIoTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTShadowClient.configureMQTTOperationTimeout(5) # 5 sec connected = False for connectivityInfo in coreInfo.connectivityInfoList: currentHost = connectivityInfo.host currentPort = connectivityInfo.port print("Trying to connect to core at %s:%d" % (currentHost, currentPort)) myAWSIoTShadowClient.configureEndpoint(currentHost, currentPort) try: myAWSIoTShadowClient.connect() connected = True break except BaseException as e: print("Error in connect!")
# Use Amazon's basicShadowUpdater.py sample to test the AWS connection # Original code at https://github.com/aws/aws-iot-device-sdk-python/blob/master/samples/basicShadow/basicShadowUpdater.py import time import serial from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient from callbacks import AWS_ShadowCallback_Update, customShadowCallback_Delete from AWS_details import LoginDetails as details # Separate place to store login details in. # Create an AWS IoT MQTT Client using TLSv1.2 Mutual Authentication myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(details["appName"]) myAWSIoTMQTTShadowClient.configureEndpoint(details["hostname"], details["port"]) myAWSIoTMQTTShadowClient.configureCredentials(details["rootCertificate"], details["privateKey"], details["certificate"]) # AWS IoT MQTT Client connection configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec myAWSIoTMQTTShadowClient.connect() # Connect to AWS IoT deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName( details["thingName"], True) # Delete shadow JSON doc. # Note: If there is no data to be deleted, it will be rejected (doesn't crash/stop the program) deviceShadowHandler.shadowDelete(customShadowCallback_Delete, 5)
def Callback_func_Update(payload, responseStatus, token): print("Update") print(responseStatus) Client_ID = "raspberrypi_lambda" Thing_Name = "raspberrypi_2" Host_Name = "a89fa2yt1cyk2-ats.iot.us-west-2.amazonaws.com" #End Point Root_CA = "/var/task/root-CA.crt" Private_Key = "/var/task/249263565b-private.pem.key" Cert_File = "/var/task/249263565b-certificate.pem.crt" Client = AWSIoTMQTTShadowClient(Client_ID) Client.configureEndpoint(Host_Name, 8883) Client.configureCredentials(Root_CA, Private_Key, Cert_File) Client.configureConnectDisconnectTimeout(10) Client.configureMQTTOperationTimeout(5) Client.connect() #Handler = Client.createShadowHandlerWithName(Thing_Name, True) ''' Handler = Client.createShadowHandlerWithName(Thing_Name, True) m = {"state": {"reported": {"connecting" : None }}} Handler.shadowUpdate(json.dumps(m), Callback_func_Update,5) ''' ''' Handler = Client.createShadowHandlerWithName(Thing_Name, True) m = {"state": {"reported": {"connecting" : "0" }}} Handler.shadowUpdate(json.dumps(m), Callback_func_Update,5) '''
args = parseArgs() if not args.certificatePath or not args.privateKeyPath: parser.error("Missing credentials for authentication.") exit(2) # If no --port argument is passed, default to 8883 if not args.port: args.port = 8883 # Init AWSIoTMQTTShadowClient myAWSIoTMQTTShadowClient = None myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(args.clientId) myAWSIoTMQTTShadowClient.configureEndpoint(args.host, args.port) myAWSIoTMQTTShadowClient.configureCredentials(args.rootCAPath, args.privateKeyPath, args.certificatePath) # AWSIoTMQTTShadowClient connection configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() # Create a device shadow handler, use this to update and delete shadow document deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName( args.thingName, True) # Delete current shadow JSON doc
class Iota: # Device State outlet1 = "off" outlet2 = "off" motion = "false" temperature = 0.0 sense = None thingEndpoint = "a3lybv9v64fkof.iot.us-west-2.amazonaws.com" awsDir = "/home/dennis/.aws" # awsDir = "/users/denni/aws" credentialFiles = (awsDir + "/aws-iot-root-ca.pem", awsDir + "/b498bb82fa-private.pem.key", awsDir + "/b498bb82fa-certificate.pem.crt") def __init__(self): logging.basicConfig(filename='iota.log', level=logging.DEBUG) #logging.basicConfig(stream=sys.__stdout__, level=logging.INFO) self.log = logging self.log.info('init(): creating an instance of Iota') self.connect() self.log.info('init(): retrieving AWS Shadow') self.shadow = self.client.createShadowHandlerWithName("iota", True) self.log.info('init(): registering delta callback') self.log.info('init(): Iota created') # Setup the Arduino Firmata interface self.log.info('init(): setting-up firmata') self.board = None for i in range(0, 10): if os.path.exists('/dev/ttyACM' + str(i)): self.log.info('init(): firmata: found serial device: ' + '/dev/ttyACM' + str(i)) self.board = Arduino('/dev/ttyACM' + str(i)) break self.log.info('init(): getting iterator for board') it = util.Iterator(self.board) it.start() self.log.info('init(): started iterator for board') self.board.analog[0].enable_reporting() self.board.analog[1].enable_reporting() self.d7 = self.board.get_pin('d:7:i') self.d8 = self.board.get_pin('d:8:o') self.d9 = self.board.get_pin('d:9:o') self.log.info('init(): finished firmata setup') def __del__(self): self.log.info("del(): disconnecting") self.disconnect() def connect(self): self.log.info('init(): connecting to AWS Shadow') self.client = AWSIoTMQTTShadowClient("iota") self.client.configureEndpoint(self.thingEndpoint, 8883) self.client.configureCredentials(*self.credentialFiles) self.client.configureConnectDisconnectTimeout(10) # 10 sec self.client.configureMQTTOperationTimeout(5) # 5 sec self.client.connect() self.log.info('init(): connected to AWS Shadow') def disconnect(self): self.log.info('disconnect(): disconnecting device client from AWS') self.client.disconnect() self.log.info('disconnect(): disconnected device client from AWS') def onResponse(self, payload, responseStatus, token): try: self.log.info("iota.onResponse(): responseStatus: " + responseStatus) # logging.debug("iota.onResponse(): responseStatus: " + responseStatus) response = json.loads(payload) pretty = json.dumps(response, indent=4) self.log.info("onResponse(): responseStatus: " + str(responseStatus) + ", token: " + str(token) + ", payload: " + str(pretty)) # logging.debug("onResponse(): responseStatus: " + str(responseStatus) + ", token: " + str(token) + ", payload: " + str(ps)) self.log.info("iota.onResponse(): payload: " + str(pretty)) except Exception as ex: self.log.info("onResponse() exception: " + str(ex)) def onDelta(self, payload, responseStatus, token): try: self.log.info("iota.onDelta(): responseStatus: " + responseStatus) changes = [] deltas = json.loads(payload) pretty = json.dumps(deltas, indent=4) for delta in deltas['state'].keys(): if delta == "outlet1": value = deltas['state'][delta] if value in ['on', 'off']: self.setOutlet1(value) changes.append(( delta, value, )) else: self.log.info( 'onDelta() invalid value for delta update to: ' + str(value)) elif delta == "outlet2": value = deltas['state'][delta] if value in ['on', 'off']: self.setOutlet2(value) changes.append(( delta, value, )) else: self.log.info( 'onDelta() invalid value for delta update to: ' + str(value)) if len(changes) > 0: self.log.info('onDelta() detected changes to: ' + str(changes)) self.shadowUpdate(reported=changes) self.log.info("onDelta(): responseStatus: " + str(responseStatus) + ", token: " + str(token) + ", payload: " + str(pretty)) except Exception as ex: self.log.info("onDelta() exception: " + str(ex)) def shadowUpdate(self, reported=None, desired=None): self.log.info( 'iota.shadowUpdate(): starting. preparing to update device shadow for reported: ' + str(reported) + ", or desired: " + str(desired)) update = {'state': {'reported': {}, 'desired': {}}} if reported is not None: for change in reported: update['state']['reported'][change[0]] = change[1] if desired is not None: for change in desired: update['state']['desired'][change[0]] = change[1] doc = json.dumps(update) self.log.info( 'iota.shadowUpdate(): calling shadow.shadowUpdate. srcJSONPayload: ' + doc) self.shadow.shadowUpdate(doc, onResponse, 5) self.log.info( 'iota.shadowUpdate(): finished request to update device shadow') def getShadow(self): logging.info("getShadow(): retrieving shadow doc from AWS") shadow = self.shadow.shadowGet(onResponse, 5) return (shadow) def getOutlet1(self): logging.info("getOutlet1: getting value of outlet1") return self.outlet1 def setOutlet1(self, value): if value in ['on', 'off']: logging.info("setOutlet1: setting value of outlet1 to: " + value) self.outlet1 = value if value == 'on': self.d8.write(False) else: self.d8.write(True) else: logging.error( "setOutlet1: invalid value given for setting outlet1: " + value) def getOutlet2(self): logging.info("getOutlet2: getting value of outlet2") return self.outlet2 def setOutlet2(self, value): if value in ['on', 'off']: logging.info("setOutlet2 setting value of outlet2 to: " + value) self.outlet2 = value if value == 'on': self.d9.write(False) else: self.d9.write(True) else: logging.error( "setOutlet2: invalid value given for setting outlet2: " + value) def getTemp(self): logging.info("getTemp(): getting temperature through Firmata") return (str(round(self.board.analog[1].read() * 500))) def getRH(self): logging.info("getTemp(): getting relative humidity through Firmata") return (str(round(100 * self.board.analog[0].read()))) def getMotion(self): logging.info("getTemp(): getting motion through Firmata") mot = self.d7.read() if mot == None: return 'na' else: return str(mot) def setMotion(self, value): if value in ['true', 'false']: logging.info("setMotion setting value of motion to: " + value) self.motion = value else: logging.error( "setMotion: invalid value given for setting motion: " + value) def getSense(self): logging.info("getSense(): getting values of all sensors") return (( self.getTemp(), self.getRH(), self.getMotion(), )) def listen(self): while True: # sense = (temp, rh, motion) sense = self.getSense() if self.sense is None or sense != self.sense: changes = [] ''' if self.sense[0] != sense[0]: changes.append( ("temp", sense[0],) ) if self.sense[1] != sense[1]: changes.append( ("rh", sense[1],) ) if self.sense[2] != sense[2]: changes.append( ("motion", sense[2],) ) ''' changes.append(( "temp", sense[0], )) changes.append(( "rh", sense[1], )) changes.append(( "motion", sense[2], )) self.shadowUpdate(reported=changes) self.sense = sense time.sleep(1)
class ThermoSimAppGUI: _usage = """Usage: Make sure that you put all your credentials under: ./certs/ with the following naming conventions: Root CA file: *CA.crt Certificate file (not required if using MQTT over WebSocket): *.pem.crt Private key file (not required if using MQTT over WebSocket): *.pem.key Use X.509 certificate based mutual authentication: python ThermostatSimulatorApp -e <endpoint> Use MQTT over WebSocket: python ThermostatSimulatorApp -e <endpoint> -w Type "python ThermostatSimulatorApp -h" for detailed command line options. """ _helpInfo = """Available command line options: -e, --endpoint: Your custom AWS IoT custom endpoint -w, --websocket: Use MQTT over websocket -h, --help: Help infomation """ def __init__(self): # Init data members # Connection related self._endpoint = "" self._rootCAFilePathList = "" self._certificateFilePathList = "" self._privateKeyFilePathList = "" self._useWebsocket = False self._AWSIoTMQTTShadowClient = None self._thermostatSimulatorShadowHandler = None # GUI related self._tkRootHandler = tkinter.Tk() self._reportedDataVariable = None self._reportedDataDisplayBox = None self._desiredDataVariable = None self._desiredDataDisplayBox = None self._setTemperatureInputBox = None self._setTemperatureButton = None # Check command line inputs if not self._checkInputs(): raise ValueError("Malformed/Missing command line inputs.") # Create and configure AWSIoTMQTTShadowClient self._AWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient("ThermostatSimulatorApp", useWebsocket=self._useWebsocket) if self._useWebsocket: self._AWSIoTMQTTShadowClient.configureEndpoint(self._endpoint, 443) self._AWSIoTMQTTShadowClient.configureCredentials(self._rootCAFilePathList[0]) else: self._AWSIoTMQTTShadowClient.configureEndpoint(self._endpoint, 8883) self._AWSIoTMQTTShadowClient.configureCredentials(self._rootCAFilePathList[0], self._privateKeyFilePathList[0], self._certificateFilePathList[0]) self._AWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 128, 20) self._AWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) self._AWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # Set keepAlive interval to be 1 second and connect # Raise exception if there is an error in connecting to AWS IoT self._AWSIoTMQTTShadowClient.connect(5) self._thermostatSimulatorShadowHandler = self._AWSIoTMQTTShadowClient.createShadowHandlerWithName("room", True) # Generate GUI self._packModule() # Validate command line inputs # Return False there is any malformed inputs # Return True if all the necessary inputs have been discovered def _checkInputs(self): gotEoughInputs = True # Check command line inputs try: opts, args = getopt.getopt(sys.argv[1:], "hwe:", ["endpoint=", "websocket", "help"]) if len(opts) == 0: raise getopt.GetoptError("No input parameters") for opt, arg in opts: if opt in ("-e", "--endpoint"): self._endpoint = arg if opt in ("-w", "--websocket"): self._useWebsocket = True if opt in ("-h", "--help"): print(self._helpInfo) gotEoughInputs = False except getopt.GetoptError: print(self._usage) gotEoughInputs = False # Check credential files if gotEoughInputs: self._rootCAFilePathList = glob.glob("./certs/*CA.crt") if self._useWebsocket: gotEoughInputs = gotEoughInputs and len(self._rootCAFilePathList) != 0 if not gotEoughInputs: print("Missing rootCA in ./certs/") else: self._certificateFilePathList = glob.glob("./certs/*.pem.crt") self._privateKeyFilePathList = glob.glob("./certs/*.pem.key") gotEoughInputs = gotEoughInputs and len(self._rootCAFilePathList) != 0 and len(self._certificateFilePathList) != 0 and len(self._privateKeyFilePathList) != 0 if not gotEoughInputs: print("Missing rootCA, certificate or private key in ./certs/") return gotEoughInputs def _packModule(self): self._tkRootHandler.title("ThermostatSimulatorApp") self._tkRootHandler.geometry("500x250") self._tkRootHandler.resizable(width=False, height=False) # Pack all frames baseFrame = tkinter.Frame(self._tkRootHandler) temperatureFrame = tkinter.Frame(baseFrame) temperatureFrame.pack(side="top") controlPanelFrame = tkinter.Frame(baseFrame) controlPanelFrame.pack(side="bottom") baseFrame.pack() # Pack all modules for temperature frame self._reportedDataVariable = tkinter.StringVar() self._reportedDataVariable.set("XX.X F") reportedDataTag = tkinter.Label(temperatureFrame, text="Reported Temperature:", justify="left") self._reportedDataDisplayBox = tkinter.Label(temperatureFrame, textvariable=self._reportedDataVariable, font=("Arial", 55), justify="left") # self._desiredDataVariable = tkinter.StringVar() self._desiredDataVariable.set("XX.X F") desiredDataTag = tkinter.Label(temperatureFrame, text="Desired Temperature:", justify="left") self._desiredDataDisplayBox = tkinter.Label(temperatureFrame, textvariable=self._desiredDataVariable, font=("Arial", 55), justify="left") # reportedDataTag.pack() self._reportedDataDisplayBox.pack() desiredDataTag.pack() self._desiredDataDisplayBox.pack() # Create a callback pool self._callbackPoolHandler = ThermoSimAppCallbackPool(self._tkRootHandler, self._reportedDataDisplayBox, self._thermostatSimulatorShadowHandler, self._reportedDataVariable, self._desiredDataVariable) # Pack all modules for control panel frame self._setTemperatureInputBox = tkinter.Entry(controlPanelFrame) self._setTemperatureInputBox.pack(sid="left") self._setTemperatureButton = tkinter.Button(controlPanelFrame, text="SET", command=lambda: self._callbackPoolHandler.buttonCallback(self._setTemperatureInputBox, self._desiredDataVariable)) self._setTemperatureButton.pack() def runApp(self): # Start and run the app self._tkRootHandler.after(500, self._callbackPoolHandler.sendShadowGetForReportedTemperature) # per 500ms self._tkRootHandler.after(500, self._callbackPoolHandler.updateReportedTemperatureDataVariable) # per 500ms self._tkRootHandler.mainloop()
print "Shadow Update Sent" # Create a deviceShadow with persistent subscription shadow = AWSIoTMQTTShadowClient(thingName) # Setup our MQTT client and security certificates # Make sure your certificate names match what you downloaded from AWS IoT # Use the endpoint from the settings page in the IoT console shadow.configureEndpoint(iotEndpoint, 8883) # rootCA.pem is the same for all devices # private.key is device-name.private.key from the ZIP file # cert.pem is device-name.cert.pem from the ZIP file shadow.configureCredentials("credentials/rootCA.pem", "credentials/private.key", "credentials/cert.pem") # AWSIoTMQTTShadowClient configuration shadow.configureAutoReconnectBackoffTime(1, 32, 20) shadow.configureConnectDisconnectTimeout(10) # 10 sec shadow.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT shadow.connect() print "Connect to IoT Core" # Create a deviceShadow with persistent subscription deviceShadowHandler = shadow.createShadowHandlerWithName(thingName, True) # Listen on deltas deviceShadowHandler.shadowRegisterDeltaCallback(customShadowCallback_Delta)
class AWS_RPI: def __init__(self): # Cofigure logging self.logger = logging.getLogger("AWSIoTPythonSDK.core") self.logger.setLevel(logging.DEBUG) self.streamHandler = logging.StreamHandler() self.formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') self.streamHandler.setFormatter(self.formatter) self.logger.addHandler(self.streamHandler) self.awsiotHost = "a130ba174k0fld-ats.iot.us-west-2.amazonaws.com" self.awsiotPort = 443 self.rootCAPath = "/home/pi/Mirror/cerf/VeriSign-Class3-Public-Primary-Certification-Authority-G5.pem" self.privateKeyPath = "/home/pi/Mirror/cerf/78755df119-private.pem.key" self.certificatePath = "/home/pi/Mirror/cerf/78755df119-certificate.pem.crt" self.myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient("RPI_RULE") self.myAWSIoTMQTTShadowClient.configureEndpoint( self.awsiotHost, self.awsiotPort) self.myAWSIoTMQTTShadowClient.configureCredentials( self.rootCAPath, self.privateKeyPath, self.certificatePath) self.myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime( 1, 32, 10) self.myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout( 10) # 10sec self.myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) #5sec self.myAWSIoTMQTTShadowClient._AWSIoTMQTTClient.configureOfflinePublishQueueing( 5, AWSIoTPythonSDK.core.util.enums.DropBehaviorTypes.DROP_OLDEST ) # Infinite offline Publish queueing #connect to AWS IoT self.myAWSIoTMQTTShadowClient.connect() #create a devcie Shadow with persistent subscription self.thingName = "my_rpi" self.deviceShadowHandler = self.myAWSIoTMQTTShadowClient.createShadowHandlerWithName( self.thingName, True) self.temperature = "" self.humidity = "" self.window = "True" self.human_presence = "True" def myShadowCallback_get(self, payload, responseStatus, token): # payload is a JSON string which will be parsed by jason lib print("into myShadowCallback_get") if (responseStatus == "timeout"): return 0 if (responseStatus == "accepted"): payloadDict = json.loads(payload) self.temperature = payloadDict["state"]["reported"]["temperature"] self.humidity = payloadDict["state"]["reported"]["humidity"] self.window = payloadDict["state"]["reported"]["window_is_open"] self.human_presence = payloadDict["state"]["reported"][ "people_at_home"] if (responseStatus == "rejected"): return -1 def myShadowGet(self, timeout=5): print("into myShadowGet") self.deviceShadowHandler.shadowGet(self.myShadowCallback_get, timeout)
#Import SDK packages import json from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient 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)
except KeyError as e: pass finally: return device_shadow.shadowUpdate(json.dumps(state),None,5) def killAll(processList): for i in processList: i.kill() led = gpiozero.LED(21) s3 = boto3.client('CLIENT_ID','ACCESS KEY', 'SECRET ACCESS KEY', region_name = 'us-east-1') bucket_name = 'YOUR BUCKET NAME' shadow_client = AWSIoTMQTTShadowClient("CLIENT ID") shadow_client.configureEndpoint("YOUR ENDPOINT", 8883) shadow_client.configureCredentials("ROOT CA","YOUR PRIVATE KEY", "YOUR CERTIFICATE") device_shadow = shadow_client.createShadowHandlerWithName( "Room_security_1", True) device_shadow2 = shadow_client.createShadowHandlerWithName( "Garage_Lights_1", True) shadow_client.configureConnectDisconnectTimeout(10) shadow_client.configureMQTTOperationTimeout(5) shadow_client.connect(1200) while True: device_shadow.shadowGet(shadow_get_callback, 5) time.sleep(2) device_shadow2.shadowGet(light_shadow_get_callback, 5) time.sleep(2)
class IotClient: def __init__(self, cfg, vehicle, delta_callback=None): self.vehicle = vehicle self.model_num = 0 self._shadow_client = AWSIoTMQTTShadowClient(cfg.CLIENT_NAME) self._shadow_client.configureEndpoint(cfg.IOT_ENDPOINT, 8883) self._shadow_client.configureCredentials(cfg.ROOT_CERT_PATH, cfg.PRIVATE_KEY_PATH, cfg.CERT_PATH_PATH) self._shadow_client.configureConnectDisconnectTimeout(10) # 10 sec self._shadow_client.configureMQTTOperationTimeout(5) # 5 sec if not self._shadow_client.connect(): print("Cannot connect to IoT. This is bad.") self.shadow_handler = self._shadow_client.createShadowHandlerWithName( cfg.THING_NAME, True) # Delete any existing shadow and create a fresh one self.shadow_handler.shadowDelete(self._delete_callback, 5) self.shadow = { "state": { "reported": { "location": 0, "destination": 0, "current_order": "0", } } } self.shadow_handler.shadowUpdate(json.dumps(self.shadow), self._update_callback, 5) # Create subscription to shadow delta topic to receive delivery requests if delta_callback: self.shadow_handler.shadowRegisterDeltaCallback(delta_callback) else: self.shadow_handler.shadowRegisterDeltaCallback( self._delta_callback) def _update_callback(self, payload, response_status, token): ''' Callback function invoked when the shadow handler updates the thing shadow. ''' if response_status == "timeout": print("Update request " + token + " time out!") if response_status == "accepted": payload_dict = json.loads(payload) print("~~~~~~~~~~~~~~~~~~~~~~~") print("Update request with token: " + token + " accepted!") print("Current location: " + str(payload_dict["state"]["reported"]["location"])) print("~~~~~~~~~~~~~~~~~~~~~~~\n\n") if response_status == "rejected": print("Update request " + token + " rejected!") def _delete_callback(self, payload, response_status, token): ''' Callback function invoked when the shadow handler deletes the thing shadow. ''' if response_status == "timeout": print("Delete request " + token + " time out!") if response_status == "accepted": print("~~~~~~~~~~~~~~~~~~~~~~~") print("Delete request with token: " + token + " accepted!") print("~~~~~~~~~~~~~~~~~~~~~~~\n\n") if response_status == "rejected": print("Delete request " + token + " rejected!") def _delta_callback(self, payload, response_status, token): ''' Callback function invoked when the shadow handler receives a new, desired state. ''' print("++++++++DELTA++++++++++") print("Response status: " + response_status) print("Payload: " + payload) payload_dict = json.loads(payload) self._set_model_num(payload_dict) print("+++++++++++++++++++++++\n\n") # self.move_vehicle(model_num) self.shadow_handler.shadowUpdate(json.dumps(self.shadow), self._update_callback, 5) def _set_model_num(self, payload_dict): ''' **Description** Set the model number for the delivery (or for return to kitchen) This function also updates reported local shadow to match desired location and current_order. ''' # The contents of the delta payload will tell us what action to take desired_state = payload_dict['state'] if 'destination' in desired_state and 'current_order' in desired_state: if desired_state['destination'] is not 0: # moving to a table # Get the model to get to the table self.model_num = desired_state['destination'] # Update shadow with new values self.shadow['state']['reported'][ 'location'] = -1 # -1 for moving self.shadow['state']['reported'][ 'destination'] = desired_state['destination'] self.shadow['state']['reported'][ 'current_order'] = desired_state['current_order'] print("Model # to use: " + str(self.model_num)) print("Current shadow: " + str(self.shadow)) elif desired_state['destination'] is 0: # going back to kitchen # The same model we used to get to the table we use to get back to the kitchen self.model_num = self.shadow['state']['reported'][ 'destination'] # Update shadow with new values self.shadow['state']['reported'][ 'location'] = -1 # -1 for moving self.shadow['state']['reported'][ 'destination'] = desired_state['destination'] self.shadow['state']['reported'][ 'current_order'] = desired_state['current_order'] print("Model # to use: " + str(self.model_num)) print("Current shadow: " + str(self.shadow)) def get_model_num(self): ''' **Description** Get the model number for the delivery (or for return to kitchen) ''' return self.model_num def moving(self): ''' **Description** Return True if the rover should be moving, False if not ''' return self.shadow['state']['reported']['location'] is -1 def get_destination(self): ''' **Description** Return the current destination ''' return self.shadow['state']['reported']['destination'] # def move_vehicle(self, model_num): # ''' # **Description** # Uses the specified model number to create a new Keras part for vehicle # then calls vehicle.run to move the rover to the desired destination. # ''' # # Get the current Keras part from vehicle to load new model # print("Using model at " + self.cfg.MODEL_MAP[model_num]) # self.vehicle.get("KerasCategorical").load(self.cfg.MODEL_MAP[model_num]) # try: # self.vehicle.run(rate_hz=self.cfg.DRIVE_LOOP_HZ, # max_loop_count=self.cfg.MAX_LOOPS) # except KeyboardInterrupt: # print('pausing') # self.vehicle.pause() # self.update_shadow_after_stop() # print("leaving move_vehicle") def update_shadow_after_stop(self): ''' Call when the rover stops moving. Update the shadow to reflect that the rover has reached it's destination. ''' print("Updating shadow...") self.shadow['state']['reported']['location'] = self.shadow['state'][ 'reported']['destination'] self.shadow_handler.shadowUpdate(json.dumps(self.shadow), self._update_callback, 5) def update_shadow_demo_lite(self): ''' Called when the rover stops moving after driving the loop during the lite demo scenario. The rover has driven either the left or right path and has returned to the starting point. Shadow should be reset to initial state. ''' print("Resetting shadow...") # Delete any existing shadow and create a fresh one. Doing this right now cause it's easy # This should be changed if I start dev on this again. self.shadow_handler.shadowDelete(self._delete_callback, 5) self.shadow = { "state": { "reported": { "location": 0, "destination": 0, "current_order": "0", } } } self.shadow_handler.shadowUpdate(json.dumps(self.shadow), self._update_callback, 5)
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)
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']
class MyMQTTClient: """ Client to maintain a connection between the Raspberry Pi and the IoT Shadow. """ def __init__(self, display, workout): self.display = display self.workout = workout self.shadowClient = AWSIoTMQTTShadowClient(clientId) self.shadowClient.configureEndpoint(host, port) self.shadowClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath) self.shadowClient.configureAutoReconnectBackoffTime(1, 32, 20) self.shadowClient.configureConnectDisconnectTimeout(10) self.shadowClient.configureMQTTOperationTimeout(1) self.display.updateStatus("Connecting to AWS IoT...") self.display.update() self.shadowClient.connect() self.shadowHandler = self.shadowClient.createShadowHandlerWithName( thingName, True) self.shadowHandler.shadowRegisterDeltaCallback(self.delta_callback) self.gotoIdle() self.display.updateStatus("") self.display.update() def isIdle(self): return self.shadowState['intensity'] == "Idle" def gotoIdle(self): self.shadowState = { 'intensity': "Idle", 'duration': None, 'distance': None } update = { 'state': { 'reported': self.shadowState, 'desired': self.shadowState } } self.shadowHandler.shadowUpdate(json.dumps(update), None, 5) def delta_callback(self, payload, token, arg): delta = json.loads(payload)['state'] print("Delta: ", delta) if 'duration' in delta: self.shadowState['duration'] = delta['duration'] if 'distance' in delta: self.shadowState['distance'] = delta['distance'] if 'intensity' in delta: self.gotoNextState(delta['intensity'], delta) if self.shadowState['intensity'] == "Idle": self.gotoIdle() return update = { 'state': { 'reported': self.shadowState, 'desired': self.shadowState } } self.shadowHandler.shadowUpdate(json.dumps(update), None, 5) def gotoNextState(self, nextState, delta): # Can go from Idle -> Start new workout if self.shadowState['intensity'] == "Idle": if nextState in [ "Easy", "Normal", "Intense", "Interval", "Cardio", "Strength", "Scheduled" ]: if self.workout.createPhases(nextState, self.shadowState['duration'], self.shadowState['distance']): self.shadowState['intensity'] = nextState return True return False # Anything else, we're in the middle of a work out. # Can only abort if nextState == "Abort": self.workout.abort() self.gotoIdle() return True # Ignore the command return False
#deltaMessage = json.dumps(payloadDict["state"]) #print(deltaMessage) # Init AWSIoTMQTTShadowClient------------------------------------ myAWSIoTMQTTShadowClient = None #skywalkers shadow myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient( "zc1bf" ) #this can be any UNIQUE string (for testing with same Thing.. use different client ID's!!!) myAWSIoTMQTTShadowClient.configureEndpoint( "a3te7fgu4kv468-ats.iot.us-west-1.amazonaws.com", 8883) #endpoint and port number myAWSIoTMQTTShadowClient.configureCredentials( "cert/rootCA.pem.crt", "cert/333052c1bf-private.pem.key", "cert/333052c1bf-certificate.pem.crt" ) #root ca and certificate used for secure connection # AWSIoTMQTTShadowClient configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() # Create a deviceShadow with persistent subscription deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName( "Pi_sense01", True)
class SodPlug(object): def device_shadow_handler(): doc = 'The device_shadow_handler property.' def fget(self): return self.device_shadow_handler def fset(self, value): self.device_shadow_handler = value def fdel(self): del self._device_shadow_handler return locals() device_shadow_handler = property(**device_shadow_handler()) def __init__(self, **kwargs): self.device_name = kwargs.get('DeviceName') print('Device name: {}'.format(self.device_name)) self.device_root = kwargs.get('DeviceRoot', './devices') self.device_path = kwargs.get( 'DevicePath', os.path.join(self.device_root, 'credentials', self.device_name)) self.iot_ca_path = kwargs.get('IotCaPath', './root/root-cert.pem') self.cert_path = kwargs.get('CertPath', os.path.join(self.device_path, 'cert.pem')) self.private_key_path = kwargs.get( 'PrivateKeyPath', os.path.join(self.device_path, 'private.key')) self.iot_endpoint = kwargs.get('IotEndPoint') self.ca_name = kwargs.get('CaName', 'root-ca.cert') self.shadow_thing_name = kwargs.get('ThingName', self.device_name) self.max_discovery_retries = int( kwargs.get('MaxDiscoveryRetries', '10')) # noqa: E501 self.ggc_addr_name = kwargs.get('CoreName', 'ggc-core') self.root_ca_path = os.path.join(self.device_path, self.ca_name) for key, value in kwargs.items(): setattr(self, key, value) self.logger = logging.getLogger('AWSIoTPythonSDK.core') self.logger.setLevel(logging.DEBUG) streamHandler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # noqa: E501 streamHandler.setFormatter(formatter) self.logger.addHandler(streamHandler) def update_shadow(self, data): doc = {} doc['state'] = {} doc['state']['desired'] = data json_payload = json.dumps(doc) print('Updating shadow: {}'.format(json_payload)) self.device_shadow_handler.shadowUpdate( json_payload, self.customShadowCallback_Update, # noqa E:501 10) def does_root_cert_exist(self): return os.path.isfile(self.root_ca_path) def check_root_cert(self): if not self.does_root_cert_exist(): self.discover_ggc() else: self.get_ggc_addr() print('Greengrass core has already been discovered.') def configure_mqtt_client(self): self.mqtt_client = self.mqtt_shadow_client.getMQTTConnection() self.mqtt_client.publish('printer', 'test', 0) self.mqtt_client.configureAutoReconnectBackoffTime(1, 32, 20) self.mqtt_client.configureOfflinePublishQueueing(-1) self.mqtt_client.configureDrainingFrequency(2) # Draining: 2 Hz self.mqtt_client.configureConnectDisconnectTimeout(10) # 10 sec self.mqtt_client.configureMQTTOperationTimeout(5) # 5 sec def configure_shadow_client(self): self.mqtt_shadow_client = AWSIoTMQTTShadowClient(self.device_name) self.mqtt_shadow_client.configureEndpoint(self.ggc_host_addr, 8883) # noqa: E501 self.mqtt_shadow_client.configureCredentials(self.root_ca_path, self.private_key_path, self.cert_path) # AWSIoTMQTTShadowClient configuration self.mqtt_shadow_client.configureAutoReconnectBackoffTime( 1, 32, 20) # noqa: E501 self.mqtt_shadow_client.configureConnectDisconnectTimeout(10) self.mqtt_shadow_client.configureMQTTOperationTimeout(5) self.mqtt_shadow_client.connect() def delta_callback(self, payload, responseStatus, token): print('delta received') pass def register_handlers(self): self.device_shadow_handler = self.mqtt_shadow_client.createShadowHandlerWithName( self.shadow_thing_name, True) # noqa: E501 print('Registered shadow handlers for {}'.format( self.shadow_thing_name)) # noqa: E501 self.device_shadow_handler.shadowRegisterDeltaCallback( self.delta_callback) # noqa: E501 def on_registered(self): pass def register(self, **kwargs): self.check_root_cert() self.configure_shadow_client() self.configure_mqtt_client() self.register_handlers() self.on_registered() def isIpAddress(self, value): match = re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}', value) if match: return True return False def get_ggc_addr(self): ggcHostPath = os.path.join(self.device_path, self.ggc_addr_name) f = open(ggcHostPath, 'r') self.ggc_host_addr = f.readline() def discover_ggc(self): backOffCore = ProgressiveBackOffCore() discoveryInfoProvider = DiscoveryInfoProvider() discoveryInfoProvider.configureEndpoint(self.iot_endpoint) discoveryInfoProvider.configureCredentials(self.iot_ca_path, self.cert_path, self.private_key_path) print('Endpoint: {}'.format(self.iot_endpoint)) print('iot_ca_path: {}'.format(self.iot_ca_path)) print('cert_path: {}'.format(self.cert_path)) print('private_key_path: {}'.format(self.private_key_path)) print('device_name: {}'.format(self.device_name)) discoveryInfoProvider.configureTimeout(10) # 10 sec retryCount = self.max_discovery_retries discovered = False groupCA = None coreInfo = None while retryCount != 0: try: discoveryInfo = discoveryInfoProvider.discover( self.device_name) # noqa: E501 caList = discoveryInfo.getAllCas() coreList = discoveryInfo.getAllCores() groupId, ca = caList[0] coreInfo = coreList[0] print('Discovered GGC: ' + coreInfo.coreThingArn + ' from Group: ' + groupId) host_addr = '' for addr in coreInfo.connectivityInfoList: host_addr = addr.host if self.isIpAddress(host_addr): break print('Discovered GGC Host Address: ' + host_addr) self.ggc_host_addr = host_addr print('Now we persist the connectivity/identity information') groupCA = os.path.join(self.device_path, self.ca_name) ggcHostPath = os.path.join(self.device_path, self.ggc_addr_name) # noqa: E501 groupCAFile = open(groupCA, 'w') groupCAFile.write(ca) groupCAFile.close() groupHostFile = open(ggcHostPath, 'w') groupHostFile.write(host_addr) groupHostFile.close() discovered = True print('Now proceed to the connecting flow...') break except DiscoveryInvalidRequestException as e: print('Invalid discovery request detected!') print('Type: ' + str(type(e))) print('Error message: ' + e.message) print('Stopping...') break except BaseException as e: print('Error in discovery!') print('Type: ' + str(type(e))) print('Error message: ' + e.message) retryCount -= 1 raise print('\n' + str(retryCount) + '/' + str(self.max_discovery_retries) + ' retries left\n') print('Backing off...\n') backOffCore.backOff() if not discovered: print('Discovery failed after ' + str(self.max_discovery_retries) + ' retries. Exiting...\n') sys.exit(-1) # Custom Shadow callback for updating the reported state in shadow def customShadowCallback_Update(self, payload, responseStatus, token): if responseStatus == 'timeout': print('Update request ' + token + ' time out!') if responseStatus == 'accepted': print('~~~~~~~~~~ Shadow Update Accepted ~~~~~~~~~~~~~') print('Update request with token: ' + token + ' accepted!') print(payload) print('~~~~~~~~~~~~~~~~~~~~~~~\n\n') if responseStatus == 'rejected': print('Update request ' + token + ' rejected!') def publish(self, topic, message, qos_level=0): print('Publishing {} to {}'.format(message, topic)) if (self.mqtt_client.publish(topic, json.dumps(message), qos_level)): print('PUBLISHED') else: print('NOT PUBLISHED')
payloadDict = json.loads(payload) deltaMessage = json.dumps(payloadDict["state"]) logger.warn(deltaMessage + "\n") muteOn = False if 'Mute' in payloadDict['state']: muteOn = payloadDict['state']['Mute'].lower() == "on" connection.setMute(payloadDict['state']['Mute']) if 'Volume' in payloadDict['state'] and not muteOn: connection.setVolume(int(payloadDict['state']['Volume'])) mqtttc = AWSIoTMQTTShadowClient(thingName) mqtttc.configureEndpoint(host, 8883) mqtttc.configureCredentials(rootCAPath, privateKeyPath, certificatePath) # AWSIoTMQTTShadowClient configuration mqtttc.configureAutoReconnectBackoffTime(1, 32, 20) mqtttc.configureConnectDisconnectTimeout(10) # 10 sec mqtttc.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT mqtttc.connect() # Create a deviceShadow with persistent subscription deviceShadowHandler = mqtttc.createShadowHandlerWithName(thingName, True) # Listen on deltas deviceShadowHandler.shadowRegisterDeltaCallback(customShadowCallback_Delta)
'%(asctime)s - %(name)s - %(levelname)s - %(message)s') streamHandler.setFormatter(formatter) logger.addHandler(streamHandler) host = "a1ii3qlfr1qukw-ats.iot.us-east-1.amazonaws.com" certPath = "/home/pi/certs_east/" clientId = "iot295b_thing" topic = "iot_temperature" thingName = "iot295b_thing" myAWSIoTMQTTShadowClient = None myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId) myAWSIoTMQTTShadowClient.configureEndpoint(host, 8883) myAWSIoTMQTTShadowClient.configureCredentials( "{}Amazon-root-CA-1.pem".format(certPath), "{}private.pem.key".format(certPath), "{}device.pem.crt".format(certPath)) myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) bus = smbus.SMBus(i2c_channel) myAWSIoTMQTTShadowClient.connect() deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName( thingName, True) deviceShadowHandler.shadowDelete(customShadowCallback_Delete, 5)
class PIRCamera: def __init__(self): #GPIO.add_event_detect(PIR_PULSE, GPIO.RISING, self.MotionDetected) self.detections = 0 self.video_recording = False self.videos_recorded_from_start = 0 self.width = 1280 self.height = 720 self.record_time = 10000 self.fps = 25 self.upload_video = False self.use_light = True self.enabled = False self.system_temp = 0.0 self.LoadSettings() self.SetupGoogleDrive() self.command = "raspivid -vf -t " + str( self.record_time) + " -w " + str(self.width) + " -h " + str( self.height) + " -fps " + str( self.fps) + " -b 1200000 -p 0,0," + str( self.width) + "," + str( self.height) # + " -o " + file_name + ".h264" self.SetupAWS() self.motionThread = Thread(target=self.motion_detect) self.motionThread.daemon = True self.motionThread.start() self.update_thread = Thread(target=self.RegularUpdate) self.update_thread.daemon = True self.update_thread.start() # Thread to regularly get temperature def RegularUpdate(self): while (True): out = subprocess.Popen(['vcgencmd', 'measure_temp'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, stderr = out.communicate() system_temp = None system_temp_str = stdout.decode('utf-8').replace("'C\n", "").split('=') self.system_temp = float(system_temp_str[1]) self.SendShadow() self.write_db() time.sleep(400.0) # Validates that there is data in the sqllite database file def test_db(self): conn = sqlite3.connect(DB_FILE) cur = conn.cursor() cur.execute("SELECT * FROM environment") rows = cur.fetchall() for row in rows: print(row) cur.close() # Writes the current data to the sql database def write_db(self): conn = None timestamp = time.time() try: conn = sqlite3.connect(DB_FILE) sql_create_table = """ CREATE TABLE IF NOT EXISTS camera ( time_stamp text, system_temp float, videos integer ); """ insert = ''' INSERT INTO camera(time_stamp,system_temp,videos) VALUES(?,?,?) ''' c = conn.cursor() c.execute(sql_create_table) conn.commit() data = (timestamp, self.system_temp, self.videos_recorded_from_start) c.execute(insert, data) conn.commit() c.close() print("Saved temperature to database...") except Error as ex: print("Unable to write to database: " + str(ex)) def SetupAWS(self): try: self.client = AWSIoTMQTTShadowClient("PIRCamera") self.client.configureEndpoint( "a2yizg9mkkd9ph-ats.iot.us-west-2.amazonaws.com", 8883) self.client.configureCredentials(PATH_TO_ROOT, PATH_TO_KEY, PATH_TO_CERT) self.client.configureConnectDisconnectTimeout(10) # 10 sec self.client.configureMQTTOperationTimeout(5) # 5 sec self.client.connect() self.shadow_connect = self.client.createShadowHandlerWithName( "SecurityCamera", True) # Setup the MQTT endpoint # Spin up resources event_loop_group = io.EventLoopGroup(1) host_resolver = io.DefaultHostResolver(event_loop_group) client_bootstrap = io.ClientBootstrap(event_loop_group, host_resolver) self.mqtt_connection = mqtt_connection_builder.mtls_from_path( endpoint=ENDPOINT, cert_filepath=PATH_TO_CERT, pri_key_filepath=PATH_TO_KEY, client_bootstrap=client_bootstrap, ca_filepath=PATH_TO_ROOT, client_id=CLIENT_ID, clean_session=False, keep_alive_secs=6) connect_future = self.mqtt_connection.connect() # Future.result() waits until a result is available connect_future.result() self.mqtt_connection.subscribe(topic=TOPIC, qos=mqtt.QoS.AT_LEAST_ONCE, callback=self.subcallback) except: print("AWS failed to setup, retrying...") time.sleep(1) self.SetupAWS() # Sets up the Google drive API for remote transfers def SetupGoogleDrive(self): try: print("Setting up Google Drive API...") creds = None # The file token.pickle stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('/home/pi/Server/PIRCamera/token.pickle'): with open('/home/pi/Server/PIRCamera/token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( '/home/pi/Server/PIRCamera/credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) self.service = build('drive', 'v3', credentials=creds) print("Google drive setup!") except Exception as ex: print("Unable to setup google drive, retrying...: " + str(ex)) time.sleep(1) self.SetupGoogleDrive() # Generates a shadow for AWS def SendShadow(self): global shadow try: dictionary = { "detections": self.detections, "recording": self.video_recording, "width": self.width, "height": self.height, "record_time": self.record_time, "fps": self.fps, "upload_video": self.upload_video, "use_light": self.use_light, "enabled": self.enabled, "videos_this_session": self.videos_recorded_from_start, "system_temp": self.system_temp } shadow["state"]["desired"] = dictionary self.shadow_connect.shadowUpdate(json.dumps(shadow), self.ShadowCallback, 5) except: print("Error: Failed to send shadow") # Subscriber callback def subcallback(self, topic, payload, **kwargs): try: dictionary = json.loads(payload) if "enable" in dictionary: self.enabled = True elif "disable" in dictionary: self.enabled = False if "fps" in dictionary: self.fps = int(dictionary["fps"]) if "use_light" in dictionary: self.use_light = dictionary["use_light"] if "upload_video" in dictionary: self.upload_video = dictionary["upload_video"] if "record_time" in dictionary: self.record_time = dictionary["record_time"] if "start_video" in dictionary and not self.video_recording: record_thread = Thread(target=self.RecordVideo) record_thread.daemon = True record_thread.start() self.SendShadow() self.SaveSettings() except Exception as e: print("Exception in subscriber: " + str(e)) # Handles recieving the shadow callback def ShadowCallback(self, data, param2, param3): print("AWS Shadow updated") # Loads settings from a file def LoadSettings(self): file_path = '/home/pi/Documents/pir_config.json' if path.exists(file_path): f = open(file_path, "r") data = f.read() dictionary = json.loads(data) self.width = dictionary["width"] self.height = dictionary["height"] self.record_time = dictionary["record_time"] self.fps = dictionary["fps"] self.use_light = dictionary["use_light"] self.upload_video = dictionary["upload_video"] else: self.SaveSettings() # Saves settings to a file def SaveSettings(self): fileStr = self.ToJson() file_path = '/home/pi/Documents/pir_config.json' f = open(file_path, "w") f.write(fileStr) f.close() # Converts the data in this class to a json string def ToJson(self): dictionary = { "detections": self.detections, "recording": self.video_recording, "width": self.width, "height": self.height, "record_time": self.record_time, "fps": self.fps, "upload_video": self.upload_video, "use_light": self.use_light, "enabled": self.enabled, "system_temp": self.system_temp } jsonStr = json.dumps(dictionary) return jsonStr # Records a video def RecordVideo(self): if self.video_recording: return self.video_recording = True try: if self.use_light: GPIO.output(PIR_LIGHT, GPIO.HIGH) print("Recording video...") now = datetime.now() # current date and time file_stamp = now.strftime("%m_%d_%Y_%H_%M_%S_sec") file_name = now.strftime("/home/pi/Videos/" + file_stamp) self.command = "raspivid -vf -t " + str( self.record_time) + " -w " + str(self.width) + " -h " + str( self.height) + " -fps " + str( self.fps) + " -b 1200000 -p 0,0," + str( self.width) + "," + str(self.height) command = self.command + " -o " + file_name + ".h264" os.system(command) os.system("MP4Box -add " + file_name + ".h264 " + file_name + ".mp4") os.system("rm " + file_name + ".h264") print("Video finished") if self.use_light: GPIO.output(PIR_LIGHT, GPIO.LOW) except Exception as e: print("Exception in record video: " + str(e)) if self.upload_video: try: print("Uploading video to Google Drive...") file_metadata = {'name': file_stamp + '.mp4'} media = MediaFileUpload(file_name + ".mp4", mimetype='video/mp4') file = self.service.files().create(body=file_metadata, media_body=media, fields='id').execute() print("Video uploaded!") except Exception as e: print("Video upload failed: " + str(e)) self.videos_recorded_from_start += 1 self.SendShadow() self.video_recording = False def motion_detect(self): #imageFiles = [] vs = VideoStream(src=0).start() time.sleep(2.0) frame_cnt = 0 # initialize the first frame in the video stream firstFrame = None out = None # loop over the frames of the video while True: # grab the current frame and initialize the occupied/unoccupied # text #timeNow = time.time() #now = datetime.now() # current date and time frame = vs.read() motion_detected = False # if the frame could not be grabbed, then we have reached the end # of the video if frame is None: break # resize the frame, convert it to grayscale, and blur it frame = imutils.resize(frame, width=500) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (21, 21), 0) # if the first frame is None, initialize it if firstFrame is None: firstFrame = gray continue # compute the absolute difference between the current frame and # first frame frameDelta = cv2.absdiff(firstFrame, gray) thresh = cv2.threshold(frameDelta, move_threshold, 255, cv2.THRESH_BINARY)[1] # dilate the thresholded image to fill in holes, then find contours # on thresholded image thresh = cv2.dilate(thresh, None, iterations=2) cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[1] for c in cnts: contour_area = cv2.contourArea(c) if (contour_area > 500): motion_detected = True if motion_detected and self.enabled: print("Motion detected") self.videos_recorded_from_start += 1 vs.stop() time.sleep(0.2) vs.stream.release() time.sleep(0.2) self.RecordVideo() print("Resume motion detect...") vs = VideoStream(src=0).start() time.sleep(0.2) firstFrame = None key = cv2.waitKey(1) & 0xFF # if the `q` key is pressed, break from the lop if key == ord("q"): break time.sleep(0.1) # cleanup the camera and close any open windows vs.stop() cv2.destroyAllWindows() # Handles motion getting detected def MotionDetected(self, pin): if self.video_recording or not self.enabled: return print("Motion detected: " + str(self.detections)) self.detections += 1 record_thread = Thread(target=self.RecordVideo) record_thread.daemon = True record_thread.start()
import RPi.GPIO as gpio from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient host = "azjctapxbp7sc-ats.iot.us-east-2.amazonaws.com" rootCAPath = "/home/pi/certification/RootCA.crt" certificatePath = "/home/pi/certification/a75d9d3b12-certificate.pem.crt" privateKeyPath = "/home/pi/certification/a75d9d3b12-private.pem.key" port = 8883 clientId = "IoT_System_Client" topic = "IoT_System_Email_Alarm" Thing_Name = "raspberrypi6" Client = AWSIoTMQTTShadowClient(clientId) Client.configureEndpoint(host, port) Client.configureCredentials(rootCAPath, privateKeyPath, certificatePath) Client.configureConnectDisconnectTimeout(10) Client.configureMQTTOperationTimeout(5) Client.connect() Handler = Client.createShadowHandlerWithName(Thing_Name, True) sensor = 21 gpio.setmode(gpio.BCM) gpio.setup(sensor, gpio.OUT) def Callback_func(payload, responseStatus, token): msg = json.index(payload) illuminance = msg{'state'}{'illuminance'} print() print('UPDATE: $aws/things/' + Thing_Name + '/shadow/update/#') print("payload = " + payload) print("responseStatus = " + responseStatus) print("token = " + token)
import math import json import boto3 import awscamdldt as awscam from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient clientId = 'DeepLens' host = 'xxx-ats.iot.us-west-2.amazonaws.com' port = 443 rootCAPath = 'AmazonRootCA1.pem' thingName = 'animals' # Init AWSIoTMQTTShadowClient myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId, useWebsocket=True) myAWSIoTMQTTShadowClient.configureEndpoint(host, port) myAWSIoTMQTTShadowClient.configureCredentials(rootCAPath) # AWSIoTMQTTShadowClient configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() # Create a deviceShadow with persistent subscription deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName( thingName, True) # Colours to use, with Hue value COLOURS = [
class AWS_RPI: def __init__(self): # Cofigure logging self.logger = logging.getLogger("AWSIoTPythonSDK.core") self.logger.setLevel(logging.DEBUG) self.streamHandler = logging.StreamHandler() self.formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') self.streamHandler.setFormatter(self.formatter) self.logger.addHandler(self.streamHandler) self.awsiotHost = "a130ba174k0fld-ats.iot.us-west-2.amazonaws.com" self.awsiotPort = 8883 self.rootCAPath = "/home/pi/Adafruit_Python_DHT/examples/wireless_connection/certificate/VeriSign-Class3-Public-Primary-Certification-Authority-G5.pem" self.privateKeyPath = "/home/pi/Adafruit_Python_DHT/examples/wireless_connection/certificate/78755df119-private.pem.key" self.certificatePath = "/home/pi/Adafruit_Python_DHT/examples/wireless_connection/certificate/78755df119-certificate.pem.crt" self.myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient("RPI_RULE") self.myAWSIoTMQTTShadowClient.configureEndpoint( self.awsiotHost, self.awsiotPort) self.myAWSIoTMQTTShadowClient.configureCredentials( self.rootCAPath, self.privateKeyPath, self.certificatePath) self.myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime( 1, 32, 20) self.myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout( 10) # 10sec self.myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(10) # 5sec self.myAWSIoTMQTTShadowClient._AWSIoTMQTTClient.configureOfflinePublishQueueing( 2, AWSIoTPythonSDK.core.util.enums.DropBehaviorTypes.DROP_OLDEST) self.myAWSIoTMQTTShadowClient.connect() # create a devcie Shadow with persistent subscription self.thingName = "my_rpi" self.deviceShadowHandler = self.myAWSIoTMQTTShadowClient.createShadowHandlerWithName( self.thingName, True) def customShadowCallback_upate(self, payload, responseStatus, token): # payload is a JSON string which will be parsed by jason lib if (responseStatus == "timeout"): print("Update request with " + token + " time out!") if (responseStatus == "accepted"): playloadDict = json.loads(payload) print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") print(payload) print("Update request with token: " + token + " accepted!") print("state: " + str(playloadDict["state"]["reported"])) print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n") if (responseStatus == "rejected"): print("Update request " + token + " rejected!") def data_upload(self): d = 5 distance = False dis0 = ultra_fun.distance() while (d > 2): dis1 = ultra_fun.distance() d = abs(dis1 - dis0) dis0 = dis1 if (dis0 >= 10): distance = True humid, temper = DHT22_fun.DHT() return distance, humid, temper def customShadowCallback_delete(self, payload, responseStatus, token): if (responseStatus == "timeout"): print("Delete request " + token + " time out!") if (responseStatus == "accepted"): print("Delete request with token " + token + " accepted!") if (responseStatus == "rejected"): print("Delete request with token " + token + " rejected!") def send2AWS(self): # #check current status of device window, humidity, temperature = self.data_upload() # print("Sending reported status to MQTT...") # jsonPayload = '{"state":{"reported":{"window status": "' + window + "; humidity is: " + humidity + "; temperature is: " + temperature + "; face detection is: " + message + '"}}}' jsonPayload = '{"state":{"reported":{"window_is_open": "' + str( window) + '", "humidity": "' + str( humidity) + '", "temperature": "' + str(temperature) + '"}}}' print("Payload is: " + jsonPayload + "\n") # Delete shadow JSON doc # self.deviceShadowHandler.shadowDelete(self.customShadowCallback_delete, 50) self.deviceShadowHandler.shadowUpdate(jsonPayload, self.customShadowCallback_upate, 10) print("=========================") # print(" Current status: " + str(window + '\n'+ humidity + temperature + face + presence)) print("=========================\n\n") def myShadowCallback_get(self, payload, responseStatus, token): # payload is a JSON string which will be parsed by jason lib if (responseStatus == "timeout"): print("Update request with " + token + " time out!") return 0 if (responseStatus == "accepted"): playloadDict = json.loads(payload) print(payload) return playloadDict if (responseStatus == "rejected"): return -1 def myShadowGet(self, timeout=5): self.deviceShadowHandler.shadowGet(self.myShadowCallback_get, timeout)
# Edit this to be your device name in the AWS IoT console thing = "pi" if __name__ == "__main__": pi = pigpio.pi() s = DHT22.sensor(pi, 22, LED=16, power=8) awsport = 8883 caPath = "aws-iot-rootCA.crt" certPath = "cert.pem" keyPath = "privkey.pem" # For certificate based connection myShadowClient = AWSIoTMQTTShadowClient(thing) myShadowClient.configureEndpoint(awshost, awsport) myShadowClient.configureCredentials(caPath, keyPath, certPath) myShadowClient.configureConnectDisconnectTimeout(60) myShadowClient.configureMQTTOperationTimeout(10) myShadowClient.connect() myDeviceShadow = myShadowClient.createShadowHandlerWithName("pi", True) while 1 == 1: s.trigger() tempreading = "{ \"state\" : { \"reported\": { \"temp\": \"%s\", \"humid\": \"%s\" } } }" % ( str(s.temperature()), str(s.humidity())) print("payload: %s" % tempreading) if s.temperature() != -999: myDeviceShadow.shadowUpdate(tempreading, None, 5) time.sleep(60)
#the print of state result after the method of shadowUpdate. def shadow_update_Callback_test(payload, response_status, token): print("Callback Test Init") print("Object Action Named Rule") print("$aws/things/crc-hj-rasp/shadow/update/#") print("payload = {}".format(payload)) print("response_status = {}".format(response_status)) #print("token = {}".format(token)) #Device connect to AWS IoT Core applicatioin myShadowClient = AWSIoTMQTTShadowClient(clientid, useWebsocket=True) print('set client id') myShadowClient.configureEndpoint(HOST, 443) print('set configuration endpoint') myShadowClient.configureCredentials(CA, PRI_KEY, CERT_KEY) print('done certificatation') myShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myShadowClient.configureConnectDisconnectTimeout(10) myShadowClient.configureMQTTOperationTimeout(5) myShadowClient.connect() print('connected!!') testDevice_shadow = myShadowClient.createShadowHandlerWithName(HANDELR, True) # parsing oximetry-heart-rate-log data clss = OxiHRMonitor() ctx = clss.serialContext('/dev/tty.KMU_MSPL-DevB') g = clss.listen(ctx) t_attr = None while True: res = next(g)
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient import os import sys CLIENT_ID = "ESP32840d8ee67d9c" HOST = "a1kdus6mbpzad4.iot.eu-west-3.amazonaws.com" PORT = 8883 ROOT_CA_PATH = "/home/developer/Projects/wizzdev-iot-starter/MicroPython/src/certificates/AWS.ca_certificate" PRIVATE_KEY_PATH = "/home/developer/Projects/wizzdev-iot-starter/MicroPython/src/certificates/AWS.private_key" CERTIFICATE_PATH = "/home/developer/Projects/wizzdev-iot-starter/MicroPython/src/certificates/AWS.certificate" # Init AWSIoTMQTTShadowClient myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(CLIENT_ID) myAWSIoTMQTTShadowClient.configureEndpoint(HOST, PORT) myAWSIoTMQTTShadowClient.configureCredentials(ROOT_CA_PATH, PRIVATE_KEY_PATH, CERTIFICATE_PATH) # AWSIoTMQTTShadowClient connection configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(25) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() print("DONE")
mac = get_mac() print (mac) s3 = boto3.client('s3', aws_access_key_id= open('keys.txt').readline().split(None, 1)[0], aws_secret_access_key= open('keys.txt').readlines()[1].split(None, 1)[0]) s3.download_file('littercam','device-'+str(mac)+'/devicename.txt', 'devicename.txt') devicename = open('devicename.txt').readline().split(None, 1)[0] print(devicename) ShadowClient = AWSIoTMQTTShadowClient("") ShadowClient.configureEndpoint("a1oa9tg9lcso0.iot.eu-west-1.amazonaws.com", 8883) ShadowClient.configureCredentials(get_rootca(), get_private(),get_cert()) ShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) ShadowClient.configureConnectDisconnectTimeout(30) # 10 sec ShadowClient.configureMQTTOperationTimeout(10) # 5 sec ShadowClient.connect() deviceShadowHandler = ShadowClient.createShadowHandlerWithName(devicename, True) #shadowCallbackContainer_Bot = shadowCallbackContainer(deviceShadowHandler) #deviceShadowHandler.shadowRegisterDeltaCallback(shadowCallbackContainer_Bot.customShadowCallback_Delta) # MQTT Connection establishement myMQTTClient = AWSIoTMQTTClient(devicename) myMQTTClient.configureEndpoint("a1oa9tg9lcso0.iot.eu-west-1.amazonaws.com", 8883) myMQTTClient.configureCredentials(get_rootca(),
aws_access_key_id=open('keys.txt').readline().split(None, 1)[0], aws_secret_access_key=open('keys.txt').readlines()[1].split( None, 1)[0]) s3.download_file('littercam', 'device-' + str(mac) + '/devicename.txt', 'devicename.txt') devicename = open('devicename.txt').readline().split(None, 1)[0] print(devicename) ShadowClient = AWSIoTMQTTShadowClient("") ShadowClient.configureEndpoint("a1oa9tg9lcso0.iot.eu-west-1.amazonaws.com", 8883) ShadowClient.configureCredentials(get_rootca(), get_private(), get_cert()) ShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) ShadowClient.configureConnectDisconnectTimeout(30) # 10 sec ShadowClient.configureMQTTOperationTimeout(10) # 5 sec ShadowClient.connect() deviceShadowHandler = ShadowClient.createShadowHandlerWithName( devicename, True) #shadowCallbackContainer_Bot = shadowCallbackContainer(deviceShadowHandler) #deviceShadowHandler.shadowRegisterDeltaCallback(shadowCallbackContainer_Bot.customShadowCallback_Delta) # MQTT Connection establishement myMQTTClient = AWSIoTMQTTClient(devicename) myMQTTClient.configureEndpoint("a1oa9tg9lcso0.iot.eu-west-1.amazonaws.com", 8883) myMQTTClient.configureCredentials(get_rootca(), get_private(), get_cert())
# Author: Randy Lin import json import time from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient import configparser import random import time #Setup Shadow client and security certificates shadowc = AWSIoTMQTTShadowClient('Light1') shadowc.configureEndpoint("ChangeToYourEndpoint.ats.iot.cn-north-1.amazonaws.com.cn",8883) shadowc.configureCredentials( './root-CA.crt', './MyIoTDevice.private.key', './MyIoTDevice.cert.pem' ) #Initialize Device Status device_state_color = 'white' device_state_brightness = '30' #Connect to IoT Core shadowc.connect() print('Shadow Client Connected to IoT Core') #Create Device Shadow Handler with persistent subscription deviceShadowHandler = shadowc.createShadowHandlerWithName('MyIoTDevice', True) #Callback: Shadow Update
# In[ ]: from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient import logging import time import json import argparse myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(aws_deviceid) myAWSIoTMQTTShadowClient.configureEndpoint(endpoint, 8883) myAWSIoTMQTTShadowClient.configureCredentials(filepath_route_ca, filepath_private_key, filepath_certificate) # AWSIoTMQTTShadowClient configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() # MQTTClient = myAWSIoTMQTTShadowClient.getMQTTConnection() # MQTTClient.configureOfflinePublishQueueing(yourQueueSize, yourDropBehavior) # Create a deviceShadow with persistent subscription deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName("test_vm_ubuntu_2", True)
exit(2) # Configure logging logger = logging.getLogger("AWSIoTPythonSDK.core") logger.setLevel(logging.DEBUG) streamHandler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') streamHandler.setFormatter(formatter) logger.addHandler(streamHandler) # Init AWSIoTMQTTShadowClient myAWSIoTMQTTShadowClient = None if useWebsocket: myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId, useWebsocket=True) myAWSIoTMQTTShadowClient.configureEndpoint(host, 443) myAWSIoTMQTTShadowClient.configureCredentials(rootCAPath) else: myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId) myAWSIoTMQTTShadowClient.configureEndpoint(host, 8883) myAWSIoTMQTTShadowClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath) # AWSIoTMQTTShadowClient configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() # Create a deviceShadow with persistent subscription deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(thingName, True)
class BpiController: def __init__(self): self.__host = 'axt811sti1q4w-ats.iot.us-east-2.amazonaws.com' self.__rootCA = '../certs/root-CA.crt' self.__certPem = '../certs/bpiController.cert.pem' self.__privateKey = '../certs/bpiController.private.key' self.__port = 8883 self.__clientId = 'bpiControllerDevice' self.__thingName = 'bpiController' self.__thingType = 'Gateway' self.mqttClient = None self.basicMqttClient = None self.deviceShadowHandler = None # Configure logging # logger = logging.getLogger('AWSIoTPythonSDK.core') # logger.setLevel(logging.DEBUG) # streamHandler = logging.StreamHandler() # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # streamHandler.setFormatter(formatter) # logger.addHandler(streamHandler) # Init AWSIoTMQTTShadowClient self.mqttClient = AWSIoTMQTTShadowClient(self.__clientId) self.mqttClient.configureEndpoint(self.__host, self.__port) self.mqttClient.configureCredentials(self.__rootCA, self.__privateKey, self.__certPem) # AWSIoTMQTTShadowClient configuration self.mqttClient.configureAutoReconnectBackoffTime(1, 32, 20) self.mqttClient.configureConnectDisconnectTimeout(10) # 10 sec self.mqttClient.configureMQTTOperationTimeout(5) # 5 sec def mqttConnect(self): # Connect to AWS IoT self.mqttClient.connect() # Create a deviceShadow with persistent subscription self.deviceShadowHandler = self.mqttClient.createShadowHandlerWithName(self.__thingName, True) return self.deviceShadowHandler def shadowUpdate(self, json_data): self.deviceShadowHandler.shadowUpdate(json.dumps({ 'state': { 'reported': json_data } }), self.shadowUpdateCallback, 5) def reportHistory(self, json_data): if not isinstance(self.basicMqttClient, AWSIoTMQTTClient): print('Create AWSIoTMQTTClient') self.basicMqttClient = AWSIoTMQTTClient('bpiControllerReporter') self.basicMqttClient.configureEndpoint(self.__host, self.__port) self.basicMqttClient.configureCredentials(self.__rootCA, self.__privateKey, self.__certPem) self.basicMqttClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing self.basicMqttClient.configureDrainingFrequency(2) # Draining: 2 Hz self.basicMqttClient.configureConnectDisconnectTimeout(10) # 10 sec self.basicMqttClient.configureMQTTOperationTimeout(5) # 5 sec self.basicMqttClient.connect() topic = '@sensor.live/thing_types/%s/things/%s/history' % (self.__thingType, self.__thingName) self.basicMqttClient.publish(topic, json.dumps(json_data), 0) # Shadow callback def shadowUpdateCallback(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: ' + str(payloadDict)) print('~~~~~~~~~~~~~~~~~~~~~~~\n\n') if responseStatus == 'rejected': print('Update request ' + token + ' rejected!') # Shadow delete callback def shadowDeleteCallback(self, payload, responseStatus, token): if responseStatus == 'timeout': print('Delete request ' + token + ' time out!') if responseStatus == 'accepted': print('~~~~~~~~~~~~~~~~~~~~~~~') print('Delete request with token: ' + token + ' accepted!') print('~~~~~~~~~~~~~~~~~~~~~~~\n\n') if responseStatus == 'rejected': print('Delete request ' + token + ' rejected!') # Listen on deltas def listenDeltaCallback(self, callback): if self.deviceShadowHandler is not None: self.deviceShadowHandler.shadowRegisterDeltaCallback(callback) else: raise Exception('deviceShadowHandler is None')