Octoprint et Domoticz
Un petit script lua pour récupérer les infos d’Octoprint dans Domoticz.
Il vous faut 7 Dummy devices :
- OctoStatusIDX=’387′ — type: Text pour afficher le status de l’imprimante
- OctoBebIDX=’388′ — type: Temperature pour afficher la température du plateau
- OctoHeadIDX=’389′ — type: Temperature pour afficher la température de la tête d’impression
- OctoTotalTimeIDX=’390′ — type: Text pour le temps total d’impression
- OctoCompleteIDX=’391′ — type: Percentage pour le pourcentage d’avancement
- OctoPrintTimeIDX=’392′ — type: Text pour la durée d’impression passé
- OctoTimeLeftIDX=’393′ — type: Text pour le temps restant.
Dans les paramètres du script, il faut modifier les IDX de ces devices lignes 14 à 20.
Renseigner l’IP d’Octoprint ligne 5, la clé API d’Octoprint ligne 7.
Et enfin, si différent, l’emplacement du script JSON.lua et de curl, lignes 9 et 11.
Le script est disponible ici : https://github.com/chatainsim/scripts_domoticz/blob/master/octoprint.lua
[pastacode lang= »c » user= »chatainsim » repos= »scripts_domoticz » path_id= »octoprint.lua » revision= » » highlight= » » lines= » » provider= »github »/]
Bonsoir,
J’ai tenté de faire les différentes étapes indiquées en modifiant comme inscrit ci-dessus certaines valeurs mais les différentes informations liées à OctoPrint ne remontent pas dans mon serveur Domoticz.
Pourriez-vous m’aider s’il vous plait? Merci.
Bonsoir, avez-vous des erreurs dans la log de Domoticz ? Sur quel système fonctionne t’il Linux ou Windows ? Le serveur Domoticz peut-il accéder au serveur Octoprint via ssh ou autre ? Si depuis le serveur Domoticz vous faites un curl http://adresse_ip_octoprint est-ce que ça fonctionne (sous Linux) ?
Bonjour Simon,
Quelles genre d’erreurs parlez vous?
Mon serveur Domoticz tourne sur un PI4 sur lequel tourne également Octoprint, donc sous Raspbian Buster.
Cordialement.
Faut-il qu’une impression soit en cours afin de voir les valeurs dans Domoticz?
Les IDX que j’ai renseignés sont ceux indiqués dans les dispositifs et non dans les Matériels mais même en les renseignant je n’ai aucune remonté.
Faut-il installer un plugin ou autre dans Octoprint afin que la liaison se fasse correctement avec Domoticz?
Voici le Script que j’ai placé dans le répertoire /home/pi/domoticz/scripts/lua
— Use Lua -> Time
— For displaying debug messages
debug=false
— IP address of octoprint (if you use a different port then 80 put IP:PORT
OctoIP=’192.168.1.20′
— Octoprint API Key (found in Settings -> API)
OctoAPI=’1A1A96EE8232443CA24338209E6CC48D’
— JSON.lua path
json = (loadfile « /home/pi/domoticz/scripts/lua/JSON.lua »)()
— Curl path
curl = ‘/usr/bin/curl’
— IDX of your Dummy devices
OctoStatusIDX=’4′ — type: Text
OctoBebIDX=’5′ — type: Temperature
OctoHeadIDX=’6′ — type: Temperature
OctoTotalTimeIDX=’7′ — type: Text
OctoCompleteIDX=’8′ — type: Percentage
OctoPrintTimeIDX=’9′ — type: Text
OctoTimeLeftIDX=’10’ — type: Text
OctoPrinter=’http://’..OctoIP..’/api/printer’
OctoJob=’http://’..OctoIP..’/api/job’
local function update(idx, value1)
local cmd = idx..’|0|’..value1
table.insert (commandArray, { [‘UpdateDevice’] = cmd } )
end
local function ping(OctoIP)
ping_success=os.execute(‘ping -W2 -c1 ‘..OctoIP)
return ping_success
end
local function online()
DataOctoTemp = assert(io.popen(curl..’ -s –max-time 8 -H « X-Api-Key: ‘..OctoAPI..' » « ‘..OctoPrinter..' »‘))
BlocOctoTemp = DataOctoTemp:read(‘*all’)
DataOctoTemp:close()
JsonOctoTemp = json:decode(BlocOctoTemp)
end
local function round(num, n)
local mult = 10^(n or 0)
return math.floor(num * mult + 0.5) / mult
end
function SecondsToClock(seconds)
local seconds = tonumber(seconds)
if seconds <= 0 then
return "00:00:00";
else
hours = string.format("%02.f", math.floor(seconds/3600));
mins = string.format("%02.f", math.floor(seconds/60 – (hours*60)));
secs = string.format("%02.f", math.floor(seconds – hours*3600 – mins *60));
return hours..":"..mins..":"..secs
end
end
commandArray = {}
local status, retval = pcall(online,10);
if(ping(OctoIP)) then
if (status) then
DataOctoTemp = assert(io.popen(curl..' -s –max-time 8 -H "X-Api-Key: '..OctoAPI..'" "'..OctoPrinter..'"'))
BlocOctoTemp = DataOctoTemp:read('*all')
DataOctoTemp:close()
JsonOctoTemp = json:decode(BlocOctoTemp)
OctoBeb = JsonOctoTemp.temperature.bed.actual
OctoHead = JsonOctoTemp.temperature.tool0.actual
OctoStatus = JsonOctoTemp.state.text
OctoState = JsonOctoTemp.state.flags.printing
update(OctoBebIDX, OctoBeb)
update(OctoHeadIDX, OctoHead)
update(OctoStatusIDX, OctoStatus)
if (OctoState) then
DataOctoTime = assert(io.popen(curl..' -s –max-time 8 -H "X-Api-Key: '..OctoAPI..'" "'..OctoJob..'"'))
BlocOctoTime = DataOctoTime:read('*all')
DataOctoTime:close()
JsonOctoTime = json:decode(BlocOctoTime)
OctoTotalTime = JsonOctoTime.job.estimatedPrintTime
OctoComplete = JsonOctoTime.progress.completion
OctoPrintTime = JsonOctoTime.progress.printTime
OctoTimeLeft = JsonOctoTime.progress.printTimeLeft
update(OctoTotalTimeIDX, SecondsToClock(OctoTotalTime))
update(OctoCompleteIDX, round(OctoComplete))
update(OctoPrintTimeIDX, SecondsToClock(OctoPrintTime))
update(OctoTimeLeftIDX, SecondsToClock(OctoTimeLeft))
end
else
if (debug) then print("Printer not connected") end
update(OctoStatusIDX, "Printer not connected")
update(OctoBebIDX, 0)
update(OctoHeadIDX, 0)
update(OctoTotalTimeIDX, SecondsToClock(0))
update(OctoCompleteIDX, 0)
update(OctoPrintTimeIDX, SecondsToClock(0))
update(OctoTimeLeftIDX, SecondsToClock(0))
end
else
update(OctoStatusIDX, "Octoprint offline.")
end
return commandArray
Pour avoir des infos dans Domoticz, il faut au moins que l’imprimante soit allumée et que Octoprint soit connecté à l’imprimante.
Sinon les valeur seront à zéro et OctoStatus sera sur Printer not connected.
Je parle des erreurs dans la log de Domoticz: Setup -> Log
Je n’ai aucune erreur dans mes Logs sauf concernant mes slamphers qui ne sont pas allumés pour le moment mais c’est normal.
Sinon, est-ce que d’après toi mon script serait bon sachant que j’ai indiqué les IDX fournis par Domoticz?
Mes températures restent à zéro, quand aux status ils apparaissent en Hello World.
Normalement le status devrait être mis à jour ainsi que les températures si octoprint est connecté a ton imprimante.
L’ip d’octoprint est bonne ? Essaye 127.0.0.1 pour voir.
Tu peux essayer en ligne de commande depuis le Pi :
curl 192.168.1.20 ou curl 127.0.0.1
Peut être avec un –location : curl 192.168.1.20 –location
Tu devrais avoir un retour normalement.
Si tu as telegram : https://t.me/easterdomo ça peut être plus pratique que les commentaires ici.
Je ne possède pas telegram mais on peut communiquer via snapshat si tu veux?
J’ai fais le test et j’obtiens bien un transfert de données lorsque je précise que le port 5000 est utilisé.
J’ai indiqué également le port dans le script mais rien y fait pfff.
Mon pseudo snap est Fredo7874.
C’est bon je me suis mis sur le groupe Easter’s Domo sur Telegram 😉
Il est nécessaire de sauver le script avec un nom de fichier commençant par ‘script_device_’, sinon Domoticz ne l’exécutera pas (c’est une erreur que j’ai commise).
Effectivement. Pour ma part, je stocke les scripts dans l’éditeur d’événements de Domoticz, comme ça quand je fais une sauvegarde de la base, les scripts sont dedans.
Bonjour et bravo pour votre travail ! J’ai un petit problème, mon OctoTimeLeftIDX ne passe jamais à 0 mais reste sur la dernière valeur avant 0. J’aurais également voulu recevoir une notification lorsque l’impression est terminée mais je ne sais pas comment le coder…
Concernant le OctoTimeLeftIDX normalement il passe à zéro quand il n’y a plus d’impression en cours.
Pour la notification, tu peux en mettre une sur le pourcentage, quand c’est supérieur à 99% tu envoie un notification.
Merci pour ta réponse. Quand l’impression est terminée, la durée restante dans octoprint est vide (tiret) mais dans Domoticz ça ne passe pas à 0. Par contre, je viens de m’apercevoir que pour l’état passe de « printing » à « operational ». Je vais essayer de baser la notification sur ce changement d’état.
Bon, j’ai essayé ça :
— envoi notification telegram en fin d impression
local subsystem = « telegram »
if (devicechanged[‘Etat Octoprint’] == ‘Operational’) then
commandArray[#commandArray+1] = {[‘SendNotification’] = ‘Ender 3# L impression 3D est à présent terminée !#0###’.. subsystem .. »}
end
mais sans succès …
Il est possible de mettre la notification sur le sensor de pourcentage OctoComplete :
Si le pourcentage est supérieur ou égale à 99% alors envoyer une notification.
Sinon en lua :
local subsystem = ‘telegram’
etatocto = ‘Etat Octoprint’
commandArray = {}
if (devicechanged[etatocto] == ‘Operational’) then
commandArray[‘SendNotification’]=’subject#L impression 3D est à présent terminée !#0#sound#extradata#’..subsystem
end
return commandArray
En version un peu plus lisible : https://gist.github.com/chatainsim/62f17885d08976eb2dad1c2c04b9f53d
J’ai testé en créant un script de type device mais je n’ai pas de notifications qui remontent ni d’erreur dans les logs ????. J’avais rajouté un print pour les logs mais le commentaire n’apparaît pas non plus.
Il faut créer un script de type time en fait.
Comme ça il s’exécute toute les minutes.
« Devicechanged » n’est pas compatible avec un script de type time, si ?
Oui, pardon je me suis mélangé les pinceaux.
Sur devices ça devrait fonctionner. Essaye de mettre un print après le commandArray et avant le if devicechanged :
commandArray = {}
print(« Ceci est un test de notification »)
if (devicechanged[etatocto] == ‘Operational’) then
Bonjour, désolé pour la réponse tardive. Quand je mets le print, je le vois bien apparaitre dans les logs.
Par contre, toujours pas de notification. Mon script est bien de type device :
commandArray = {}
local subsystem = ‘telegram’
etatocto = ‘Etat imprimante’
msg = ‘L impression 3D est à présent terminée !’
if (devicechanged[etatocto] == ‘Operational’) then
commandArray[‘SendNotification’]=’Ender3#’..msg..’#0#sound#extradata#’..subsystem
end
return commandArray
En plus de cela, le temps restant ne passe jamais à 0 et le pourcentage d’impression, pour les petites pièces, peut parfois rester à 97%. J’ai repris ton script mais je ne vois pas pourquoi ça ne met pas à jour avec les dernières valeurs
Je viens de faire les test, ce script là ne fonctionne pas chez moi non plus apparemment.
Je sais que mettre une notification sur le pourcentage n’est pas non plus fonctionnel à chaque fois.
J’ai des décalage entre ce que me donne l’API d’Octoprint et le statut réel.
Pour les notifications, j’utilise le plugin Telegram directement dans Octoprint et ça fonctionne vraiment bien.
Il t’envoie en même temps une photo de la camera. Et tu peux lui demander régulièrement le status.
Bonjour,
Cela fonctionne plutôt bien, bravo,
J’ai tout de même une erreur dans les logs et pas toutes les métriques qui remontent bien.
Dans les logs j’ai ceci qui revient tout le temps :
Error: EventSystem: Warning!, lua script Octoprint has been running for more than 10 seconds
Ensuite, je n’ai rien qui s’affiche pour le temps d’impression et le % qui est resté bloqué sur 64%.
Merci d’avance.
Hello, par contre tu as bien les températures qui remontent dans Domoticz ?
Oui.
J’ai aussi une autre demande, c’est comment faire pour que le script LUA ne soit exécuter que quand OctoPrint est disponible/allumé ? Je ne laisse pas le RPI allumé en permanence car il sature pas mon LAN. Et du coup, quand il est éteint, je vois quand même dans les logs, que Domoticz exécute le script pour rien.
Je me dis que ce n’est pas forcément la peine de le laisser tourner si OctoPrint n’est pas On.
Merci !
J’ai essayé de reproduire le problème chez moi mais impossible.
J’ai deux domoticz, un stable et l’autre beta et je n’ai pas de problème.
Je ne vois pas d’ou peux venir le soucis.
Pour ce qui est de l’arrêt du script quand le rpi est arrêté, je ne sais pas trop.
Peut être essayer de voir si avec un autre script il est possible de tester si le rpi répond et désactiver le script d’octoprint.
Bonjour,
Tout fonctionne bien pour ma part, je vous remercie !
En revanche, j’aimerai bien que le rafraichissement des données soit plus espacé (ping moins fréquent) car le script bouffe toute la « bande passante » de Domoticz. Je m’explique : si je veux ajouter un interrupteur via Domoticz par la détection automatique, je dois désactiver le script OctoprintDomoticz car sinon il me met un message comme quoi c’est déjà utilisé donc impossible. En désactivant le script, RAS.
Ma question est donc ; est-il possible d’effectuer une récupération sur le serveur Octoprint toutes les 30 secondes par exemple au lieu que ce soit en permanence ?
Merci d’avance,
Cordialement,
CB
Bonjour, étrange qu’il soit si consommateur. Pour limiter a 30 secondes entre chaque appel il faudrait rajouter la condition de temps.
En début de script :
time = os.date("*t")
puis rajouter dans la boucle commandArray :
if (time.min == 0 or time.min == 30) then
En n’oubliant pas de fermer le if.
Comme pour le script de vigicrue : https://github.com/chatainsim/scripts_domoticz/blob/master/vigicrue2.lua
Bonjour,
Merci pour cette réponse ultra rapide !
Je n’avais pas testé avant aujourd’hui, mais c’est OK. J’ai seulement modifié le « time.min » en « time.sec » pour les secondes et ça fonctionne. J’ai mis un « or time.sec == 30 » : il ne prend pas à chaque fois le 30 secondes, mais
bon ça me va bien comme ceci 🙂
Mon problème de « saturation » est résolu.
Merci encore,
Clement.
Bonjour, j’ai changé la carte mère de mon ender 3 avec une creality ender 3 v4.2.7 et depuis je n’arrive plus à avoir les températures. J’ai toujours le défaut « Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_octoprint.lua: /home/pi/domoticz/scripts/lua/script_time_octoprint.lua:71: attempt to index a nil value (field ‘temperature’) »
La ligne 71 correspond à « OctoBeb = JsonOctoTemp.temperature.bed.actual ».
Ce qui est bizarre, c’est que quand je lance l’API dans une page web, j’ai bien toutes les infos qui apparaissent : « {« sd »:{« ready »:true}, »state »:{« error »: » », »flags »:{« cancelling »:false, »closedOrError »:false, »error »:false, »finishing »:false, »operational »:true, »paused »:false, »pausing »:false, »printing »:false, »ready »:true, »resuming »:false, »sdReady »:true}, »text »: »Operational »}, »temperature »:{« bed »:{« actual »:20.62, »offset »:0, »target »:0.0}, »tool0″:{« actual »:25.0, »offset »:0, »target »:0.0}}} »
La température n’est donc pas à 0
Tu peux essayer de passer debug à true :
debug=true
à la troisième ligne, pour voir si tu peux avoir plus d’information.
Bonjour, octoprint tourne sur un pi zero et j’ai domoticz installé sur un autre raspberry. Est-ce qu’il est possible de commander un GPIO (relais) du pi zero avec le raspberry domoticz ? Je pensais à une commande en http mais je ne trouve pas comment faire…
Bonjour, il devrait être possible de partir sur ce tutoriel :
http://emery.claude.free.fr/raspberry-controle-gpio-web.html
Un simple appel http via Domoticz.
Il existe aussi des plugins pour octoprint :
https://plugins.octoprint.org/plugins/gpiocontrol/
Je ne l’ai pas testé mais ça devrait le faire.
Merci pour la réponse rapide. J’ai effectivement un plugin sous octoprint qui me permet d’allumer un éclairage alimenté par un relais activé par un GPIO. Je pensais pouvoir le piloter simplement par une commande http, mais il semble que ce soit plus compliqué… Merci quand même !
Je n’ai pas de raspberry pour tester mais il faudrait voir s’il n’y a pas une api de disponible. Voir pourquoi pas utiliser le navigateur pour afficher les infos développeur pour récupérer les infos nécessaires lorsque l’on clique sur un des boutons des gpio configuré.
Je viens de poser la question sur le GitHub du plugin gpio. Si j’ai une réponse je la ferai suivre.