Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast relay switching based on power increase #21

Open
tobetobe66 opened this issue May 21, 2020 · 92 comments
Open

Fast relay switching based on power increase #21

tobetobe66 opened this issue May 21, 2020 · 92 comments

Comments

@tobetobe66
Copy link

Hi Gemu,

thanks a lot for the beautiful scripting feature.

I am using a Gosund SP1, GPIO4: 134, GPIO5: 132, GPIO12: 131, GPIO14: 21.
I am monitoring power and switch off the relay as soon as power is over 1 Watt using the following code:

T
_pow=ENERGY#Power

F
.
.
.
if ((_pow>1) and (_s==S)) {
->power1 0
e_eP=1
}

This works perfectly fine, however it takes sometimes way above 1 second for the relay to switch off. This is a bit too slow for me. The load is 800W, power rise should be instant.
Is there a way to do this faster? Maybe it's not possible at all, because sampling rate of power measurement is too slow.

I would be grateful for some ideas.
Thank you very much.

@gemu2015
Copy link
Owner

gemu2015 commented May 21, 2020 via email

@tobetobe66
Copy link
Author

Thank you.
I will check.

@tobetobe66
Copy link
Author

OK, I found some cmds that might be of help. Have to do a bit of reading and testing. Will report back once done.

@gemu2015
Copy link
Owner

because if found this an interesting application i implemented direct access to some energy registers which are updated instantly. try my new version!
i however don't know how they are mapped in gosund

enrg[0] = should be total energy
enrg[1] = voltage p1
enrg[2] = voltage p2
enrg[3] = voltage p3
enrg[4] = current p1
enrg[5] = current p2
enrg[6] = current p3

@gemu2015
Copy link
Owner

you need to define
#define USE_ENERGY_SENSOR

@gemu2015
Copy link
Owner

updated again after testing with my MODBus device
added 3 power regs
enrg[7] = power p1
enrg[8] = power p2
enrg[9] = power p3

for a single phase meter only p1 values should be > 0

@tobetobe66
Copy link
Author

OK,

what I tried so far is using cmd powerdelta and cmd powerhigh.
I catch the event in the E-Section:

E
print EVENT
if ((_pow>PON) and (_s==S)) {
->power1 0
e_eP=1
}

_pow is still in T-Section.

The result is comparable to what I had before doing polling in the F-Section.
0.5-2 seconds.

My application is a network of Gosunds to do load managment of the devices attatched to them. I need this. because I am partly OFFGRID and my inverter is limited in power. Therefor I have to detect if a device attached to a Gosund is switched on by the user. This has to be done in a very short time, as the inverter can take some overload for a short amount of time.

@tobetobe66
Copy link
Author

Thank you for the energy registers. I will give it a try and report.
Thanks a lot.

@gemu2015
Copy link
Owner

you may also speed up relay switching by directly setting the relay GPIO by spin(x 1)
don't know how fast ->power1 is

@tobetobe66
Copy link
Author

I already compared spin vs ->power, there is not much difference. However I still had relay 1 defined, because otherwise power measurement didn't work. Just found out today that there is a switch to enable power measurement when power is off. Might give that a try later and compare spin vs ->power again, however I do not expect any speedup. Just compiled your version, will check energy registers now.

@tobetobe66
Copy link
Author

Hi Gemu,

holy cow, it works!! It is fast and reliable with respect to switching time.
I am way below 1 second all the time.

T
;_pow=ENERGY#Power

F
if ((enrg[4]>0.01) and (_s==S)) {
;->power1 0
spin(14 0)
e_eP=1
}

In the above example I used current instead of power, however that does not make a difference.
Using the registers I can skip the T-Section, saving script space, which is prime to me. Will you include the registers feature in a PR? That would be very helpful.

Thank you so much.

I have another issue which is not bothering me anymore because I found a work around. Anyway, I noticed a strange behavior using the short form of if, then, else, i.e. if {} else {}. Once enclosed in a subroutine it was gone. I will do some further testing with respect to this and maybe come back to you.

Best regards
Tobi

@gemu2015
Copy link
Owner

gemu2015 commented May 21, 2020 via email

@tobetobe66
Copy link
Author

I read about rule buffer being compressed. Was hoping for that to happen for scripting also. Great.
Thanks a lot.
Shall I close the Issue?

@gemu2015
Copy link
Owner

leave open, better to find for others

@tobetobe66
Copy link
Author

Hi Gemu,

Just noticed that every time I access a register a mqtt message is sent:

tele/DVES_XXXXX/SENSOR = {"Time":"2020-05-22T17:34:38","ENERGY":{"TotalStartTime":"2019-04-07T18:00:28","Total":0.085,"Yesterday":0.003,"Today":0.042,"Power":0,"ApparentPower":0,"ReactivePower":0,"Factor":0.00,"Voltage":238,"Current":0.000}}

Is there a way to switch this off as it is causing a lot of traffic? Am I missing a Tasmota switch to turn it off?

Thanks.
Cheers tobi

@gemu2015
Copy link
Owner

Hi tobi,
accessing the register should not generate a MQTT message.
it is just the same as reading an internal variable.
must be caused by something else.
you may switch off MQTT completely but i guess that is not what you want.

this is a tele message that should be generated every teleperiod seconds.

Greets Gerhard

@tobetobe66
Copy link
Author

Hmmm, strange.
Checking again. I was accessing the register in the >S section and I got mqtt messages every second. I will do some further testing. Teleperiod is definitely switched off (0).
I cannot switch off mqtt, as this is the way may Gosunds communicate.
I will be back.
Thanks for fast reply

@tobetobe66
Copy link
Author

OK, got it. Running three Gosunds in parallel, one had teleperiod on 300. thats the one I checked.
Sorry for bothering you.

@tobetobe66
Copy link
Author

Hi Gemu,

is it possible to change the last will and testament to a different topic from within the script?
The standard seems to be: tele/DVES_XXXXXXX/LWT.
I would like to change it for example to: abc/LWT.

Thanks a lot
Tobi

@gemu2015
Copy link
Owner

gemu2015 commented May 23, 2020 via email

@tobetobe66
Copy link
Author

OK.
Thx a lot. I will check the code first. Maybe I can hard code it.
Tobi

@tobetobe66
Copy link
Author

Hi Gerhard,

the following script gives me a hard time:

D
m:p_array=0 10
x=1
cnt=1

B
for cnt 1 10 1
if cnt<4
then
print %cnt%
else
break
endif
next

print end
print %cnt%

It seems like the break terminates the whole B section, as I get the following output:
1
2
3

and nothing else.
I really do not get it.

Thx
Tobi

@gemu2015
Copy link
Owner

Hi Tobi,

This was a bug!
is fixed now.

Gerhard

@tobetobe66
Copy link
Author

Thanks Gerhard.
glad I found one! :-)

Tobi

@tobetobe66
Copy link
Author

Hello Gerhard,

see below the result of a fast polling of enrg7 and enrg3 on my gosunds after switching off.
Power (left column) still gives values long after switch off and is oscillating, whereas current is zero as it should be. As I use current it does not bother me, however the behaviour of enrg7 seems strange.

Tobi

08:25:26 P: 0.00 I: 0.00
08:25:26 P: 13.80 I: 0.00
08:25:26 P: 13.80 I: 0.00
08:25:26 P: 13.80 I: 0.00
08:25:26 P: 13.80 I: 0.00
08:25:26 P: 13.80 I: 0.00
08:25:26 P: 0.00 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 0.00 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:27 P: 13.80 I: 0.00
08:25:28 P: 13.80 I: 0.00
08:25:28 P: 0.00 I: 0.00

@gemu2015
Copy link
Owner

gemu2015 commented May 25, 2020 via email

@tobetobe66
Copy link
Author

Energy resolution is far better than 13.8Watts. I don't think its because of noise.
I can only use two registers, as it is a one phase system. I can live with the current register.

Was just wondering about the readings of the power register. It reads 13.8W long after the device is switched off and also when current is already 0 for some time.

@tobetobe66
Copy link
Author

Dear Gerhard,

the docu states:
There are two syntax alternatives for conditional statements (if, then, else or if {} else {}). You may NOT mix both formats.

Does this NOT mixing refer to the whole script or just to not nesting both formats?

Thx
Tobi

@gemu2015
Copy link
Owner

gemu2015 commented May 26, 2020 via email

@tobetobe66
Copy link
Author

Hi Gerhard,

I have a strange behavior in the following code if I change the highlighted section from if then to if{}. The function FSM is called from the F Section.
It does not work with, however both variants should be equivalent.
if e_eP==1 {
_s=N
sc=1
}

If I use {} the part with
e_Te=0
e_Mr=0
e_eP=0

seems to be skipped. I.E. in the print statement e_Mr is 1 instead of zero.
I do not see where I could have made an error as it works with if then.

Thx Tobi

#FSM
print BEG FSM: sc:%sc% State:%_s% e_eP: %e_eP%, e_Te: %e_Te% e_Mr: %e_Mr%
sc=0
switch _s
case S
print S
->power1 1
_if e_eP==1
then
s=N
sc=1
endif

case N
print N
->power1 0
if r==1
then
_s=O
sc=1
endif

case O
print O
->power1 1
ends

print clear events
e_Te=0
e_Mr=0
e_eP=0

print EOF FSM: sc:%sc% State:%_s% e_eP: %e_eP%, e_Te: %e_Te% e_Mr: %e_Mr%

@tobetobe66
Copy link
Author

Ok, mache ich gleich.

Nur fürs Protokoll:

  • irgendeinen pin als counter definieren und auf pulsetime stellen.

dann
res = mpt(-P) in D-Section???? oder einfach in F oder S Section?
res=mpt(0) zum auslesen?

@gemu2015
Copy link
Owner

gemu2015 commented Jun 3, 2020

z.B.
>D
res=0

>B
; definiere GPIO 4 als Pulse Timer
res=mpt(-4)

>S
res=mpt(0)

print %res%

@gemu2015
Copy link
Owner

gemu2015 commented Jun 3, 2020

so noch ne kleine Änderung
>D
res=0

>B
; definiere GPIO 4 als Pulse Timer
res=mpt(4)

>S
res=mpt(-1)

print %res%

wenn man 128 auf die Pin Nummer draufzählt
misst er zwischen fallend und steigend sonst umgekehrt
res=mpt(128+4)

@tobetobe66
Copy link
Author

va bene, gerade am testen.
dann geh ich mal compilieren :-)

@tobetobe66
Copy link
Author

Läuft so wie es aussieht. Danke.
20:24:52 963.00
20:24:53 1008.00
20:24:54 1008.00
20:24:55 1016.00
20:24:56 1016.00
20:24:57 1016.00

Das ist der Output bei in S-Section flippendem GPIO5. Passt also. Getestet mit res=mpt(128+4)
Echt klasse.

@tobetobe66
Copy link
Author

Die Möglichkeit, im Script zwischen den Messarten mit res=mpt(128+4) oder res=mpt(4) umzuschalten, ist grossartig.

@gemu2015
Copy link
Owner

gemu2015 commented Jun 4, 2020

Morgen Tobi,

so habe mal drüber geschlafen und weiter verbessert.

mpt(x) definiert den Pin

mpt(-1) liest die high low Zeit
mpt(-2) liest die low high Zeit
die Pulszeit wird nach dem Auslesen auf Null gesetzt.
Damit kannst du erkennen ob überhaupt eine Periode statt gefunden hat.
(du must ja den DCF Sync alle Minute finden)

und weil diese Funktion sicher selten gebraucht wird und kostbaren IRAM verbraucht habe ich sie optional gemacht mit anderen seltenen Funktionen
du must #define USE_ANGLE_FUNC angeben.

Grüße

Gerhard

@tobetobe66
Copy link
Author

Moin Gerhard,

Perfekt. Die Erkennung des Sync hätte auch so funktioniert, aber so ist es viel besser.
Die m:, bzw. M: Variablen sind bei der Umsetzung sehr hilfreich. Einfach vollschreiben und dann nach Detektion des Sync einfach auslesen und berechnen. Sollte eigentlich funktionieren.

Vielen Dank.
Gruss Tobi

@gemu2015
Copy link
Owner

gemu2015 commented Jun 4, 2020

Hab jetzt noch was ganz verwegenes eingebaut.
Wenn du 128 zur Pinnummer addierst wird bei der steigenden Flanke die Sektion >I in scripter aufgerufen. Damit wärst du komplett synchron mit dem Signal.
Da das aber im Interrupt geschieht darf da nichts schief gehen und es darf nur ganz wenig Code im >I Teil stehen, also nur Wert abholen und in array schreiben oder so.
Das würde auch schief gehen wenn das Signal prellt, habe zwar ein debounce von 20 ms drin aber besser sollte das Signal sauber sein, also kein Switch oder so.

@tobetobe66
Copy link
Author

Das ist ja ein Träumchen.
Kann erst in 5 Stunden weiter machen.
Ich habe es noch nicht probiert, deswegen frage ich jetzt einfach. Kann man den aktuellen Index eines arrays, also array[0] auch setzten?

Danke
Gruss
Tobi

@gemu2015
Copy link
Owner

gemu2015 commented Jun 4, 2020

ja den kann man auch setzen!

@gemu2015
Copy link
Owner

gemu2015 commented Jun 4, 2020

ja das mit der >I section war leider ein Irrtum. Da der Interrupt auch während eines Flash update passieren kann darf man von dort keine Flash Programme aufrufen.
Hab das wieder ausgebaut. Wär schön gewesen.
Da deine >S oder >F Sektionen nicht synchron mit dem DCF sind könnte es gelegentlich zu Fehldetektionen kommen. Kann man aber sicher abfangen.

@tobetobe66
Copy link
Author

Schade, das wäre der Knaller gewesen.
In der F-Section bin ich max 100ms daneben, damit habe ich kein Problem.
Bin gespannt ob es funktioniert. Muss man eben ausprobieren.

@tobetobe66
Copy link
Author

Morgen Gerhard,

so habe jetzt einen alten Funkwecker zerlegt und versucht das DCF-Signal zu verwenden. Hat leider nicht lange funktioniert:-). Danach noch einen zerlegt, den kann ich jetzt zum Testen verwenden. Liefert auch schöne 100ms und 200ms Pulse am Oszi.

Mit deiner letzten Version liefert folgendes Skript:

D
res=0

B
; definiere GPIO 4 als Pulse Timer
res=mpt(4)
spinm(4 0)
F
res=mpt(-2)
print %res%

Den folgenden Output:

06:40:57 897.00
06:40:57 0.00
06:40:57 1099.00
06:40:57 0.00
06:40:57 0.00
06:40:57 0.00
06:40:57 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:58 0.00
06:40:59 0.00
06:40:59 0.00
06:40:59 0.00
06:40:59 1798.00
06:40:59 1900.00
06:40:59 0.00
06:40:59 0.00
06:40:59 0.00
06:40:59 0.00
06:40:59 0.00
06:41:00 0.00
06:41:00 0.00
06:41:00 0.00
06:41:00 898.00
06:41:00 0.00
06:41:00 1100.00
06:41:00 0.00
06:41:00 0.00
06:41:00 0.00
06:41:00 0.00
06:41:01 0.00
06:41:01 0.00
06:41:01 0.00
06:41:01 796.00
06:41:01 894.00
06:41:01 0.00
06:41:01 0.00
06:41:01 0.00
06:41:01 0.00
06:41:01 0.00
06:41:02 0.00
06:41:02 0.00
06:41:02 0.00
06:41:02 902.00
06:41:02 0.00
06:41:02 1105.00

Man erkennt sehr schön den langen Sync-Puls.
Auffällig ist:

  • Es werden immer 2 Werte geliefert
  • ein Aufruf von res=mpt(-1) anstatt -2 liefert immer 0

Eigentlich müsste ich doch bei Aufruf von -1, nur jeweils einen Wert (100 oder 200) bekommen und bei Aufruf von -2 jeweils auch nur einen Wert (800, 900, 1800, 1900) oder?

Danke
Grüsse
Tobi

@gemu2015
Copy link
Owner

gemu2015 commented Jun 5, 2020 via email

@gemu2015
Copy link
Owner

gemu2015 commented Jun 5, 2020

Hab das mal jetzt aufgebaut und erst mal mit einem Taster ausprobiert.
Einen DCF habe ich gerade nicht zur Hand. Den Funktionsgenerator müsste ich erst anpassen (hat 5 Volt Ausgang)

Die Ergebnisse sind plausibel.
Habe jetzt noch eine Unterdrückung von kurzen Spikes eingebaut (erst mal 10 ms)
Teste mal meine aktuelle Version

@gemu2015
Copy link
Owner

gemu2015 commented Jun 5, 2020

so, habe jetzt mit Funktionsgenerator getestet und alles funktioniert wie es soll.

@tobetobe66
Copy link
Author

Ich teste

@tobetobe66
Copy link
Author

Hallo Gerhard,

bei mir läuft jetzt auch alles wie es soll.
Hatte zunächst den Pegel der Funkuhr direkt abgegriffen. Der war entweder zu niedrig oder es hat nicht gereicht den Eingang des Wemos zu treiben oder beides. Hat aber zu interessanten Ergebnissen geführt.
An dieser Stelle ein grosses MEA CULPA. Hätte ich besser prüfen müssen.
Das positive an der Sache ist, es ist jetzt 2 mal getestet worden: Einmal Funktionsgenerator und dann mit DCF77 Empfänger aus Funkuhr. Vermutlich würde es sogar ohne debounce 10ms funktionieren.
Ich teste jetzt das DCF77 Script und melde mich dann.
Gruss und DANKESCHÖN
Tobi

@tobetobe66
Copy link
Author

Ich vergass, Abhilfe schufen 2 Widerstände und ein NPN Transistor.

@gemu2015
Copy link
Owner

gemu2015 commented Jun 5, 2020

Hi Tobi,
Baue gerade einen Editor mit Syntaxcolorierung für die Scripte.
Falls du Interesse hast das mit zu testen schicke ich dir eine Version.
Das Script wird local editiert und soll dann per Tastendruck an den ESP geschickt und direkt gestartet werden.Davor werden alle Kommentare und Indents entfernt damit das script möglichst kompakt wird.
Die Kolorierung geht schon, das kompakt file wird abgespeichert (unter compressed_script.txt) aber noch nicht gepostet. daran arbeite ich noch.

Habe Mac und PC version

Gruß Gerhard

@tobetobe66
Copy link
Author

Hallo Gerhard,

natürlich helfe ich beim Testen. Ist doch klar.
Brauche Mac.

Bezüglich DCF77: Ist aufwändiger als gedacht. Eigentlich einfach, Problem ist aber tatsächlich die Synchronisation. Da ich in der F-Section arbeiten muss, kann es vorkommen, dass aufgrund unterschiedlicher Laufzeiten der Section sich das Sampling-Fenster verschiebt. Kann gerade nicht mehr weitertesten, da mein Testrechner belegt ist. Sind aber bisher alles nur Vermutungen.

Die I-Section wäre extrem hilfreich gewesen. Ein Interrupt der im Script zugänglich ist, wäre der Knaller gewesen.

Gruss Tobi

@gemu2015
Copy link
Owner

gemu2015 commented Jun 6, 2020

Moin Tobi

https://www.dropbox.com/s/pj44bmxzkipebzd/uVariotest.zip?dl=0
hier die version die auch das file sendet. auf GitHub der zugehörige scripter

Die scripts müssen .txt suffix haben und in der ersten Zeile muss >D stehen, dann erkennt er die Datei als Tasmota script.

Du kannst jetzt beliebig kommentieren und einrücken.

in irgend einer Zeile muss IP=xxx.xxx.xxx.xxx
die IP deines Tasmota stehen

Jetzt CMD R oder im Menu run eingeben und das script wird gesendet und sofort gestartet.

Viel Spass damit

Gerhard

@tobetobe66
Copy link
Author

War gerade am ausprobieren.
Dann lade ich jetzt die neue Version.
Funktioniert bei Dir das highlighting bereits komplett und fehlerfrei?

Gruss
Tobi

Repository owner deleted a comment from tobetobe66 Jun 6, 2020
Repository owner deleted a comment from tobetobe66 Jun 6, 2020
Repository owner deleted a comment from tobetobe66 Jun 6, 2020
@kugelkopf123
Copy link

kugelkopf123 commented Jun 10, 2020

Moin Gerhard.

Ich versuche dir schon seit Tagen auf deine Nachricht zu Antworten. Allerdings zickt das Forum wieder. Gibt es in GH eigentlich eine PN Funktion?
Habe nun über die Tasmota Docs die Beschreibung zum externen Script Editor gefunden. Tolle Arbeit von euch beiden!
Allerdings funktioniert er nicht bei mir, wenn nach dem >D eine Zahl folgt.

>D 37
Syntax Error in Line 1. Ist die Fehlermeldung.

Oh und wie verhält es sich mit dem Kompressionsfaktor, wenn man beim Kompilieren
#define ESP32_SCRIPT_SIZE 8192
angibt?
Konnte diese definition überhaupt nicht in den tasmota Docs finden. Vielleicht existiert sie ja garnicht mehr.

Viele Grüße
Chris

@tobetobe66
Copy link
Author

Nur fürs Protokoll: Ich habe nicht viel gemacht :-)
Grüsse
Tobi

Repository owner deleted a comment from kugelkopf123 Jun 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants