HTTP-Anfrage, Berechnung des gesendeten Werts

Bonsoir,

Je ne sais pas comment « caster » le résultat qui semble être envoyé sous forme de chaine, alors qu’est attendue une valeur numérique dans le cas suivant :

Votre aide serait appréciée, merci par avance,
Belle soirée,
Jean

Salut @jean_bruder :slight_smile:

Effectivement, il n’est pas possible de faire ce que tu fais; il faut que tu décomposes le calcul et l’envoi du JSON.

  1. Tu peux modifier l’état d’un capteur avec une valeur « calculée » dans « Contrôler un appareil ».
  2. Ensuite, tu peux injecter cette valeur calculée dans un JSON comme tu fais ici.

Bonjour @pierre-gilles

Je ne sais pas comment appliquer ta réponse à ma scène : la valeur calculée à renvoyer via HTTP/POST est issue d’une opération sur une valeur réceptionnée par HTTP/GET à quoi on ajoute/retire une valeur, et doit être au format numérique. Comment utiliser la valeur calculée d’un appareil ?

Merci à toi,
Jean

Tu peux utiliser un appareil virtuel (intégration MQTT) qui fait office de « tampon » pour la valeur finale que tu envoies ensuite en HTTP.

Guten Abend @pierre-gilles :slight_smile:

Ich nutze die aktuelle gute Stimmung im Forum und aller Entwickler, die nicht aufhören zu innovieren, um alte Anfragen auszugraben, die ich nicht zu Ende geführt habe … :stuck_out_tongue:

Glaubst du, dass es immer noch unmöglich ist, eine Berechnung auf einen gesendeten Wert anzuwenden, denn das könnte wirklich viele Anwendungsfälle vereinfachen: Man könnte eine GET-Anfrage durchführen und dann eine POST als interaktive Reaktion :slight_smile:

Bis bald,

Schönen Abend,

Jean

Hallo @jean_bruder :slight_smile:

Also, ich werde dir anders antworten, als du es erwartest: Ich denke nicht, dass man die Berechnung in den Block „HTTP-Anfrage“ einfügen sollte, denn alles, was du beschreibst, ist heute schon möglich :slight_smile:

Zuerst zum „Warum nicht“: Der Body einer HTTP-Anfrage ist freier Text. Es kann JSON, XML, form-urlencoded oder irgendetwas anderes sein. Wenn wir damit beginnen würden, Berechnungen darin auszuwerten, müsste Gladys erraten, welcher Teil des Textes eine Formel ist und welcher Teil der Inhalt ist, der unverändert gesendet werden soll, mit dem Risiko, dabei perfekt gültige Bodies zu beschädigen. Das würde bedeuten, eine spezielle Syntax zu erfinden, sie zu dokumentieren, sie zu warten… während das Trennen von „ich berechne“ und „ich sende“ klarer bleibt und dir zusätzlich ermöglicht, den berechneten Wert anderswo in der Szene wiederzuverwenden.

Und vor allem: Das GET, dann Berechnung, dann POST kannst du schon machen, ohne neue Funktionalität.

Was in deiner Szene letztes Jahr fehlte, ist einfach, dass die Antwort einer HTTP-Anfrage als Szenenvariable exponiert wird. Du machst dein GET, klickst einmal auf „Ausprobieren“, damit Gladys die Schlüssel der Antwort entdeckt, und kannst sie dann mit {{ in alle folgenden Blöcke injizieren, einschließlich in einen zweiten HTTP-Aufruf. Konkret:

  1. HTTP-Anfrage (GET): Du holst deinen Wert, z. B. data.temperature
  2. Gerät steuern: Dein virtuelles Gerät (MQTT-Integration), Registerkarte „Berechnet“: {{ data.temperature }} + 2
  3. Letzten Zustand abrufen desselben Geräts: Du erhältst eine saubere numerische Variable
  4. HTTP-Anfrage (POST): Du injizierst diese Variable in dein JSON mit {{

Es funktioniert und hat sogar einen angenehmen Nebeneffekt: Dein berechneter Wert wird zu einem echten Sensor mit Historie und Diagrammen.

Aber ich verstehe dich, das Puffergerät ist etwas umständlich, wenn der Wert nicht historisiert werden soll.

Deshalb gute Nachricht: Eine neue Aktion „Variable definieren“ kommt :slight_smile:

https://github.com/GladysAssistant/Gladys/pull/2863

Sie ermöglicht es dir, einen Wert einmal zu setzen, entweder Text oder eine Berechnung (Registerkarte „Berechnet“, z. B. {{ data.temperature }} + 2), ihm einen Namen zu geben und ihn in allen folgenden Aktionen der Szene wiederzuverwenden. Keine Notwendigkeit mehr, ein permanentes MQTT-Gerät zu erstellen, keine Notwendigkeit des Blocks „Letzten Zustand abrufen“. Deine Szene wird:

  1. HTTP-Anfrage (GET)
  2. Variable definieren „Wert zum Senden“, Registerkarte „Berechnet“: {{ data.temperature }} + 2
  3. HTTP-Anfrage (POST) mit {{ zum Injizieren deiner Variable in den Body

Drei Blöcke, jeder mit einer klaren Rolle, und die Berechnung bleibt im dafür vorgesehenen Block. Das ist genau dein Anwendungsfall :slight_smile:

@pierre-gilles Danke, danke, danke, danke :heart:

Guten Abend @pierre-gilles,

Keine Eile mit der Antwort :slight_smile:

Ich habe eine Frage zum Berechnungsvorgang und dem Ergebnis: Gibt der Berechnungsvorgang tatsächlich einen numerischen Ganzzahlwert zurück?

Denn im Log habe ich diesen Fehler:

Gladys | 2026-08-14T18:55:03+0200 scene.executeActions.js:42 (executeAction) Error: Parse error on line 1:
Gladys | …{{1.0.else.0.0.value}}}
Gladys | -----------------------^
Gladys | Expecting ‹ CLOSE ›, ‹ OPEN_SEXPR ›, ‹ ID ›, ‹ STRING ›, ‹ NUMBER ›, ‹ BOOLEAN ›, ‹ UNDEFINED ›, ‹ NULL ›, ‹ DATA ›, got ‹ CLOSE_UNESCAPED ›
Gladys | at Parser.parseError (/src/server/node_modules/handlebars/lib/handlebars/compiler/parser.js:199:11)
Gladys | at Parser.parse (/src/server/node_modules/handlebars/lib/handlebars/compiler/parser.js:251:22)
Gladys | at parseWithoutProcessing (/src/server/node_modules/handlebars/lib/handlebars/compiler/base.js:28:20)
Gladys | at HandlebarsEnvironment.parse (/src/server/node_modules/handlebars/lib/handlebars/compiler/base.js:34:13)
Gladys | at compileInput (/src/server/node_modules/handlebars/lib/handlebars/compiler/compiler.js:532:19)
Gladys | at ret (/src/server/node_modules/handlebars/lib/handlebars/compiler/compiler.js:546:18)
Gladys | at Object.http.request (/src/server/lib/scene/scene.actions.js:572:11)
Gladys | at executeAction (/src/server/lib/scene/scene.executeActions.js:34:37)
Gladys | at /src/server/lib/scene/scene.executeActions.js:75:15
Gladys | at tryCatcher (/src/server/node_modules/bluebird/js/release/util.js:16:23)
Gladys | at MappingPromiseArray._promiseFulfilled (/src/server/node_modules/bluebird/js/release/map.js:68:38)
Gladys | at MappingPromiseArray.PromiseArray._iterate (/src/server/node_modules/bluebird/js/release/promise_array.js:115:31)
Gladys | at MappingPromiseArray.init (/src/server/node_modules/bluebird/js/release/promise_array.js:79:10)
Gladys | at MappingPromiseArray._asyncInit (/src/server/node_modules/bluebird/js/release/map.js:37:10)
Gladys | at _drainQueueStep (/src/server/node_modules/bluebird/js/release/async.js:97:12)
Gladys | at _drainQueue (/src/server/node_modules/bluebird/js/release/async.js:86:9)
Gladys | at Async._drainQueues (/src/server/node_modules/bluebird/js/release/async.js:102:5)
Gladys | at Immediate.Async.drainQueues (/src/server/node_modules/bluebird/js/release/async.js:15:14)
Gladys | at processImmediate (node:internal/timers:534:21)

Zusätzlich scheint bei meinem HTTP-Aufruf etwas nicht zu stimmen, denn das Format scheint nicht korrekt zu sein: Es muss numerisch sein.

Vielen Dank für dein Feedback dazu,

Schönen Abend noch,

Jean

Hallo @jean_bruder :blush:

Gute Nachricht: Deine Berechnung hat nichts mit dem Fehler zu tun :grinning_face_with_smiling_eyes:

1. Der Fehler im Log kommt vom Body deiner HTTP-Anfrage, nicht von der Berechnung.

Schau dir das Ende der Zeile an: {{1.0.else.0.0.value}}} — es gibt drei } hintereinander. Die beiden geschweiften Klammern schließen deine Variable, und die dritte schließt dein JSON. Handlebars liest diese drei geschweiften Klammern als das Schließen einer « dreifachen geschweiften Klammer » {{{ }}} und beschwert sich (got 'CLOSE_UNESCAPED').

Es reicht, sie nicht zusammenzusetzen. Statt:

{"puissance": {{1.0.else.0.0.value}}}

schreibe:

{
  "puissance": {{1.0.else.0.0.value}}
}

(Ein einfacher Leerraum vor der abschließenden geschweiften Klammer reicht auch: {"puissance": {{1.0.else.0.0.value}} }). Achte darauf, dass der Leerraum außerhalb der Variable nichts ändert: {{ 1.0.else.0.0.value }}} stürzt genauso ab, es muss direkt nach den }} ein Leerraum sein.

2. Für das numerische Format: Auf keinen Fall Anführungszeichen um die Variable.

Gladys parst den Body in JSON, bevor er gesendet wird, also:

  • "puissance": "{{ma_variable}}" → sendet "22.5", eine Zeichenkette :cross_mark:
  • "puissance": {{ma_variable}} → sendet 22.5, eine echte Zahl :white_check_mark:

3. Ja, die Berechnung gibt eine Zahl zurück, aber nicht unbedingt eine ganze Zahl: Wenn dein Ursprungswert 20.5 ist, gibt {{ma_variable}} + 2 22.5 zurück. Wenn deine API eine ganze Zahl erwartet, kannst du direkt im Tab « Berechnet » runden:

  • round({{ma_variable}} + 2) → 23
  • round({{ma_variable}} + 2, 2) → zwei Dezimalstellen

Guten Abend @pierre-gilles,

Thema jetzt geschlossen und Multimedia-Button jetzt vollständig funktionsfähig für Radio und Musik. Danke für deine Geduld und dein Zuhören :folded_hands: