Kannst ja das hier mal versuchen, aber mehr kann ich dann wahrscheinlich auch nicht helfen …
<?php
################################################################################
# Script: HomeMatic.TempSchedule.ips.php
# Version: 1.2.20200219
# 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)
# 19.02.2020 - Bugfixes, ReadParamSet erweitert für Request ohne "channel"
#
# ------------------------------ Konfiguration ---------------------------------
#
# RPC clients
$client = array();
#
# Service IP (CCUx)
$ip = 'xxx.xxx.x.x';
#
# 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-CC-RT-DN - Kanal:2 - CLIMATECONTROL_RECEIVER (ungetestet!!!)
# HM-TC-IT-WM-W-EU - Kanal:2 - THERMALCONTROL_TRANSMIT (ungetestet!!!)
$room = array (
array(12, '1 - KG: Hoppyraum', '', -1, 50660, 26857),
array(21, '2 - EG: Küche', '', -1, 21113, 23635, 11542),
array(22, '2 - EG: Wohnen', '', -1, 23498, 58689),
array(31, '3 - OG: Bad', '', -1, 56832, 33650),
array(32, '3 - OG: Gäste', '', -1, 20199, 11234),
array(33, '3 - OG: Arbeit', '', -1, 55797, 56530),
array(34, '3 - OG: Schlafen', '', -1, 30734, 43879, 52032),
array(41, '4 - DG: Studio', '', -1, 20652, 52057),
array(42, '4 - DG: Bad', '', -1, 50467, 13788),
);
# Wochenplan Profil
$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', '', 0x008000),
array(1, 'Speichern', '', 0xFF0000)
);
# Kopieren Profil
$copy = array(
array(0, ">", "", -1),
array(1, "Kopieren", "", 0x008000),
);
# Übertragen Profil
$move = array(
array(0, ">", "", -1),
array(1, "Übertragen", "", 0x008000),
);
# Wochentag Profil
$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)
);
# Zeit Profil
$time = array(
array(1, '-1 h', '', 0x00FF00),
array(2, '-10 min', '', 0x00FF00),
array(3, '+10 min', '', 0xFF8000),
array(4, '+1 h', '', 0xFF8000)
);
# Temperatur Profil
$temperature = array(
array(1, '-1 °C', '', 0x3366FF),
array(2, '-0,5 °C', '', 0x3366FF),
array(3, '+0,5 °C', '', 0xFF0000),
array(4, '+1 °C', '', 0xFF0000)
);
# Abschnitt Profil
$slot = array(
array(1, 'Löschen', '', 0xFFCC99),
array(2, 'Anfügen', '', 0xCCFFCC)
);
# Wochentage
$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 aktivierten 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, null);
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 ($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; // 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>\n");
$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
$value = $address;
if($channel != null) {
$value .= ":".$channel;
}
$request = new xmlrpcmsg("getParamset",
array(new xmlrpcval("$value", "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!\n");
}
}
return $messages;
}
// 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.'body {margin: 0px;}';
$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 = '<style>
body {margin: 0px;}
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #555; border-radius: 20px; }
::-webkit-scrollbar-thumb:hover { background: #555; }
ul {font-size:12px;padding-left: 20px;}
em {font-size: xx-small;}
.time {font-size:12px;}
.list {font-size:14px; font-weight: bold; padding-top: 10px;}
</style>';
$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));
}
################################################################################
?>
Musst natürlich die richtigen Geräte eintragen!
Viel Erfolg Heiko