Skip to content

Instantly share code, notes, and snippets.

@sanchezcarlosjr
Last active March 22, 2023 07:41
Show Gist options
  • Save sanchezcarlosjr/1769cf2347c49823f3c5dd9ca07ee3b8 to your computer and use it in GitHub Desktop.
Save sanchezcarlosjr/1769cf2347c49823f3c5dd9ca07ee3b8 to your computer and use it in GitHub Desktop.
mqtt-producer-consumer.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyND6EUgpAzvrtvCvBccSSaJ",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/sanchezcarlosjr/1769cf2347c49823f3c5dd9ca07ee3b8/mqtt-producer-consumer.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"source": [
"! pip install paho-mqtt"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ZTxzwZpCYtiV",
"outputId": "05c366d0-6fba-4a2c-bd16-bda633005a4b"
},
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
"Collecting paho-mqtt\n",
" Downloading paho-mqtt-1.6.1.tar.gz (99 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m99.4/99.4 KB\u001b[0m \u001b[31m12.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
"Building wheels for collected packages: paho-mqtt\n",
" Building wheel for paho-mqtt (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
" Created wheel for paho-mqtt: filename=paho_mqtt-1.6.1-py3-none-any.whl size=62135 sha256=fd09971e70238bcd277a2d4abb737a6aaba453b8dfa26fbf2b272ef477aadc13\n",
" Stored in directory: /root/.cache/pip/wheels/0f/90/29/db29bb8ddc98ec5f2363b959130c9ddbcf5cfdb4a00b6184dd\n",
"Successfully built paho-mqtt\n",
"Installing collected packages: paho-mqtt\n",
"Successfully installed paho-mqtt-1.6.1\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"! pip install asyncio-mqtt"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "lz8YjNEZcmaX",
"outputId": "d7a7914e-31f5-411a-bbb6-47e60dbb6ccb"
},
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
"Collecting asyncio-mqtt\n",
" Downloading asyncio_mqtt-0.16.1-py3-none-any.whl (17 kB)\n",
"Requirement already satisfied: typing-extensions>=4.4.0 in /usr/local/lib/python3.9/dist-packages (from asyncio-mqtt) (4.5.0)\n",
"Requirement already satisfied: paho-mqtt>=1.6.0 in /usr/local/lib/python3.9/dist-packages (from asyncio-mqtt) (1.6.1)\n",
"Installing collected packages: asyncio-mqtt\n",
"Successfully installed asyncio-mqtt-0.16.1\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"# Coroutines version"
],
"metadata": {
"id": "T3SzRuztYGV0"
}
},
{
"cell_type": "code",
"source": [
"import asyncio\n",
"import asyncio_mqtt as aiomqtt\n",
"\n",
"queue = asyncio.Queue()\n",
"\n",
"async def listen():\n",
" async with aiomqtt.Client(\"test.mosquitto.org\") as client:\n",
" async with client.messages() as messages:\n",
" for key in ['hermes/asr/stopListening', 'hermes/hotword/toggleOn']:\n",
" await client.subscribe(key)\n",
" async for message in messages:\n",
" await queue.put((message.topic.value, message.payload.decode()))\n",
"\n",
"async def animate(payload=[None]):\n",
" print(\"ANIMATE\", payload)\n",
" await asyncio.sleep(0.5)\n",
"\n",
"async def off(payload=[None]):\n",
" print(\"OFF\", payload)\n",
" await asyncio.sleep(0.5)\n",
"\n",
"async def start_service():\n",
" translator = {\n",
" 'hermes/asr/stopListening': 'off',\n",
" 'hermes/hotword/toggleOn': 'animate'\n",
" }\n",
" current_state = 'off'\n",
" payload = [None]\n",
" while True:\n",
" await asyncio.sleep(0.5)\n",
" await globals()[current_state](payload)\n",
" topic, payload = await queue.get()\n",
" current_state = \\\n",
" 'animate' if current_state == 'off' and translator[topic] == 'animate' else \\\n",
" 'off' if current_state == 'animate' and translator[topic] == 'off' else current_state\n",
"async def main():\n",
" loop = asyncio.get_event_loop()\n",
" task = loop.create_task(listen())\n",
" service = loop.create_task(start_service())\n",
"\n",
" await task\n",
" await service\n",
"\n",
"\n",
"await main() # asyncio.run(main())"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"id": "PudkXEryXvVd",
"outputId": "cdd1e165-8967-45b7-c173-097e3fbce82c"
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"OFF {\"text\":0}\n",
"OFF {\"text\":1}\n",
"OFF {\"text\":2}\n",
"OFF {\"text\":3}\n",
"ANIMATE {\"text\":0}\n",
"ANIMATE {\"text\":1}\n",
"ANIMATE {\"text\":2}\n",
"ANIMATE {\"text\":3}\n",
"ANIMATE {\"text\":0}\n",
"ANIMATE {\"text\":1}\n",
"ANIMATE {\"text\":2}\n",
"ANIMATE {\"text\":3}\n",
"ANIMATE {\"text\":4}\n",
"ANIMATE {\"text\":5}\n",
"ANIMATE {\"text\":6}\n",
"ANIMATE {\"text\":7}\n",
"ANIMATE {\"text\":8}\n",
"ANIMATE {\"text\":9}\n",
"OFF {\"text\":0}\n",
"OFF {\"text\":1}\n",
"OFF {\"text\":2}\n",
"OFF {\"text\":3}\n",
"OFF {\"text\":4}\n",
"OFF {\"text\":5}\n",
"OFF {\"text\":6}\n",
"OFF {\"text\":7}\n",
"OFF {\"text\":8}\n",
"OFF {\"text\":9}\n"
]
},
{
"output_type": "error",
"ename": "CancelledError",
"evalue": "ignored",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mCancelledError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-1-a34dbbff9a5f>\u001b[0m in \u001b[0;36mlisten\u001b[0;34m()\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubscribe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0;32masync\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mmessage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mmessages\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmessage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtopic\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmessage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpayload\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.9/dist-packages/asyncio_mqtt/client.py\u001b[0m in \u001b[0;36m_generator\u001b[0;34m()\u001b[0m\n\u001b[1;32m 610\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 611\u001b[0;31m done, _ = await asyncio.wait(\n\u001b[0m\u001b[1;32m 612\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_disconnected\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreturn_when\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0masyncio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFIRST_COMPLETED\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib/python3.9/asyncio/tasks.py\u001b[0m in \u001b[0;36mwait\u001b[0;34m(fs, loop, timeout, return_when)\u001b[0m\n\u001b[1;32m 412\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 413\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0m_wait\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreturn_when\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 414\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib/python3.9/asyncio/tasks.py\u001b[0m in \u001b[0;36m_wait\u001b[0;34m(fs, timeout, return_when, loop)\u001b[0m\n\u001b[1;32m 524\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 525\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mwaiter\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 526\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCancelledError\u001b[0m: ",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001b[0;31mCancelledError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-1-a34dbbff9a5f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 45\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# asyncio.run(main())\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-1-a34dbbff9a5f>\u001b[0m in \u001b[0;36mmain\u001b[0;34m()\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[0mservice\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mloop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_task\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstart_service\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 41\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mtask\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 42\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mservice\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCancelledError\u001b[0m: "
]
}
]
},
{
"cell_type": "markdown",
"source": [
"# Coroutine version 2"
],
"metadata": {
"id": "jn1kmcYo-LCy"
}
},
{
"cell_type": "code",
"source": [
"! pip install jsonschema"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "WakhiwGn_Vyy",
"outputId": "c2c648d6-4df9-44f0-a151-efaf6bdad818"
},
"execution_count": 7,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
"Requirement already satisfied: jsonschema in /usr/local/lib/python3.9/dist-packages (4.3.3)\n",
"Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.9/dist-packages (from jsonschema) (22.2.0)\n",
"Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.9/dist-packages (from jsonschema) (0.19.3)\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"# https://matrix-io.github.io/matrix-documentation/matrix-lite/py-reference/everloop/\n",
"from time import sleep\n",
"import json\n",
"from math import pi, sin\n",
"\n",
"everloop = ['black'] * 5\n",
"\n",
"ledAdjust = 0.0\n",
"if len(everloop) == 35:\n",
" ledAdjust = 0.51 # MATRIX Creator\n",
"else:\n",
" ledAdjust = 1.01 # MATRIX Voice\n",
"\n",
"frequency = 0.375\n",
"counter = 0.0\n",
"tick = len(everloop) - 1\n",
"animation = {\n",
" 'onInit': {\n",
" 'frames': ['black']\n",
" },\n",
" 'onExec': {\n",
" 'unlimited': True,\n",
" 'sleep': 0.5,\n",
" 'frames': []\n",
" },\n",
" 'onDestroy': {\n",
" 'frames': ['black']\n",
" }\n",
"}\n",
"\n",
"for i in range(0, 6): # led.length\n",
" # Create rainbow\n",
" for i in range(len(everloop)):\n",
" r = round(max(0, (sin(frequency*counter+(pi/180*240))*155+100)/10))\n",
" g = round(max(0, (sin(frequency*counter+(pi/180*120))*155+100)/10))\n",
" b = round(max(0, (sin(frequency*counter)*155+100)/10))\n",
"\n",
" counter += ledAdjust\n",
"\n",
" everloop[i] = {'r':r, 'g':g, 'b':b}\n",
"\n",
" # Slowly show rainbow\n",
" if tick != 0:\n",
" for i in reversed(range(tick)):\n",
" everloop[i] = {}\n",
" tick -= 1\n",
" animation['onExec']['frames'].append(everloop)\n",
"\n",
"json.dumps(animation)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 134
},
"id": "O0fUwpAC_bNf",
"outputId": "4d61788a-c82b-4d45-82b3-4e30fb1470a7"
},
"execution_count": 3,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"'{\"onInit\": {\"frames\": [\"black\"]}, \"onExec\": {\"unlimited\": true, \"frames\": [[{\"r\": 24, \"g\": 0, \"b\": 9}, {\"r\": 25, \"g\": 1, \"b\": 4}, {\"r\": 25, \"g\": 6, \"b\": 0}, {\"r\": 22, \"g\": 12, \"b\": 0}, {\"r\": 18, \"g\": 18, \"b\": 0}], [{\"r\": 24, \"g\": 0, \"b\": 9}, {\"r\": 25, \"g\": 1, \"b\": 4}, {\"r\": 25, \"g\": 6, \"b\": 0}, {\"r\": 22, \"g\": 12, \"b\": 0}, {\"r\": 18, \"g\": 18, \"b\": 0}], [{\"r\": 24, \"g\": 0, \"b\": 9}, {\"r\": 25, \"g\": 1, \"b\": 4}, {\"r\": 25, \"g\": 6, \"b\": 0}, {\"r\": 22, \"g\": 12, \"b\": 0}, {\"r\": 18, \"g\": 18, \"b\": 0}], [{\"r\": 24, \"g\": 0, \"b\": 9}, {\"r\": 25, \"g\": 1, \"b\": 4}, {\"r\": 25, \"g\": 6, \"b\": 0}, {\"r\": 22, \"g\": 12, \"b\": 0}, {\"r\": 18, \"g\": 18, \"b\": 0}], [{\"r\": 24, \"g\": 0, \"b\": 9}, {\"r\": 25, \"g\": 1, \"b\": 4}, {\"r\": 25, \"g\": 6, \"b\": 0}, {\"r\": 22, \"g\": 12, \"b\": 0}, {\"r\": 18, \"g\": 18, \"b\": 0}], [{\"r\": 24, \"g\": 0, \"b\": 9}, {\"r\": 25, \"g\": 1, \"b\": 4}, {\"r\": 25, \"g\": 6, \"b\": 0}, {\"r\": 22, \"g\": 12, \"b\": 0}, {\"r\": 18, \"g\": 18, \"b\": 0}]]}, \"onDestroy\": {\"frames\": [\"black\"]}}'"
],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "string"
}
},
"metadata": {},
"execution_count": 3
}
]
},
{
"cell_type": "code",
"source": [
"import asyncio\n",
"from jsonschema import validate\n",
"import asyncio_mqtt as aiomqtt\n",
"import json\n",
"\n",
"queue = asyncio.Queue()\n",
"\n",
"async def listen():\n",
" async with aiomqtt.Client(\"test.mosquitto.org\") as client:\n",
" async with client.messages() as messages:\n",
" for key in ['eva/matrixvoice/leds']:\n",
" await client.subscribe(key)\n",
" async for message in messages:\n",
" await queue.put((message.topic.value, json.loads(str(message.payload.decode(\"utf-8\")))))\n",
"\n",
"schema = {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"onInit\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"frames\": {\n",
" \"type\": \"array\",\n",
" \"items\": {}\n",
" }\n",
" },\n",
" \"required\": [\n",
" \"frames\"\n",
" ]\n",
" },\n",
" \"onExec\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"sleep\": {\n",
" \"type\": \"number\"\n",
" },\n",
" \"unlimited\": {\n",
" \"type\": \"boolean\"\n",
" },\n",
" \"frames\": {\n",
" \"type\": \"array\",\n",
" \"items\": {}\n",
" }\n",
" },\n",
" \"required\": [\n",
" \"sleep\",\n",
" \"unlimited\",\n",
" \"frames\"\n",
" ]\n",
" },\n",
" \"onDestroy\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"frames\": {\n",
" \"type\": \"array\",\n",
" \"items\": {}\n",
" }\n",
" },\n",
" \"required\": [\n",
" \"frames\"\n",
" ]\n",
" }\n",
" },\n",
" \"required\": [\n",
" \"onInit\",\n",
" \"onExec\",\n",
" \"onDestroy\"\n",
" ]\n",
"}\n",
"\n",
"def onInit(payload):\n",
" print(\"onInit\", payload)\n",
" # led.set(payload['frames'][0])\n",
"\n",
"def onExec(payload, frame=0):\n",
" unlimited = 'unlimited' in payload and payload['unlimited']\n",
" while unlimited or frame < len(payload['frames']):\n",
" print(payload['frames'][frame%len(payload['frames'])])\n",
" # led.set(payload['frames'][frame%len(payload['frames'])])\n",
" yield True\n",
" yield False\n",
"\n",
"def onDestroy(payload):\n",
" print(\"\\nonDestroy\", payload)\n",
" # led.set(payload['frames'][0])\n",
"\n",
"async def start_service():\n",
" while True:\n",
" topic, payload = await queue.get()\n",
" try:\n",
" validate(instance=payload, schema=schema)\n",
" onInit(payload['onInit'])\n",
" frame = 0\n",
" while queue.empty() and next(onExec(payload['onExec'], frame)):\n",
" frame += 1\n",
" await asyncio.sleep(payload['onExec']['sleep'])\n",
" onDestroy(payload['onDestroy'])\n",
" except Exception as e:\n",
" print(payload,e)\n",
"\n",
"async def main():\n",
" loop = asyncio.get_event_loop()\n",
" task = loop.create_task(listen())\n",
" service = loop.create_task(start_service())\n",
" await service\n",
" await task\n",
"\n",
"\n",
"await main() # asyncio.run(main())"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 506
},
"id": "HjrXrXLx-Nv2",
"outputId": "2d5dc389-7b30-4676-f65c-e76b2574d2fc"
},
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"[{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] [{'r': 24, 'g': 0, 'b': 9}, {'r': 25, 'g': 1, 'b': 4}, {'r': 25, 'g': 6, 'b': 0}, {'r': 22, 'g': 12, 'b': 0}, {'r': 18, 'g': 18, 'b': 0}] "
]
},
{
"output_type": "error",
"ename": "CancelledError",
"evalue": "ignored",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mCancelledError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-8-048c6481fa01>\u001b[0m in \u001b[0;36mstart_service\u001b[0;34m()\u001b[0m\n\u001b[1;32m 95\u001b[0m \u001b[0mframe\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 96\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0masyncio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpayload\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'onExec'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'sleep'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 97\u001b[0m \u001b[0monDestroy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpayload\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'onDestroy'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib/python3.9/asyncio/tasks.py\u001b[0m in \u001b[0;36msleep\u001b[0;34m(delay, result, loop)\u001b[0m\n\u001b[1;32m 651\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 652\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mfuture\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 653\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCancelledError\u001b[0m: ",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001b[0;31mCancelledError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-8-048c6481fa01>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 108\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 109\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# asyncio.run(main())\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-8-048c6481fa01>\u001b[0m in \u001b[0;36mmain\u001b[0;34m()\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0mtask\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mloop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_task\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlisten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0mservice\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mloop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_task\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstart_service\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 105\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mservice\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 106\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mtask\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCancelledError\u001b[0m: "
]
}
]
},
{
"cell_type": "markdown",
"source": [
"# WakeFace"
],
"metadata": {
"id": "ICmcGK3IRNmb"
}
},
{
"cell_type": "code",
"source": [
"# https://gist.github.com/khalidmeister/ea292150905d748457d8f6c19ec095c3\n",
"import cv2\n",
"import mediapipe as mp\n",
"import numpy as np\n",
"\n",
"mp_face_mesh = mp.solutions.face_mesh\n",
"face_mesh = mp_face_mesh.FaceMesh(min_detection_confidence=0.5, min_tracking_confidence=0.5)\n",
"cap = cv2.VideoCapture(0)\n",
"\n",
"async def publish_camera_device(client):\n",
" while cap.isOpened():\n",
" success, image = cap.read()\n",
"\n",
" # Flip the image horizontally for a later selfie-view display\n",
" # Also convert the color space from BGR to RGB\n",
" image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)\n",
"\n",
" # To improve performance\n",
" image.flags.writeable = False\n",
" \n",
" # Get the result\n",
" results = face_mesh.process(image)\n",
" \n",
" # To improve performance\n",
" image.flags.writeable = True\n",
" \n",
" # Convert the color space from RGB to BGR\n",
" image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)\n",
"\n",
" img_h, img_w, img_c = image.shape\n",
" face_3d = []\n",
" face_2d = []\n",
"\n",
" if results.multi_face_landmarks:\n",
" for face_landmarks in results.multi_face_landmarks:\n",
" for idx, lm in enumerate(face_landmarks.landmark):\n",
" if idx == 33 or idx == 263 or idx == 1 or idx == 61 or idx == 291 or idx == 199:\n",
" if idx == 1:\n",
" nose_2d = (lm.x * img_w, lm.y * img_h)\n",
" nose_3d = (lm.x * img_w, lm.y * img_h, lm.z * 8000)\n",
"\n",
" x, y = int(lm.x * img_w), int(lm.y * img_h)\n",
"\n",
" # Get the 2D Coordinates\n",
" face_2d.append([x, y])\n",
"\n",
" # Get the 3D Coordinates\n",
" face_3d.append([x, y, lm.z]) \n",
" \n",
" # Convert it to the NumPy array\n",
" face_2d = np.array(face_2d, dtype=np.float64)\n",
"\n",
" # Convert it to the NumPy array\n",
" face_3d = np.array(face_3d, dtype=np.float64)\n",
"\n",
" # The camera matrix\n",
" focal_length = 1 * img_w\n",
"\n",
" cam_matrix = np.array([ [focal_length, 0, img_h / 2],\n",
" [0, focal_length, img_w / 2],\n",
" [0, 0, 1]])\n",
"\n",
" # The Distance Matrix\n",
" dist_matrix = np.zeros((4, 1), dtype=np.float64)\n",
"\n",
" # Solve PnP\n",
" success, rot_vec, trans_vec = cv2.solvePnP(face_3d, face_2d, cam_matrix, dist_matrix)\n",
"\n",
" # Get rotational matrix\n",
" rmat, jac = cv2.Rodrigues(rot_vec)\n",
"\n",
" # Get angles\n",
" angles, mtxR, mtxQ, Qx, Qy, Qz = cv2.RQDecomp3x3(rmat)\n",
"\n",
" # Get the rotation degrees\n",
" x = angles[0] * 360\n",
" y = angles[1] * 360\n",
"\n",
" # See where the user's head tilting\n",
" payload = \"L\" if y < -10 else \"R\" if y > 10 else \"D\" if x < -10 else \"F\" \n",
" await client.publish(\"eva/camera/headtilting\", payload={'position': payload})"
],
"metadata": {
"id": "3H5X5wtwRMzs"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"import asyncio\n",
"import asyncio_mqtt as aiomqtt\n",
"\n",
"async def listen():\n",
" async with aiomqtt.Client(\"test.mosquitto.org\") as client:\n",
" publish_camera_device(client)\n",
"\n",
"\n",
"await listen()# asyncio.run(main())"
],
"metadata": {
"id": "jwA3EmLrRvqh"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Thread version"
],
"metadata": {
"id": "H86sZJEdYK2W"
}
},
{
"cell_type": "code",
"source": [
"import threading\n",
"import time\n",
"import queue\n",
"from dataclasses import dataclass, field\n",
"from typing import Any\n",
"\n",
"class Subject:\n",
" def __iter__(self):\n",
" self.queue = queue.Queue()\n",
" return self\n",
" def __next__(self):\n",
" value = None if self.queue.empty() else self.queue.get()\n",
" return value\n",
" def publish(self, value):\n",
" self.queue.put(value)\n",
"\n",
"@dataclass(order=True)\n",
"class PrioritizedItem: \n",
" data: Any=field(compare=False)\n",
" state: Any=field(compare=False)\n",
" priority: int=field(default=3)\n",
" def __post_init__(self):\n",
" self.calculate_priority()\n",
" def __repr__(self):\n",
" return f\"{self.state}\"\n",
" def calculate_priority(self):\n",
" try:\n",
" self.priority = self.data['priority'] if 'priority' in self.data and \\\n",
" (type(self.data['priority']) == int or type(self.data['priority']) == float) \\\n",
" else self.priority\n",
" except:\n",
" return self\n",
" return self\n",
"\n",
"# Pushdown automata - Priority Queue\n",
"\n",
"class State:\n",
" def __init__(self, resource):\n",
" self.resource = resource\n",
" def keep_in_state(self, next_state):\n",
" print(\"State Queue \", self.resource.buffer.queue.queue)\n",
" state = next(self.resource.buffer)\n",
" return state == None or state.__class__.__name__ != next_state.__class__.__name__ \n",
" def __repr__(self):\n",
" return f'State={self.__class__.__name__}'\n",
" def exec(self, payload):\n",
" pass\n",
"\n",
"class Idle(State):\n",
" def __init__(self, resource):\n",
" super().__init__(resource)\n",
" def exec(self, payload):\n",
" print(self)\n",
"\n",
"class Animation(State):\n",
" def __init__(self, resource, next_state):\n",
" super().__init__(resource)\n",
" self.next_state = next_state\n",
" def exec(self, payload):\n",
" while self.keep_in_state(self.next_state):\n",
" print(self)\n",
" time.sleep(0.5)\n",
"\n",
"class ResourceManagementThread(threading.Thread):\n",
" def __init__(self):\n",
" super().__init__(daemon=True)\n",
" self.resource_queue = queue.PriorityQueue()\n",
" self.lock = threading.Lock()\n",
" self.subject = Subject()\n",
" self.buffer = iter(self.subject)\n",
" def front(self):\n",
" self.lock.acquire()\n",
" temp = None if self.resource_queue.empty() else self.resource_queue.queue[0].state\n",
" self.lock.release()\n",
" return temp\n",
" def run(self):\n",
" while True:\n",
" print(\"Resource Queue \", self.resource_queue.queue)\n",
" prioritizedItem = self.resource_queue.get()\n",
" print(f'Working on ', prioritizedItem)\n",
" prioritizedItem.state.exec(prioritizedItem)\n",
" print(f'Finished ', prioritizedItem)\n",
" self.resource_queue.task_done()\n",
" def put(self, input):\n",
" self.resource_queue.put(input)\n",
" self.subject.publish(input.state)"
],
"metadata": {
"id": "oYuVsYAJVSiR"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"import paho.mqtt.client as mqtt\n",
"import json\n",
"\n",
"resource = ResourceManagementThread()\n",
"idle = Idle(resource)\n",
"animation = Animation(resource, idle)\n",
"\n",
"# The callback for when the client receives a CONNACK response from the server.\n",
"def on_connect(client, userdata, flags, rc):\n",
" print(\"Connected with result code \"+str(rc))\n",
"\n",
" # Subscribing in on_connect() means that if we lose the connection and\n",
" # reconnect then subscriptions will be renewed.\n",
" client.subscribe(\"hermes/hotword/toggleOn\")\n",
" client.subscribe(\"hermes/asr/stopListening\")\n",
"\n",
"# The callback for when a PUBLISH message is received from the server.\n",
"def on_message(client, userdata, msg):\n",
" print(msg.topic+\" \"+str(msg.payload))\n",
"\n",
"\n",
"def toggle_on(client, userdata, msg):\n",
" print(\"Turn on \"+msg.topic)\n",
" resource.put(PrioritizedItem(json.loads(str(msg.payload.decode(\"utf-8\"))), animation))\n",
"\n",
"def stop_listening(client, userdata, msg):\n",
" print(\"Turn off \"+msg.topic)\n",
" resource.put(PrioritizedItem(json.loads(str(msg.payload.decode(\"utf-8\"))), idle))\n",
"\n",
"client = mqtt.Client()\n",
"client.on_connect = on_connect\n",
"client.message_callback_add('hermes/hotword/toggleOn', toggle_on)\n",
"client.message_callback_add('hermes/asr/stopListening', stop_listening)\n",
"client.on_message = on_message\n",
"\n",
"client.connect(\"mqtt.eclipseprojects.io\", 1883, 60)\n",
"\n",
"\n",
"resource.start()\n",
"client.loop_forever()"
],
"metadata": {
"id": "KwbrWEvGWhwP",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"outputId": "491c2301-a96a-4f46-b871-f1a95a245f7b"
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Resource Queue []\n",
"Connected with result code 0\n",
"Turn on hermes/hotword/toggleOn\n",
"Working on State=Animation\n",
"State Queue deque([State=Animation])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"State Queue deque([])\n",
"State=Animation\n",
"Turn off hermes/asr/stopListening\n",
"State Queue deque([State=Idle])\n",
"Finished State=Animation\n",
"Resource Queue [State=Idle]\n",
"Working on State=Idle\n",
"State=Idle\n",
"Finished State=Idle\n",
"Resource Queue []\n"
]
},
{
"output_type": "error",
"ename": "KeyboardInterrupt",
"evalue": "ignored",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-2-cb9639909575>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[0mresource\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m \u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloop_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/usr/local/lib/python3.9/dist-packages/paho/mqtt/client.py\u001b[0m in \u001b[0;36mloop_forever\u001b[0;34m(self, timeout, max_packets, retry_first_connection)\u001b[0m\n\u001b[1;32m 1754\u001b[0m \u001b[0mrc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mMQTT_ERR_SUCCESS\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1755\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mrc\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mMQTT_ERR_SUCCESS\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1756\u001b[0;31m \u001b[0mrc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_loop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1757\u001b[0m \u001b[0;31m# We don't need to worry about locking here, because we've\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1758\u001b[0m \u001b[0;31m# either called loop_forever() when in single threaded mode, or\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.9/dist-packages/paho/mqtt/client.py\u001b[0m in \u001b[0;36m_loop\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 1148\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1149\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1150\u001b[0;31m \u001b[0msocklist\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mselect\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mselect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrlist\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwlist\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1151\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1152\u001b[0m \u001b[0;31m# Socket isn't correct type, in likelihood connection is lost\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment