Commander un relais Wi-Fi depuis mes scripts Python via l'endpoint commands
Traduit de English par IA ·
Je suis analyste de données, alors soyez indulgents avec moi sur l’électronique.Notre laboratoire d’essais dispose d’une lampe au-dessus du banc d’endurance, que les opérateurs veulent allumée pendant qu’un test est en cours. Les essais sont lancés depuis mes scripts Python, j’aimerais donc que le script commande aussi la lampe. J’ai acheté un relais Wi-Fi Sonoff Basic R2, mais à sa sortie de boîte il ne fonctionne qu’avec son application téléphone, et je ne trouve aucune API documentée pour lui.Nous utilisons déjà Hermetry pour les capteurs du banc (un ESP32 qui envoie vibrations et températures via MQTT, ça fonctionne bien). Idéalement, mon script parlerait à Hermetry, et Hermetry parlerait au relais, ainsi je n’aurais rien à ouvrir sur le réseau du laboratoire et les opérateurs verraient l’état de la lampe sur le même tableau.Est-ce une configuration correcte ? Si oui, quel endpoint dois-je appeler, et comment le relais « entend »-il la commande ? J’ai trouvé /api/iot/devices/{deviceId}/rpc dans la documentation de l’API, mais je ne suis pas sûr de ce qui doit exister côté appareil.
Data analyst here, so go easy on me with the electronics.
Our test lab has a lamp over the endurance rig that the operators want on while a test is running. The test runs are started from my Python scripts, so I’d like the script to switch the lamp too. I bought a Sonoff Basic R2 Wi-Fi relay, but out of the box it only works with its own phone app and I can’t find any documented API for it.
We already use Hermetry for the rig’s sensors (an ESP32 sending vibration and temperature over MQTT, works fine). Ideally my script would talk to Hermetry and Hermetry would talk to the relay, so I don’t have to open anything in the lab network and the operators see the lamp state on the same board.
Is that a sane setup? If yes, which endpoint do I call, and how does the relay « hear » it? I found /api/iot/devices/{deviceId}/rpc in the API docs but I’m not sure what has to exist on the device side.
Traduit de English par IA ·
Le Sonoff Basic embarque un ESP8266. Vous pouvez y flasher votre propre sketch via le connecteur 4 broches avec un adaptateur USB-série (3.3 V, pas 5 V !). Ensuite, ce n’est plus qu’un appareil Hermetry comme les autres.
The Sonoff Basic has an ESP8266 inside. You can flash your own sketch on it through the 4-pin header with a USB-serial adapter (3.3 V, not 5 V!). Then it’s just another Hermetry device.
Traduit de English par IA ·
Je l’ai flashé avec un adaptateur FTDI emprunté, il m’a fallu trois essais pour le mettre en mode boot (maintenir le bouton enfoncé pendant le branchement). Il se connecte maintenant à Hermetry avec son propre jeton d’accès et envoie {"relay": 0} toutes les minutes. La partie envoi est donc terminée. Et pour le commuter ?
Flashed it with a borrowed FTDI adapter, took me three tries to get it into boot mode (hold the button while plugging in). It now connects to Hermetry with its own access token and sends {"relay": 0} every minute. So the sending part is done. What about switching it?
Traduit de English par IA ·
Bien, c’est la même configuration que nous utilisons pour quelques lampes de signalisation. Trois éléments :
- Profil d’appareil du relais, onglet Commands : ajouter une commande
light.set, niveau Basic, un paramètreonde type Yes / no. Le niveau est important, car une clé API ne peut envoyer que les méthodes présentes dans le catalogue du profil. - Firmware : s’abonner à
v1/rpc/req/+, commuter GPIO12 (le relais de la Basic R2), répondre avec le même identifiant et signaler le nouvel état.
void onMsg(char* topic, byte* p, unsigned int n) {
// topic: v1/rpc/req/42
String id = String(topic).substring(11);
StaticJsonDocument<128> d; deserializeJson(d, p, n);
bool on = d["params"]["on"];
digitalWrite(12, on ? HIGH : LOW);
mqtt.publish(("v1/rpc/res/" + id).c_str(), "{"ok":true}");
mqtt.publish("v1/telemetry", on ? "{"relay":1}" : "{"relay":0}");
}
- Votre script : une clé API depuis API Keys (menu Developer) avec uniquement ce dont elle a besoin. La route d’envoi demande
iot_rpc.readainsi que la permission du niveau ; cochez ces deux-là et rien d’autre, renseignez la liste d’adresses IP autorisées avec l’adresse du PC du laboratoire et conservez l’expiration à 90 jours.
import requests
r = requests.post(
f"https://{HOST}/tenant/{TENANT}/api/iot/devices/{DEVICE}/rpc",
headers={"Authorization": f"Bearer {KEY}"},
json={"method": "light.set", "params": {"on": True}, "timeoutMs": 10000},
)
print(r.status_code, r.json()["rpc"]["status"])
Une commande bidirectionnelle avec un délai d’attente de 30 s ou moins attend et renvoie 200 avec SUCCESSFUL. Référence : Commands APIL’ESP8266 gère le TLS, mais la mémoire est limitée ; utilisez BearSSL avec des tampons plus petits si la connexion échoue.
Good, that’s the same setup we use for a few signal lamps. Three pieces:
- Device profile of the relay, Commands tab: add a command
light.set, tier Basic, one parameteronof type Yes / no. Tier matters, because an API key can only send methods that are in the profile’s catalog. - Firmware: subscribe to
v1/rpc/req/+, switch GPIO12 (the relay on the Basic R2), answer on the same id, and report the new state.
void onMsg(char* topic, byte* p, unsigned int n) {
// topic: v1/rpc/req/42
String id = String(topic).substring(11);
StaticJsonDocument<128> d; deserializeJson(d, p, n);
bool on = d["params"]["on"];
digitalWrite(12, on ? HIGH : LOW);
mqtt.publish(("v1/rpc/res/" + id).c_str(), "{"ok":true}");
mqtt.publish("v1/telemetry", on ? "{"relay":1}" : "{"relay":0}");
}
- Your script: an API key from API Keys (Developer menu) with only what it needs. The send route wants
iot_rpc.readplus the tier’s permission, so tick those two and nothing else, fill the IP allowlist with the lab PC’s address and keep the 90-day expiry.
import requests
r = requests.post(
f"https://{HOST}/tenant/{TENANT}/api/iot/devices/{DEVICE}/rpc",
headers={"Authorization": f"Bearer {KEY}"},
json={"method": "light.set", "params": {"on": True}, "timeoutMs": 10000},
)
print(r.status_code, r.json()["rpc"]["status"])
A two-way command with a timeout of 30 s or less waits and comes back 200 with SUCCESSFUL. Reference: Commands API
The ESP8266 does TLS, but memory is tight; use BearSSL with smaller buffers if the connect fails.
Traduit de English par IA ·
Ça fonctionne. Le premier appel a renvoyé 403 parce que j’avais seulement coché la permission d’envoi et pas iot_rpc.read. Après l’avoir ajoutée, le voyant clique et l’appel renvoie 200 / SUCCESSFUL en environ 300 ms. J’ai aussi placé une carte Switch sur le tableau des opérateurs, liée à relay, pour qu’ils voient l’état. Merci à vous deux.
Works. First call came back 403 because I had only ticked the send permission and not iot_rpc.read. After adding it the lamp clicks and the call returns 200 / SUCCESSFUL in about 300 ms. I also put a Switch card on the operators’ board bound to relay, so they see the state. Thanks both.
Traduit de English par IA ·
Super ! Il y a du secteur sur cette carte, alors remets-la dans son boîtier avant que quelqu’un n’y touche 😄
Nice! Mains on that board, so put it back in its case before anyone touches it 😄
- Vous devez être connecté pour répondre à ce sujet.
Rejoignez la discussion
Connectez-vous pour poser et répondre à des questions, aimer les messages utiles et marquer la réponse qui a résolu votre problème. Chaque contribution rapporte des points et des niveaux.

