Hallo zusammen,
über Weihnachten hatte ich versucht die vorhandenen Scripte bei mir zu installieren, aber irgendwie wollte das alles nicht so wie ich und überhaupt …
Habe dann damit rumgespielt und gemerkt das es auch funktioniert mit den neuen WHT-2 und eTRV-2 Geräten und so fing das dann an …
Michael (@Nall-chan) wird sicher mit den Augen rollen, aber es ist wieder ein einzelnes Script geworden, wo die Variablen unterhalb des Scriptes liegen
Ich habe versucht soviel wie nötig zu dokumentieren. Danke auch an @Marc der mir auf dem letzten Meter geholfen hat beim Testen und entsprechendes Feedback gegeben hat.
Trotzdem der HINWEIS - NUTZUNG AUF EIGENE GEFAHR!!
<?
################################################################################
# Scriptbezeichnung: HomeMatic.TempSchedule.ips.php
# Version: 1.1.20190222
# Author: Heiko Wilknitz (@Pitti)
# Basierend auf Zapp (2011) for the IPS Community
# Erweitert von Swifty (Heizungs_Scripte v 0.1 - 15.02.2014)
#
# Auslese, Modifizieren und Speichern von Temperatur-Wochenplan
# von HomeMatic(IP)-Themostaten.
#
# !!! KEINE ÜBERNAHME VON GARANTIEN - NUTZUNG AUF EIGENE GEFAHR !!!
#
# ------------------------------ Installation ----------------------------------
#
# Dieses Skript richtet automatisch alle nötigen Objekte bei manueller
# Ausführung ein. Eine weitere manuelle Ausführung setzt alle benötigten Objekte
# wieder auf den Ausgangszustand.
#
# - Neues Skript erstellen
# - Diesen PHP-Code hineinkopieren
# - Abschnitt 'Konfiguration' den eigenen Gegebenheiten anpassen
# - Skript Abspeichern
# - Skript Ausführen
# - Visualisierung per Link auf entstandene Variablen erstellen
#
# ------------------------------ Visualisierung --------------------------------
#
# Kann natürlich jeder machen wie er möchte, hier ein schematischer Vorschlag
# wie man vorgehen könnte:
#
# Zweischpaltiges Splitpane Layout (Vertikal 50:50)
#
# LINKE SEITE RECHTE SEITE
# 1. Link auf "Zimmer" Dummy Modul "Profil editieren"
# 2. Link auf "Wochenprogramm" 1. Link auf "Tag"
# 3. Link auf "Profil" 2. Link auf "Zeitabschnitt"
# 4. Link auf "Wochenprofil" 3. Link auf "Zeit"
# 5. Link auf "Tagesprofil" 4. Link auf "Temperatur"
# 5. Link auf "Abschnitt"
# Dummy Modul "Tagesprofil kopieren"
# 1. Link auf "Tagesauswahl"
# 2.Link auf "Kopieren"
# Dummy Modul "Wochenprofil übertragen"
# 1. Link auf "Zimmerauswahl"
# 2. Link auf "Programmauswahl"
# 1. Link auf "Übertragen"
#
# ------------------------------ Changelog -------------------------------------
#
# 02.01.2019 - Initalversion (v1.0)
# 22.02.2019 - Bugfixes, mehr Doku(Hinweise) und Speichern ermöglicht (v1.1)
#
# ------------------------------ Konfiguration ---------------------------------
#
# RPC clients
$client = array();
#
# Service IP (CCUx)
$ip = 'xxx.xxx.xxx.xxx';
#
# Nach dem Übertragen eines Profils an die Geräte wird eine Meldung ausgegeben.
# Soll dafür WFC_SendNotification verwendet werden dann bitte die notwendige
# WebFront-ID hinterlegen, ansonsten erfolgt eine nicht ganz so schöne
# Echo-Ausgabe, welche leider die Überschrift "Fehler" hat :(
$wfc = 0;
#
# BidCos Service Port (true = vorhanden & aktiv)
$service = array(
array('ID' => 0, 'TYPE' =>'RF', 'PORT' =>2001, 'ACTIVE' => true), // HM
array('ID' => 1, 'TYPE' =>'IP', 'PORT' =>2010, 'ACTIVE' => true), // HM IP
array('ID' => 2, 'TYPE' =>'WD', 'PORT' =>2000, 'ACTIVE' => false) // Wired
);
#
# Räume (siehe nachfolgende Elementbelegung)
# (0) Logische Id (einfach von 0 durchnummerieren, oder eigene Logik verwenden)
# (1) Name des Raumes
# (2) Icon (sollte leer bleiben)
# (3) Farbe (RGB-Wert, default -1)
# (4) Wandthermostat-ID (oder auch direkt ein Heizkörperthermostat möglich)
# (5) 1.Heizkörperthermostat-ID [mit Wandtherostat gekoppelt] - optional
# (6) 2.Heizkörperthermostat-ID [mit Wandtherostat gekoppelt] - optional
# (+) x.Heizkörperthermostat-ID [mit Wandtherostat gekoppelt] - optional
#
# HINWEIS IDs:
# HmIP-WTH-2 - Kanal:1 - HEATING_CLIMATECONTROL_TRANSCEIVER
# HmIP-eTRV - Kanal:1 - HEATING_CLIMATECONTROL_TRANSCEIVER
# HmIP-eTRV-2 - Kanal:1 - HEATING_CLIMATECONTROL_TRANSCEIVER
# HM-CC-TC - Kanal:2 - CLIMATECONTROL_REGULATOR
# HM-TC-IT-WM-W-EU - Kanal 2 - THERMALCONTROL_TRANSMIT (ungetestet!!!)
#
$room = array (
array(12, '1 - KG: Hoppyraum', '', -1, 50660 /*[Systeme\Homematic\Thermostat\000A98A9A4E0C6 (HmIP-WTH-2)\000A98A9A4E0C6:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 26857 /*[Systeme\Homematic\Stellantrieb\000A18A994402D (HmIP-eTRV-2)\000A18A994402D:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(21, '2 - EG: Küche', '', -1, 21113 /*[Systeme\Homematic\Thermostat\000A98A9A4E0BE (HmIP-WTH-2)\000A98A9A4E0BE:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 23635 /*[Systeme\Homematic\Stellantrieb\000A18A9943FD9 (HmIP-eTRV-2)\000A18A9943FD9:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 11542 /*[Systeme\Homematic\Stellantrieb\000A18A994405C (HmIP-eTRV-2)\000A18A994405C:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(22, '2 - EG: Wohnen', '', -1, 23498 /*[Systeme\Homematic\Thermostat\000A98A9A4E10D (HmIP-WTH-2)\000A98A9A4E10D:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 58916 /*[Systeme\Homematic\Stellantrieb\000A18A9944035 (HmIP-eTRV-2)\000A18A9944035:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(31, '3 - OG: Bad', '', -1, 56832 /*[Systeme\Homematic\Thermostat\000A98A9A4E0F5 (HmIP-WTH-2)\000A98A9A4E0F5:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 33650 /*[Systeme\Homematic\Stellantrieb\000A18A9944068 (HmIP-eTRV-2)\000A18A9944068:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(32, '3 - OG: Luise', '', -1, 20199 /*[Systeme\Homematic\Thermostat\000A98A9A4E110 (HmIP-WTH-2)\000A98A9A4E110:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 11234 /*[Systeme\Homematic\Stellantrieb\000A18A9944066 (HmIP-eTRV-2)\000A18A9944066:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(33, '3 - OG: Pia', '', -1, 55797 /*[Systeme\Homematic\Thermostat\000A98A9A4E096 (HmIP-WTH-2)\000A98A9A4E096:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 56530 /*[Systeme\Homematic\Stellantrieb\000A18A9943FDB (HmIP-eTRV-2)\000A18A9943FDB:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(34, '3 - OG: Schlafen', '', -1, 30734 /*[Systeme\Homematic\Thermostat\000A98A9A4E0F7 (HmIP-WTH-2)\000A98A9A4E0F7:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 43879 /*[Systeme\Homematic\Stellantrieb\000393C98D1395 (HmIP-eTRV)\000393C98D1395:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 52032 /*[Systeme\Homematic\Stellantrieb\000393C98D1380 (HmIP-eTRV)\000393C98D1380:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(41, '4 - DG: Studio', '', -1, 20652 /*[Systeme\Homematic\Thermostat\000A9709A0D78D (HmIP-WTH-2)\000A9709A0D78D:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/, 52057 /*[Systeme\Homematic\Stellantrieb\000393C98D1313 (HmIP-eTRV)\000393C98D1313:1 - HEATING_CLIMATECONTROL_TRANSCEIVER]*/),
array(42, '4 - DG: Bad', '', -1, 40693 /*[Systeme\Homematic\Thermostat\JEQ0194704 (HM-CC-TC)\JEQ0194704:2 - CLIMATECONTROL_REGULATOR]*/)
);
#
$program = array (
array(1, 'Arbeitswoche', '', 255), // oder Normal
array(2, 'Zuhause', '', 255), // oder Frei
array(3, 'Aus', '', 255) // oder Abwesend
);
# Auslesen/Speichern Profil
$readwrite = array(
array(0, 'Auslesen', '', 32768),
array(1, 'Speichern', '', 16711680)
);
# Kopieren Profil
$copy = array(
array(0, ">", "", -1),
array(1, "Kopieren", "", 0x008000),
);
# Übertragen Profil
$move = array(
array(0, ">", "", -1),
array(1, "Übertragen", "", 0x008000),
);
#
$day = array(
array(0, 'Mo', '', -1),
array(1, 'Di', '', -1),
array(2, 'Mi', '', -1),
array(3, 'Do', '', -1),
array(4, 'Fr', '', -1),
array(5, 'Sa', '', -1),
array(6, 'So', '', -1)
);
#
$time = array(
array(1, '-1 h', '', 65280),
array(2, '-10 min', '', 65280),
array(3, '+10 min', '', 16744448),
array(4, '+1 h', '', 16744448)
);
#
$temperature = array(
array(1, '-1 °C', '', 3368703),
array(2, '-0,5 °C', '', 3368703),
array(3, '+0,5 °C', '', 16711680),
array(4, '+1 °C', '', 16711680)
);
#
$slot = array(
array(1, 'Löschen', '', 16764057),
array(2, 'Anfügen', '', 13434828)
);
#
$weekday = array("MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY");
#
################################################################################
# HINWEIS: Ich arbeite mit einer alten Version der Xml-RPC API Datei,
# welche ich extra patchen musste damit alles funktioniert.
# Wer das nicht möchte kann auch die Version 4.3.0 installieren!
# DANN die nachfolgende Zeile durch ...
# require "phpxmlrpc-4.3.0/lib/xmlrpc.inc"; oder so ersetzen!!!
require "__xmlrpc.inc.php" ;
################################################################################
//Init XMLRPC clients
Init();
// wichtig, da sonst am Tag der Zeitumstellung WZ/SZ Konflikte auftreten.
date_default_timezone_set('UTC');
// INSTALLATION
if ($_IPS['SENDER']=='Execute') {
$pos = 0;
// Zimmer
$vpn = "HM.Heating.Room";
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
CreateProfileInteger($vpn, 'HouseRemote', '', '', 0, 0, 0, 0, $room);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Wochenprogramm
$vpn = "HM.Heating.Program";
$vid = CreateVariableByName($_IPS['SELF'], "Wochenprogramm", 1);
CreateProfileInteger($vpn, 'Temperature', '', '', 0, 0, 0, 0, $program);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
SetValue($vid, 1);
// Auslese/Speichern Button
$vpn = "HM.Heating.ReadWrite";
$vid = CreateVariableByName($_IPS['SELF'], "Profil", 1);
CreateProfileInteger($vpn, 'Script', '', '', 0, 0, 0, 0, $readwrite);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
SetValue($vid, 0);
// Wochen(Temperatur)profil
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprofil', 3);
IPS_SetIcon($vid, "Calendar");
IPS_SetVariableCustomProfile($vid, '~HTMLBox');
IPS_SetPosition($vid, $pos++);
// Tages(Temperatur)profil
$vid = CreateVariableByName($_IPS['SELF'], 'Tagesprofil', 3);
IPS_SetIcon($vid, "Clock");
IPS_SetVariableCustomProfile($vid, '~HTMLBox');
IPS_SetPosition($vid, $pos++);
// Tagesauswahl
$vpn = "HM.Heating.Day";
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
CreateProfileInteger($vpn, 'Calendar', '', '', 0, 0, 0, 0, $day);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Zeitabschnitt auswählen
$vpn = "HM.Heating.Slot";
$vid = CreateVariableByName($_IPS['SELF'], "Zeitabschnitt", 1);
CreateProfileInteger($vpn, 'Database', '', '. Zeitabschnitt', 1, 3, 1, 0);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Zeit editieren
$vpn = "HM.Heating.Time";
$vid = CreateVariableByName($_IPS['SELF'], "Zeit", 1);
CreateProfileInteger($vpn, 'Clock', '', '', 0, 0, 0, 0, $time);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Temperatur editieren
$vpn = "HM.Heating.Temperature";
$vid = CreateVariableByName($_IPS['SELF'], "Temperatur", 1);
CreateProfileInteger($vpn, 'Temperature', '', '', 0, 0, 0, 0, $temperature);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Abschnitt editieren
$vpn = "HM.Heating.Edit";
$vid = CreateVariableByName($_IPS['SELF'], "Abschnitt", 1);
CreateProfileInteger($vpn, 'Edit', '', '', 0, 0, 0, 0, $slot);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Tagesauswahl kopieren
$vpn = "HM.Heating.Day";
$vid = CreateVariableByName($_IPS['SELF'], "Tagesauswahl", 1);
CreateProfileInteger($vpn, 'Calendar', '', '', 0, 0, 0, 0, $day);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Kopieren
$vpn = "HM.Heating.Copy";
$vid = CreateVariableByName($_IPS['SELF'], "Kopieren", 1);
CreateProfileInteger($vpn, 'Script', '', '', 0, 0, 0, 0, $copy);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
SetValue($vid, 0);
// Zimmerauswahl
$vpn = "HM.Heating.Room";
$vid = CreateVariableByName($_IPS['SELF'], "Zimmerauswahl", 1);
CreateProfileInteger($vpn, 'HouseRemote', '', '', 0, 0, 0, 0, $room);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
// Programmauswahl
$vpn = "HM.Heating.Program";
$vid = CreateVariableByName($_IPS['SELF'], "Programmauswahl", 1);
CreateProfileInteger($vpn, 'Temperature', '', '', 0, 0, 0, 0, $program);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
SetValue($vid, 1);
// Übertragen
$vpn = "HM.Heating.Move";
$vid = CreateVariableByName($_IPS['SELF'], "Übertragen", 1);
CreateProfileInteger($vpn, 'Script', '', '', 0, 0, 0, 0, $move);
IPS_SetVariableCustomProfile($vid, $vpn);
IPS_SetVariableCustomAction($vid, $_IPS['SELF']);
IPS_SetPosition($vid, $pos++);
SetValue($vid, 0);
// Profile Cache
$vid = CreateVariableByName($_IPS['SELF'], "Profiles", 3);
IPS_SetHidden($vid, true);
IPS_SetPosition($vid, -1);
// Types Cache
$vid = CreateVariableByName($_IPS['SELF'], "Types", 3);
IPS_SetHidden($vid, true);
IPS_SetPosition($vid, -1);
}
// AKTION VIA WEBFRONT
else if($_IPS['SENDER'] == "WebFront") {
// Aktion
$name = IPS_GetName($_IPS['VARIABLE']);
// ZIMMER -------------------------------------------------------------------
if($name == 'Zimmer') {
// Welcher Raum?
$rn = $_IPS['VALUE'];
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Rendern
RenderProfile($rn, $wp, $wd);
}
// WOCHENPROGRANN -----------------------------------------------------------
if($name == 'Wochenprogramm') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$wp = $_IPS['VALUE'];
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Rendern
RenderProfile($rn, $wp, $wd);
}
// AUSLESEN/SPEICHERN -------------------------------------------------------
if( $name == 'Profil') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// AUSLESEN
if($_IPS['VALUE'] == 0) {
// Temperatur Profil vom Gerät auslesen
foreach($room as $value) {
if($value[0] == $rn) {
$profile = ReadTempProfile($value[4], false);
SetWeeklyProfile($rn, $profile);
break;
}
}
// Rendern
RenderProfile($rn, $wp, $wd);
}
// SPEICHERN
if($_IPS['VALUE'] ==1) {
// Wochenprofil ermitteln
$profile = GetWeeklyProfile($rn, $wp);
// Teste Integrität der Tagesprofile
$check = CheckWeeklyProfile($profile);
if($check == "OK") {
foreach($room as $value) {
if($value[0] == $rn) {
// Profil zum Gerät übertragen
$count = count($value);
for($d = 4; $d < $count; $d++) {
//echo $value[$d].PHP_EOL;
$check = WriteTempProfile($value[$d], $profile, $wp);
// IPS_Sleep(2000);
}
}
}
if ($check == true) {
$check ="Speichern Erfolgreich";
}
}
// Erolgsmeldung?!
if($wfc != 0) {
WFC_SendNotification($wfc, 'HM Heizungsplan', $check, 'Information', 5);
}
else {
echo $check;
}
}
$_IPS['VALUE'] = 0;
}
// TAG ----------------------------------------------------------------------
if( $name == 'Tag') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$wd = $_IPS['VALUE'];
// Rendern
RenderProfile($rn, $wp, $wd);
}
// ZEITABSCHNITT ------------------------------------------------------------
if( $name == 'Zeitabschnitt') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Profil extrahieren
$profile = GetWeeklyProfile($rn, $wp);
$profile = GetDailyProfile($profile, $wd);
// Welcher Zeitabschnitt?
$ts = $_IPS['VALUE'];
// Render Tagesprofil
$vid = CreateVariableByName($_IPS['SELF'], 'Tagesprofil', 3);
SetValue($vid, RenderDailyProfile($profile, $ts));
}
// ZEIT EDITIEREN -----------------------------------------------------------
if($name == 'Zeit') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Welcher Zeitabschnitt?
$vid = CreateVariableByName($_IPS['SELF'], "Zeitabschnitt", 1);
$ts = GetValue($vid);
// Wochenprofil ermitteln
$profile = GetWeeklyProfile($rn, $wp);
// Tagesprofil ermitteln
$profile = GetDailyProfile($profile, $wd);
// Aktion nur für die ersten Zeitabschnitte
if($ts < count($profile['EndTimes'])) {
// Verhindert dass die Zeit des letzten Slots geändert wird (immer 24:00)
if($ts == 1) {
$start = "00:00";
}
else {
$start = $profile['EndTimes'][$ts-2];
}
$end = $profile['EndTimes'][$ts-1];
$next = $profile['EndTimes'][$ts];
// Welche Aktion?
switch($_IPS['VALUE']) {
case 1: // -1h
if((strtotime($end)-(60*60))> strtotime($start)) {
$end = date("H:i", (strtotime($end)-(60*60)));
}
$profile['EndTimes'][$ts-1] = $end;
break;
case 2: // -10min
if((strtotime($end)-(10*60))> strtotime($start)) {
$end = date("H:i", (strtotime($end)-(10*60)));
}
$profile['EndTimes'][$ts-1] = $end;
break;
case 3: // +10min
if((strtotime($end)+(10*60))< strtotime($next)) {
$end = date("H:i", (strtotime($end)+(10*60)));
}
$profile['EndTimes'][$ts-1] = $end;
break;
case 4: // +1h
if((strtotime($end)+(60*60))< strtotime($next)) {
$end = date("H:i", (strtotime($end)+(60*60)));
}
$profile['EndTimes'][$ts-1] = $end;
break;
}
// Schreiben
SetDailyProfile($rn, $wp, $wd, $profile);
// Rendern
RenderProfile($rn, $wp, $wd, $ts);
}
// Keine Auswahl
$_IPS['VALUE'] = 0;
}
// TEMPERATUR EDITIEREN -----------------------------------------------------
if($name == 'Temperatur') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Welcher Zeitabschnitt?
$vid = CreateVariableByName($_IPS['SELF'], "Zeitabschnitt", 1);
$ts = GetValue($vid);
// Wochenprofil ermitteln
$profile = GetWeeklyProfile($rn, $wp);
// Tagesprofil ermitteln
$profile = GetDailyProfile($profile, $wd);
// Welche Temperatur?
$temperatur = $profile['Values'][$ts-1];
// Welche Aktion?
switch($_IPS['VALUE']) {
case 1: // -1°C
if(($temperatur-1) >= 4.99) {
$temperatur = $temperatur-1;
$profile['Values'][$ts-1] = $temperatur;
}
break;
case 2: // -0.5°C
if(($temperatur-0.5) > 4.9) {
$temperatur = $temperatur-0.5;
$profile['Values'][$ts-1] = $temperatur;
}
break;
case 3: // +0.5°C
if(($temperatur+0.5) < 30.1) {
$temperatur = $temperatur+0.5;
$profile['Values'][$ts-1] = $temperatur;
}
break;
case 4: // +1°C
if(($temperatur+1) <= 30.01) {
$temperatur = $temperatur+1;
$profile['Values'][$ts-1] = $temperatur;
}
break;
}
// Schreiben
SetDailyProfile($rn, $wp, $wd, $profile);
// Rendern
RenderProfile($rn, $wp, $wd, $ts);
// Keine Auswahl
$_IPS['VALUE'] = 0;
}
// ABSCHNITT EDITIEREN ------------------------------------------------------
if( $name == 'Abschnitt') {
// Welches Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Welcher Zeitabschnitt?
$vid = CreateVariableByName($_IPS['SELF'], "Zeitabschnitt", 1);
$ts = GetValue($vid);
// Wochenprofil ermitteln
$profile = GetWeeklyProfile($rn, $wp);
// Tagesprofil ermitteln
$profile = GetDailyProfile($profile, $wd);
// Wieviel Zeitabschnitte?
$count = count($profile['EndTimes']);
// Welche Aktion?
switch($_IPS['VALUE']) {
case 1: // Löschen
// letzter TimeSlot darf nicht gelöscht werden
if ($count >1) {
array_splice($profile['EndTimes'], $ts-1, 1);
array_splice($profile['Values'], $ts-1, 1);
// letzten TimeSlot Ende immer 24:00
$profile['EndTimes'][$count-2]="24:00";
}
break;
case 2: // Anfügen
// max 13 TimeSlots zulässig (manche können auch 24, aber das sollte reichen)
If ($count <13)
{
array_splice($profile['EndTimes'], $count, 0, "24:00");
array_splice($profile['Values'], $count, 0, "17");
// minimaler TimeSlot ist 10 min
$profile['EndTimes'][$count-1]="23:50";
}
break;
}
// Wurde was geändert?
if($count <> count($profile['EndTimes'])) {
SetDailyProfile($rn, $wp, $wd, $profile);
// Rendern
RenderProfile($rn, $wp, $wd);
}
// Keine Auswahl
$_IPS['VALUE'] = 0;
}
// TAGESPROFIL KOPIEREN -----------------------------------------------------
if( $name == 'Kopieren') {
if($_IPS['VALUE'] ==1) {
// Welchem Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Von welcher Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tag", 1);
$wd = GetValue($vid);
// Nach Welchen Tag?
$vid = CreateVariableByName($_IPS['SELF'], "Tagesauswahl", 1);
$ta = GetValue($vid);
if($wd == $ta) {
echo ('Bitte anderen Tag auswählen!');
}
else {
// Wochenprofil ermitteln
$profile = GetWeeklyProfile($rn, $wp);
// Tagesprofil von
$profile = GetDailyProfile($profile, $wd);
// kopieren nach
SetDailyProfile($rn, $wp, $ta, $profile);
// Rendern
RenderProfile($rn, $wp, $wd);
}
}
$_IPS['VALUE'] = 0;
}
// WOCHENPROFIL ÜBERTRAGEN --------------------------------------------------
if( $name == 'Übertragen') {
if($_IPS['VALUE'] ==1) {
// Welchem Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmer", 1);
$rn = GetValue($vid);
// Welches Wochenprogramm?
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprogramm', 1);
$wp = GetValue($vid);
// Nach welchen Zimmer?
$vid = CreateVariableByName($_IPS['SELF'], "Zimmerauswahl", 1);
$za = GetValue($vid);
// Nach welchen Program?
$vid = CreateVariableByName($_IPS['SELF'], "Programmauswahl", 1);
$pa = GetValue($vid);
if(($rn == $za) and ($wp == $pa)) {
echo ('Auf sich selber zu übertragen macht keinen Sinn!');
}
else {
// Wochenprofil holen
$profile = GetWeeklyProfile($rn, $wp);
// Übertragen
SetWeeklyProfile($za, $profile, $pa);
}
}
$_IPS['VALUE'] = 0;
}
// DATENÜBERNAHME ------------------------------------------------------
SetValue($_IPS['VARIABLE'], $_IPS['VALUE']);
}
# ------------------------------ Funktionen ------------------------------------
// Erzeugt pro aktiven Interface ein Client.
function Init() {
global $ip, $service, $client;
# Return Code
$ret = true;
# Check all Services
foreach($service as $s) {
if($s['ACTIVE'] == true) {
if (!isset($client[$s['TYPE']]) || $client[$s['TYPE']] !== false) {
$client[$s['TYPE']] = new xmlrpc_client("http://".$ip.":".$s['PORT']);
if ($client[$s['TYPE']] !== false) {
$ret &= true;
}
else {
$ret = false;
}
}
}
}
// client existieren schon
return false;
}
// Liefert alle Geräte der aktierten Interfaces
function DevicesList()
{
global $service, $client;
// listDevices
$request = new xmlrpcmsg('listDevices');
// merge all together
$devices = array();
foreach($service as $s) {
if($s['ACTIVE'] == true) {
$ret = Send($request, $s['TYPE']);
foreach($ret as $device) {
$device['INTERFACE'] = $s['ID'];
$devices[] = $device;
}
//$devices = array_merge($devices, Send($request, $s['TYPE']));
}
}
return $devices;
}
// Ermittelt den Typ des HM Gerätes (HM terminology)
function DeviceType($device) {
// Cache auslesen
$cid = CreateVariableByName($_IPS['SELF'], "Types", 3);
$types = unserialize(GetValue($cid));
// HM Adresse vom Device
$address = explode(":", IPS_GetProperty($device, 'Address'));
$serial = $address[0];
$channel = $address[1];
// schon mal gelesen
if(!is_array($types) || array_key_exists($serial, $types) == false) {
$type = false;
$list = DevicesList();
foreach($list as $dev) {
if (strpos($dev['ADDRESS'], $serial) !== false) {
$type = $dev['TYPE'].':'.$dev['INTERFACE'];
$types[$serial] = $type;
SetValue($cid, serialize($types));
break; // We stop at the first one we find
}
}
}
else
{
$type=$types[$serial];
}
return $type;
}
// Liest das Temperaturprofil von einem Thermostat für den übergebenen Tag.
// $device: IPS Instance ID
// $day: Name des Tages in English (not case-sensitive) oder false für alle Tage
// $weekprofil: nur für HM-TC-IT-WM-W-EU & HmIP-WTH-2;
// gültige Werte 1,2,3; bei -1 werden alle Profile (1-3) zurückgegeben
function ReadTempProfile($device, $day = false, $weekprofil =-1) {
global $service, $weekday;
// HM Adresse vom Device
$address = explode(":", IPS_GetProperty($device, 'Address'));
$serial = $address[0];
$channel = $address[1];
$days = $weekday;
$temp = array();
if ($day != false) {
if(!in_array($day, $weekday)) die("Error: Unknown Day parameter in function ReadTempProfile!");
$days = array($day);
}
// Was für ein HM Gerätetyp & Interface
$dt = explode(":", DeviceType($device));
$type = $dt[0];
$if = $dt[1];
// Konvert Interface
foreach($service as $s) {
if($s['ID'] == $if) {
$if = $s['TYPE'];
break;
}
}
// HM-CC-TC Profil auslesen (hat nur eins)
if($type == "HM-CC-TC") {
$params = ReadParamSet($if, $serial, $channel);
foreach($days as $day) {
$thisEndTimes = array();
$thisValues = array();
$timePrevious = "00:00";
for($index = 1; $index <= 24; $index++) {
$keyTemp = "TEMPERATUR_".strtoupper($day)."_".$index;
$keyTO = "TIMEOUT_".strtoupper($day)."_".$index;
$thisTemp = $params[$keyTemp];
$thisTO = $params[$keyTO];
$thisTime = date('H:i', mktime(0, $thisTO)); // $timePassed + TO
if($thisTO >= 1440) $thisTime = "24:00";
$timePrevious = $thisTime;
array_push($thisEndTimes, $thisTime);
array_push($thisValues, $thisTemp);
if($thisTO >= 1440) break;
}
$temp["P1"][$day]['EndTimes'] = $thisEndTimes;
$temp["P1"][$day]['Values'] = $thisValues;
}
return $temp;
}
// HM-CC-RT-DN Profil auslesen (hat nur eins)
if($type == "HM-CC-RT-DN") {
$params = ReadParamSet($if, $serial, $channel);
foreach($days as $day) {
$thisEndTimes = array();
$thisValues = array();
$timePrevious = "00:00";
for($index = 1; $index <= 13; $index++) {
$keyTemp = "TEMPERATURE_".strtoupper($day)."_".$index;
$keyTO = "ENDTIME_".strtoupper($day)."_".$index;
$thisTemp = $params[$keyTemp];
$thisTO = $params[$keyTO];
$thisTime = date('H:i', mktime(0, $thisTO)); // $timePassed + TO
if($thisTO >= 1440) $thisTime = "24:00";
$timePrevious = $thisTime;
array_push($thisEndTimes, $thisTime);
array_push($thisValues, $thisTemp);
if($thisTO >= 1440) break;
}
$temp["P1"][$day]['EndTimes'] = $thisEndTimes;
$temp["P1"][$day]['Values'] = $thisValues;
}
return $temp;
}
// HM-TC-IT-WM-W-EU Profil auslesen (1-3)
if($type == "HM-TC-IT-WM-W-EU") {
$params = ReadParamSet($if, $serial, $channel);
// 3 Profile
for ($p=1; $p<=3; $p++) {
foreach($days as $day) {
$thisEndTimes = array();
$thisValues = array();
$timePrevious = "00:00";
for($index = 1; $index <= 13; $index++) {
$keyTemp = "P". $p ."_TEMPERATURE_".strtoupper($day)."_".$index;
$keyTO = "P". $p ."_ENDTIME_".strtoupper($day)."_".$index;
//* notwendig da Firmeware beim LAN-Adapter abweicht und beim Profil 1 dort das Präfix "P1_" fehlt.
if(array_key_exists($keyTemp, $params)) {
$thisTemp = $params[$keyTemp];
$thisTO = $params[$keyTO];
}
else {
$keyTemp = "TEMPERATURE_".strtoupper($day)."_".$index;
$keyTO = "ENDTIME_".strtoupper($day)."_".$index;
$thisTemp = $params[$keyTemp];
$thisTO = $params[$keyTO];
}
$thisTime = date('H:i', mktime(0, $thisTO)); // $timePassed + TO
if ($thisTO >= 1440) $thisTime = "24:00";
$timePrevious = $thisTime;
array_push($thisEndTimes, $thisTime);
array_push($thisValues, $thisTemp);
if($thisTO >= 1440) break;
}
$temp["P".$p][$day]['EndTimes'] = $thisEndTimes;
$temp["P".$p][$day]['Values'] = $thisValues;
}
}
if($weekprofil > 0 and $weekprofil <= 3) {
return $temp["P".$weekprofil];
}
else {
return $temp;
}
}
// HmIP-WTH-2 || HMIP-eTRV || HmIP-eTRV-2 Profil auslesen (1-3 von 6)
if($type == "HmIP-WTH-2" or $type =="HmIP-eTRV-2" or $type == "HMIP-eTRV") {
$params = ReadParamSet($if, $serial, $channel);
// 3 Profile
for ($p=1; $p<=3; $p++) {
foreach($days as $day) {
$thisEndTimes = array();
$thisValues = array();
$timePrevious = "00:00";
for($index = 1; $index <= 13; $index++) {
$keyTemp = "P". $p ."_TEMPERATURE_".strtoupper($day)."_".$index;
$keyTO = "P". $p ."_ENDTIME_".strtoupper($day)."_".$index;
$thisTemp = $params[$keyTemp];
$thisTO = $params[$keyTO];
$thisTime = date('H:i', mktime(0, $thisTO)); // $timePassed + TO
if ($thisTO >= 1440) $thisTime = "24:00";
$timePrevious = $thisTime;
array_push($thisEndTimes, $thisTime);
array_push($thisValues, $thisTemp);
if($thisTO >= 1440) break;
}
$temp["P".$p][$day]['EndTimes'] = $thisEndTimes;
$temp["P".$p][$day]['Values'] = $thisValues;
}
}
if($weekprofil > 0 and $weekprofil <= 3) {
return $temp["P".$weekprofil];
}
else {
return $temp;
}
}
echo $type;
if($type != "HM-CC-RT-DN" and $type != "HM-CC-TC" and $type != "HM-TC-IT-WM-W-EU" and $type != "HmIP-WTH-2" and $type != "HMIP-eTRV" and $type != "HmIP-eTRV-2") {
die("Error: ReadTempProfile() Device $device is not of Type HM-CC-TC,HM-CC-RT-DN, HM-TC-IT-WM-W-EU, HmIP-WTH-2, HMIP-eTRV or HmIP-eTRV-2!");
}
}
// Schreibt das Temperaturprofil in ein Thermostat/Stellantrieb.
// $device: IPS Instance ID
// $profile: Temperaturprofil wie von ReadTempProfile() geliefert
// $weekprofil: nur für HM-TC-IT-WM-W-EU & HmIP-WTH-2;
// gültige Werte 1,2,3; bei -1 werden alle Profile (1-3) zurückgegeben
function WriteTempProfile(int $device, array $profile, int $weekprofile=0) {
global $service, $weekday;
// HM Adresse vom Device
$address = explode(":", IPS_GetProperty($device, 'Address'));
$serial = $address[0];
$channel = $address[1];
// Was für ein HM Gerätetyp & Interface
$dt = explode(":", DeviceType($device));
$type = $dt[0];
$if = $dt[1];
// Konvert Interface
foreach($service as $s) {if($s['ID'] == $if) {$if = $s['TYPE'];break;}}
// HM-CC-TC Profil schreiben (hat nur eins)
if($type == "HM-CC-TC") {
$params = new xmlrpcval();
foreach($profile as $day => $values) {
$timePrevious = "00:00";
for($index=1; $index <= count($values['EndTimes']); $index++) {
$key = "TEMPERATUR_".strtoupper($day)."_".$index;
$temp = array($key => new xmlrpcval($values['Values'][$index-1], "double"));
$params->addStruct($temp);
$key = "TIMEOUT_".strtoupper($day)."_".$index;
if ($values['EndTimes'][$index-1] > $timePrevious) {
// Convert end time to Timeout
$thisDayStart = mktime(0, 0);
$timeEndArray = explode(":", $values['EndTimes'][$index-1]);
if ($timeEndArray[1] % 10) die("Error: Invalid End Time (must be 10mn increments) for $day at index $index in WriteTempProfile()!");
$timeEndts = mktime($timeEndArray[0], $timeEndArray[1]);
$timeout = (($timeEndts - $thisDayStart)/60); // TODO, works ?
$paramTime = array($key => new xmlrpcval("$timeout", "int")); // i4
$params->addStruct($paramTime);
}
else {
die("Error: Invalid End Time for $day at index $index in WriteTempProfile()!");
}
$timePrevious = $values['EndTimes'][$index-1];
}
}
$request = new xmlrpcmsg("putParamset",
array(new xmlrpcval("$serial:2", "string"),
new xmlrpcval("MASTER", "string"), $params));
$result = Send($request, $if);
return true;
}
// HM-CC-RT-DN Profil schreiben (hat nur eins)
if($type == "HM-CC-RT-DN") {
$params = new xmlrpcval();
foreach ($profile as $day => $values) {
$timePrevious = "00:00";
for($index=1; $index <= count($values['EndTimes']); $index++) {
$key = "TEMPERATURE_".strtoupper($day)."_".$index;
$temp = array($key => new xmlrpcval($values['Values'][$index-1], "double"));
$params->addStruct($temp);
$key = "ENDTIME_".strtoupper($day)."_".$index;
if ($index>13) break; // HM-CC-RT-DN hat nur 13 Tages - Timeslots
if ($values['EndTimes'][$index-1] > $timePrevious) {
// Convert end time to Timeout
$thisDayStart = mktime(0, 0);
$timeEndArray = explode(":", $values['EndTimes'][$index-1]);
if ($timeEndArray[1] % 10) die("Error: Invalid End Time (must be 10mn increments) for $day at index $index in WriteTempProfile()!");
$timeEndts = mktime($timeEndArray[0], $timeEndArray[1]);
$timeout = (($timeEndts - $thisDayStart)/60); // TODO, works ?
$paramTime = array($key => new xmlrpcval("$timeout", "int")); // i4
$params->addStruct($paramTime);
}
else {
die("Error: Invalid End Time for $day at index $index in WriteTempProfile()!");
}
$timePrevious = $values['EndTimes'][$index-1];
}
}
$request = new xmlrpcmsg("putParamset",
array(new xmlrpcval("$serial", "string"), // no channel NOT TESTED????
new xmlrpcval("MASTER", "string"), $params));
$result = Send($request, $if);
return true;
}
// HM-TC-IT-WM-W-EU Profil schreiben (1-3)
if ($type == "HM-TC-IT-WM-W-EU") {
$prefix="P".$weekprofile."_";
$params = new xmlrpcval();
foreach ($rofile as $day => $values) {
$timePrevious = "00:00";
for ($index=1; $index <= count($values['EndTimes']); $index++) {
$key = $prefix ."TEMPERATURE_".strtoupper($day)."_".$index;
$temp = array($key => new xmlrpcval($values['Values'][$index-1], "double"));
$params->addStruct($temp);
$key = $prefix ."ENDTIME_".strtoupper($day)."_".$index;
if ($index>13) break; // HM-TC-IT-WM-W-EU hat nur 13 Tages - Timeslots
if ($values['EndTimes'][$index-1] > $timePrevious) {
// Convert end time to Timeout
$thisDayStart = mktime(0, 0);
$timeEndArray = explode(":", $values['EndTimes'][$index-1]);
if ($timeEndArray[1] % 5) die("Error: Invalid End Time (must be 10mn increments) for $day at index $index in WriteTempProfile()!");
$timeEndts = mktime($timeEndArray[0], $timeEndArray[1]);
$timeout = (($timeEndts - $thisDayStart)/60); // TODO, works ?
$paramTime = array($key => new xmlrpcval("$timeout", "int")); // i4
$params->addStruct($paramTime);
}
else {
die("Error: Invalid End Time for $day at index $index in WriteTempProfile()!");
}
$timePrevious = $values['EndTimes'][$index-1];
}
}
$request = new xmlrpcmsg("putParamset",
array(new xmlrpcval("$serial", "string"), // no channel NOT TESTED????
new xmlrpcval("MASTER", "string"), $params));
$result = Send($request, $if);
return true;
}
// HmIP-WTH-2 || HMIP-eTRV || HmIP-eTRV-2 Profil schreiben (1-3 von 6)
if($type == "HmIP-WTH-2" or $type =="HmIP-eTRV-2" or $type == "HMIP-eTRV") {
$prefix="P".$weekprofile."_";
$params = new xmlrpcval();
foreach ($profile as $day => $values) {
$timePrevious = "00:00";
for ($index=1; $index <= count($values['EndTimes']); $index++) {
$key = $prefix ."TEMPERATURE_".strtoupper($day)."_".$index;
$temp = array($key => new xmlrpcval($values['Values'][$index-1], "double"));
$params->addStruct($temp);
$key = $prefix ."ENDTIME_".strtoupper($day)."_".$index;
if ($index>13) break; // nur 13 Tages - Timeslots
if ($values['EndTimes'][$index-1] > $timePrevious) {
// Convert end time to Timeout
$thisDayStart = mktime(0, 0);
$timeEndArray = explode(":", $values['EndTimes'][$index-1]);
if ($timeEndArray[1] % 5) die("Error: Invalid End Time (must be 10mn increments) for $day at index $index in HMXML_setTempProfile()<br>
");
$timeEndts = mktime($timeEndArray[0], $timeEndArray[1]);
$timeout = (($timeEndts - $thisDayStart)/60); // TODO, works ?
$paramTime = array($key => new xmlrpcval("$timeout", "int")); // i4
$params->addStruct($paramTime);
}
else {
die("Error: Invalid End Time for $day at index $index in WriteTempProfile()!");
}
$timePrevious = $values['EndTimes'][$index-1];
}
}
$request = new xmlrpcmsg("putParamset",
array(new xmlrpcval("$serial:$channel", "string"),
new xmlrpcval("MASTER", "string"), $params));
//var_dump($params);
$result = Send($request, $if);
return true;
}
if($type != "HM-CC-RT-DN" and $type != "HM-CC-TC" and $type != "HM-TC-IT-WM-W-EU" and $type != "HmIP-WTH-2" and $type != "HMIP-eTRV" and $type != "HmIP-eTRV-2") {
die("Error: WriteTempProfile() Device $device is not of Type HM-CC-TC,HM-CC-RT-DN, HM-TC-IT-WM-W-EU, HmIP-WTH-2, HMIP-eTRV or HmIP-eTRV-2!");
}
}
// Liest die Parameter von einem Gerät aus.
// $if: HM Inteface
// $adress: HM adress
// $channel: HM device chanvel
// $param: Ein spezifischer Parameter wird ausgelesen (siehe HomeMatic Specficiation),sonst alle
function ReadParamSet($if, $address, $channel, $param = false) {
// Build request
$request = new xmlrpcmsg("getParamset",
array(new xmlrpcval("$address:$channel", "string"), new xmlrpcval("MASTER", "string")));
$messages = Send($request, $if);
//var_dump($messages);
if ($param !== false) return $messages[$param];
return $messages;
}
// Creates XMLRPC Client Instance and sends request
function Send($request, $type)
{
global $client;
// If the client does not exist, initialise it here
if (isset($client[$type]) && $client[$type] !== false) {
$response = $client[$type]->send($request);
if ( $response->errno == 0 ) {
$messages = php_xmlrpc_decode($response->value());
}
else {
die("Error: Send() Request to $type Service failed -> $response->errstr!
");
}
}
return $messages;
}
// Erzeugt eine Variable unterhalb {id} mit dem Namen {name} vom Typ [type}
// Existiert die Variable schon wird diese zurückgeliefert.
// Types: 0 = Boolean, 1 = Integer, 2 = Float, 3 = String
function CreateVariableByName($id, $name, $type) {
$vid = @IPS_GetVariableIDByName($name, $id);
if($vid===false) {
$vid = IPS_CreateVariable($type);
IPS_SetParent($vid, $id);
IPS_SetName($vid, $name);
}
return $vid;
}
// Erzeugt ein Variablenprofil vom Typ {type} mit Name n{name}
function CreateProfile($name, $type) {
if(!IPS_VariableProfileExists($name)) {
IPS_CreateVariableProfile($name, $type);
}
else {
$profile = IPS_GetVariableProfile($name);
if($profile['ProfileType'] != $type)
throw new Exception("Variable profile type does not match for profile ".$name);
}
}
// Erzeugt ein Integer-Variablenprofil
function CreateProfileInteger($name, $icon, $prefix, $suffix, $minvalue, $maxvalue, $step, $digits, $asso = NULL) {
CreateProfile($name, 1);
IPS_SetVariableProfileIcon($name, $icon);
IPS_SetVariableProfileText($name, $prefix, $suffix);
IPS_SetVariableProfileDigits($name, $digits);
if(($asso !== NULL) && (sizeof($asso) !== 0)){
$minvalue = 0;
$maxvalue = 0;
}
IPS_SetVariableProfileValues($name, $minvalue, $maxvalue, $step);
if(($asso !== NULL) && (sizeof($asso) !== 0)){
foreach($asso as $ass) {
IPS_SetVariableProfileAssociation($name, $ass[0], $ass[1], $ass[2], $ass[3]);
}
}
}
// Extrahiert für den übergebenen Raum und Wochenprofil das entsprechende
// Temperaturprofil soweit es schon man ausgelesen und gecached wurde.
function GetWeeklyProfile(int $rn, int $wp) {
// Rückgabefeld
$profil = array();
// Cache auslesen
$cid = CreateVariableByName($_IPS['SELF'], "Profiles", 3);
$profiles = unserialize(GetValue($cid));
// unseres dabei?
if(isset($profiles[$rn])) {
if(isset($profiles[$rn]["P".$wp])) {
// "HM-TC-IT-WM-W-EU" oder "HmIP-WTH-2"
$profil = $profiles[$rn]["P".$wp];
}
else {
// Quickhack :( "HM-CC-TC" oder "HM-CC-RT-DN"
$profil = $profiles[$rn]["P1"];
}
}
return $profil;
}
// Speichert für den übergebenen Raum die Wochenprofil(e).
function SetWeeklyProfile(int $rn, array $profile, int $wp =-1) {
// Cache auslesen
$cid = CreateVariableByName($_IPS['SELF'], "Profiles", 3);
$profiles = unserialize(GetValue($cid));
if($wp > 0 and $wp <= 3) {
$profiles[$rn]["P".$wp] = $profile;
}
else {
$profiles[$rn] = $profile;
}
// Cache updaten
SetValue($cid, serialize($profiles));
}
// Extrahiert für den übergebenen Tag das Tagesprofil
function GetDailyProfile(array $week, int $day) {
global $weekday;
// Rückgabefeld
$profil = array();
// unseres dabei?
if(isset($week[$weekday[$day]])) {
$profil = $week[$weekday[$day]];
}
return $profil;
}
// Speichert für den übergebenen Raum die Wochenprofil(e).
function SetDailyProfile(int $rn, int $wp, int $day, array $dp) {
global $weekday;
// Cache auslesen
$cid = CreateVariableByName($_IPS['SELF'], "Profiles", 3);
$profiles = unserialize(GetValue($cid));
// Tagesprofil austauschen
if(isset($profiles[$rn]["P".$wp])) {
// "HM-TC-IT-WM-W-EU" oder "HmIP-WTH-2"
$profiles[$rn]["P".$wp][$weekday[$day]] = $dp;
}
else {
// "HM-CC-TC" oder "HM-CC-RT-DN"
$profiles[$rn][$weekday[$day]] = $dp;
}
// Cache updaten
SetValue($cid, serialize($profiles));
}
// Prüfen ob Profil konsistent ist
function CheckWeeklyProfile($profile) {
global $weekday;
// Ergebniss
$ret = "OK";
foreach($weekday as $key => $day) {
$time1='00:00';
foreach($profile[$weekday[$key]]['EndTimes'] as $ts => $time2) {
// Speicherslots des HM WT in min
if(strtotime($time2) <= strtotime($time1)) {
$slot = $ts+1;
$ret="Fehler im Tagesprofil $weekday[$key] (Slot: $slot Start: $time1 - Ende: $time2 )";
break;
}
$time1 = $time2;
}
}
return $ret;
}
// Zeitabschnitt Auswahl im Webfront Anzeige auf Anzahl
// der belegten Slots im HM WT beschränken
function SetTimeSlotProfile($profile, $hl=99) {
// Profilename
$vpn = "HM.Heating.Slot";
// Anzahl Slots
$count = 0;
if(!empty($profile)) {
$count = count($profile['EndTimes']);
}
// Auswahl anpassen?!
$vid = CreateVariableByName($_IPS['SELF'], "Zeitabschnitt", 1);
if($count > 0) {
IPS_SetVariableProfileValues ($vpn, 1, $count, 1);
if($hl <= $count) {
SetValue($vid, $hl);
return $hl;
}
else {
SetValue($vid, 1);
return 1;
}
}
else {
IPS_SetVariableProfileValues ($vpn, 1, 1, 1);
SetValue($vid, 0);
}
return 99;
}
// Erzeugt vom übergebenen Wochen-Temperaturprofil das entsprechende HTML
function RenderWeeklyProfile(array $profile, $hl = 99) {
global $day, $weekday;
// Temeraturen => 15, 16, 17, 18, 19, 20, 21, 22
if(!empty($profile)) {
foreach ($weekday as $k => $d) {
$time1='00:00';
foreach ($profile[$weekday[$k]]['EndTimes'] as $time2) {
// Speicherslots des HM WT in min
$times[$d][]=(strtotime("01.01.2001 ". $time2)-strtotime("01.01.2001 ". $time1))/60;
$time1=$time2;
}
foreach ($profile[$weekday[$k]]['Values'] as $v) {
if($v <= 15) $temp[$d][] = 't15'; // sehr kalt
elseif ($v <= 16) $temp[$d][] = 't16'; // kalt
elseif ($v <= 17) $temp[$d][] = 't17'; // Kühl
elseif ($v <= 18) $temp[$d][] = 't18'; // normal
elseif ($v <= 19) $temp[$d][] = 't19'; // warm
elseif ($v <= 20) $temp[$d][] = 't20'; // sehr warm
elseif ($v <= 21) $temp[$d][] = 't21'; // heiß
else $temp[$d][] = 't22'; // sehr heiß
}
}
}
else {
// kein Profil kein Highlight!
$hl = 99;
}
// styles definieren
$style = '';
$style = $style.'<style type="text/css">';
$style = $style.'table.tp {border-collapse: collapse; font-size: 11px; width: 100%; border-right: 1px solid rgba(255, 255, 255, 0.2);}';
$style = $style.'td.fst {vertical-align: middle; text-align: center; width: 4%; padding: 2px; border-left: 1px solid rgba(255, 255, 255, 0.2); border-right: 1px solid rgba(255, 255, 255, 0.2); border-top: 1px solid rgba(255, 255, 255, 0.1); }';
$style = $style.'td.mid {vertical-align: middle; text-align: center; width: 4%; padding: 2px; border-right: 1px solid rgba(255, 255, 255, 0.2); border-top: 1px solid rgba(255, 255, 255, 0.1); }';
$style = $style.'td.lst {vertical-align: middle; text-align: center; width: 4%; padding: 2px; border-right: 1px solid rgba(255, 255, 255, 0.2); border-top: 1px solid rgba(255, 255, 255, 0.1); }';
$style = $style.'tr:last-child {border-bottom: 1px solid rgba(255, 255, 255, 0.2); }';
$style = $style.'.th { color: rgb(255, 255, 255); background-color: rgba(255, 255, 255,0.25); font-weight:bold; background-image: linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.3) 28%,rgba(0,0,0,0.3) 100%); background-image: -o-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.3) 28%,rgba(0,0,0,0.3) 100%); background-image: -moz-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.3) 28%,rgba(0,0,0,0.3) 100%); background-image: -webkit-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.3) 28%,rgba(0,0,0,0.3) 100%); background-image: -ms-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.3) 28%,rgba(0,0,0,0.3) 100%); }';
$style = $style.'.hl {background-color: black; opacity: 0.5;}';
$style = $style.'.t15 {background-color: #6600CC; opacity: 0.9;}'; // lila (sehr kalt) <= 15
$style = $style.'.t16 {background-color: #0000FF; opacity: 0.9;}'; // dunkelblau (kalt) = 16
$style = $style.'.t17 {background-color: #0080FF; opacity: 0.9;}'; // hellblau (kühl) = 17
$style = $style.'.t18 {background-color: #00FFFF; opacity: 0.9;}'; // türkis (normal) 18
$style = $style.'.t19 {background-color: #00FF00; opacity: 0.9;}'; // grün (warm) =19
$style = $style.'.t20 {background-color: #FFFF00; opacity: 0.9;}'; // gelb (sehr warm) = 20
$style = $style.'.t21 {background-color: #FF8000; opacity: 0.9;}'; // orange (heiß) = 21
$style = $style.'.t22 {background-color: #FF0000; opacity: 0.9;}'; // rot (sehr heiß) >= 22
$style = $style.'</style>';
// HTML Table erzeugen
$html = $style;
$html = $html.'<table class="tp">';
$html = $html.'<tr>';
for($i=0; $i <= 24; $i++) {
if($i == 0) {
$html = $html.'<td class=""></td>';
}
elseif ($i == 24) {
$html = $html.'<td class="lst th" colspan="12">'.sprintf("%02d", $i).'</td>';
}
else {
$html = $html.'<td class="mid th" colspan="12">'.sprintf("%02d", $i).'</td>';
}
}
$html = $html.'</tr>';
foreach ($weekday as $k => $d) {
// wurde Wochentag mit übergeben (0=Mo, 1=Di ... 99=kein Wochentag vorgegeben)
if($hl <> $k) {
$html = $html.'<tr><td class="fst th">'. $day[$k][1] .'</td>';
}
else {
$html = $html.'<tr class="hl"><td class="fst th">'. $day[$k][1] .'</td>';
}
if(isset($times)) {
foreach ($times[$d] as $key => $time) {
$html = $html.'<td colspan="'.($time/5).'" class="'.$temp[$d][$key].'"> </td>';
}
}
else {
for($i=0; $i < 24; $i++) {
$html = $html.'<td colspan="12"> </td>';
}
}
$html = $html.'</tr>';
}
$html = $html.'</table>';
$html = $html.'<div style="height:8px;"><nbsp /></div>';
// Index Tabelle (Temperatur-Spektrum)
$html = $html.'<table style="border: 0px; font-size:11px; text-shadow:1px 1px #000000; width:100%; text-align: center">';
$html = $html.'<tr>';
$html = $html.'<td class="t15" style="width:12%"><= 15°C</td>';
$html = $html.'<td class="t16" style="width:13%"><= 16°C</td>';
$html = $html.'<td class="t17" style="width:12%"><= 17°C</td>';
$html = $html.'<td class="t18" style="width:13%"><= 18°C</td>';
$html = $html.'<td class="t19" style="width:12%"><= 19°C</td>';
$html = $html.'<td class="t20" style="width:13%"><= 20°C</td>';
$html = $html.'<td class="t21" style="width:12%"><= 21°C</td>';
$html = $html.'<td class="t22" style="width:13%">>= 22°C</td>';
$html = $html.'</tr></table>';
// Rückgabe
return $html;
}
// Erzeugt vom übergebenen Tages-Temperaturprofil das entsprechende HTML
function RenderDailyProfile(array $profile, int $hl=99) {
// styles definieren
$html = "";
$html = $html.'<table class="tp">';
$html = $html.'<tr><td class=""></td><td class="mid th">Startzeit</td><td class="mid th">Endzeit</td><td class="lst th">Temperatur</td></tr>';
// rendern
if(!empty($profile)) {
$start="00:00";
foreach($profile['EndTimes'] as $key => $end) {
$temp = number_format($profile['Values'][$key], 1,",",".");
if($key <> $hl-1) {
$html = $html.'<tr><td class="fst th">'.($key+1) .'. Zeitabschnitt</td><td class="mid">'.$start.'</td><td class="mid">'.$end.'</td><td class="lst">'.$temp.' °C</td></tr>';
}
else {
$html = $html.'<tr class ="hl"><td class="fst th">'.($key+1). '. Zeitabschnitt</td><td class="mid">'.$start.'</td><td class="mid">'.$end.'</td><td class="lst">'.$temp.' °C</td></tr>';
}
$start=$end;
}
}
else {
// kein Profil vorhanden!
$html = $html.'<tr><td class="fst th">-<td class="mid">-</td><td class="mid">-</td><td class="lst">-</td></tr>';
}
$html = $html.'</table>';
// Rückgabe
return $html;
}
// Update HTML
function RenderProfile(int $rn, int $wp, int $wd, int $ts = 99) {
// Profil extrahieren
$profile = GetWeeklyProfile($rn, $wp);
// Rendern Wochenprofil
$vid = CreateVariableByName($_IPS['SELF'], 'Wochenprofil', 3);
SetValue($vid, RenderWeeklyProfile($profile, $wd));
// Profil extrahieren
$profile = GetDailyProfile($profile, $wd);
$ts = SetTimeSlotProfile($profile, $ts);
// Render Tagesprofil
$vid = CreateVariableByName($_IPS['SELF'], 'Tagesprofil', 3);
SetValue($vid, RenderDailyProfile($profile, $ts));
}
################################################################################
?>
Viel Erfolg
Heiko