from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient import time import board from busio import I2C import adafruit_bme680 import json myMQTTClient = AWSIoTMQTTClient("badge-and-printer") myMQTTClient.disableMetricsCollection() myMQTTClient.configureCredentials("/home/pi/workspace/AmazonRootCA1.pem", "/home/pi/workspace/fbb3f88aee-private.pem.key", "/home/pi/workspace/fbb3f88aee-certificate.pem.crt") myMQTTClient.configureEndpoint("ayecs2a13r9pv-ats.iot.us-west-2.amazonaws.com", 8883) myMQTTClient.connect() # myMQTTClient.subscribe("myTopic", 1, customCallback) # myMQTTClient.unsubscribe("myTopic") # Create library object using our Bus I2C port i2c = I2C(board.SCL, board.SDA) bme680 = adafruit_bme680.Adafruit_BME680_I2C(i2c, debug=False) # change this to match the location's pressure (hPa) at sea level # this could be dynamically updated from, e.g., # https://forecast.weather.gov/MapClick.php?x=266&y=134&site=sew&zmx=&zmy=&map_x=266&map_y=134#.X2jtB2hKiUk bme680.sea_level_pressure = 1013.89 # You will usually have to add an offset to account for the temperature of # the sensor. This is usually around 5 degrees but varies by use. Use a # separate temperature sensor to calibrate this one. temperature_offset = -5
class AIoTBroker(object): def __init__(self, device): self.logger = logging.getLogger("Plugin.aIoTBroker") self.logger.setLevel(logging.DEBUG) streamHandler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') streamHandler.setFormatter(formatter) self.logger.addHandler(streamHandler) self.deviceID = device.id address = device.pluginProps.get('address', "") port = int(device.pluginProps.get('port', "")) ca_bundle = indigo.server.getInstallFolderPath( ) + '/' + device.pluginProps.get('ca_bundle', "") cert_file = indigo.server.getInstallFolderPath( ) + '/' + device.pluginProps.get('cert_file', "") private_key = indigo.server.getInstallFolderPath( ) + '/' + device.pluginProps.get('private_key', "") self.logger.debug( f"{device.name}: Broker __init__ address = {address}:{port}, ca_bundle = {ca_bundle}, cert_file = {cert_file}, private_key = {private_key}" ) device.updateStateOnServer(key="status", value="Not Connected") device.updateStateImageOnServer(indigo.kStateImageSel.SensorOff) try: self.aIoTClient = AWSIoTMQTTClient("indigo-mqtt-{}".format( device.id), useWebsocket=False) self.aIoTClient.configureEndpoint(address, port) self.aIoTClient.configureCredentials(ca_bundle, private_key, cert_file) self.aIoTClient.configureAutoReconnectBackoffTime(1, 64, 20) self.aIoTClient.configureOfflinePublishQueueing( -1) # Infinite offline Publish queueing self.aIoTClient.configureDrainingFrequency(2) # Draining: 2 Hz self.aIoTClient.configureConnectDisconnectTimeout(10) # 10 sec self.aIoTClient.configureMQTTOperationTimeout(5) # 5 sec self.aIoTClient.disableMetricsCollection() self.aIoTClient.onOnline = self.onOnline self.aIoTClient.onOffline = self.onOffline self.aIoTClient.onMessage = self.onMessage self.aIoTClient.connectAsync(ackCallback=self.onConnect) except (Exception, ): self.logger.exception( f"{device.name}: Exception while creating Broker object") def disconnect(self): device = indigo.devices[self.deviceID] self.aIoTClient.disconnect() device.updateStateOnServer(key="status", value="Not Connected") device.updateStateImageOnServer(indigo.kStateImageSel.SensorOff) def publish(self, topic, payload=None, qos=0, retain=False): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Publishing to: {} ({}), payload = {}".format( device.name, topic, qos, payload)) self.aIoTClient.publishAsync(str(topic), str(payload), qos, ackCallback=self.onPublish) def subscribe(self, topic, qos=0): device = indigo.devices[self.deviceID] self.logger.info(u"{}: Subscribing to: {} ({})".format( device.name, topic, qos)) self.aIoTClient.subscribeAsync(str(topic), int(qos), ackCallback=self.onSubscribe) def unsubscribe(self, topic): device = indigo.devices[self.deviceID] self.logger.info(u"{}: Unsubscribing from: {}".format( device.name, topic)) self.aIoTClient.unsubscribeAsync(str(topic), ackCallback=self.onUnsubscribe) ################################################################################ # Callbacks ################################################################################ def onConnect(self, mid, rc): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Client Connected, mid = {}, rc = {}".format( device.name, mid, rc)) device.updateStateOnServer(key="status", value="OnLine") device.updateStateImageOnServer(indigo.kStateImageSel.SensorOn) # Subscribing in onConnect() means that if we lose the connection and reconnect then subscriptions will be renewed. subs = device.pluginProps.get(u'subscriptions', None) if subs: for s in subs: qos = int(s[0:1]) topic = s[2:] self.subscribe(topic, qos) def onOnline(self): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Client is Online".format(device.name)) def onOffline(self): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Client is OffLine".format(device.name)) device.updateStateOnServer(key="status", value="OffLine") device.updateStateImageOnServer(indigo.kStateImageSel.SensorTripped) def onTopicMessage(self, client, userdata, msg): device = indigo.devices[self.deviceID] self.logger.debug( u"{}: onTopicMessage - client: {}, userdata: {} message: '{}', payload: {}" .format(device.name, client, userdata, msg.topic, msg.payload)) def onMessage(self, msg): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Message received: {}, payload: {}".format( device.name, msg.topic, msg.payload)) indigo.activePlugin.processReceivedMessage(device.id, msg.topic, msg.payload) def onPublish(self, mid): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Message published: {}".format( device.name, mid)) def onSubscribe(self, mid, data): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Subscribe complete: {}, {}".format( device.name, mid, data)) def onUnsubscribe(self, mid): device = indigo.devices[self.deviceID] self.logger.debug(u"{}: Unsubscribe complete: {}".format( device.name, mid))
def main(): signal.signal(signal.SIGINT, signal_handler) print(device_id) ######################## ### #AWS IoT MQTT client setup global mqttClient mqttClient = AWSIoTMQTTClient(device_id) #Setup del client mqtt di aws iot mqttClient.disableMetricsCollection() mqttClient.configureEndpoint(endpoint, 8883) mqttClient.configureCredentials( rootCAPath, privateKeyPath, certificatePath, ) # Backoff per riconnessione in caso di mancanza di connessione mqttClient.configureAutoReconnectBackoffTime(1, 32, 20) # Coda dei messaggi in caso di mancanza di connessione # Infinite offline Publish queueing mqttClient.configureOfflinePublishQueueing(-1) mqttClient.configureDrainingFrequency(10) # Draining: 2 Hz mqttClient.configureConnectDisconnectTimeout(10) # 10 sec mqttClient.configureMQTTOperationTimeout(5) # 5 sec #callback in caso di mancanza di connessione mqttClient.onOffline = disconnessoAInternet ############################# #### DEVICE SHADOW setup global shadowClient shadow = AWSIoTMQTTShadowClient(shadow_clientId, awsIoTMQTTClient=mqttClient) shadowClient = shadow.createShadowHandlerWithName(thingName, True) shadowClient.shadowRegisterDeltaCallback(shadowDeltaCallback) ############################# connect() #avvia il tentativo di connessione (ASYNC) #iscrizione al topic di richiesta info mqttClient.subscribe("pcTelemetry/{}/infoRequest".format(device_id), 1, infoRequest) ## Avvia 3 thread: # - uno pubblica una misurazione ogni 10s # - uno pubblica un array di 30 misurazioni. Con una misurazione ogni secondo # - uno pubblica una misurazione ogni 2 min. Misurazioni possibili: batteria, spazio Disco t1 = threading.Thread(target=detailData, args=(parametri, 1)) t2 = threading.Thread(target=liveData, args=(parametri, 10)) t3 = threading.Thread(target=slowUpdateData, args=(parametri, 120)) t1.setDaemon(True) t2.setDaemon(True) t3.setDaemon(True) t1.start() t2.start() t3.start() while True: time.sleep(1)