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

Leistungsreduzierung HM300 #35

Closed
klahus1 opened this issue Jul 19, 2022 · 102 comments
Closed

Leistungsreduzierung HM300 #35

klahus1 opened this issue Jul 19, 2022 · 102 comments

Comments

@klahus1
Copy link

klahus1 commented Jul 19, 2022

Hallo tbnobody,

hier das Protokoll zur Leistungsreduzierung HM300:
Erste Version quick and dirty mit dem openDTU implementiert und getestet:

limit = zwei Byte, eine Dezimalstelle. Z.B: 30.0W = 300dez = 0x01 0x2c

<0x51> <WR>     <DTU>    <0x81>   <0x0b 0x00> <0x01 0x2c> <0x01 0x00>            <CRC16/modbus> <crc8>
<Cmd>  <target> <source> <subcmd> <ctrlmode>  <limit>     <?desc?-fix 0x01 0x00> <crc16/modbus> <crc8>

22:28:13.964 > Fetch inverter: 112172615582
22:28:13.964 > sendPackSetPowerLimitCommand
22:28:13.966 > sendEsbPacket
22:28:13.969 > TX 51 72 61 55 82 78 56 34 12 81 0B 00 01 2C 01 00 C5 C0 3E 
...
22:28:14.897 > Interrupt received
22:28:14.897 > 
22:28:14.897 > >> RX  OK: D1 72 61 55 82 72 61 55 82 81 00 00 0B 00 14 07 48 
22:28:14.903 > 
22:28:15.271 > RX Period End
22:28:15.271 > getLastRequest() == RequestType::Cmd
22:28:15.275 > Success
bool HM_Abstract::sendPackSetPowerLimitCommand(HoymilesRadio* radio) // hus:
{

    inverter_transaction_t payload;

    memset(payload.payload, 0, MAX_RF_PAYLOAD_SIZE);

    payload.target.u64 = serial();
    payload.mainCmd = 0x51;
    payload.subCmd = 0x81;
    payload.timeout = 400;
    payload.len = 8;

    payload.payload[0] = 0x0b;
    payload.payload[1] = 0x00; 
    payload.payload[2] = 0x01;
    payload.payload[3] = 0x2c;   
    payload.payload[4] = 0x01;   
    payload.payload[5] = 0x00;

    uint16_t crc = crc16(&payload.payload[0], 6);

    payload.payload[6] = (crc >> 8) & 0xff;
    payload.payload[7] = (crc)&0xff;

    payload.requestType = RequestType::Cmd;

    radio->enqueTransaction(&payload);
    return true;
}

Siehe auch :

usart_nrf3.cpp
UsartNrf_Send_DevControlUpdate()
...
                    MIMajor[PortNO].Property.Pass.PowerPFDev.SetValut[0] = (u8)(relative_value >> 8);
                    MIMajor[PortNO].Property.Pass.PowerPFDev.SetValut[1] = (u8)(relative_value);
                    MIMajor[PortNO].Property.Pass.PowerPFDev.Desc[0] = 0;
                    MIMajor[PortNO].Property.Pass.PowerPFDev.Desc[1] = 1;

Viele Grüße
Klaus

@tbnobody
Copy link
Owner

Ohh das klingt ja sehr vielversprechend. Hast du herausbekommen was der Response vom WR zur DTU ist wenn das erfolgreich angewendet wurde?

Grüße
Thomas

@klahus1
Copy link
Author

klahus1 commented Jul 19, 2022

Hallo Thomas,
um den Respose hab ich mich (noch) nicht gekümmert.
Nach dem ich anfänglich die Byte-Reihenfolge der uint16_t falsch hatte (wie immer die endianess, zusätzlich wird ja auch im usart_nrf3.cpp zwei mal verschoben) antwortete der WR mit :
F1 ( | 0xA0 ) anstelle D1 ( | 0x80 )

19:49:28.473 > Fetch inverter: 112172615582
19:49:28.473 > sendPackSetPowerLimitCommand
19:49:28.475 > sendEsbPacket
19:49:28.479 > TX 51 72 61 55 82 78 56 34 12 81 00 0B 00 96 01 00 80 
19:49:28.521 > Interrupt received
19:49:28.521 > 
19:49:28.521 > >> RX  OK: F1 72 61 55 82 72 61 55 82 81 80 00 00 00 00 00 00 00 00 00 00 00 00 01 81 EB 9B 
19:49:28.529 > 
19:49:28.907 > RX Period End
19:49:28.907 > getLastRequest() == RequestType::Cmd
19:49:28.911 > Success

DanielR92 hat mir viele Hinweise gegeben.

VG
Klaus

@tbnobody
Copy link
Owner

Hm 2 Fragen wären mir spontan noch eingefallen. Überlebt eine Limitierung die Nacht? Also befindet sich diese persistent im WR? Oder muss diese jeden Tag neu gesetzt werden?
Gibt es eine Möglichkeit die aktuelle Limitierung zu lesen?

Also ich denke nur daran, wenn man z.B. 2 MQTT Topics haben möchte, zum setzen der Limitierung und zum auslesen des aktuellen Wertes.

@klahus1
Copy link
Author

klahus1 commented Jul 19, 2022

Hallo Thomas,
kann ich aktuell noch nichts zu sagen.
Der HM300 läuft erst einmal heute Nacht mit eingestellten 30W ~ real 24.5W an den Batterien.

grafik

Alles Weitere werden die nächsten Tage / Tester zeigen.

Viele Grüße
Klaus

@stefan123t
Copy link

@tbnobody die Antwort der Hoymiles 2G und 3G Protokolle ist in der Regel MainCmd | 0x80, also hier 0x51 | 0x81 = 0xd1.

22:28:13.969 > TX 51 72 61 55 82 78 56 34 12 81 0B 00 01 2C 01 00 C5 C0 3E
...
22:28:14.897 > Interrupt received
22:28:14.897 >
22:28:14.897 > >> RX OK: D1 72 61 55 82 72 61 55 82 81 00 00 0B 00 14 07 48

@klahus1
Copy link
Author

klahus1 commented Jul 20, 2022

Moin Moin,
nach dem Abschalten von DC, wurde YieldDay auf Null gesetzt und der HM300 startet wieder mit der eingestellten, reduzierten Leistung. Sprich die Reduzierung bleibt -auch nach kurzem Ausschalten- erhalten.

VG
Klaus

@DanielR92
Copy link

DanielR92 commented Jul 20, 2022

Guten Morgen,

zum letzten Kommentar kann ich bestätigen. Ich habe mein WR am Labornetzteil hängen. Wenn ich diesen vom DC trenne (warte...) und wieder Einschalte bleibt die limitierung erhalten.

@a-marcel
Copy link

a-marcel commented Jul 20, 2022

Hallo, ich kann bestätigen, das die Limitierung auch bei einem HM400 geht. Er trifft zwar nicht genau die Werte, aber immerhin. Ich habe es mit 30 W (was dann 24 W AC ergibt) und 50W (was dann 40W AC ergibt). Kann aber ggf. daran liegen, das ich derzeit noch immer mein StepUp Wandler davor dran habe.

[18:59:20][I][hoymiles.esp32:229]: Sending Limitation
[18:59:20]I: Transmit (Limit) 19 | 51 73 10 90 25 78 56 34 12 81 0B 00 01 F4 01 00 FE 40 4F 
[18:59:21][D][hoymiles.esp32:127]: Received 17 bytes channel 75: 
[18:59:21]D1 73 10 90 25 73 10 90 25 81 00 00 0B 00 14 07 48 
[18:59:21][D][hoymiles.esp32:127]: Received 17 bytes channel 75: 
[18:59:21]D1 73 10 90 25 73 10 90 25 81 00 00 0B 00 14 07 48 
[18:59:21][D][hoymiles.esp32:127]: Received 17 bytes channel 75: 
[18:59:21]D1 73 10 90 25 73 10 90 25 81 00 00 0B 00 14 07 48 

Vielen Dank für die Arbeit von allen. Ich bau das jetzt in mein esphome plugin ein und dann kann ich endlich automatisieren.

Marcel

P.s.: Ein und Ausschalten wäre noch ein Feature das ganz nett wäre, da derzeit mein Yield Day nicht stimmt, weil der HM 24h durchläuft. Ich glaube auch das die 24h Laufzeit dazu führt, das der HM so aller 36h mal kurz aussetzt. Also ein und ausschalten wäre eine super Lösung.

@ahinrichs
Copy link
Contributor

Es fällt auf, dass die realen Werte bisher immer ziemlich exakt 80% des Sollwerts sind.

Vielleicht ein Puffer, für die Fälle wo das mit dem Limit rechtlich wichtig ist?

@stefan123t
Copy link

stefan123t commented Jul 21, 2022

@a-marcel Ein-/Ausschalten habe ich in lumapu/ahoy#31 bzw. im Forum dokumentiert.
@DanielR92 kannst Du mal prüfen ob ein Restart/Reset/Reboot mit 0x02 die eingestellte Limitierung und/oder die DailyYields evtl. neu setzt ?
Alternativ geht das vielleicht mit Type_CleanState_LockAndAlarm 0x14

@a-marcel
Copy link

a-marcel commented Jul 21, 2022

@stefan123t : Ich habe beide Commands (Turn On / Turn Off) ausprobiert, sie gehen, aber nach dem Einschalten bleibt die voreingestellte Limitierung bestehen. Auch die Tageswerte bleiben bestehen. Interessant ist aber auch, das selbst wenn der HM aus ist (Turn Off) dieser dennoch auf alle Anfragen brav antwortet.

Da in EspHome eine Wattgenaue Limitierung für den Benutzer schwer zu senden ist, sollte doch auch die Prozentuale Limitierung gehen.

Ich habe mit den Werten mal rumgespielt aber nichts klappte:

Limitierung auf 1000 (dachte an 100%)
und die zwei nachfolgenden bytes dann auf den % Wert mal 10 : 40% = 400

Hatte ich im Forum so gelesen, das wohl die nachfolgenden Bytes (<?desc?-fix 0x01 0x00) die Prozentualen Werte sind.

Ich hatte auch probiert die Limit werte so zu setzen, das sie der Wattzahl meines Wechselrichters entsprechen und dann die nachfolgenden Bytes auf den Prozentualen Wert, aber dann speist er mit voller Power ein.

also 400 Watt und dann 30 %

<0x51> <WR>     <DTU>    <0x81>   <0x0b 0x00> <0x01 0x2c>     <0x01 0x00>            <CRC16/modbus> <crc8>
<Cmd>  <target> <source> <subcmd> <ctrlmode>  <limit>         <prozent ?>            <crc16/modbus> <crc8>
                                              0x0F 0xA0       0x01 0x2C

Marcel

@tbnobody
Copy link
Owner

Entstehen durch das Schalten oder Setzen der Limits eigentlich Einträge im Eventlog? Ich bin immer noch am durchkämmen des Sourcecodes ob es möglich ist den Status auszulesen.. Das Ein/Aus hätte ich mir noch vorstellen können das es im Run_Status steht. aber der kommt eben über Eventlog Einträge

@klahus1
Copy link
Author

klahus1 commented Jul 22, 2022

Hallo zusammen,

so wie ich es der usart_nrf.c / usart_nrf3.c und usart_nrf.h ... entnehme, ist der Wert von .Desc abhängig von zwei Entscheidungen.
Ich setze dabei voraus, dass .Desc mit 0 initialisiert wird. -> Aufruf von UsartNrf_ClearInverterMajor()

usart_nrf.h :

typedef struct
{
    vu8 SetValut[2];
    vu8 Desc[2];
} PowerPFDevType;
...
typedef union
{
    PowerPFDevType PowerPFDev;
    ClearAlarmDevType ClearAlarmDev;
    EletricSetType EletricSet;
    PassWordSetType PassWordSet;
    vu8  Data [ 18 ];                 //Parameter setting
}  PassValueType ;
typedef union
{
    struct
    {
        vu8  Pre_Id[2];                     //
        vu8  Id[4];                         //Network command specified Id + polling Id+Search Id
        PortType Port;                      //Port type
        vu8  Id_In_Phase;                   //The phase where the ID is located 1: A 2: B 3: C
        vu8  Acq_Switch;                    //Micro-inverse acquisition switch
        vu16 Power_Limit;                   ​​//Power limit
        PassValueType Pass;
    } Property;                             //After executing the current inverter network command, the polling of the inverter will be executed
    vu8 PropertyMsg[30];
} InverterMajor;

usart_nrf.c :
Initialisierung der gesamten Struktur mit 0

void UsartNrf_ClearInverterMajor(void)
{
    vu16 i;

    for(i = 0; i < PORT_LEN; i++)
    {
        memset((InverterMajor *) & (MIMajor[i]), 0, sizeof(MIMajor[i]));
    }
}
void UsartNrf_MemInit(void)
{
...
    UsartNrf_ClearInverterMajor();

NetProtocol.c :

void Network_Function_Reset(void)
{
    UsartNrf_ClearMIReal();
    UsartNrf_ClearInverterMajor();

usart_nrf3.c :
Hier die Entscheidungen: UsartNrf_Send_DevControlUpdate()

            if((Dtu3Detail.Property.DRM_Limit_Switch == 1) ||
                    (Dtu3Detail.Property.SunSpec_Switch == 1))
...

                    MIMajor[PortNO].Property.Pass.PowerPFDev.SetValut[0] = (u8)(relative_value >> 8);
                    MIMajor[PortNO].Property.Pass.PowerPFDev.SetValut[1] = (u8)(relative_value);
                    MIMajor[PortNO].Property.Pass.PowerPFDev.Desc[0] = 0; // hus: desc = absteigend?
                    MIMajor[PortNO].Property.Pass.PowerPFDev.Desc[1] = 1;
                }
            }
            else if((Dtu3Detail.Property.Zero_Export_Switch == 1) || (Dtu3Detail.Property.Phase_Balance_Switch == 1))
            {
                TotalIndex_Para = 4;
                MIMajor[PortNO].Property.Pass.PowerPFDev.SetValut[0] = (u8)(MIMajor[PortNO].Property.Power_Limit >> 8);
                MIMajor[PortNO].Property.Pass.PowerPFDev.SetValut[1] = (u8)(MIMajor[PortNO].Property.Power_Limit);
            }

Dtu3Detail.Property.DRM_Limit_Switch oder Dtu3Detail.Property.SunSpec_Switch dann
.Desc[1] 0x01 .Desc[0] = 0x00

Dtu3Detail.Property.Zero_Export_Switch oder Dtu3Detail.Property.Phase_Balance_Switch dann
.Desc[1] 0x00 .Desc[0] = 0x00

andere Vorkommnisse von .Desc konnte ich bisher nicht finden.

Danach wird UsartNrf3_Send_PackDevControl() gerufen

        Uart_SendBufferLen = UsartNrf3_Send_PackDevControl(
                (u8 *)MIMajor[PortNO].Property.Id, 
                (u8 *)MIMajor[PortNO].Property.Id, 
                (u16)(SubCmd << 8), 
                (u8 *)MIMajor[PortNO].Property.Pass.Data + Index_Para, 
                0x81 + ((Index_Para + 4) / 16), 
                TotalIndex_Para - Index_Para
            );

Auffällig ist hier z.B. das Schieben des SubCmd in das "linke" Byte von uint16_t -> 0x0b00

Die Signatur von UsartNrf3_Send_PackDevControl()

u8 UsartNrf3_Send_PackDevControl(
    u8 *target_adr, 
    u8 *rout_adr, 
    u16 ControlMode, 
    u8 *ControlData, 
    u8 nub, 
    u8 Num)

Hier wird es jetzt ein wenig "unübersichtlich" abhängig von nub wird dann ControlMode (SubCmd) wieder "zurückgeschoben" sprich 0x000b.

    if((nub & 0x0f) == 1)
    {
        temp_dat[10] = (u8)(ControlMode >> 8); // control type
        temp_dat[11] = (u8)(ControlMode);// Control type
    }

nub = 0x81 + ((Index_Para + 4) / 16)

TotalIndex_Para = 4
Index_Para = ???

Ohne Debugger kann ich hier nur noch schwer folgen.

Also wären

Property.DRM_Limit_Switch || Dtu3Detail.Property.SunSpec_Switch

0x0b 0x00 0x03 0xE8 0x01 0x00
^^^^^^^^^----------------------- ControlMode
          ^^^^^^^^^^^^^^^^^^^--- *ControlData
          ^^^^^^^^^------------- .Power_Limit 03 E8 ~ 1000 ~ 100.0 W
                    ^^^^^^^^^--- .Desc ( descending / absteigend ? )

bzw.

Dtu3Detail.Property.Zero_Export_Switch || Dtu3Detail.Property.Phase_Balance_Switch

0x0b 0x00 0x03 0xE8 0x00 0x00
^^^^^^^^^----------------------- ControlMode
          ^^^^^^^^^^^^^^^^^^^--- *ControlData
          ^^^^^^^^^------------- .Power_Limit 03 E8 ~ 1000 ~ 100.0 W
                    ^^^^^^^^^--- .Desc ( descending / absteigend ? )

meine Interpretationen.

Die endianess des µC der DTU bzw des WR könnten hier auch eine Rolle spielen.

Viele Grüße
Klaus

@stefan123t
Copy link

stefan123t commented Jul 22, 2022

@klahus1 Desc / Asc könnte hier tatsächlich die richtige Übersetzung sein.
Vielleicht ist das die absteigende / aufsteigende Flanke / Nulldurchgang der Sinus Welle ?
Ich meine @DanielR92 hatte auch bemerkt daß sich der PowerFactor indirekt mit der Desc Einstellung verändert / verändern läßt.
Wenn man den Phasenwinkel Phi mit dem Type_PFSet 0x0d einstellen kann, dann kann man vielleicht die 180° hiermit ergänzen ?

@klahus1
Copy link
Author

klahus1 commented Jul 22, 2022

Die Frage ist halt,
worin besteht der Unterschied in Bezug auf die Leistung bei DRM/SunSpec und Zero_Export/Phase_Balance.
Und was macht der Wechselrichter daraus.
Ich habe auch weitere Werte für .Desc ausprobiert, konnte jedoch bei mir immer nur die beiden "Zustände / Verhalten" 0x00 0x00 und 0x01 0x00 erkennen.
Das könnte jedoch auch daran liegen, dass ich nur einen einkanaligen HM300 ( zusätzlich noch limitiert auf 70% Leistung [214.2W] ) zum Testen habe.

@De-Ichirou
Copy link

Die Frage ist halt, worin besteht der Unterschied in Bezug auf die Leistung bei DRM/SunSpec und Zero_Export/Phase_Balance. Und was macht der Wechselrichter daraus.

DRM/SunSpec ist eine externe Limitierung. DRM ist australischer Standart wie bei uns die Kontrolloption durch den Netzbetreiber. SunSpec ist eine externe Kontrolle durch ein lokales Steuerungssystem wie z.B. Victron, was die WR einzeln ansteuern kann.
Bei SunSpec setzt die DTU die Steuerbefehle je WR um. In beiden Fällen ist die DTU ein Slave.
Bei Zero-Export/Phasebalance ist die DTU der Master und entscheidet selbst, was für Werte die richtigen sind.

@stefan123t
Copy link

@De-Ichirou schön, kurz und knapp erklärt!
Bei PhaseBalance und mW SunSpec kommen noch die Algorithmen in AntiReflux zum tragen, die dafür sorgen dass mehrere Wechselrichter auf den bis zu drei Phasen immer so viel einspeisen, dass es zu keiner zu großen Phasenverschiebung kommt. Die DTU bzw die ModBus Messgeräte steuern die Wechselrichter dann ( je nachdem an welcher Phase diese hängen ) entsprechend an.

@stefan123t
Copy link

stefan123t commented Jul 31, 2022

Hallo @a-marcel,
die Limitierung bei den MI-Wechselrichtern mit 0x5a5a braucht beides % und Watt Angaben.

Die Limitierung bei den HM-Wechselrichtern mit MainCmd 0x51 und SubCmd / ControlMode 0x0b00 braucht nur die Watt Angabe und einen sog. PowerPFDev.Desc Parameter.
0x012C = 30.0 Watt (immer mit einer Dezimalstelle als mit Faktor 10 angeben) bzw. 0x0FA0 = 400.0 Watt
und immer 0x0000 (oder 0x0001 ?) als PowerPFDev.Desc.
Der ist bei den bisherigen Aufzeichnungen / Traces der DTU-Pro immer 0x0000.

<0x51> <WR>     <DTU>    <0x81>  <0x0b00>   <0x012c> <0x0000>          <CRC16/modbus> <crc8>
<Cmd>  <target> <source> <FrmId> <ctrlmode> <limit>  <PowerPFDev.Desc> <crc16/modbus> <crc8>
                                            <0x0FA0> <0x0001>

Laut dem Source Code kann PowerPFDev.Desc aber auch 0x0001 sein.
@klahus1 hat das heute getestet mit für uns alle noch etwas unklarer Erkenntnis.

@FSys77
Copy link

FSys77 commented Aug 3, 2022

Wird dieser Power-Wert im EEPROM persistiert? Das wäre ziemlich blöd, denn wenn wir den ein paar hundert mal pro Tag setzen ist das EEPROM nach relativ kurzer Zeit im Eimer.

@kpwg
Copy link

kpwg commented Aug 6, 2022

In diesem Fall gehört der Wert in den RAM. Der EEPROM sollte nur einen default-Wert vorhalten, den man dann sicherheitshalber entsprechend (niedrig) wählt.

@hubsi5
Copy link

hubsi5 commented Aug 8, 2022

Ist es geplant die Leistungsreduzierung auch per MQTT zu steuern?
Ahoy hat das ja schon ein bisschen, nur läuft ahoy bei mir ziemlich unstabil.
OpenDTU läuft bei mir wie eine Uhr und ich hoffe, dass ihr es schafft, das zu realisieren.

@tbnobody
Copy link
Owner

tbnobody commented Aug 8, 2022

Geplant ist das auf jeden Fall. Habe auch schon viele Vorbereitungen im Code getroffen. Aber mühsam ernährt sich das Eichhörnchen :)

@hubsi5
Copy link

hubsi5 commented Aug 8, 2022

Danke für die Top Arbeit!
Wenn ich helfen könnte, würde ich es ja tun. Leider kenne ich mich da ja Nüsse aus.

@FSys77
Copy link

FSys77 commented Aug 8, 2022

Bei Ahoy hat das @aschiffler sehr schön gemacht:
lumapu/ahoy@7ed5a0a

(1) in der Web UI Page: Das Power Limit persistent setzen
(2) via MQTT non-persistent setzen

Die Lösung find ich sehr gut; durch (1) startet der WR immer in einem definierten Zustand. Durch (2) wird dafür gesorgt, dass das EEPROM vom WR nicht vorzeitig gekillt wird weil pro Tag ein paar hundert mal die Leistung an den Verbrauch angepasst wird (-> Nulleinspeisung).

Nur leider läuft Ahoy bei mir absolut unstabil, kein Vergleich zu OpenDTU (das läuft seit 14 Tagen absolut stabil!)

Ich würde mir wünschen, dass die Leistungsreduzierung (von der Logik her) bei OpenDTU ähnlich umgesetzt wird wie bei Ahoy.

@docklugscheiss
Copy link

Hallo Zusammen, ich schaue hier recht regelmäßig vorbei, um von etwaige Neuerungen hins. des Leistungsbegrenzungsfeatures zu erfahren. Im Verlauf des Mikrocontroller-Forums scheinen ja etliche das Feature bereits intensiv zu nutzen, nur werde ich nicht schlau "wie",

daher Frage in die Runde:

  1. Gibt es die Leistungsbegrenzung bislang nur in Ahoy? Oder auch bereits in OpenDTU?
  2. Ist geplant, dass die Leistungsbegrenzung irgendwann in OpenDTU in der Weboberfläche konfigurierbar sein soll?
  3. So wie ich es verstanden habe, kann es aktuell via MQTT bereist genutzt werden, korrekt? - gibts evtl. irgendwo eine Beschreibung wie das zu bewerkstelligen ist?

VG und Danke im Voraus und sorry für die Rückfragen...

@aschiffler
Copy link

@docklugscheiss

  1. Ahoy: Prototyp; OpenDTU: So wie ich @tbnobody verstanden habe: Geplant
  2. Ich denke, ja
  3. Ja, hier

@docklugscheiss
Copy link

Tausend Dank für die Infos, @aschiffler!

@aschiffler
Copy link

aschiffler commented Aug 16, 2022

@klahus1 @tbnobody
Ich habe nun wie folgt das Setzen des Active Power Limit implementiert. Dazu gekommen ist es durch Rückmeldungen von Nutzern. Ganz kann das noch nicht bestätigt werden. Die Idee ist jedoch mit der Verwendung dieser Defines (s.u.) möglichst vielen die Option zum Test zu geben, damit dass dann einheitlich und verifiziert in Ahoy/OpenDTU einfließen kann.

typedef enum { // ToDo: to be verified by field tests
    AbsolutNonPersistent = 0x0000, // 0
    RelativNonPersistent = 0x0001, // 1
    AbsolutPersistent = 0x0100,    // 256
    RelativPersistent = 0x0101  // 257
} PowerLimitControlType;

EDIT: Habe gerade gesehen, dass ich im "anderen" Repository geschrieben habe. Daher wenn ich implementiert schreibe meine ich im Projekt "Ahoy".

@ntfrnd
Copy link

ntfrnd commented Oct 11, 2022

@wib100 das habe ich ja getan. Egal wer es published, alle anderen sehen es, nur den inverter interessiert es nicht. Oder reden wir aneinander vorbei?

@hubsi5
Copy link

hubsi5 commented Oct 11, 2022

@wib100 das habe ich ja getan. Egal wer es published, alle anderen sehen es, nur den inverter interessiert es nicht. Oder reden wir aneinander vorbei?

Hast du in der Instanz den Topic richtig eingetragen?
image

@ntfrnd
Copy link

ntfrnd commented Oct 11, 2022

Da steht mqtt.0.*
Habe auch nur die eine Instanz.
Kann es sein, dass - entweder OpenDTU oder der Inverter selbst- das aus irgendeinem Grund ignoriert?
Muss mal schauen, ob ich die nächsten Tage mit dem Notebook in die Nähe des Inverterss gehe und mal schaue, was ich auf der seriellen Konsole sehe.

@hubsi5
Copy link

hubsi5 commented Oct 11, 2022

zeige einmal deinen kompletten Objektbaum von mqtt.0

@ntfrnd
Copy link

ntfrnd commented Oct 11, 2022

image
image

Ich habe nur 3 mqtt-Geräte: Ein Tool zum Auslesen meines Gaszählers, OpenDTU und ahoy (inverter).

Wenn ich mit dem MQTT-Explorer das Geschehen beobachte, sehe ich dass der z.B. aus einem iobroker js-Skript gepublishte Wert (200) auch dort ankommt, genauso wie in der MQTT-Objekt-Ansicht.... sieht für mich eigentlich stimmig aus.
image

@hubsi5
Copy link

hubsi5 commented Oct 11, 2022

Meiner sieht so aus
image

Bei mir klappt es jetzt. Habe es aber nur einmal probieren können, da die Sonne weg ist.
Warum hast du eine Ebene mehr? Du Hast die OpenDTU Ebene und dann noch einmal Hoymiles.
Du könntest versuchen eine neue MQTT Instanz zu installieren und dort einen eigenen Port für OpenDTU vergeben.

@ntfrnd
Copy link

ntfrnd commented Oct 11, 2022

Naja, einmal oder zweimal ging es bei mir auch.
Dann habe ich versucht, dies aus dem js-Skript zu tun (analog zu meinen bisherigen ahoy-Versuchen) und dann ging irgendwann nix mehr.

Die Ebene mehr kommt wohl von meinem config-Einstellungen:
image
Mir kommt das übersichtlicher vor. Wobei ich die Nummer des Inverters nicht bräuchte, da ich nur einen habe. Aber das kann man glaube ich auch nicht deaktivieren.

Du könntest morgen mal versuchen, ob es bei Dir mehrmals funktioniert.

@hubsi5
Copy link

hubsi5 commented Oct 11, 2022

Ja bei ahoy läuft mein blockly.
werde morgen OpenDTU testen.
Bei ahoy klappts bei mir aber auch nur mit dem sendMessage2Client Befehl.
Eine direkte Eingabe im Datenpunkt mag er auch dort nicht, warum auch immer.

@ntfrnd
Copy link

ntfrnd commented Oct 12, 2022

So, heute ist alles grau in grau, nur wenige Watt kommen von der Sonne.
Aber trotzdem ist der HM600 schon mal angesprungen und siehe da, alle Tests die ich gestern gemacht habe funktionieren jetzt einwandfrei. Soll heißen: Powerlimit aus js-Skript setzen (SetState), aus dem MQTT-Explorer oder direkt im MQTT-Objektbaum. Der Inverter ändert innerhalb 2 sec. sein Limit, passt die Anzeige auf der Website an und schickts per MQTT - alles so wie es sein soll. Und in allen anderen MQTT-Tools sehe ich den Wert. Prima!

Was gestern los war...keine Ahnung. Ich weiß nur, es lag nicht an meinem MQTT usw.
Man merkt auch, dass der Inverter nun sehr schnell auf die Änderung reagiert, gestern hat es 20....30 sec. oder noch länger gedauert. Einziger Unterschied: gestern hatte er was zu tun (200...300W), heute aktuell nicht wirklich (10...15W).
Mal sehen, wie es heute weitergeht....

@hubsi5
Copy link

hubsi5 commented Oct 12, 2022

Merkwürdig.
Heute geht bei mir gar nichts, plötzlich.
Kannst du die Werte auch direkt im Datenpunkt senden?

@tbnobody
Copy link
Owner

Wenn ihr die Serielle Konsole anzeigt solltet ihr beim setzen folgende Ausgaben sehen:
Received MQTT message on topic: OpenDTU/Hoymiles/....
bzw. darauffolgend dann
Limit Non-Persistent: xx%

Nach dem Abschicken eines neuen Wertes an die MQTT Topic geht im Webinterface der "Current Set Status" auf "Pending". Wenn der Befehl erfolgreich verschickt und vom Wechselrichter bestätigt wurde geht dies zurück auf "Ok". Dies kann aber auch sehr schnell gehen (<4Sek)

@ntfrnd
Copy link

ntfrnd commented Oct 12, 2022

Merkwürdig. Heute geht bei mir gar nichts, plötzlich. Kannst du die Werte auch direkt im Datenpunkt senden?

Ja, das geht.
Wie gesagt heute gehts ab wie nix. Innerhalb 2 sec. sehe ich auch die von @tbnobody genannten Änderungen im Webinterface und die Bestätigung in OpenDTU/Hoymiles/x/status/limit_absolute.

Falls es wieder nicht mehr gehen sollte, werde ich mal die serielle Konsole bemühen müssen.
Was mich wundert: ich hatte schon eine quasi-Nulleinspeisung mittels ahoy realisiert (wenn es mal nicht abgestürzt ist). Über den Tag hatte ich somit rund 50 Limit-Änderungen. Die hat der HM600 problemlos übernommen, da gabs nie Probleme. Kürzestes Änderungsintervall ist 1 min. Deshalb wundert es mich, dass es gestern nach 1...2...3 Änderungen nicht mehr ging.
Ich werde weiter berichten....

@hubsi5
Copy link

hubsi5 commented Oct 12, 2022

Habe eigentlich ales genau gleich. Auch der mqtt-Explorer zeigt die Werte im richtigen Topic an, nur OpenDTU ignoriert das.
Könntest du vom Datenpunkt vielleicht die Einstellungen im Expertenmodus zeigen?

@ntfrnd
Copy link

ntfrnd commented Oct 12, 2022

image

@ntfrnd
Copy link

ntfrnd commented Oct 12, 2022

@hubsi5 Ich glaube dass der ioBroker-Objektbaum nicht immer sauber funktioniert.
Gerade folgende Situation: Mein js-Skript will die Leistung anpassen, sendet mittels SetState den neuen Wert. Das OpenDTU-Webinterface zeigt nach wenigen Sekunden den neuen Wert an. Der MQTT-Explorer, der nebenher mitläuft, zeigt sowohl in OpenDTU/Hoymiles/x/cmd/limit_nonpersistent_absolute den neuen Wunschwert an, als auch den vom Inverter zurück gelieferten neuen Istwert unter OpenDTU/Hoymiles/x/status/limit_absolute. Soweit prima.

Nun läuft ein weiteres Skript, das auf Änderung von OpenDTU/Hoymiles/x/status/limit_absolute reagiert. Hier sehe ich an den Logausgaben, dass dies funktioniert. Mir wird der neue Wert ausgegeben. Soweit auch wie erwartet.

Nun kommts aber: Schaue ich im ioBroker->Objekte->mqtt unter OpenDTU/Hoymiles/x/status/limit_absolute steht noch der alte Wert drin. Zeitstempel letzte Änderung mehrere Stunden her. Einerseits scheint der das nicht mitgekriegt zu haben, aber wie kann ein Skript auf eine Änderung reagieren, die es lt. dieser Ansicht gar nicht gibt???
Dann habe ich oben links mit dem Pfeil händisch aktualisiert, passiert nichts. Mit F5 aktualisiert, passiert nichts. Irgendwie merkwürdig. Plötzlich, über 5 min. später, sehe ich den neuen Wert. Zeitstempel zeigt aktuelle Zeit, nicht die wo tatsächlich geändert wurde. Ich versteh's nicht ganz. Entweder spielt mir der ioBroker->Objekt-Explorer immer wieder mal einen Streich oder ich hab tatsächlich noch ein Problem?

@hubsi5
Copy link

hubsi5 commented Oct 12, 2022

Im Objektbaum geht es bei mri gar nicht. Auch nicht mit ahoy.
Dort sende ich direkt per mqqt und setze den Datenpunkt selbst nicht, da es nicht funktioniert.
Bei OpenDTU geht momentan leider auch das nicht,
Merkwürdig.
Im MQTT-Explorer sieht man aber schön die Werte die gesendet werden

@hubsi5
Copy link

hubsi5 commented Oct 14, 2022

@ntfrnd ich glaub ich hab die Lösung
Der Adapter MQTT Broker/Client hat so seine Probleme und Bugs.
In unserem Fall brauchst du den Broker zu OpenDTU.
Dann musst du noch eine zweite MQTT Instanz anlegen als Client, mit dem selben Port zu OpenDTU.
Und in der Instanz der Clientobjekten kannst du die Werte zu OpenDTU senden.
Das funktioniert bei mir schon ein paar Stunden einwandfrei.
Die Objekte in der Brokerinstanz lässt du in Ruhe.

@ntfrnd
Copy link

ntfrnd commented Oct 15, 2022

@hubsi5 Interessant, d.h. die Objekte in der Broker-Instanz verwendest Du lesend im Skript oder für die Visu.
Und für die wenigen cmd's (Powerlimit setzen, inverter ein-/ausschalten) nutzt Du die Client-Instanz. Hab ich das soweit richtig verstanden?

@hubsi5
Copy link

hubsi5 commented Oct 15, 2022

Im Prinzip kannst du alles von der Client Instanz verwenden.
Der Broker ist nur dazu da, um das ganze am Leben zu halten.
Funktioniert bis jetzt einwandfrei.

@klahus1
Copy link
Author

klahus1 commented Oct 17, 2022

Hallo @tbnobody ,

zur Bestimmung der Leistung der WR hab ich noch etwas beizutragen.
Wenn ich es richtig sehe, bestimmst du die Leistung des WR aus drei von vier Bytes der Hardware Part Number.
Insbesondere bei meinen HM300 reicht es wohl nicht aus, da ist das vierte Byte auch relevant.
Ich besitze einen HM300 der auf 70% (214.2W ~ 100%) gedrosselt ist.
Ein weiterer HM300 (306W ~ 100%) ist nicht gedrosselt.

HM300 (70%)
Hardware Part Number:
269488149 ~ 10 10 10 15

HM300 (100%)
Hardware Part Number:
269488135 ~ 10 10 10 07

Gibt es noch mehr Leute, bei denen eine Drosselung auf 70% o.ä besteht?

@ntfrnd
Copy link

ntfrnd commented Nov 8, 2022

Im Prinzip kannst du alles von der Client Instanz verwenden. Der Broker ist nur dazu da, um das ganze am Leben zu halten. Funktioniert bis jetzt einwandfrei.

Ich hab's wie von Dir beschrieben getestet....läuft seit guten 3 Wochen fehlerfrei. Danke für den Tipp!

@hubsi5
Copy link

hubsi5 commented Nov 8, 2022

Stimmt bei mir auch.
Habe ich auch mit meinen anderen Geräten jetzt so realisiert

@stefan123t
Copy link

@klahus1 Danke für die eingehende Analyse der Leistungslimitierung durch Dich!
Ich vermute das Problem mit der 70%igen Drosselung Deines Wechselrichters läßt sich nur durch Anpassung/Wechsel des GridProfile beheben. Vielleicht schickst Du Deinen Wechselrichter mal an einen der Kollegen mit einer DTU Pro, der könnte dann auch gleich den Upload des GridProfile auf den TX/RX Tespunkten mit tracen ?
Das ist aber m.E. ein eigenes Thema, willst Du dieses Issue dennoch offen lassen ?

@tbnobody
Copy link
Owner

tbnobody commented Dec 2, 2022

Ich mache das Issue hier mal zu, da die Limitierung ja generell erledigt ist.

Copy link

github-actions bot commented Apr 7, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new discussion or issue for related concerns.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests