HomeHub 4.1
Moderator: Co-Administratoren
-
- Beiträge: 327
- Registriert: 28.10.2013, 18:38
- Hat sich bedankt: 20 Mal
- Danksagung erhalten: 46 Mal
Re: HomeHub 4.1
@log22: kannst du die "HmIP-BBL.php" unter components kopieren und als "HmIP-BBL-2.php" speichern. Darin den Funktionsnamen "HmIP_BBL($component)" durch "HmIP_BBL_2($component)" anpassen.
Im Ordner ja wäre die "script.js.php" noch anzupassen, in Zeile 214 noch zusätzlich einfügen "case 'HmIP-BBL-2':".
Wenn das passt, wird es übernommen.
Ggf. Kann jemand anderes es kurz prüfen und bei GitHub bereitstellen. Danke
Im Ordner ja wäre die "script.js.php" noch anzupassen, in Zeile 214 noch zusätzlich einfügen "case 'HmIP-BBL-2':".
Wenn das passt, wird es übernommen.
Ggf. Kann jemand anderes es kurz prüfen und bei GitHub bereitstellen. Danke
- gnom
- Beiträge: 358
- Registriert: 23.06.2022, 05:33
- System: Alternative CCU (auf Basis OCCU)
- Wohnort: Brühl
- Hat sich bedankt: 28 Mal
- Danksagung erhalten: 61 Mal
Re: HomeHub 4.1
@log22 - habe die Änderungen mal in das ZIP gepackt. Kannst Du das mal checken, habe das gerät nicht
@steingarten - wollte das mal ausprobieren/üben, habe 2 pull requests geschickt. Wenn log22 das bestätigt, könnte das ja gemerged werden
Gruss, Chris
don't fear dying, fear not living (Marc Aurel)
strebst Du nach Respekt, handle selber danach (unbekannt)
2 Systeme:
- Home: Debmatic & IOBroker unter Debian 12 auf Laptop, HM-IP, Asksin++ (HB-+Innogy Devices), Zigbee, Tasmota/Shelly
- WE-Shed: Debmatic & IOBroker unter Debian 11 auf Laptop, HM classic, Asksin++ (HB-+Innogy Devices), RF, Tasmota/Shelly
don't fear dying, fear not living (Marc Aurel)
strebst Du nach Respekt, handle selber danach (unbekannt)
2 Systeme:
- Home: Debmatic & IOBroker unter Debian 12 auf Laptop, HM-IP, Asksin++ (HB-+Innogy Devices), Zigbee, Tasmota/Shelly
- WE-Shed: Debmatic & IOBroker unter Debian 11 auf Laptop, HM classic, Asksin++ (HB-+Innogy Devices), RF, Tasmota/Shelly
-
- Beiträge: 327
- Registriert: 28.10.2013, 18:38
- Hat sich bedankt: 20 Mal
- Danksagung erhalten: 46 Mal
-
- Beiträge: 15
- Registriert: 25.10.2023, 10:57
- System: CCU
- Hat sich bedankt: 1 Mal
- Danksagung erhalten: 1 Mal
Re: HomeHub 4.1
Ich hätte noch eine Frage:
Da ich die Rauchmelder HmIP-SWSD auch für Alarmfunktionen nutze, würde ich gern über die Oberfläche den Alarm aus- ( oder auch an) schalten können.
Aktuell wird nur der case 'SMOKE_DETECTOR_ALARM_STATUS' abgebildet.
Kann man das in der script.js.php hinzufügen?
Da ich die Rauchmelder HmIP-SWSD auch für Alarmfunktionen nutze, würde ich gern über die Oberfläche den Alarm aus- ( oder auch an) schalten können.
Aktuell wird nur der case 'SMOKE_DETECTOR_ALARM_STATUS' abgebildet.
Kann man das in der script.js.php hinzufügen?
- gnom
- Beiträge: 358
- Registriert: 23.06.2022, 05:33
- System: Alternative CCU (auf Basis OCCU)
- Wohnort: Brühl
- Hat sich bedankt: 28 Mal
- Danksagung erhalten: 61 Mal
Re: HomeHub 4.1
da müßten die Coder ran
Als workaround kannst Du aber entweder über eine SysVar oder in der Art vorgehen.
Die Variable kannst Du dann ja in HH leicht einbinden und umschalten.
Das aber von dieser Nutzung regelmäßig von den Experten tunlichst abgeraten wird, weißt Du?
Ich hätte auch keine Lust, alle zwei Jahre oder so fest eingebaute Lithium-Batterien auszutauschen - nur einer der threads dazu. Auch z.B. das häufige scharf/unscharf schalten des Alarms kostet Strom.
Deine Entscheidung
Kap 10 im Gerätehandbuch.
![Wink :wink:](./images/smilies/icon_wink.gif)
Als workaround kannst Du aber entweder über eine SysVar oder in der Art vorgehen.
Die Variable kannst Du dann ja in HH leicht einbinden und umschalten.
Das aber von dieser Nutzung regelmäßig von den Experten tunlichst abgeraten wird, weißt Du?
Ich hätte auch keine Lust, alle zwei Jahre oder so fest eingebaute Lithium-Batterien auszutauschen - nur einer der threads dazu. Auch z.B. das häufige scharf/unscharf schalten des Alarms kostet Strom.
Deine Entscheidung
![Smile :)](./images/smilies/icon_smile.gif)
Kap 10 im Gerätehandbuch.
Ob man diese Option per default in HH einbauen sollte - imho eher neinDie Batterielebensdauer von typisch 10 Jahren kann nur
unter folgenden Bedingungen erreicht werden:
•
Pro Jahr dürfen max. 52 Funktionstests durchge-
führt werden und ein Vollalarm für 60 Sekunden
auftreten.
•
Während der gesamten Laufzeit dürfen eine In-
betriebnahme, zwei Reichweitentests sowie ein
einmaliges Anlernen an eine Gruppe durchge-
führt werden.
Gruss, Chris
don't fear dying, fear not living (Marc Aurel)
strebst Du nach Respekt, handle selber danach (unbekannt)
2 Systeme:
- Home: Debmatic & IOBroker unter Debian 12 auf Laptop, HM-IP, Asksin++ (HB-+Innogy Devices), Zigbee, Tasmota/Shelly
- WE-Shed: Debmatic & IOBroker unter Debian 11 auf Laptop, HM classic, Asksin++ (HB-+Innogy Devices), RF, Tasmota/Shelly
don't fear dying, fear not living (Marc Aurel)
strebst Du nach Respekt, handle selber danach (unbekannt)
2 Systeme:
- Home: Debmatic & IOBroker unter Debian 12 auf Laptop, HM-IP, Asksin++ (HB-+Innogy Devices), Zigbee, Tasmota/Shelly
- WE-Shed: Debmatic & IOBroker unter Debian 11 auf Laptop, HM classic, Asksin++ (HB-+Innogy Devices), RF, Tasmota/Shelly
-
- Beiträge: 400
- Registriert: 19.06.2017, 09:24
- Hat sich bedankt: 20 Mal
- Danksagung erhalten: 70 Mal
Re: HomeHub 4.1
Was heißt laienhaft, ich würde sagen, Du hast da schon gewaltig was aus dem Boden gestampft.steingarten hat geschrieben: ↑24.05.2024, 10:26Ich freue mich auf jegliche Verbesserung meines hinzugefügten doch in viele stellen laienhaften Codes.
Ich habe die interface.php so umgebaut, dass man die einzelnen Funktionen auch direkt aus anderen Skripten heraus aufrufen kann.
Auf den ersten Blick funktioniert bei mir alles, müsste aber trotzdem unbedingt noch ausgiebig in verschiedenen Konstellationen getestet werden.
Code: Alles auswählen
<?php
// CCU User -> Falls authentifizierung notwendig, bitte in "config/config.php" wie folgt eintragen:
/*
$ccu_user = ""; // in die Anführungsstriche den Benutzernamen
$ccu_pass = ""; // in die Anführungsstriche das dazugehörige Kennwort
*/
require_once(__DIR__.'/config/config.php');
// Konfiguration als Array aus Config-Variablen zusammenbauen
if (!is_array($ccu)) $ccu = array(
'host' => $homematicIp,
'https' => !empty($ccu_https),
'user' => $ccu_user,
'pw' => $ccu_pass
);
// --
$ccu['url'] = "http".(!empty($ccu['https']) ? 's' : '')."://" . $ccu['host'] . ":".(!empty($ccu['https']) ? '4' : '')."8181/remoteskript.exe";
function ccu_remote($ccu, $ccu_request, $plain_result = false) {
// Als indikator für die Rückgabe, um den Overhead zu filtern
$delimeter = '---'.uniqid('hm-end').'---';
if (!$plain_result) $ccu_request = $ccu_request."\nWriteLine(\"".$delimeter."\");";
// curl Anfrage bauen
$curl = curl_init($ccu['url']);
if (!empty($ccu['user']) and !empty($ccu['pw'])) curl_setopt($curl, CURLOPT_USERPWD, $ccu['user'].':'.$ccu['pw']);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $ccu_request);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
if (!empty($ccu['https'])) {
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
}
$content = curl_exec($curl);
curl_close($curl);
#var_dump($content);
// Trenne Rückgabe vom Overhead
if (!$plain_result) $content = strstr($content, $delimeter, true);
// Konvertiere XML kritische Zeichen in HTML-Format # Maskierung sollte eigentlich nicht notwendig sein.
#$content = str_replace('<', '<', $content); # Ggf. sollten wir uns eine elegantere Variante überlegen, RegEx oder ähnliches,
#$content = str_replace('>', '>', $content); # oder im HM-Skript mit .replace() maskieren.
#$content = str_replace('*<*', '<', $content);
#$content = str_replace('*>*', '>', $content);
return $content;
}
// ALLE STATES
if (strpos($_SERVER['QUERY_STRING'], "statelist.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_statelist($ccu, isset($_GET['debug']));
}
function api_statelist($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
WriteLine("<stateList>");
integer show_remote = 1;
integer show_internal = 1;
string id;
! Alle Datenpunkte durchlaufen
!foreach(id, dom.GetObject(ID_DEVICES).EnumUsedIDs()) {
foreach(id, root.Devices().EnumUsedIDs()) {
! Einzelnen Datenpunkt holen
object oDevice = dom.GetObject(id);
integer iDevInterfaceId = oDevice.Interface();
object oDeviceInterface = dom.GetObject(iDevInterfaceId);
! Namen und Wert des Elements ausgeben - geht nicht -> logged info
boolean bDevReady = oDevice.ReadyConfig();
string sDevInterface = oDeviceInterface.Name();
string sDevType = oDevice.HssType();
WriteLine("<device name='" # oDevice.Name() #"' ise_id='" # oDevice.ID() # "' unreach='false' sticky_unreach='false' config_pending='false'>");
string cid;
integer x = 0;
! Alle Datenpunkte durchlaufen
foreach(cid, oDevice.Channels()) {
! Einzelnen Kanal holen
var ch = dom.GetObject(cid);
! Namen und Wert des Kanals ausgeben
Write("<channel name='"#ch.Name()#"' ise_id='"#ch.ID()#"' direction='' index='"# x #"'");
if (false == ch.Internal()) {
Write(" visible='" # ch.Visible() # "'");
} else {
Write(" visible=''");
}
Write(" ready_config='' operate='");
if (false == ch.Internal()) {
if( ch.UserAccessRights(iulOtherThanAdmin) == iarFullAccess ) {
Write("true");
} else {
Write("false");
}
}
Write("'>");
WriteLine("");
string did;
! Alle Datenpunkte durchlaufen
foreach(did, ch.DPs().EnumUsedIDs()) {
var dp = dom.GetObject(did);
string dpA = dp.Name().StrValueByIndex(".", 2);
if( (dpA != "ON_TIME") && (dpA != "INHIBIT") && (dpA != "CMD_RETS") && (dpA != "CMD_RETL") && (dpA != "CMD_SETS") && (dpA != "CMD_SETL") ) {
WriteLine("<datapoint name='"#dp.Name()#"' type='" # dp.Name().StrValueByIndex(".", 2) #"' ise_id='"#dp.ID()#"' state='"#dp.Value()#"' value='"#dp.Value()#"' valuetype='"#dp.ValueType()#"' valueunit='" # dp.ValueUnit() # "' timestamp='" # dp.Timestamp().ToInteger()# "' operations='"#dp.Operations()#"'/>");
}
}
WriteLine("</channel>");
x=x+1;
}
WriteLine("</device>");
}
WriteLine("</stateList>");
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// ALLE STATES
if (strpos($_SERVER['QUERY_STRING'], "statelistall.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_statelistall($ccu, isset($_GET['debug']));
}
function api_statelistall($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
WriteLine("<stateList>");
integer show_remote = 1;
integer show_internal = 1;
string id;
! Alle Datenpunkte durchlaufen
!foreach(id, dom.GetObject(ID_DEVICES).EnumUsedIDs()) {
foreach(id, root.Devices().EnumUsedIDs()) {
! Einzelnen Datenpunkt holen
object oDevice = dom.GetObject(id);
integer iDevInterfaceId = oDevice.Interface();
object oDeviceInterface = dom.GetObject(iDevInterfaceId);
! Namen und Wert des Elements ausgeben - geht nicht -> logged info
boolean bDevReady = oDevice.ReadyConfig();
string sDevInterface = oDeviceInterface.Name();
string sDevType = oDevice.HssType();
WriteLine("<device name='" # oDevice.Name() #"' ise_id='" # oDevice.ID() # "' unreach='false' sticky_unreach='false' config_pending='false'>");
string cid;
integer x = 0;
! Alle Datenpunkte durchlaufen
foreach(cid, oDevice.Channels()) {
! Einzelnen Kanal holen
var ch = dom.GetObject(cid);
! Namen und Wert des Kanals ausgeben
Write("<channel name='"#ch.Name()#"' ise_id='"#ch.ID()#"' direction='' index='"# x #"' timestamp='" # ch.LastTimestamp().ToInteger()# "'");
if (false == ch.Internal()) {
Write(" visible='" # ch.Visible() # "'");
} else {
Write(" visible=''");
}
Write(" ready_config='' operate='");
if (false == ch.Internal()) {
if( ch.UserAccessRights(iulOtherThanAdmin) == iarFullAccess ) {
Write("true");
} else {
Write("false");
}
}
Write("'>");
WriteLine("");
string did;
! Alle Datenpunkte durchlaufen
foreach(did, ch.DPs()) {
var dp = dom.GetObject(did);
string dpA = dp.Name().StrValueByIndex(".", 2);
if( (dpA != "ON_TIME") && (dpA != "INHIBIT") && (dpA != "CMD_RETS") && (dpA != "CMD_RETL") && (dpA != "CMD_SETS") && (dpA != "CMD_SETL") ) {
WriteLine("<datapoint name='"#dp.Name()#"' type='" # dp.Name().StrValueByIndex(".", 2) #"' ise_id='"#dp.ID()#"' state='"#dp.Value()#"' value='"#dp.Value()#"' valuetype='"#dp.ValueType()#"' valueunit='" # dp.ValueUnit() # "' timestamp='" # dp.LastTimestamp().ToInteger()# "' operations='"#dp.Operations()#"'/>");
}
}
WriteLine("</channel>");
x=x+1;
}
WriteLine("</device>");
}
WriteLine("</stateList>");
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// ALLE DEVICES
if (strpos($_SERVER['QUERY_STRING'], "devicelist.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_devicelist($ccu, isset($_GET['debug']));
}
function api_devicelist($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
WriteLine("");
string PARTNER_INVALID = "65535";
integer show_internal = "} 1 {";
integer show_remote = "} 1 {";
WriteLine("<deviceList>");
string id;
! Alle Datenpunkte durchlaufen
foreach(id, dom.GetObject(ID_DEVICES).EnumUsedIDs()) {
! foreach(id, root.Devices().EnumUsedIDs()) {
! Einzelnen Datenpunkt holen
object oDevice = dom.GetObject(id);
integer iDevInterfaceId = oDevice.Interface();
object oDeviceInterface = dom.GetObject(iDevInterfaceId);
! Namen und Wert des Elements ausgeben - geht nicht -> logged info
boolean bDevReady = oDevice.ReadyConfig();
string sDevInterface = oDeviceInterface.Name();
string sDevType = oDevice.HssType();
Write("<device name='" # oDevice.Name() #"' address='" # oDevice.Address() # "' ise_id='" # oDevice.ID() # "' interface='" # sDevInterface # "' device_type='" # sDevType # "' ready_config='" # bDevReady # "' >");
WriteLine("");
string cid;
integer x = 0;
! Alle Datenpunkte durchlaufen
foreach(cid, oDevice.Channels()) {
! Einzelnen Kanal holen
var ch = dom.GetObject(cid);
! Namen und Wert des Kanals ausgeben
!WriteLine(ch.Name() # ": " # ch.ID());
string sChnPartnerId = ch.ChnGroupPartnerId();
if (PARTNER_INVALID == sChnPartnerId) { sChnPartnerId = ""; }
Write("<channel name='"#ch.Name()#"' type='"#ch.ChannelType()#"' address='"#ch.Address()#"' ise_id='"#ch.ID()#"' direction='' parent_device='"#ch.Device()#"' index='"# x #"' group_partner='" # sChnPartnerId # "' aes_available='' transmission_mode=''");
if (false == ch.Internal()) {
Write(" visible='" # ch.Visible() # "'");
} else {
Write(" visible=''");
}
Write(" ready_config='' operate='");
if (false == ch.Internal()) {
if( ch.UserAccessRights(iulOtherThanAdmin) == iarFullAccess ) {
Write("true");
} else {
Write("false");
}
}
Write("' />");
WriteLine("");
x=x+1;
}
WriteLine("</device>");
}
WriteLine("</deviceList>");
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// ALLE PROGRAMME
if (strpos($_SERVER['QUERY_STRING'], "programlist.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_programlist($ccu, isset($_GET['debug']));
}
function api_programlist($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
WriteLine("<programList>");
string id;
! Alle Datenpunkte durchlaufen
foreach(id, dom.GetObject(ID_PROGRAMS).EnumUsedIDs()) {
! Einzelnen Datenpunkt holen
var sysProgram = dom.GetObject(id);
! Namen und Wert des Elements ausgeben - speziell -> operate=''
Write("<program id='" # sysProgram.ID() # "' active='" # sysProgram.Active() # "' timestamp='" # sysProgram.ProgramLastExecuteTime().ToInteger() # "' name='" # sysProgram.Name() # "' description='" # sysProgram.PrgInfo() # "' visible='" # sysProgram.Visible() # "' operate='");
object o_sysVar = dom.GetObject(sysProgram.ID());
if( o_sysVar.UserAccessRights(iulOtherThanAdmin) == iarFullAccess ) {
Write("true'/>");
} else {
Write("false'/>");
}
WriteLine("");
}
WriteLine("</programList>");
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// ALLE SYSTEMVARIABLEN
if (strpos($_SERVER['QUERY_STRING'], "sysvarlist.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_sysvarlist($ccu, isset($_GET['debug']));
}
function api_sysvarlist($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
WriteLine("<systemVariables>");
string id;
! Alle Datenpunkte durchlaufen
foreach(id, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs()){
! Einzelnen Datenpunkt holen
var oSysVar = dom.GetObject(id);
! Namen und Wert des Elements ausgeben - fehlt -> visible
Write("<systemVariable name='" # oSysVar.Name() # "' ");
if (oSysVar.ValueSubType() == 6) {
Write("variable='" # oSysVar.AlType() # "' ");
} else {
Write("variable='" # oSysVar.Variable() # "' ");
}
Write("value='" # oSysVar.Value() # "' ");
Write("value_list='");
if (oSysVar.ValueType() == 16) {
Write( oSysVar.ValueList());
}
Write("' ise_id='"#oSysVar.ID()#"' ");
Write(" min='");
if (oSysVar.ValueType() == 4) {
Write( oSysVar.ValueMin());
}
Write("' max='");
if (oSysVar.ValueType() == 4) {
Write( oSysVar.ValueMax());
}
Write("' ");
Write("unit='" # oSysVar.ValueUnit() # "' type='" # oSysVar.ValueType() # "' subtype='" # oSysVar.ValueSubType() # "' logged='" # oSysVar.DPArchive() # "' visible='" # oSysVar.Visible() # "' timestamp='" # oSysVar.Timestamp().ToInteger()# "' value_name_0='" # oSysVar.ValueName0() # "' value_name_1='" # oSysVar.ValueName1() # "' info='" # oSysVar.DPInfo() # "'/>\n");
}
WriteLine("</systemVariables>");
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// PROGRAMM
if (strpos($_SERVER['QUERY_STRING'], "runprogram.cgi") !== false) {
$prog_id = ( !empty($_GET['program_id']) ? intval($_GET['program_id']) : false );
// Beende wenn keine Program_ID übergeben wird
if(empty($prog_id))
{
die('Program-ID fehlt');
}
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_runprogram($ccu, $prog_id, isset($_GET['debug']));
}
function api_runprogram($ccu, int $prog_id, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
dom.GetObject("$prog_id").ProgramExecute();
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// WERTÄNDERUNG
if (strpos($_SERVER['QUERY_STRING'], "statechange.cgi") !== false) {
// Beende, wenn keine Ise_ID übergeben wird
if (empty($_GET['ise_id'])) die('Ise-ID fehlt');
// Beende, wenn keine Werte übergeben werden
if (!isset($_GET['new_value'])) die('Wert fehlt');
// Trenne ise_id und new_value anhand , auf und setze als assoziatives Array zusammen
$iseids = $_GET['ise_id'];
$a_iseids = str_getcsv($iseids, ',', '"', '\\');
$iseids = ( count($a_iseids) ? $a_iseids : $iseids );
$newvalues = $_GET['new_value'];
$a_newvalues = str_getcsv($newvalues, ',', '"', '\\');
$newvalues = ( count($a_newvalues) ? array_map('rawurldecode', $a_newvalues) : rawurldecode($newvalues) );
if (count($iseids) != count($newvalues)) die('Anzahl Parameter stimmt nicht überein');
$set = array_combine($iseids, $newvalues);
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_statechange($ccu, $set, isset($_GET['debug']));
}
function api_statechange($ccu, $set, $debug = false) {
// Baue Skript zusammen
$ccu_request = '';
foreach ($set as $ise_id => $new_value) {
if (ctype_digit($ise_id)) {
$ccu_request = $ccu_request."dom.GetObject(\"".$ise_id."\").State(\"".addslashes($new_value)."\");\n";
}
}
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request, true);
}
//SYSVAR
if (strpos($_SERVER['QUERY_STRING'], "sysvar.cgi") !== false) {
// Beende, wenn keine Ise_ID übergeben wird
if (empty($_GET['ise_id'])) die('Ise-ID fehlt');
$ise_id = $_GET['ise_id'];
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_sysvar($ccu, $ise_id, isset($_GET['debug']));
}
function api_sysvar($ccu, $ise_id, $debug = false) {
// Baue Skript zusammen
$ccu_request = "WriteLine(\"<systemVariables>\");
string id;
! Alle Datenpunkte durchlaufen
foreach(id, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs()){
! Einzelnen Datenpunkt holen
var sysVar = dom.GetObject(id);
if(".$ise_id." == sysVar.ID()) {
! Namen und Wert des Elements ausgeben - fehlt -> visible
Write(\"<systemVariable name='\" # sysVar.Name() # \"' variable='\" # sysVar.Variable() # \"' value='\" # sysVar.Value() # \"' value_list='\" # sysVar.ValueList() # \"' ise_id='\" # sysVar.ID() # \"' min='\" # sysVar.ValueMin() # \"' max='\" # sysVar.ValueMax() # \"' unit='\" # sysVar.ValueUnit() # \"' type='\" # sysVar.ValueType() # \"' subtype='\" # sysVar.ValueSubType() # \"' logged='\" # sysVar.DPArchive() # \"' visible='\" # sysVar.Visible() # \"' timestamp='\" # sysVar.Timestamp().ToInteger()# \"' value_name_0='\" # sysVar.ValueName0() # \"' value_name_1='\" # sysVar.ValueName1() # \"' info='\" # sysVar.DPInfo() # \"'/>\");
WriteLine(\"\");
}
}
WriteLine(\"</systemVariables>\");
";
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// STATUS
if (strpos($_SERVER['QUERY_STRING'], "state.cgi") !== false) {
// Beende, wenn keine Program_ID übergeben wird
if (empty($_GET['datapoint_id'])) die('Datapoint-ID fehlt');
$datapoints = $_GET['datapoint_id'];
$datapoints = str_replace("t", "", $datapoints);
$a_datapoints = str_getcsv($datapoints, ',', '"', '\\');
$datapoints = ( count($a_datapoints) ? $a_datapoints : $datapoints );
//Bei Diagram Collect darf nicht optimiert werden
if(!isset($_GET['onlyvalue']))
{
$datapoints = array_unique($datapoints);
}
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_state($ccu, $datapoints, isset($_GET['debug']));
}
function api_state($ccu, $datapoints, $debug = false) {
// Baue Skript zusammen
$ccu_request = "WriteLine(\"<state>\");\r\n";
foreach ($datapoints as $datapoint) {
if (ctype_digit($datapoint) ) {
$ccu_request = $ccu_request . "object oDatapoint = dom.GetObject(".$datapoint.");\r\n";
// Wenn es sich um ein Datenpunkt handelt gib value aus
$ccu_request = $ccu_request . "if (oDatapoint.IsTypeOf(OT_DP)) {\r\n";
$ccu_request = $ccu_request . "WriteLine(\"<datapoint ise_id='".$datapoint."' value='\"#dom.GetObject(".$datapoint.").Value().ToString()#\"'/>\");\r\n";
$ccu_request = $ccu_request . "}\r\n";
if (!isset($_GET['onlyvalue']))
{
// Wenn es sich um einen Channel handelt gib Timestamp aus
$ccu_request = $ccu_request . "if (oDatapoint.IsTypeOf(OT_CHANNEL)) {\r\n";
$ccu_request = $ccu_request . "WriteLine(\"<datapoint ise_id='".$datapoint."t' value='\"#dom.GetObject(".$datapoint.").LastDPActionTime().ToString(\"%m.%d.%Y %H:%M:%S\")#\"'/>\");";
$ccu_request = $ccu_request . "}\r\n";
// Wenn es sich um einen Datenpunkt handelt gib Timestamp aus
$ccu_request = $ccu_request . "if (oDatapoint.IsTypeOf(OT_DP)) {\r\n";
$ccu_request = $ccu_request . "WriteLine(\"<datapoint ise_id='".$datapoint."t' value='\"#dom.GetObject(".$datapoint.").Timestamp().ToString(\"%m.%d.%Y %H:%M:%S\")#\"'/>\");";
$ccu_request = $ccu_request . "}\r\n";
// Wenn es sich um ein Programm handelt gib Timestamp aus
$ccu_request = $ccu_request . "if (oDatapoint.IsTypeOf(OT_PROGRAM)) {\r\n";
$ccu_request = $ccu_request . "WriteLine(\"<datapoint ise_id='".$datapoint."t' value='\"#dom.GetObject(".$datapoint.").ProgramLastExecuteTime().ToString(\"%m.%d.%Y %H:%M:%S\")#\"'/>\");";
$ccu_request = $ccu_request . "}\r\n";
}
}
}
$ccu_request = $ccu_request . "WriteLine(\"</state>\");\r\n";
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// SYSTEMNOTIFICATION
if (strpos($_SERVER['QUERY_STRING'], "systemNotification.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_systemNotification($ccu, $prog_id, isset($_GET['debug']));
}
function api_systemNotification($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
WriteLine("<systemNotification>");
string id;
! Alle Datenpunkte durchlaufen
foreach(id, dom.GetObject(ID_SERVICES).EnumUsedIDs()){
! Einzelnen Datenpunkt holen
var serviceVar = dom.GetObject(id);
object trigDP = dom.GetObject(serviceVar.AlTriggerDP());
if( serviceVar.IsTypeOf( OT_ALARMDP ) && ( serviceVar.AlState() == asOncoming ) ){
! Namen und Wert des Elements ausgeben - fehlt -> visible
Write("<notification ise_id='" # serviceVar.AlTriggerDP() # "' name='" # trigDP.Name() # "' type='" # trigDP.HssType() # "' timestamp='" # serviceVar.LastTriggerTime().ToInteger() # "'/>");
WriteLine("");
}
}
WriteLine("</systemNotification>");
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request);
}
// SYSTEMNOTIFICATIONCLEAR
if (strpos($_SERVER['QUERY_STRING'], "systemNotificationClear.cgi") !== false) {
header("Content-Type: text/xml; charset=ISO-8859-1");
echo api_systemNotificationClear($ccu, isset($_GET['debug']));
}
function api_systemNotificationClear($ccu, $debug = false) {
// Baue Skript zusammen
$ccu_request = <<<EOHM
string itemID;
string address;
object aldp_obj;
foreach(itemID, dom.GetObject(ID_DEVICES).EnumUsedIDs()) {
address = dom.GetObject(itemID).Address();
aldp_obj = dom.GetObject(\"AL-\" # address # \":0.STICKY_UNREACH\");
if (aldp_obj) {
if (aldp_obj.Value()) {
aldp_obj.AlReceipt();
}
}
}
EOHM;
// Debug Mode
if ($debug) return($ccu_request);
// Schreibe Ausgabe
return "<?xml version='1.0' encoding='ISO-8859-1' ?>\n".ccu_remote($ccu, $ccu_request, true);
}
?>
Code: Alles auswählen
<?php
ini_set('display_errors', 'on');
ini_set('display_startup_errors', 'on');
$beginn = microtime(true);
$exportFile = __DIR__.'/config/export.json';
// Wenn Konfiguration nicht existiert wechsele zum Setup
if(!file_exists(__DIR__.'/config/config.php'))
{
header('Location: ./setup.php');
exit;
}
require_once(__DIR__.'/interface.php');
$export = array();
// Devices und Channels von der CCU laden
$devicesXml = simplexml_load_string(api_devicelist($ccu));
$statesXml = simplexml_load_string(api_statelist($ccu));
// Devices
foreach ($devicesXml->device as $device) {
$dummy = array();
foreach($device->attributes() as $attribute => $value) {
$dummy[strval($attribute)] = strval($value);
}
$statesXmlDevice = $statesXml->xpath('//device[@ise_id="' . strval($device['ise_id']) . '"]');
if(isset($statesXmlDevice[0])) {
foreach($statesXmlDevice[0]->attributes() as $attribute => $value) {
$dummy[strval($attribute)] = strval($value);
}
}
$export['devices'][] = $dummy;
}
// Virtuelle Fernbedienung
$device = $statesXml->xpath('//device[contains(@name, "HM-RCV-50")]');
if(count((array)$device) > 0) {
$device = $device[0];
$dummy = array(
'name' => strval($device['name']),
'address' => 'BidCos-RF',
'ise_id' => strval($device['ise_id']),
'interface' => 'BidCos-RF',
'device_type' => 'HM-RCV-50'
);
$export['devices'][] = $dummy;
}
// Channels
$channelDevicesXml = $devicesXml->xpath('//channel');
foreach ($channelDevicesXml as $channel) {
$device = $devicesXml->xpath('//device[@ise_id="' . strval($channel['parent_device']) . '"]');
$device = $device[0];
$dummy = array();
if(strval($device['interface']) <> 'CUxD') {
$dummy['component'] = strval($device['device_type']);
} else {
$dummy['component'] = substr(strval($device['address']), 0, 7);
}
$dummy['parent_device_type'] = strval($device['device_type']);
$dummy['parent_device_interface'] = strval($device['interface']);
foreach($channel->attributes() as $attribute => $value) {
$dummy[strval($attribute)] = strval($value);
}
$channelStatesXml = $statesXml->xpath('//channel[@ise_id="' . strval($channel['ise_id']) . '"]');
if(isset($channelStatesXml[0])) {
foreach($channelStatesXml[0]->attributes() as $attribute => $value) {
$dummy[strval($attribute)] = strval($value);
}
foreach($channelStatesXml[0]->datapoint as $datapoint) {
$dummy2 = array();
foreach($datapoint->attributes() as $attribute => $value) {
$dummy2[strval($attribute)] = strval($value);
}
$dummy['datapoints'][] = $dummy2;
}
}
$export['channels'][] = $dummy;
}
// Channels Virtuelle Fernbedienung
$device = $statesXml->xpath('//device[contains(@name, "HM-RCV-50")]');
if(count((array)$device) > 0) {
$device = $device[0];
$channelXml = $statesXml->xpath('//device[@ise_id="' . strval($device['ise_id']) . '"]/channel');
foreach ($channelXml as $channel) {
$dummy = array();
$dummy['component'] = 'HM-RCV-50';
$dummy['parent_device_type'] = 'HM-RCV-50';
$dummy['parent_device_interface'] = 'BidCos-RF';
foreach($channel->attributes() as $attribute => $value) {
$dummy[strval($attribute)] = strval($value);
}
foreach ($channel->datapoint as $datapoint) {
$dummy2 = array();
foreach($datapoint->attributes() as $attribute => $value) {
$dummy2[strval($attribute)] = strval($value);
}
$dummy['datapoints'][] = $dummy2;
}
$export['channels'][] = $dummy;
}
}
// Aufräumen
unset($devicesXml);
unset($statesXml);
// Systemvariablen von der CCU laden
$sysvarsXml = simplexml_load_string(api_sysvarlist($ccu));
// Systemvariablen
foreach ($sysvarsXml->systemVariable as $sysvar) {
$dummy = array();
$dummy['component'] = 'SysVar';
foreach($sysvar->attributes() as $attribute => $value) {
$dummy[strval($attribute)] = strval($value);
}
$export['systemvariables'][] = $dummy;
}
// Aufräumen
unset($sysvarsXml);
// Programme von der CCU laden
$programsXml = simplexml_load_string(api_programlist($ccu));
// Programme
foreach ($programsXml->program as $program) {
$dummy = array();
$dummy['component'] = 'Program';
foreach($program->attributes() as $attribute => $value) {
// Unstimmigkeit in der XML-API korrigieren
if(strval($attribute) == 'id') {
$dummy['ise_id'] = strval($value);
} else {
$dummy[strval($attribute)] = strval($value);
}
}
$export['programs'][] = $dummy;
}
// Aufräumen
unset($programsXml);
// Umlaute ersetzen
$json = str_replace(
array('\u00c4', '\u00e4', '\u00d6', '\u00f6', '\u00dc', '\u00fc', '\u00df'),
array('Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', 'ß'),
json_encode($export)
);
file_put_contents($exportFile, $json);
if(isset($_GET['debug']))
{
$dauer = microtime(true) - $beginn;
echo "Verarbeitung des Skripts: ".$dauer." Sek.";
exit();
}
else
{
header('Location: index.php');
}
?>
Code: Alles auswählen
...
require_once(__DIR__.'/interface.php');
...
Zeile 426 von
$xml = simplexml_load_file($interface.'interface.php?systemNotification.cgi');
ändern zu
$xml = simplexml_load_string(api_systemNotification($ccu));
Da ich mir die anderen Skripte noch nicht im Detail angeschaut habe, ist die Frage, welcher Aufwand es wäre, das überall anzupassen.
Code: Alles auswählen
$ccu = Array(
'host' => 'homematic-ccu', // Hostname oder IP-Adresse der CCU. In der CCU-Firewall muss die IP-Adresse dieses Servers freigegeben sein.
'user' => 'Remote-User', // Benutzername für die Remote-Skript API
'pw' => 'Remote-Password', // Kennwort für die Remote-Skript API
'https' => true // true, wenn die Verbindung zur CCU über HTTPS aufgebaut werden soll, ansonsten false
);
-
- Beiträge: 327
- Registriert: 28.10.2013, 18:38
- Hat sich bedankt: 20 Mal
- Danksagung erhalten: 46 Mal
Re: HomeHub 4.1
Eine Anpassung der config halte ich immer für sehr kritisch, da dann ein Update nicht mehr einfach möglich ist, daher habe ich dort die Finger immer möglichst weggelassen.
Ggf, könnte man den Code aber so Anpassen, das die config bei nicht validen oder fehlenden Einstellungen ein Setup aufruft und die config entsprechend schreibt. Das müsste man noch programmieren, aber dies könnte bei Updates so etwas "abfangen".
Deine Verbesserungen spiele ich mal Zuhause durch, ich befürchte, außer den den bei dir genannten Servicemeldungen und dem Import werden wir keine Optimierung hinbekommen, da alle anderen Aufrufe über Javascript getriggert werde . Aber jede Millisekunde zählt![Wink ;-)](./images/smilies/icon_wink.gif)
P. S. : Ggf. noch bei den Diagrammen.
Ggf, könnte man den Code aber so Anpassen, das die config bei nicht validen oder fehlenden Einstellungen ein Setup aufruft und die config entsprechend schreibt. Das müsste man noch programmieren, aber dies könnte bei Updates so etwas "abfangen".
Deine Verbesserungen spiele ich mal Zuhause durch, ich befürchte, außer den den bei dir genannten Servicemeldungen und dem Import werden wir keine Optimierung hinbekommen, da alle anderen Aufrufe über Javascript getriggert werde . Aber jede Millisekunde zählt
![Wink ;-)](./images/smilies/icon_wink.gif)
P. S. : Ggf. noch bei den Diagrammen.