script editor für Tasmota

  • Hallo,


    Da ich die Syntax von rules noch nie mochte habe ich einen richtigen script interpreter eingebaut, der alternativ (nicht gleichzeitig) zu rules verwendet werden kann.

    Damit kann man mit if, then else (nested) und beliebigen Formeln sowie eigenen Variablennamen Programme schreiben.

    Ist noch Work in progress funktioniert aber schon recht gut. etwas Info zur Syntax steht im Quelltext (xdrv_10_scripter.ino)

    benötigt etwa die gleiche Menge Flash wie rules. Den Ram Speicher übernehme ich direkt von rules, so dass zur Zeit nur ca 1,5 kb Quelltext im script erlaubt sind.

    Wenn ihr meinem Fork herunter ladet ist scripter jetzt default. Der Editor ist im Webinterface unter "Einstellungen => Edit script"


    Gruß gemu2015



  • Das find ich richtig gut !!


    Weil mir der Rules Syntax auch nicht wirklich gefällt ...


    lässt sich der script interpreter auch integrieren ohne den ganzen Fork zu ziehen?

    Tasmota 6.6.0 - Arduino-IDE - 1.8.7

    Sonoff-Basic / Sonoff-RF / Sonoff-Touch / Sonoff S20 / PowStro Basic / HomeMagic / Sonoff-RF-Bridge mit diversen 433MHz RF Sender/Empfänger / Shelly_1 / ESP-WiFi-Dimmer / Gosund SP111 / ESP12E Sensoren

    Sensoren: BME280/BMP280/HC-SR501/HC-SR04/ACS712

    mosquitto/bash/html/cgi auf RPI 2B+/Sprachsteuerung via IFTTT/3xGoogle-Home-Mini

  • leider geht das nicht. Theo Arends hat etliche labels und calls geändert.


    das wird eine Menge Arbeit meinen Fork auf den neuesten Stand zu bringen da es unmöglich ist das alles automatisch zu mergen.


    Werde ich bei Gelegenheit mal machen. Bisher sind mir die Neurungen in Tasmota aber nicht wirklich wichtig gewesen.

  • Mercie 4 Info.


    Naja wenn ich das richtig sehe 6.4.1? Ist mir eigentlich aktuell genug :thumbup:

    Tasmota 6.6.0 - Arduino-IDE - 1.8.7

    Sonoff-Basic / Sonoff-RF / Sonoff-Touch / Sonoff S20 / PowStro Basic / HomeMagic / Sonoff-RF-Bridge mit diversen 433MHz RF Sender/Empfänger / Shelly_1 / ESP-WiFi-Dimmer / Gosund SP111 / ESP12E Sensoren

    Sensoren: BME280/BMP280/HC-SR501/HC-SR04/ACS712

    mosquitto/bash/html/cgi auf RPI 2B+/Sprachsteuerung via IFTTT/3xGoogle-Home-Mini

  • so, habe auf Tasmota 6.5 upgedated. hier ist ein Wemos binary für die die es mal ausprobieren wollen => https://www.dropbox.com/s/b6p9dkf1tlrelto/wemods-d1-4m.bin?dl=0

    anbei auch die doku


    Gruß gemu2015


    ps die binary kann auch emails verschicken.


    forum.creationx.de/index.php?attachment/3899/

  • PERFEKT - jetzt offiziell ab Version 6.5.0.11 in Tasmota enthalten


    "* Add initial support for Scripts as replacement for Rules. Default disabled but can be enabled in my_user_config.h (#5689)"


    GROSSES DANKE dafür :thumbup: :thumbup: :thumbup:


    Aktivieren mit:

    Code
    1. // -- Rules or Script ----------------------------
    2. // Select none or only one of the below defines
    3. //#define USE_RULES // Add support for rules (+8k code)
    4. #define USE_SCRIPT // Add support for script (+15k code)


    oder in der user_config_override.h

    Code
    1. #undef USE_RULES
    2. #define USE_SCRIPT // Add support for script (+15k code)


    Aufruf in Tasmota über Einstellungen -> Edit script

  • GROSSES DANKE dafür :thumbup::thumbup::thumbup:

    Auch von mir !!! :thumbup::thumbup:

    Tasmota 6.6.0 - Arduino-IDE - 1.8.7

    Sonoff-Basic / Sonoff-RF / Sonoff-Touch / Sonoff S20 / PowStro Basic / HomeMagic / Sonoff-RF-Bridge mit diversen 433MHz RF Sender/Empfänger / Shelly_1 / ESP-WiFi-Dimmer / Gosund SP111 / ESP12E Sensoren

    Sensoren: BME280/BMP280/HC-SR501/HC-SR04/ACS712

    mosquitto/bash/html/cgi auf RPI 2B+/Sprachsteuerung via IFTTT/3xGoogle-Home-Mini

  • Hallo gemu2015

    Erstmal super vielen Dank für diesen Scrip Interpreter. Sieht deutlich effizienter aus als die Rules, mit denen ich mein kleines Projekt (Steuerung Solarheizung Pool mit Sonoff Dual, Pumpe, Bypassventil, DS18B20 und BH1750) nicht hinbekomme. Gibt es zu den Script noch etwas mehr zu lesen als Deine Beschreibung im GIT? Ich finde so gut wie nichts.

    Derzeit scheitere ich daran ein abgelaufenen Timer zu erkennen (a la Rules: on Clock#timer=1 do var1 1 endon ). Geht das überhaupt?


    Danke & Viele Grüße!


  • ja klar geht das, in scripter.m gibt es einige Beispiele

    wenn es mal mehr Nutzer gibt sollten wir eine Sammlung von Anwendungsbeispielen erstellen.

    meine eigenen sind fast immer in Kombination mit Displays die Graphen und Werte von Umweltsensoren und Solarwechselrichtern etc anzeigen.

    Inzwischen nutze ich auch SD Karten und kann z.B. auch farbige Bilder anzeigen, oder Sensorwerte in Logfiles schreiben, oder einen akustischen Alarm bei Überschreitungen auslösen inclusive email senden.

    Damit könnte man mit diesem Setup alle möglichen Steuerungen auch ohne Broker realisieren.


    so gehts =>


    also in der D Sektion einen Timer definieren in dem du ein t vor die Variablendefinition schreibst


    t:timer=0


    der timer startet wenn er auf einen Wert > 0 gesetzt wird automatisch


    also z.B. timer=60 für 60 Sekunden


    dann in Sektion S


    immer abfragen ob er abgelaufen ist


    if timer==0

    then

    ; hier ist er abgelaufen, damit diese Bedingung nur einmal auftritt, jetzt den timer auf -1 setzen, oder neu stellen

    timer=-1

    endif



    Gruß Gerhard

  • Hallo Gerhard,


    Danke für die schnelle Antwort! Ich verstehe ein wenig daraus, dass es noch nicht so viele Anwender für Script gibt (?). Kann ich gar nicht verstehen! Was Du damit machst klingt beeindruckend, aber sicher nicht am Sonoff..oder??

    Ich bastle, wie gesagt, an einer Solarthermielösung (also auch Solar!) für einen Pool. Die Funktionsbeschreibung hänge ich unten mal dran (ist etwas länger). Gerne poste ich das, wenn es läuft, sozusagen als Beispiel für die Möglichkeiten die Script eröffnen.


    Zum Thema:

    Ich habe mich bezüglich der Timer etwas verquer ausgedrückt, ich meine die Zeitpläne aus der Tasmota Oberfläche. In den Rules bekommt man ein Trigger dafür (das ist das Beispiel). In Script weiß ich nicht wie man überhaupt auf diese Timer zugreifen kann. Im Moment habe ich das "fest verdrahtet".


    Mir sind noch zwei Sachen aufgefallen:

    1.

    In den Variablendefinitionen kann man wohl einen Startwert übergeben:

    p:tmn=25

    Bei Permanentwerten scheint das nicht zu klappen, diese sind bei mir 0. Ich muss Sie dann per Konsole setzen, dann passt es.


    2.

    Ich hänge mal einen Testcode zum Nachvollziehen an. In der Konsole kann man den Output schön nachvollziehen.

    Im Bereich S soll etwas nur aller x Sekunden abgearbeitet werden (hier 5). Wenn ich den mit "Problemcode" eingefassten Code (if then else) drin habe wird der Ablauf gestört: der nachfolgende Code wird unregelmäßig oft mehrfach abgearbeitet (sieht man an den Meldungen Pumpe an aus). Lösche ich den Problemcode raus funktioniert das. Wenn ich nicht ein Fehler in der Syntax habe (und ich habe stundenlang probiert!) sieht das für mich so aus als ob es mit den Verschachtelungen vom if (lt. Doku max 8) nicht richtig klappt (?)


    Hier mal der Code:


    >D

    p:tmn=25

    p:tmx=30

    p:tck=10

    p:lmn=1200

    fx=0

    sn=0

    lx=0

    tfx=0

    tsn=0

    tlx=0

    st=0

    sl=0

    mn=0


    >B ;boot


    >T

    ;st=DS18B20#Temperature

    st=25

    if st>=tmx

    then

    sn=1

    endif

    if st<=tmn

    then

    sn=0

    endif

    ;sl=BH1750#Illuminance

    sl=300

    if sl>lmn

    and st<tmx

    then lx=1

    else

    lx=0

    tlx=-101

    endif


    >S

    mn=time

    if upsecs%tck==0 ; SysTick

    then

    =>print sun:%sn% tsun:%tsn% /fix:%fx% tfix:%tfx% /lx:%lx% lux:%sl% tlx:%tlx% /temp:%st% time:%mn%


    if lx==0

    then =>print a

    else

    =>print b


    ;Problemcode

    if lx==1

    then =>print c

    else

    =>print d

    endif

    ;ende Problemcode


    endif


    if sn==1

    or fx==1

    ;then =>power2 1

    then =>print Pumpe Ein

    tfx+=1

    else

    ;=>power2 0

    =>print Pumpe Aus

    endif

    if sn==1

    ;then =>power1 1

    then =>print Ventil Ein

    tsn+=1

    else

    ;=>power1 0

    =>print Ventil Aus

    endif


    endif ;SysTick




    Und hier noch die Beschreibung dessen was das Ganze mal werden soll, nur zur Info. Wenn gewünscht poste ich es wenn es fertig ist.


    Wenn keine Soletemperatur oberhalb eines Wertes festgestellt wird, wird die Umwälzpumpe bei geöffneten Bypass Ventil (Solarkreis ist damit überbrückt, das bedeutet maximales Fördervolumen) zu den Zeiten im Zeitplan ein-/ ausgeschaltet. Die Summe dieser Zeiten sollte mindestens einen Wert betragen, der ein 2-maliges Umwälzen des Beckenvolumens/ Tag gewährleistet (hier 6,5h). Das entspricht einer normalen zeitgesteuerten Pumpensteuerung.

    Wenn die Soletemperatur am Temperatursensor einen definierten Wert (Bsp.: 30°C) übersteigt, wird das Bypass Ventil geschlossen (Relais 1 ON). Sollte die Pumpe nicht laufen wird sie auch außerhalb der festen Zeiten eingeschaltet. Damit wird das Wasser durch die Solarpaneele gefördert, gleichzeitig sinkt aber das Fördervolumen/Zeit.

    Wenn die Temperatur einen definierten Wert (26°C) unterschreitet, wird das Bypass Ventil wieder geschlossen (Relais 2 OFF) und ggf. die Pumpe ausgeschaltet (wenn außerhalb der Zeitfenster).

    Wenn die Temperatur am Sensor1 den definierten Wert noch nicht überschritten hat, ein Lux-Sensor aber für eine Zeit x (1 Tick, s.u.) Sonneneinstrahlung feststellt, wird die Pumpe für eine Zeit y (2 Ticks) eingeschaltet und das Bypass Ventil geschlossen, um ggf. bereits erwärmtes Wasser an den Sensor zu fördern. Dann greift das Procedere oben. Dieser Vorgang wird bei Sonneneinstrahlung in Abständen wiederholt.

    Am Ende eines Tages wird geprüft, ob das Fördervolumen ausreichte, um das Wasser 2x umzuwälzen. Dazu wird die Laufzeit der Pumpe bei geöffneten Bypass Ventil mit 100%, die Zeit bei geschlossenem Ventil mit (im Bsp.) 50% gewichtet. Eine sich ergebende Fehlzeit wird nach Mitternacht bei geöffnetem Bypass Ventil nachgeholt.

    Es wird auch die Laufzeit bei geschlossenem Bypass Ventil geprüft: ist diese 0 wird das Paneel 1x mit frischem Wasser durchgespült (soll Algenansatz verhindern).

    Die Ansteuerung der Aktoren wird in einem Zeitraster ausgeführt. Das soll zu aufgeregtes Schalten verhindern und viel wichtiger sicherstellen, dass das sich im stromlosen Zustand selbst schließende Bypass Ventil sicher schließen kann: es benötigt dazu eine minimale Einschaltzeit, um die Kondensatoren zu landen (>2min).



    Viel Grüße

    Ekkehard

  • Hallo Ekkehard


    da hast du ja einiges vor. Mal sehen ob das alles am Ende in den script Speicher passt (ca 1500 bytes)


    werd mal versuchen das zu simulieren wegen der Problem mit der Verschachtelung


    also es gibt bisher keinen Zugriff auf die Tasmota timer. das würde auch keinen Sinn machen da die ja immer ein Relais schalten, was du ja nicht willst.

    werde mal prüfen ob wenn sie inaktiv sind man trotzdem den Zustand abfragen kann.

    ansonsten kannst du alle Zeitinfos wie stunde minute etc auch selbst abfragen


    meines Erachtens brauchst du sicher eine Hysterese


    mir persönlich gefallen bei solchen Aufgaben state machines am besten, also mit switch case ends


    Gruß Gerhard



    PS

    ", aber sicher nicht am Sonoff..oder??"

    nicht sonoff da nicht genügend pins herausgeführt sind aber z.B. Wemos ESP und Tasmota sogar mit einem Display mit 1024x600 Auflösung und touchscreen.

  • Hi Gerhard,

    zum Thema Tasmota Timer: die haben die Option "Rules", damit vermeidet man dass sie direkt auf die Relais zugreifen. Ich hatte das Projekt schon mal mit Rules angefangen (ist aber zu begrenzt dafür), dort waren die Zeitpläne eine schöne Möglichkeit über das Web-Interface die Zeiten einzustellen.


    Hab das jetzt so gelöst (mn ist die aktulle time; hier wird allerdings noch mehr verschachtelt, läuft aber..):


    if mn>=963

    and mn<965

    then

    fx=1

    else

    if mn>=480

    and mn<615)

    then

    fx=1

    else

    if mn >=780

    and mn <855

    then

    fx=1

    else

    if mn >=1080

    and mn <1200

    then

    fx=1

    else

    fx=0

    endif

    endif

    endif

    endif



    Gibt es das switch case in Scripts? Würde das oben sicher etwas vereinfachen.

    Was meinst Du mit der Hysterese? Für die Temperatur gibt es das, bei den Lux ist das m.E. nicht notwendig.


    Zu den Bytes: hab das meiste schon drin und noch 700 Zeichen frei. Deswegen sind übrigens die Variablennamen so "sprechend"!


    Übrigens läuft bei mit die Version 6.6.0.1 vom Theo.


    Danke dass Du es Dir anschaust..


    Ekkehard..

  • Wenn ich in Sektion >E


    ts1=clock#timer1 (oder ts1=clock#timer)


    eingebe startet der Sonoff neu:

    11:10:59 RSL: INFO3 = {"RestartReason":"Fatal exception:28 flag:2 (EXCEPTION) epc1:0x40247d70 epc2:0x00000000 epc3:0x00000000 excvaddr:0x00000000 depc:0x00000000"}


    Scheint auch so, das der Flash etwas ramponiert wird, jedenfalls die festen Variablen sind weg.


    switch habe ich gefunden, Danke, sorry hatte immer in die Script.md in dem ersten GIT von Dir geguckt..

  • also bei mir gibt es keinen crash, sollte auch nicht crashen wenn etwas falsch geschrieben ist.


    muss allerdings


    var=Clock#Timer


    heissen, da bei scripts Groß Kleinschreibung eine Rolle spielt.


    wenn es bei dir immer noch crashed schicke mir dein script damit ich den Fehler suchen kann.

  • Hi Gerhard,


    hab das mit dem Counter getestet, komischerweise klappt das jetzt bei mir auch, ohne crash. Kann den auch nicht mehr reproduzieren. Weiss der Fuchs was dass war. Der Timer liefert die Nummer des auslösenden Zeitplans zurück. Sehr schön und mal wieder Danke!


    Ich habe das mit der vermutlichen Verschachteln nochmal probiert und folgenden einfachen Testcode ohne irgendwelche Spezialitäten getestet:


    >D

    p:tck=10

    fx=0

    sn=0

    mn=0

    sw=0


    >B

    tck=5


    >S

    mn=upsecs%tck

    if mn==0 ; SysTick

    then

    =>print %mn% ######### Systick ############


    if fx==1 ;fx==1

    then =>print Pumpe AN %mn%


    ;Problemcode

    if sw==0 ;sw==0

    then sw=1

    else ;sw==0

    sw=0

    endif ;sw==0

    ;Problemcode


    else ;fx==1

    =>print Pumpe off %mn%

    endif ;fx==1


    if sn==1 ;sn==1

    then =>print Ventil AN %mn%


    else ;sn==1

    =>print Ventil off %mn%

    endif ;sn==1


    endif ;SysTick



    Ich nutze die Konsole um die Ausgaben zu prüfen.


    Wenn der mit "Problemcode" gekennzeichnete Block gelöscht ist funktioniert es erwartungsgemäß, aller 5sec ein "Pumpe off" und "Ventil off" auf der Konsole. Ist der Code drin, wird (nur!) "Ventil off" mehrfach durchlaufen, mn zählt dabei hoch.

    Habe ich da einen Denkfehler?


    Viele Grüße!

  • du hast recht da stimmt was nicht.

    werde nachforschen woran es liegt.

    ist komisch da ich natürlich selbst scripts mit Verschachtelungen verwende.


    als workaround kannst du den Problemcode (die verschachtelte if then else Bedingung) erst mal in eine subroutine auslagern


    also z.B.


    =#toggle


    und am Ende der Sektion

    #toggle

    if sw==0

    then

    sw=1

    else

    sw=0

    endif


    wobei toggeln natürlich viel einfacher geht mit sw^=1

  • hab eben was merkwürdiges festgestellt.

    in meinen scipts steht natürlich nicht nur ein print Befehl in einer Bedingung

    wenn ich in deinem script überall dazwischen "richtigen" code eintrage geht es.

    Mal sehen was die Ursache ist

  • Hi Gerhard,

    habe noch was rausbekommen:


    wenn ich den Code auf diese Notation umschreibe:

    >D

    p:tck=10

    fx=0

    sn=0

    mn=0

    sw=0


    >B

    tck=5


    >S

    mn=upsecs%tck


    if mn==0 {


    =>print %mn% ######### Systick ############


    if fx==1 {

    =>print Pumpe AN %mn%


    ;Problemcode

    if sw==0 {

    sw=1

    } else {

    sw=0

    }

    ;Problemcode


    } else {

    =>print Pumpe off %mn%

    }


    if sn==1 {

    =>print Ventil AN %mn%

    } else {

    =>print Ventil off %mn%

    }


    ticker=tck


    }


    gibts auch das Problem, dass der Problemcode zum Problem führt, der Effekt ist nur ein anderer. Es sieht hier so aus als ob beide else Zweige nicht mehr durchlaufen werden.


    Ich habe ja auch in anderen Sektionen Verschachtelungen die funktionieren..


    Ich probiere Deinen Tipp aus.

    Viel Erfolg!!!:thumbup:Du schaffst das!!:thumbup:

    Ansonsten habe ich mein Projektchen (fast) fertig, fängt an mir zu gefallen. Macht aus diesen kleinen Sonoff's kleine Wunderkästchen!