Statusabfrage Modbus Instanz

Hallo zusammen,

ich habe leider über die Suche und in der Doku nichts gefunden, oder vll. falsch gesucht.
Ist es möglich den Status einer Modbus Instanz abzufragen, bevor man darauf Daten liest/schreibt?

Danke im Voraus.
Grüße weazel


08.09.2020, 20:57:11 | ScriptEngine         | Result for Event 22376
<br />
<b>Warning</b>:  Zeitüberschreitung beim Warten auf Antwort in <b>/var/lib/symcon/scripts/45781.ips.php</b> on line <b>6</b><br />
<br />
08.09.2020, 20:57:16 | FlowHandler          | Kann Daten nicht zur Instanz #16476 weiterleiten: TransactionID stimmt nicht überein

Hi,

https://www.symcon.de/service/dokumentation/befehlsreferenz/instanzenverwaltung/ips-getinstance/

Gruß

:banghead: Danke, fürs betreute suchen

Doch noch eine weitere Frage im Speziellen zu einem ModBus Gerät (Typ in IP-Symcon: „ModBus Adresse“).
Bei welcher Instanz(en) muss ich den ‚InstanceStatus‘ 102 abfragen, damit ich von der Adresse die Daten korrekt lesen kann? Aktuell erhalte ich vom FlowHandler die Meldung, dass er die Daten nicht an das „ModBus Gateway“ leiten kann, da die TransactionID nicht übereinstimmt. Im meinem Skript frage ich aber explizit den ‚InstanceStatus‘ vom „ModBus Gateway“ ab. Reicht es nur den Status des ModBus Gerätes sprich ModBus Adresse abzufragen?

Hast du evtl. mehrere Geräte am selben RS485 Strand welche die gleich GeräteID haben? Denn der Fehler bedeutet, dass das Gerät nicht korrekt auf unsere Anfrage antwortet.

Welche IPS Version nutzt du?

paresy

Ich nutze zwei Solar-Log Base 15 Geräte mit unterschiedlichen IP-Adressen. Der Fehler tritt ja nicht immer auf und auch nur bei einem Gerät (bis zu 5x mal am Tag), welches über VPN angebunden ist. Dieses hat etwas erhöhte Latenzen ~24ms, aber grundsätzlich sehr stabil und kein Packet Loss. Wahrscheinlich sind die Fehler auf kurzzeitige Verbindungsabbrüche zurückzuführen. Ich würde einfach gerne diese Fehler im Skript abfangen.

Es gibt von diesen je 6 Adressen nur 2 Adressen die minütlich abgefragt werden, der Rest einmal am Tag
Jedes Gerät ist wie folgt aufgebaut:

<< 6x Modbus Device (Typ: ModBus Address) >> — << 1x Splitter Instanz (Typ:ModBus Gateway) >> — << 1x I/O Instanz (Typ: Client Socket) >>


<?php

$ModBus_Gateway = IPS_GetInstance(16476);

if($ModBus_Gateway['InstanceStatus'] == 102){
  ModBus_RequestRead(39226); // Ertragserfassung - Live
  ModBus_RequestRead(11946); // Ertragserfassung - Heute
} else {
  IPS_LogMessage("[Skript: " . $_IPS['SELF'] . "] SolarLog - every minute", "ModBus Gateway ist nicht aktiv");
}

IP-Symcon 5.4, Docker, 04.09.2020, a6230799a923

Gestern habe ich zum ersten Mal diese Meldung erhalten. Wie muss ich das Skript anpassen, damit sichergestellt ist, dass ohne Fehler Daten gelesen werden können?

22.09.2020, 17:37:07 | FlowHandler          | Kann Daten nicht zur Instanz #16476 weiterleiten: Waiting for buffer usage timed out

Danke im Voraus.
Gruß weazel

Gar nicht.
Wie willst du Vorhersagen treffen, ob ein Gerät rechtzeitig antwortet?!
In die Zukunft schauen geht auch mit Symcon nicht.
Michael

Hallo Michael, da hast du natürlich vollkommen Recht mit diesem Fehler. Gibt es dann ein eine Möglichkeit den TimeOut anzupassen?

Ich wollte eigentlich eine Lösung für folgende Problematik:

Das Timeout ist fix in den Modul von Symcon, da kannst du nichts einstellen.
Du kannst aber den bool Rückgabewert der Instanz-Funktionen auswerten.
Und z.b. den Befehl noch ein zweites Mal senden. ModBus_WriteRegister — IP-Symcon :: Automatisierungssoftware
Michael

Du erstellst folgendes Script mit einem zyklischen Ereignis:

 <?
foreach(IPS_GetChildrenIDs($_IPS['SELF']) as $item){   // alle Unterobjekte
    $id_info = IPS_GetObject($item);
    $id_typ = $id_info['ObjectType'];
    if ($id_typ == 2){                                      // nur bei Variablen
        $id_adr = $id_info['ObjectInfo'];
        $ping = Sys_Ping($id_adr, 1000);             // Ping max. 1 Sek. warten
        if($_IPS == "Execute") {                     // zum Testen
            echo "IP: $id_adr 
";
            echo "Ping: " .(int)$ping. "

";
        }
        SetValue($item, $ping);                      // Ping-Ereignis speichern
    }
}
?> 

Unter diesem Script erstellst Du eine Boolean Variable, in dem Beschreibungsfenster steht die IP Adresse Deiner zu überwachenden Modbus-IP-Adresse. Geht natürlich auch mit zB der Handyadresse in Deinem WLAN-Netz. Das stellt dann fest ob Du zu Hause bist.
Bei mir im Bild ein Pokeys57E
Gruß Helmut

Danke euch beiden, jetzt weiß ich in welche Richtung es gehen muss.

Ich hätte nochmal eine Frage hierzu. Seit dem letzten Update (IP-Symcon 5.5, Docker, 13.03.2021, 49b4a2f13b56) habe ich das Problem, dass sich der Status des Modus Gateways nicht mehr sauber auslesen lässt. Ich bekomme immer den InstanceStatus 102 zurück obwohl das Gateway de facto nicht verbunden ist (testweise einfach mal den Stecker gezogen). Gibt es denn keine Möglichkeit dies zu optimieren?

Aktuell versuche ich es so:

$ModBus_IO = IPS_GetInstance(20186);
if($ModBus_IO['InstanceStatus'] == 102){
    DM_UpdateStatus(23069);
    $Online_State = GetValueBoolean(46619);
    if($Online_State == true) {
        ModBus_RequestRead(39226);
        ModBus_RequestRead(11946);
        SetValueFloat(53774, GetValue(15562) * $preis_pro_kwh);
    } else {
        IPS_LogMessage("[Skript: " . $_IPS['SELF'] . "] SolarLog - every minute", "ModBus I/O Instanz ist offline");
    }
 
} else {
    IPS_LogMessage("[Skript: " . $_IPS['SELF'] . "] SolarLog - every minute", "ModBus I/O Instanz ist nicht aktiv");
    IPS_SetProperty($ModBus_IO['InstanceID'], "Open", false);
    IPS_ApplyChanges($ModBus_IO['InstanceID']);
    IPS_LogMessage("[Skript: " . $_IPS['SELF'] . "] SolarLog - every minute", "ModBus I/O Instanz wurde deaktiviert");
    IPS_SetProperty($ModBus_IO['InstanceID'], "Open", true);
    IPS_ApplyChanges($ModBus_IO['InstanceID']);
    IPS_LogMessage("[Skript: " . $_IPS['SELF'] . "] SolarLog - every minute", "ModBus I/O Instanz wurde aktiviert");  
}

Du willst den Zustand an der I/O Instanz auslesen. Die Gateway Instanz hat eigentlich immer den 102er.

paresy

@paresy die Beschreibung der Variable war noch falsch. Hinter der ID versteckt sich aber die I/O Instanz (Client Socket). Diese Instanz erkennt aber nicht, dass die Socket Verbindung nicht mehr auf gebaut ist und steht somit immer auf 102. Wenn ich den Socket deaktiviere und aktivere funktioniert der Socket wieder. Hab das Skript oben nochmal angepasst, aber wenn der Client Socket den Verbindungsabbruch nicht erkennte wird es glaube ich schwierig. Gibt es weitere Debug-Möglichkeiten?