Octoprint et Domoticz

4 octobre 2019

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

-- Use Lua -> Time
-- For displaying debug messages
debug=false
-- IP address of octoprint 
OctoIP='OctoprintIPAddress'
-- Port of Octoprint - Default 80
OctoPort='80'
-- Octoprint API Key (found in Settings -> API)
OctoAPI='OctoprintAPIKey'
-- JSON.lua path
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
-- Curl path
curl = '/usr/bin/curl'

-- IDX of your Dummy devices
OctoStatusIDX='387' -- type: Text
OctoBebIDX='388' -- type: Temperature
OctoHeadIDX='389' -- type: Temperature
OctoTotalTimeIDX='390' -- type: Text
OctoCompleteIDX='391' -- type: Percentage
OctoPrintTimeIDX='392' -- type: Text
OctoTimeLeftIDX='393' -- type: Text

-- If you don't have a heated bed, put this to false
HeatedBed=true

OctoPrinter='http://'..OctoIP..':'..OctoPort..'/api/printer'
OctoJob='http://'..OctoIP..':'..OctoPort..'/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
      if (HeatedBed) then update(OctoBebIDX, OctoBeb) end
      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")
      if (HeatedBed) then update(OctoBebIDX, 0) end
      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
Température du plateau et de la tête.
Status de l’imprimante et des temps d’impression ainsi que le pourcentage d’avancement.

9 commentaires

  • Frédéric 14 janvier 2020 à22 h 05 min

    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.

    • simon 14 janvier 2020 à22 h 22 min

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

  • Frédéric 16 janvier 2020 à15 h 32 min

    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.

  • Frédéric 16 janvier 2020 à16 h 03 min

    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

    • simon 16 janvier 2020 à16 h 29 min

      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

  • Frédéric 16 janvier 2020 à17 h 16 min

    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.

    • simon 16 janvier 2020 à17 h 21 min

      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.

  • Frédéric 16 janvier 2020 à18 h 35 min

    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.

  • Frédéric 16 janvier 2020 à18 h 48 min

    C’est bon je me suis mis sur le groupe Easter’s Domo sur Telegram 😉

Laisser un commentaire

Votre adresse de messagerie 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.