Wie kann ich den Wert einer ReadOnly Statusvariablen zur Simulation ändern?

Hallo,

ich möchte gerne den Wert einer Statusvariablen (konkret LEVEL Variable eines Homematic-Aktors) zu Simulationszwecken ändern. Im Objektbaum kann ich die Variable ändern wenn ich den Hinweis ‚Diese Variable ist als Nur Lesen markiert. … Wollen Sie trotzdem eine Änderung simulieren?‘ entsprechend bestätige.

Wenn ich es aber durch ein Skript versuche:

SetValueFloat(47111, 0.5);

Dann erhalte ich eine Warning ‚Variable is marked as read-only and cannot be changed‘.:frowning:

Gibt es eine Möglichkeit, die Simulation auch durch ein Skript zu erreichen?

Gruß

Burkhard

Das funktioniert mit RequestAction.

Gesendet von iPhone XS mit Tapatalk

Nicht ganz:)

Ich möchte nur ‚simulieren‘, nicht tatsächlich eine Aktion auslösen. Also genau das machen, als wenn ich im Objektbaum die Variable direkt verändere.

Das geht dann nur wenn Du den Inhalt der Variable auf eine eigene Variable spiegelst, die eigene Variable kannst Du dann auch mit SetValue verändern.

Wie gesagt, ich möchte eine Änderung/Aktualisierung der Statusvariablen simulieren. So wie ich es im Objektbaum kann. Dazu suche ich eine Möglichkeit.

Das ist wahrscheinlich zu hoch für mich. [emoji6]

Wenn ich ne Variable nicht schalten, sondern nur simulieren möchte, dann nehme ich halt eine simulierte Teilumgebung (im Objektbaum angelegt), mit der ich beliebig spielen kann.
Ich mache das zumindest so.

Bin gespannt, was hier die Lösung ist.

Es gibt keine Lösung. Geht nicht.

Habe gerade die Lösung gefunden: Datenaustausch — IP-Symcon :: Automatisierungssoftware

Über JSONRPC funktioniert es:

$rpc = new JSONRPC("http://user:password@127.0.0.1:3777/api/");
$rpc->SetValue(38809, 18.5);

Da frage ich mich allerdings, warum es direkt über SetValue nicht funktioniert:eek:

Genau das ist der Trick, den man nutzen kann. Bei PHP kommt die Fehlermeldung, da die meisten Kunden versuchen über SetValue zu schalten. (JSON-RPC nutzen die wenigsten ;)) Dies ist aber bekannterweise nicht der korrekte weg. Demnächst sollten wir die Fehlermeldung umbauen, sodass wir Werbung für RequestAction dort machen :slight_smile:

paresy

Bahnhof? :confused:

RequestAction ist offenbar das, was die Nutzer eigentlich wollten, wenn sie mit SetValue auf die Statusvariable zugreifen?
Und was macht der Umweg über JSONRPC dann anders?

Verwirrt-ratlose Grüße
Volker

Der Umweg über die JSON API erlaubt das ändern von Statusvariablen (von Geräten/Modulen) per Skript, OHNE die dahinterliegende Modul-Funktion auszuführen (also die Aktion nur simulieren). Wo hingegen es bei SetValue im Skript einen Fehler gibt, wenn man damit versucht eine Statusvariable zu ändern.

Ansonsten geht es nur über die IPS-Console (nachdem man den Hinweis mit dem Simulieren bestätigt hat) - nicht aber per Skript.

RequestAction im Skript ändert die Variable und ruft die dahinterliegende Modul-Funktion auf (wie bei einer Bedienung übers WebFront) - aber Burkhard will nur simulieren, nicht wirklich was auslösen/schalten.

Viele Grüße,
Chris

Danke, Chris! Den Begriff der Simulation hatte ich vorher im GUI noch nicht wahrgenommen.

Und mit der „Simulation“ könnte man dann Skripte o.ä. testen, die auf diese Werte triggern?

Genau. Das kann man damit machen.

Ich will es aber genaugenommen für einen anderen Fall anwenden. Und zwar geht es um den HmIp-BROLL und HmIp-FROLL, die Homematic Rollladenaktoren. Sie haben leider das (Firmware)Problem, dass bei manueller Bedienung der Aktoren die LEVEL Variable des Kanals 4 nicht nachgeführt wird. Sie springt - je nach Fahrtrichtung - auf 0.0 bzw. 1.0 und gibt dann nicht die tatsächliche Position wieder.:eek:

Die zugleich gelieferte LEVEL Variable des Kanals 3 hat dagegen den korrekten Wert. Diesen Fehler will ich solange es noch keine Behebung gibt dadurch umgehen, dass ich den Wert von Kanal 3 bei Aktualisierung in den Kanal 4 schreibe.

Gruß

Burkhard

Hi Burkhard!

Ist hier auch eine zusätzliche Abfrage (temporär) mit HM_RequestStatus unwirksam? Oder ist das allgemein ein Fehler in HM mit dem Aktor?

Viele Grüße,
Chris

2 x ja :wink:

Das Thema wird auch im HM Forum diskutiert: HmIP-BROLL Probleme mit der Firmware 1.6.2

LG Burkhard

Dies ist übrigens das Skript, mit dem ich den Fehler des HmIP-BROLLS umgehe:

EDIT: ich habe das Skript noch etwas erweitert

  • Unterstützung auch von LEVEL_2 Variablen (Lamellen)
  • Unterstützung auch von Mehrfachaktoren (HmIPW-DRBL4)
  • Unterstüzung von Fernzugriffspassworten mit Sonderzeichen
<?php
// das Skript dient zur Umgehung eines "Fehlers" bei HmIp-BROLL und HmIp-FROLL Aktoren
// es sollte gestriggert werden, wenn die LEVEL Variable(n) des Statuskanals (z.B.3) aktualisiert wird.
// es wird dann der Wert in den Aktorkanal (z.B.4) geschrieben

declare(strict_types=1);

//Zugriff über RPC. Siehe https://www.symcon.de/service/dokumentation/entwicklerbereich/datenaustausch/
//'USER' und 'PASSWORD' sind zu setzen, wenn der Fernzugriff aktiviert ist
const USER = '';      //Lizenz-Benutzernamen
const PASSWORD = ''  //Fernzugriff Kennwort
const LOGGING_ACTIVE = true;

if ($_IPS['SENDER'] !== 'Variable'){
    echo 'Das Skript kann nur von einer Variablen getriggert werden.';
    return;
}

$ident = IPS_GetObject($_IPS['VARIABLE'])['ObjectIdent'];

if (!in_array($ident, ['LEVEL', 'LEVEL_2'])){
    echo 'Das Skript kann nur von einer LEVEL oder LEVEL_2 Variablen getriggert werden.';
    return;
}

//wir warten 0.5 Sekunden, damit der Wert des Aktorkanals ebenfalls angekommen ist
usleep(500000);

if (LOGGING_ACTIVE){
    IPS_LogMessage(__file__, sprintf('Variable: #%s, Value: %s', $_IPS['VARIABLE'], GetValueFloat($_IPS['VARIABLE'])));
}

//wir suchen den zugehörigen Wert des AKtorkanals ...
//die eigene Instanz suchen
$instanceID_status = IPS_GetObject($_IPS['VARIABLE'])['ParentID'];

//die HM Addresse der Status Instanz auslesen (als Wertepaar)
$address_status = explode(':', IPS_GetProperty($instanceID_status, 'Address'));

//dann lautet die Adresse des AKtorkanals:
$address_aktor_ch = (int) $address_status[1] + 1;
$address_aktor = [$address_status[0], $address_aktor_ch];

//nach der Instanz des Aktorkanals im Objektbaum suchen
// alle HM Devices durchgehen
$instanceID_aktor = 0;

foreach (IPS_GetInstanceListByModuleID('{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}') as $instanceID){
    if (IPS_GetProperty($instanceID, 'Address') === implode(':', $address_aktor)){
        //Instanz gefunden
        $instanceID_aktor = $instanceID;
        break;
    }
}

if ($instanceID_aktor === 0){
    echo sprintf('Es wurde keine Homematic-Instanz mit der Adresse %s gefunden', implode(':', $address_aktor));
    return;
}

//wenn die Instanz gefunden wurde, dann ID der LEVEL Variablen ermitteln

$levelId_aktor = 0;

if ($instanceID_aktor !== 0){
    $levelId_aktor = IPS_GetObjectIDByIdent($ident, $instanceID_aktor);
} else {
    echo sprintf('Die Aktor Instanz %s hat kein Objekt mit dem Ident %s', $instanceID_aktor_ch, 'LEVEL');
    return;
}

//wenn die LEVEL Variable gefunden wurde und der neue Wert ungleich dem alten ist, dann den neuen Wert setzen

$status_ch_Value = GetValueFloat($_IPS['VARIABLE']);
$aktor_ch_Value = GetValueFloat($levelId_aktor);
if (LOGGING_ACTIVE){
    IPS_LogMessage(__file__, sprintf('Der Vergleich von Kanal %s (%s) mit %s (%s) wird durchgeführt', $address_status[1], $status_ch_Value, $address_aktor_ch, $aktor_ch_Value));
}

if ($status_ch_Value !== $aktor_ch_Value){
    if (USER !== ''){
        $rpc = new JSONRPC('http://' . USER . ':' . urlencode(PASSWORD) . '@127.0.0.1:3777/api/');
    } else {
        $rpc = new JSONRPC('http://127.0.0.1:3777/api/');
    }
    if (LOGGING_ACTIVE){
        IPS_LogMessage(__file__, sprintf('Der alte Wert von Kanal %s (#%s: %s) wird durch den neuen Wert ersetzt (#%s: %s)', $address_aktor_ch, $levelId_aktor, $aktor_ch_Value, $_IPS['VARIABLE'], $status_ch_Value));
    }

    $rpc->SetValueFloat($levelId_aktor, $status_ch_Value);
}