[tuto] : Déclencher des API Octoprint dans Jeedom

Un scénario pour pouvoir déclencher facilement les API octoprint

Le plugin octoprint permet de récupérer des valeurs (température plateau etc…) mais pas de les imposer. Il permet de déclencher certaines actions mais pas toutes.
On peut le faire via des curl en se servant des API octoprint.

En gros, une API se décompose en deux parties :
Une partie que l’on va appeler API et qui donne la famille d’action (par exemple ‹ connection ›
Une seconde partie qui décrit la commande à réaliser dans cette famille (par exemple ‹ connect › ou ‹ disconnect ›)

La liste des API se trouve ici : REST API — OctoPrint master documentation
et vous aurez sans doute aussi besoin de renseignements sur les GCODE, ça se trouve par exemple ici:
Retract | Marlin Firmware

Pour simplifier l’appel à des API via curl, je me suis créé un scénario qui permettra de déclencher des actions. C’est un peu une « fonction » où l’on passe en paramètre les deux parties de l’API via les tags #API# et #commande#

J’ai fait le choix de placer l’url d’octopi et la clef octoprint dans deux infos d’un virtuel.
Créez un virtuel nommé « V imprimante 3D »
image

dans lequel vous placez une info « URL octopi »


et vous y placez l’url de votre octopi. L’url peut être une adresse IP.

Vous allez aussi créer une info API key octopi pour y placer votre clef octoprint qui se trouve dans octoprint ici :
image

(remplacez les xxxxxxx par votre clef octoprint)

Le scénario à créer :

Son code :

// Lance une API Octopi
//-------------------------

// mettre en tag dans le lancement du scénario: 
// connexion à l'imprimante : 	#api#="connection" #commande#="connect"
// imposer une température de 40 pour le bed: #api#=printer/command #commande#="M140 S040"
// imposer une température de 100 pour la buse: #api#=printer/command #commande#="M104 S100"
// Sélectionner le fichier à imprimer : #api#="nomfichier.gcode" #commande#="select"
// lance l'impression #api#="job" #commande#="start"
//-------------------------------------------------------------------------------------------

// On récupère la veleur des tags
$tags = $scenario->getTags();
$api 			= $tags['#api#'];
$commandeOctopi	= $tags['#commande#'];


$urlOctopi=cmd::byString('#[imp 3d][V imprimante 3D][Url octopi]#')->execCmd(); // url de votre octopi. Peut aussi être de la forme http://ip
$apiKey=cmd::byString('#[imp 3d][V imprimante 3D][API key octopi]#')->execCmd(); // la clef API

$cmd="curl -H 'Content-Type: application/json' -H 'X-Api-Key: " .$apiKey
      ."' -X POST -d '{\"command\":\""
      .$commandeOctopi
      ."\"}' "
      .$urlOctopi
      ."/api/"
      .$api
      ."& ";

exec ($cmd);

Utilisation :

Personnellement, dans le même virtuel que précédemment (V imprimante 3D) image, j’ai créé des commandes qui appellent ce scénario :
ici : une commande connect.


En cliquant sur
image

puis configuration, vous pouvez placer ainsi l’appel au scénario

N’oubliez pas de sauvegarder
image
Il ne vous reste plus qu’à tester :
image

Un autre exemple :

imposer une température de 50 pour le Bed

image
et

Faire un retract de 50 mm

je fais toujours avec un appel au même scénario(3 fois) (en cours de test) avec comme tag :

#api#=printer/command  #commande#="M83"
#api#=printer/command  #commande#="G1 E-50 F300"
#api#=printer/command  #commande#="M82"

Il faut le faire dès que l’impression est fini car les retracts, enfin avec mon imprimante, ne peuvent pas se faire si la buse n’est pas assez chaude.
Dans un scénario, je suis obligé de relancer la chauffe de la buse à 175° avant de faire cette rétractation.

#api#=printer/command #commande#="M109 S180"

Scénario pour l’extinction de l’imprimante.

En fait, il ne se sert que du plugin, pas des API.
Déclencheurs :

En commentaire, en haut :

Action du scénario : 
Si l'info En impression a changé et si on est pas en impression alors j'enclenche le processus d'arrêt. Arrêt qui ne se fera que si la température de la buse est descendu en dessous d'une certaine valeur.
Dans ce qui suit, Octopi dans par exemple #[imp 3d][Octopi][En impression]# est le nom que j'ai donné à l'équipement du plugin octoprint correspondant à mon imprimante
dans l'onglet général du scénario, mettre en déclenchement : 
#[imp 3d][Octopi][En impression]#
et
#[imp 3d][Octopi][Actuelle tool0]#<40
si vous voulez que l'arrêt se fasse pour une température de la buse < 40°

Copie écran de mon scénario

Dans ce qui suit, Octopi dans par exemple #[imp 3d][Octopi][En impression]# est le nom que j’ai donné à l’équipement du plugin octoprint correspondant à mon imprimante


Version plus complète de scénario de fin d’impression.

Cette version est plus complète que la précédente car elle intègre un dialogues via ask /telegram pour confirmation de l’arrêt de l’imprimante et savoir si on veut une forte rétractation du filament ou pas (pour pouvoir retirer la bobine)



Comment connaitre les Gcodes à envoyer ?

Dans Octopi, il y a une fonction qui vous permet de voir tous les gcodes qui sont envoyés à l’imprimante.

Cochez ces cases afin de filtrer pour ne pas voir tous les messages :
image

Puis, si vous voulez par exemple voir les codes qui permettent de chauffer la buse, allez dans

Et modifiez la température par exemple de la buse (tool) (ici 14°)
Vous verrez alors les codes correspondant défiler.


(ici M104 S14) on devine que le S14 sert à donner la température à atteindre. On a donc deviné le Gcode qui sert à imposer une température.
En allant sur Retract | Marlin Firmware
vous pouvez en appendre plus sur ce code :

et vous apprenez qu’il existe un code M109 qui fait la même chose mais qui attend avant de déclencher l’action suivante

N’hésitez pas à tester toutes ces actions :
image

pour voir ce que cela donne dans le terminal
image
Et n’hésitez pas à aller voir la signification des codes dans
Retract | Marlin Firmware

6 « J'aime »

Hello
Excellente initiative mais pourquoi ne pas modifier le plugin ?
@chris94440

Malheureusement, j’en suis incapable. Par contre, si l’auteur peut faire des modifs, je peux, s’il en a besoin (mais vu ce qu’il a déjà fait, il ne doit pas en avoir besoin :smiley: ) lui donner les API que j’ai déjà expérimenté. Effectivement, faire un update du plugin serait la meilleure des choses.

Bonsoir

Excellent ça super boulot

  • Allumage de l’imprimante via prise connectée
  • Connexion au serveur Octoprint
  • Mise en chauffe c’est déjà top

En tout cas cela me permet de préparer mes impressions depuis mon canapé et de voir à la webcam si tout va bien ou non et donc de descendre à la cave pour traiter le sujet :clap:

Sur le Gcode de la buse c’est pas plutôt

#api#=printer/command #commande#=« M104 S100 »

au lieu de

#api#=printer/command #commande#=« M104 S2100 »

Oui oui, faute de frappe. Je vais corriger !

Sinon, pour compléter le fait de tout faire depuis ton canapé : Via le plugin, tu peux savoir quand l’impression est fini puis quand la température de la buse est < à une certaine valeur et quand la température du bed est < à une certaine valeur afin de te prévenir que tu peux aller récupérer ta pièce (chez moi, je fais sonner le téléphone, je m’envoie un message telegram et je fais clignoter une lampe du salon).

Je suis en train de regarder pour qu’à la fin de l’impression, si je le souhaite, ça me fasse un retract de 50 mm
J’ai déjà les api et commandes pour ça.
Edit : fait.

1 « J'aime »

Il y a aussi les quote simple à mettre en double pour les tag dans le virtuel sinon ça passe pas en tout cas chez moi

J’ai mis aussi le disconnect en route sur le même principe que le Connect

Reste à mettre aussi une température cible basse pour le bed et la buse afin de les lancer en fin d’impression pour enfin permettre de l’éteindre propre

Je réfléchi à un scénario comme tu évoques oui

Si tu veux, demain je peux décrire comment j’ai fais cette notion de contrôle de températures pour extinction.propre.

Bizarre cet histoire de guillemet simple / double
Chez moi, ça ça marche :


Donc chez toi, tu es obligé de mettre :
#api#=printer/command #commande#=« M104 S100 »
et non
#api#=printer/command #commande#=‹ M104 S100 ›

Là, je ne peux pas tester, mais demain je testerai avec des " …" et si ça marche chez moi, je remplacerai les ‹ … › par des « … » dans les exemples.

Ah oui je veux bien en effet
Cela me fera découvrir plus vite plus d’API d’octoprint

Bon déjà, en complément, pour à la fin faire un retract de 50 mm (en cours de test chez moi, mais ça a l’air de marcher), je fais toujours avec un appel au même scénario avec comme tag :

#api#=printer/command  #commande#="M83"
#api#=printer/command  #commande#="G1 E-50 F300"
#api#=printer/command  #commande#="M82"

Il faut le faire dès que l’impression est fini car les retracts, enfin avec mon imprimante, ne peuvent pas se faire si la buse n’est pas assez chaude.
Dans un scénario, je suis obligé de relancer la chauffe de la buse à 175° avant de faire cette rétractation.

#api#=printer/command #commande#="M109 S180"

Noter le 109 et non 104 afin que l’imprimante attende la fin de monté en température pour effectuer l’ordre suivant.
Au passage, là j’ai des doubles guillemets. Cela marche donc aussi avec les doubles guillemets chez moi.
Edit : je confirme, les doubles guillemets fonctionnent aussi chez moi, je vais éditer mon premier message.

Scénario pour l’extinction de l’imprimante.

Scénario déplacé vers le premier message afin d’avoir un premier message qui regroupe tout

Super merci pour ce partage
Je regarde ce soir ou demain je pense

Pour les guillemets c’est toujours le piège en fait donc il vaut mieux être vigilant en le double et le simple

Oui j’avais vu que le scenario n’était pas tout là :wink:
Tu reprends la réponse de ton ask pour éteindre ou non ton imprimante ?

Et oui dans la suite de « je veux éteindre » il pleut y avoir la question de la rétractation du fil pour changement de bobine effectivement

Je vais alors partager la version complète, et oui, j’ai la question de la rétractation dans le ask.

Une version plus complète de mon scénario de fin d’impression.
Cette version est plus complète que la précédente car elle intègre un dialogue via ask / telegram.

J’ai déplacé cette version pour la placer dans le premier message afin de tout regrouper.

Ca te suffit comme renseignement et explication ?
N’hésite pas à demander…

1 « J'aime »

Pour compléter :

Comment connaitre les Gcodes à envoyer ? :

J’ai déplacé ce tuto pour l’intégrer au premier message (histoire de regrouper pour faciliter la lecture).

J’ai bien vu le déplacement et merci

J’ai commencé à regarder mais je ne comprends pas comment tu gères les SI.


Trigger(#[Imprimante 3D][Ender 3 Pro][En impression]#) && ! #[Imprimante 3D][Ender 3 Pro][En impression]# && tag(ImprDoitEteindreSiTempBed)

Pour moi il manque des éléments de contrôle comme ceci :


Trigger(#[Imprimante 3D][Ender 3 Pro][En impression]#) && #[Imprimante 3D][Ender 3 Pro][En impression]# != 1 && tag(ImprDoitEteindreSiTempBed)= "false " 

Non ?

En fait dire

&& #[Imprimante 3D][Ender 3 Pro][En impression]# != 1

ou

&& ! #[Imprimante 3D][Ender 3 Pro][En impression]#

C’est pareil sous réserve que #[Imprimante 3D][Ender 3 Pro][En impression]# soit un boolean.
Ce qui est le cas :
image

Dit autrement :
Un boolean vaut soit 0 (faux) soit 1 (vrai)

Résultat d’un « test » Si :

Si 0 vaut 0 donc faux
si 1 vaut 1 donc vrai.

Admettons un boolean nommé par exemple « bool » et qui vaut false (et donc il vaut 0)

tester si bool alors faire l’action ne va pas faire l’action
tester si bool=1 alors faire l’action ne va pas non plus faire l’action

et si bool vaut true (et donc 1)
tester si bool alors faire l’action va faire l’action
tester si bool=1 alors faire l’action va faire aussi l’action

Bref, c’est pareil
Enfin, il y a une subtilité car là on a pour moi un ! au début et toi tu as un différent (=!)
mais c’est pareil (un ! devant un booléan inverse sa valeur : si b vaut 0 (false) un !b renverra 1 true) et un b !=1 renverra aussi 1 (true)
Tu aurais aussi pu écrire sous la forme b==0 qui aurait renvoyé 1 (true)

Par contre, à la fin de ta ligne, tu as

&& tag(ImprDoitEteindreSiTempBed)= "false "

alors que moi, j’ai

&& tag(ImprDoitEteindreSiTempBed)

En fait, avec ta façon d’écrire, j’aurais plutôt

&& tag(ImprDoitEteindreSiTempBed)==true

Sans guillemet et un double = (==)
Ca se vérifie dans le testeur d’expression :
image
Alors que là, on a un résultat bizarre :
image
Résultat bizarre donc

Pourquoi tu avais mis un false et non un true ?

Salut
Super intéressant je ne connaissais pas cette manière d’écrire, je viens encore d’apprendre un truc donc si booléen on peut simplifier un peu l’écriture

Ensuite j’utilise plutôt les tag que les variable pour alléger un peu le système
J’ai certainement fait des erreurs de syntaxe car j’ai fait ça super vite au milieu de sujets encours pour tester l’affaire et voir le fonctionnement. Mais à vouloir aller trop vite on boulette

Pourquoi j’ai mis false plutôt que true aucune idée là de suite, enfin je me souviens pas. Sauf si c’est la syntaxe du si où la ligne est cachée à la fin.

J’ai trop fait à la va vite !!

Tu n’as plus qu’à t’y remettre ! :smiley:

1 « J'aime »

C’est exactement ça mais sur la tablette pas top à faire on verra demain en lançant une impression en plus