Vous pouvez coder toutes vos actions directement en python.
Une autre solution que j'utilise beaucoup est d'utiliser le couple MQTT - Node Red pour réaliser les actions.
Dans le plugin, on envoie juste un message MQTT.
Dans Node Red, on récupère le message et l'on traite. Si besoin de faire parler l'assistant, on envoie un message MQTT à l'assistant
Quelques une de mes flow node-red :
Pour tester : copier le texte ci-dessous et dans node-red : menu/import/clipboard/...
C'est ma config : faudra surement importer quelques modules et adapter un peu.
[{"id":"2a6ede4e.100272","type":"mqtt in","z":"c624c89c.f72d88","name":"","topic":"T-HOME/QUESTION","qos":"0","broker":"a4c87fe8.0452d","x":130,"y":122,"wires":[["fcf5475.6af85b8"]]},{"id":"fcf5475.6af85b8","type":"switch","z":"c624c89c.f72d88","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"HEURE","vt":"str"},{"t":"eq","v":"DATE","vt":"str"},{"t":"eq","v":"FUEL","vt":"str"},{"t":"eq","v":"CAVA","vt":"str"},{"t":"eq","v":"METEO","vt":"str"},{"t":"eq","v":"CHUCK","vt":"str"}],"checkall":"true","outputs":6,"x":340,"y":122,"wires":[["fe897337.fb3ac"],["de3650d9.3ce33"],["e2eab9b1.787fe"],["a0dc3e60.581ca8"],["a9351f97.dd1218"],["93b7b7c4.22c77"]]},{"id":"fe897337.fb3ac","type":"function","z":"c624c89c.f72d88","name":"Heure","func":"var moment = global.get('moment');\nmoment.locale('fr');\nmsg.payload = \"Il est \" + moment().format('H[ heure ]m');\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":62,"wires":[["b8baeb81.201858"]]},{"id":"b8baeb81.201858","type":"mqtt out","z":"c624c89c.f72d88","name":"","topic":"T-HOME/PI-SALON/SPEAK","qos":"0","retain":"false","broker":"a4c87fe8.0452d","x":1000,"y":122,"wires":[]},{"id":"de3650d9.3ce33","type":"function","z":"c624c89c.f72d88","name":"Date","func":"var moment = global.get('moment');\nmoment.locale('fr');\nmsg.payload = \"Nous sommes le \" + moment().format(\"dddd Do MMMM YYYY\")\nmsg.payload = msg.payload + \" et il est \" + moment().format('H[ heure ]m');\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":102,"wires":[["b8baeb81.201858"]]},{"id":"e2eab9b1.787fe","type":"function","z":"c624c89c.f72d88","name":"Fuel","func":"if (context.global.VALEURS.CuveFuel){\n msg.payload = \"Il y a \" + Math.round(context.global.VALEURS.CuveFuel.payload) + \" litres de fuel dans la cuve.\";\n}else{\n msg.payload = \"Je n'en ai aucune idée.\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":142,"wires":[["b8baeb81.201858"]]},{"id":"a0dc3e60.581ca8","type":"function","z":"c624c89c.f72d88","name":"CAVA","func":"msg.payload = \"Ouais, ça boume grave.\"\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":182,"wires":[["b8baeb81.201858"]]},{"id":"a9351f97.dd1218","type":"change","z":"c624c89c.f72d88","name":"Météo","rules":[{"t":"set","p":"payload","pt":"msg","to":"VALEURS['T-HOME/METEO'].payload","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":222,"wires":[["b8baeb81.201858"]]},{"id":"1682b644.fed61a","type":"function","z":"c624c89c.f72d88","name":"set VALEURS","func":"if (!context.global.VALEURS) {\n context.global.VALEURS={};\n}\nif (!context.global.VALEURS[msg.topic]){\n context.global.VALEURS[msg.topic]={};\n}\ncontext.global.VALEURS[msg.topic].date = new Date();\ncontext.global.VALEURS[msg.topic].payload = msg.payload;\n","outputs":"0","noerr":0,"x":921,"y":674,"wires":[]},{"id":"345a1e7c.9b23d2","type":"openweathermap","z":"c624c89c.f72d88","name":"","wtype":"forecast","lon":"","lat":"","city":"Epinal","country":"France","language":"fr","x":469,"y":673,"wires":[["81398159.08b5e","36dca140.e6bebe"]]},{"id":"fbb6b79e.632db8","type":"inject","z":"c624c89c.f72d88","name":"","topic":"T-HOME/METEO","payload":"","payloadType":"date","repeat":"3600","crontab":"","once":true,"x":170,"y":673,"wires":[["345a1e7c.9b23d2"]]},{"id":"81398159.08b5e","type":"function","z":"c624c89c.f72d88","name":"","func":"var text = \"Météo à Epinal. \";\ntext += \"Aujourd'hui, le temps est \" + msg.payload[0].weather[0].description + \". \";\ntext += \"La température est comprise entre \" + Math.round(msg.payload[0].temp.min)+\" et \"+Math.round(msg.payload[0].temp.max) +\" degrés. \";\ntext += \"Demain, le temps sera \" + msg.payload[1].weather[0].description + \". \";\ntext += \"La température sera comprise entre \" + Math.round(msg.payload[1].temp.min)+\" et \" + Math.round(msg.payload[0].temp.max) + \"degrés.\";\ntext += \"Après demain, le temps sera \"+msg.payload[2].weather[0].description+\".\";\ntext += \"La température sera comprise entre \"+Math.round(msg.payload[2].temp.min)+\" et \"+Math.round(msg.payload[0].temp.max)+\"degrés.\";\nmsg.payload = text;\nreturn msg;","outputs":1,"noerr":0,"x":696,"y":673,"wires":[["1682b644.fed61a"]]},{"id":"93b7b7c4.22c77","type":"http request","z":"c624c89c.f72d88","name":"www.chucknorrisfacts.fr","method":"GET","ret":"obj","url":"https://www.chucknorrisfacts.fr/api/get?data=tri:alea;nb:1","tls":"","x":610,"y":262,"wires":[["5b97c488.9a6b3c"]]},{"id":"5b97c488.9a6b3c","type":"change","z":"c624c89c.f72d88","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[0].fact","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":990,"y":242,"wires":[["b8baeb81.201858"]]},{"id":"9954b98f.5f7e98","type":"http request","z":"c624c89c.f72d88","name":"blague","method":"POST","ret":"txt","url":"http://192.168.10.10/blague.html","tls":"","x":390,"y":302,"wires":[["9f3abbd4.5492b8"]]},{"id":"f3f66570.1b218","type":"inject","z":"c624c89c.f72d88","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":171,"y":253,"wires":[["93b7b7c4.22c77"]]},{"id":"9f3abbd4.5492b8","type":"debug","z":"c624c89c.f72d88","name":"","active":true,"console":"false","complete":"true","x":792,"y":296,"wires":[]},{"id":"32b79850.183af8","type":"function","z":"c624c89c.f72d88","name":"","func":"var iconv = global.get(\"iconvlite\");\nvar str = iconv.decode(msg.payload, 'latin1');\nmsg.payload = str.toString('utf8');\nreturn str;","outputs":1,"noerr":0,"x":770,"y":202,"wires":[[]]},{"id":"36dca140.e6bebe","type":"debug","z":"c624c89c.f72d88","name":"","active":true,"console":"false","complete":"true","x":622.5,"y":783.2999954223633,"wires":[]},{"id":"22c36520.aafd52","type":"mqtt in","z":"c624c89c.f72d88","name":"","topic":"T-HOME/SALON/LISTEN/maison/before","qos":"2","broker":"a4c87fe8.0452d","x":217,"y":390,"wires":[["8c0ee5c8.b97268"]]},{"id":"8c0ee5c8.b97268","type":"change","z":"c624c89c.f72d88","name":"mute","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"volume\":\"mute\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":474,"y":390,"wires":[["76666a4f.e3ec44"]]},{"id":"d8c80995.547e38","type":"mqtt in","z":"c624c89c.f72d88","name":"","topic":"T-HOME/SALON/LISTEN/maison/before_s2t","qos":"2","broker":"a4c87fe8.0452d","x":228,"y":452,"wires":[["3986a72a.956d4"]]},{"id":"3986a72a.956d4","type":"change","z":"c624c89c.f72d88","name":"unmute","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"volume\":\"unmute\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":487,"y":451,"wires":[["76666a4f.e3ec44"]]},{"id":"76666a4f.e3ec44","type":"sonos-control","z":"c624c89c.f72d88","playnode":"5aeb3072.549be8","name":"","mode":"","track":"","volume":"","volume_value":"","x":676.5,"y":413,"wires":[]},{"id":"a4c87fe8.0452d","type":"mqtt-broker","z":"","broker":"192.168.0.15","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":""},{"id":"5aeb3072.549be8","type":"sonos-config","z":"","name":"SALON","ipaddress":"192.168.0.14","port":""}]