class AdafruitIoClient(threading.Thread): def __init__(self, my_key, my_username): threading.Thread.__init__(self) self.my_key = my_key self.my_username = my_username self.mqttdevice = MQTTClient(self.my_username, self.my_key) self.device = Client(self.my_username, self.my_key) def subscribe(self, feed_id): self.mqttdevice.subscribe(feed_id) def set_on_connect(self, callback): self.mqttdevice.on_connect = callback def set_on_disconnect(self, callback): self.mqttdevice.on_disconnect = callback def set_on_message(self, callback): self.mqttdevice.on_message = callback def get_feeds(self): return self.device.feeds() def create_feed(self, feed): return self.device.create_feed(feed) def run(self): self.mqttdevice.connect() self.mqttdevice.loop_blocking() def send_data(self, name, value): self.device.send_data(str(name).lower(), value)
def test_subscribe_and_publish(self): # Create MQTT test client. client = MQTTClient(self.get_test_username(), self.get_test_key()) # Save all on_message handler responses. messages = [] def on_message(mqtt_client, feed, payload): self.assertEqual(mqtt_client, client) messages.append((feed, payload)) client.on_message = on_message # Connect and wait until on_connect event is fired. client.connect() self.wait_until_connected(client) # Subscribe to changes on a feed. client.subscribe('TestFeed') # Publish a message on the feed. client.publish('TestFeed', 42) # Wait for message to be received or timeout. start = time.time() while len(messages) == 0 and (time.time() - start) < TIMEOUT_SEC: client.loop() time.sleep(0) # Verify one update message with payload is received. self.assertListEqual(messages, [('TestFeed', '42')])
def main(): args = ArgumentParser( description= "An MQTT client that gets messages from an Adafruit IO feed and sends its payload to a NEXA server" ) args.add_argument( "--feed-name", "-f", default="NEXA Switches", help="The name of the feed on Adafruit.io that you want to subscribe to" ) args.add_argument( "--server-url", "-u", default="http://localhost:5000", help="The URL of the server that controls the NEXA switches") ns = args.parse_args() FEED_NAME = ns.feed_name SERVER_URL = ns.server_url # List feeds aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY) feeds = aio.feeds() feed_names = [f.name for f in feeds] if FEED_NAME not in feed_names: print(f"The feed \"{FEED_NAME}\" does not exist") print(f"Please choose between the available feeds: {feed_names}") sys.exit(-1) # Connect to Adafruit IO MQTT server client = MQTTClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY) lamp_endpoint = SERVER_URL + "/lamp" client.on_message = get_on_message(lamp_endpoint) # For modifying TLS settings (since it did not work, due to self-signed certificate) import ssl client._client._ssl_context = None client._client.tls_set_context(ssl._create_unverified_context()) client.connect() client.subscribe(FEED_NAME) client.loop_blocking()
def test_subscribe_and_publish(self): # Create MQTT test client. client = MQTTClient(self.get_test_username(), self.get_test_key()) # Save all on_message handler responses. messages = [] def on_message(mqtt_client, feed, payload): self.assertEqual(mqtt_client, client) messages.append((feed, payload)) client.on_message = on_message # Connect and wait until on_connect event is fired. client.connect() self.wait_until_connected(client) # Subscribe to changes on a feed. client.subscribe('testfeed') # Publish a message on the feed. client.publish('testfeed', 42) # Wait for message to be received or timeout. start = time.time() while len(messages) == 0 and (time.time() - start) < TIMEOUT_SEC: client.loop() time.sleep(0) # Verify one update message with payload is received. self.assertListEqual(messages, [('testfeed', '42')])
class Beacon(object): connectState = ConnectState.Disconnected failConnectCount = 0 configData = None commandsData = None client = None soundDir = os.path.join(launchDir, 'sounds/') rgbLED = None button = None buttonHoldTime = None persistentLedRule = None def __init__(self): logging.info("Beacon service initialized") with open(os.path.join(launchDir, 'beacon.json')) as data_file: self.configData = json.load(data_file) #need to account for no json data loaded if (self.configData.get("gpio")): gpioData = self.configData["gpio"] if gpioData.get("button"): self.button = Button(int(gpioData["button"])) self.button.when_released = self.buttonReleased self.button.when_held = self.buttonHeld else: logging.error( "config json gpio object missing required button id") if gpioData.get("red_led") and gpioData.get( "green_led") and gpioData.get("blue_led"): self.rgbLED = RGBLED(int(gpioData["red_led"]), int(gpioData["green_led"]), int(gpioData["blue_led"]), False, (0, 0, 0), True) else: logging.error( "config json gpio object missing required redled, greenled, and blueled ids" ) else: logging.error("config json missing require gpio object") if self.configData.get("directories"): dirObj = self.configData["directories"] if dirObj.get("sound"): soundDir = dirObj["sound"] if self.configData.get("commands"): self.commandsData = self.configData["commands"] self.ledDisplay(LedDisplayRule(0, 1, 0, 1, 1)) sleep(1) self.client = MQTTClient(self.configData["credentials"]["username"], self.configData["credentials"]["key"]) self.client.on_connect = self.connected self.client.on_disconnect = self.disconnected self.client.on_message = self.message while True: if self.connectState == ConnectState.Disconnected: self.connect() elif self.connectState == ConnectState.PendingReconnect: self.reconnect() try: self.client.loop() except RuntimeError: logging.exception("runtime error caught from mqtt client loop") self.reconnect() def buttonHeld(self): self.buttonHoldTime = time.time() def buttonReleased(self): if self.buttonHoldTime is not None: heldTime = time.time() - self.buttonHoldTime + 1 self.buttonHoldTime = None print heldTime if heldTime > 5: self.ledDisplay(LedDisplayRule(1, 0, 0, 3, .5)) sleep(2) self.stopLED() os.system('sudo shutdown -r now') else: self.stopLED() self.persistentLedRule = None print self.commandsData if mixer.get_init() and mixer.music.get_busy(): mixer.music.stop() mixer.quit() elif self.commandsData is not None: self.client.publish(self.configData["feeds"]["outbound"], self.commandsData[0]) def message(self, client, feed_id, payload): msgStr = 'Feed {0} received new value: {1}'.format(feed_id, payload) log_data = "" with open(logFilePath, 'r') as myfile: log_data = myfile.read().replace('\n', '') if log_data.find(msgStr) == -1 or testing: logging.info(msgStr) messageData = None try: messageData = json.loads(payload) except: pass sound = None volume = 1 redVal = 0 greenVal = 1 blueVal = 0 blinkCount = 1 blinkRate = 1 persistent = False pulse = False if self.configData.get("sounds"): sound = self.configData["sounds"]["default"] if messageData is not None: if messageData.get("sound"): sound = self.configData["sounds"][messageData["sound"]] if messageData.get("persistent") and str( messageData["persistent"]).lower() == "true": persistent = True if messageData.get("volume") is not None: volume = float(messageData.get("volume")) if messageData.get("blinkCount") is not None: blinkCount = int(messageData.get("blinkCount")) if messageData.get("blinkRate") is not None: blinkRate = float(messageData.get("blinkRate")) if messageData.get("pulse") is not None and str( messageData["pulse"]).lower() == "true": pulse = True if messageData.get("color") is not None: try: colorArr = str(messageData.get("color")).split("/") redVal = float(colorArr[0]) greenVal = float(colorArr[1]) blueVal = float(colorArr[2]) except: pass if sound is not None: mixer.init() mixer.music.set_volume(volume) mixer.music.load(self.soundDir + sound) mixer.music.play() self.ledDisplay( LedDisplayRule(redVal, greenVal, blueVal, blinkCount, blinkRate, pulse, persistent)) def stopLED(self): self.rgbLED._stop_blink() self.rgbLED.off() def ledDisplay(self, rule): self.stopLED() blinkCount = rule.blinkCount if (rule.persistent): blinkCount = None self.persistentLedRule = rule if (rule.pulse): self.rgbLED.pulse(fade_in_time=rule.blinkRate, fade_out_time=rule.blinkRate, on_color=(rule.r, rule.g, rule.b), off_color=(0, 0, 0), n=blinkCount, background=True) else: self.rgbLED.blink(on_time=rule.blinkRate, off_time=rule.blinkRate, fade_in_time=0, fade_out_time=0, on_color=(rule.r, rule.g, rule.b), off_color=(0, 0, 0), n=blinkCount, background=True) def connected(self, client): logging.info("Connected to Adafruit IO") self.connectState = ConnectState.Connected self.failConnectCount = 0 self.client.subscribe(self.configData["feeds"]["inbound"]) def disconnected(self, client): logging.info('Disconnected from AdafruitIO') self.connectState = ConnectState.Disconnected self.reconnect() def connect(self): logging.info("init connect to Adafruit IO") self.connectState = ConnectState.Connecting try: self.client.connect() except Exception as e: logging.exception("Exception from Adafruit client connect") self.reconnect() def reconnect(self): self.failConnectCount += 1 logging.info('pending Adafruit IO reconnect - failcount=' + str(self.failConnectCount)) self.connectState = ConnectState.Connecting sleep(10) self.connect()