Seite 1 von 1
Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Samstag 28. März 2020, 19:04
von dom1989
Hallo Beisammen,
ich bin neu und hab folgende Frage:
Ich nutzte zur Heimautomasierung ein Programm namens iobroker, welches per javascript über einen "exec" befehl, Befehle an Python senden kann. Um meine Rollos (via Warema web control) in den iobroker zu integrieren, habe ich ein Python Skript auf Github / pypig.org gefunden.
https://pypi.org/project/warema-wms-controller/
ich selbst kenne mich in Python noch nicht wirklich aus, habe es aber immerhin geschafft, mir Pycharm runterzuladen und mir das Script zur Rollosteuerung via pip zu installieren und das Skript sowie die Rollos auf dem PC erstmal zum laufen gebracht. Das ganze soll am Schluss mal auf dem Raspi laufen.
Laut dem Ersteller des Skriptes ist wie folgt anzuwenden:
Code: Alles auswählen
from warema_wms import Shade
shades = Shade.get_all_shades()
shades[0].set_shade_position(25) #0=open; 100=closed
shades[1].get_shade_state(True) #Force update and get shade state
Wenn ich nun das ganze in Pycharm ausführe und debugge, dauert der Befehl "shades = Shade.get_all_shades()" ca 40 sekunden, dann fährt der erste rollo shades[0]. und das wars. ich sehe keinen output der letzen Zeile. Wenn ich jetzt den nächsten Rollo fahren möchte, würde das ja per shades[1].set_shade_position(25) geschehen. Jedoch ist das Programm nun schon beendet, womit ich das Skript ja nun erneut ausführen muss, um den Rollo fahren zu können. Stelle ich mich gerade zu dumm an oder wie kann ich dem Skript immer wieder sagen, welcher rollo fahren soll, bzw mir den Status übermittelt, ohne das ich "shades = Shade.get_all_shades()" jedes mal ausführen muss? bzw bei shades[1].get_shade_state(True) nicht print(shades[1].get_shade_state(True)) schreiben muss? Also wie kann ich an ein Skript welches gerade läuft, immer wieder input befehle senden?
Ich hab das mal so probiert, aber wie ich das dann weiter umsetzen kann bin ich mir unsicher. Also wie ich per cmd Befehl den input für v1/v2/v3 schicken kann...
Code: Alles auswählen
shades = Shade.get_all_shades()
v1 = 1
v2 = 2
v3 = 3
while v1 < 100:
value11 = input("welcher rollo:\n")
v1 = int(value11)
value12 = input("welcher position:\n")
v2 = int(value12)
value13 = input("1=set 0=get:\n")
v3 = int(value13)
if v3 == 1 :
shades[v1].set_shade_position(v2)
else:
print(shades[v1].get_shade_state(True))
ich hoffe ich hab mich so gut es geht ausgedrückt. Nur schwierig zu beschreiben alles
Gruß Dominik
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Samstag 28. März 2020, 22:02
von __blackjack__
@dom1989: Wenn Du den Rückgabewert des Methodenaufrufs in der letzten Zeile des ersten Codesnippets ausgeben willst, dann musst Du das mit `print()` machen. Das hast Du doch selbst erkannt, was ist also das Problem dabei?
Bein zweiten Codesnippet sind die Variablennamen bis auf `shades` grauenvoll. Einbuchstabige Namen sind selten gute Namen und man nummeriert keine Namen durch. Ein Name soll dem Leser vermitteln was der Wert dahinter bedeutet.
`v1` bis `v3` sollten auch nicht vor der Schleife mit irgendwelchen willkürlichen Dummy-Werten belegt werden die dann letztlich nirgends wirklich verwendet werden.
Mal abgesehen von `v1` was da aber so keinen Sinn macht, denn man kommt da ja einen Wert >100 hin wenn man den in der Schleife tatsächlich eingibt – was aber entweder zu einer Ausnahme führen wird wenn man das 101. Rollo ansprechen will. Oder hast Du tatsächlich so viele? Falls ja wird das dann auch tatsächlich angesprochen bevor die Endbedingung geprüft wird.
Für so etwas schreibt man üblicherweise eine Endlosschleife die dann an entsprechender Stelle mit der ``break``-Anweisung verlassen wird. Oder man benutzt Strg+C zum Abbruch des Programms.
Die Reihenfolge der Abfragen ist ungünstig, denn wenn man den Zustand abfragen möchte, muss man trotzdem die Position eingeben, die dann gar nicht verwendet wird.
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 09:46
von dom1989
Hi blackjack,
danke für deine Antwort.
Der zweite Code war von mir geschrieben, damit ich überhaupt mit dem Skript arbeiten kann. Du hast Recht die Variablen V1 V2 V3 sowie die Abfrage >100 sowie der Codeablauf macht so nicht viel Sinn bzw ist nicht schön geschrieben. Das habe ich mal neu gemacht, wobei ich das mit dem break erstmal noch nicht implemntiert habe, da ich da nicht genau weiß, wo und wie ich das machen soll.
Code: Alles auswählen
from warema_wms import Shade
shades = Shade.get_all_shades()
set_rollo = 1
while set_rollo < 100:
string = input("1=set 0=get? / welcher rollo / welche position:\n")
s = string.split('/')
set_case = int(s[0])
set_rollo = int(s[1])
set_position = int(s[2])
if set_case == 0:
print(shades[set_rollo].get_shade_state(True))
else:
shades[set_rollo].set_shade_position(set_position)
Ziel ist es ja für mich das ganze mal von Javascript automatisch laufen zu lassen. Daher war nun mein Gedanke, ich schicke den zb. den String 1/0/20 (also get/rollo=0/position=20) und das Python script und der Rollo fährt. Wenn ich das Script via CMD in Windows starte, wartet das Script ja nun auf meine Eingabe. Diese will ich nun aber via Javascript an Python senden. Aber wie mache ich das?
Das Skript starten klappt wie folgt "sudo python /pfad_zum_programm/programmname.py aber den Befehl 1/0/20, da hänge ich gerade. Mit "sudo python /pfad_zum_programm/programmname.py 1/0/20 " würde es ja keinen Sinn machen, da das Programm ja dann diesen "shades = Shade.get_all_shades()" Befehl immer ausführt, sobald ich das Script starte.ich möchte daher an das laufende Script nur "1/0/20" per cmd schicken.
I
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 10:30
von Sirius3
Das ist ja jetzt eher eine Javascript-Frage.
Wie sieht denn der Aufruf in Javascript aus?
Je nach Implementierung in IOBroker kann es auch einfacher sein, in Python einen kleinen Server zu programmieren, der dauerhaft läuft und auf Befehle wartet.
Warum verwendest Du nicht gleich ein JavaScript-Pakete?
Auf die Schnelle:
https://www.npmjs.com/package/warema-wm ... ian-blinds
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 10:58
von dom1989
ja ich denke in python einen kleinen servers zu schreiben wäre ja sozusagen der plan gewesen. Hier brauche ich dann eure Hilfe
Wie genau der Befehl in Javasript aussieht weiß ich jetzt auch noch nicht... Ich dachte mir es sollte in der Art so funktionieren:
python /pfad_zum_programm/program_1.py (startet den Server und wartet auf Eingabe-Befehle)
python /pfad_zum_programm/program_2.py 0/0/100 (Befehle werden an das erste Skript program_1.py gesendet und ausgeführt.
python /pfad_zum_programm/program_2.py 1/1/100 ( und so weiter dann).
Danke für den Link, so nutze ich das ganze schon, aber das ist leider alles sehr buggy, weil man hier den Warema WMS Anlernstick nimmt, um die Befehle zu senden, wofür der Stick ja eigentlich nicht gemacht ist. Da kommt es immer vor das 1 oder 2 Rollos von 20 nicht fahren... daher der umstieg auf diese Lösung, da hier auf das Webcontrol zugegriffen wird, was ja zum steuern der Rollos entwickelt wurde.
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 11:03
von __blackjack__
@dom1989: Also wenn Du node.js auf dem gleichen Rechner laufen hast wo auch das Python-Programm liegt, dann könnte das hier einen Blick Wert sein:
https://www.npmjs.com/package/python-shell
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 11:08
von dom1989
ah super, glaube sowas hab ich gesucht, schau ich mir später gleich mal genauer an
node.js läuft auf dem gleichen rechner

Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 11:08
von __deets__
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 11:34
von __blackjack__
@dom1989: Anmerkungen zu Deinem Quelltext:
Auf Modulebene steht normalerweise nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Dass der Code noch so kurz ist, ist IMHO kein Grund das nicht als richtiges Programm zu schreiben, denn der wird noch wachsen. Im Moment ist ja beispielsweise gar keine Behandlung von ungültigen Eingaben vorhanden.
Mir ist nicht so wirklich klar warum die Variablen diesen `set_*`-Präfix haben. Das sind keine `set`-Objekte – wobei Grunddatentypen sowieso nicht in Namen stehen sollten — und es sind auch keine Funktionen oder Methoden die einen Wert setzen.
Abbrechen könnte man leicht über eine leere Eingabe umsetzen.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
from warema_wms import Shade
def main():
shades = Shade.get_all_shades()
while True:
line = input("1=set 0=get / welcher rollo / welche position: ")
if not line:
break
is_set_operation, shade_index, position = map(int, line.split("/"))
if is_set_operation:
shades[shade_index].set_shade_position(position)
else:
print(shades[shade_index].get_shade_state(True))
if __name__ == "__main__":
main()
Das man die Position auch angeben muss wenn man den aktuellen Zustand abfragt ist immer noch unschön. Ich würde für eine Kommunikation mit JavaScript wahrscheinlich auch eher auf JSON setzen statt selbst ein Datenformat zu basteln und zu parsen.
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 12:44
von dom1989
das ist das gleiche wie Sirius 3 schon meinte, aber das läuft auch über diesen Anlern-Stick, was total buggy ist. so läuft es gerade bei mir, was eben nicht so toll ist... Der Stick ist eigentlich nur da um Komponenten zum System hinzufügen und nicht damit die Rollos zu steuern.
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 15:34
von dom1989
@ blackjack
also das script was du abgeändert hast, läuft soweit, danke.
Wie meinst du das mit dem JSON format genau?
Bei ungültigen Eingaben sowie das Thema der Position bei Status abholen, würde ich gerne mal hinten anstellen.
Re: Befehle per cmd senden und empfangen / Rollosteuerung
Verfasst: Sonntag 29. März 2020, 15:41
von __blackjack__
@dom1989: Das `python-shell`-npm-Package hat auch einen JSON-Modus bei dem JSON-Werte gesendet und als Antworten erwartet werden. Auf Python-Seite braucht man dann das `json`-Modul aus der Standardbibliothek um die JSON-Werte zu parsen/serialisieren.