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 »/]

Température du plateau et de la tête.
Status de l’imprimante et des temps d’impression ainsi que le pourcentage d’avancement.
Hi, I’m simon

36 Comments

  1. 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.

    1. 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) ?

  2. 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.

  3. 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

    1. 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

  4. 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.

    1. 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.

  5. 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.

  6. 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).

    1. 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.

  7. 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…

    1. 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.

  8. 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.

    1. 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 …

      1. 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

  9. 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.

        1. 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

  10. 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

    1. 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.

  11. 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.

      1. 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 !

        1. 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.

  12. 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

      1. 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.

  13. 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

    1. Tu peux essayer de passer debug à true :
      debug=true
      à la troisième ligne, pour voir si tu peux avoir plus d’information.

  14. 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…

      1. 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 !

        1. 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é.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.