# HomeMatic EasyInstall
################################################################################
# Version : 1.50
# Datum : 19.11.2017
# Author: Michael Tröger (mt@neo-ami.de)
#
# Beschreibung:
#
# Dieses Script richtet automatisch alle HM-Geräte in IPS ein.
#
# Vorraussetzungen:
# - min. IPS Pro (es werden jede Menge Variablen angelegt)
# - CCU1 oder CCU2 (Windows-BidCos-Dienst wird nicht unterstützt)
# - Firewall in der CCU muss so konfiguriert sein, das IPS Zugriff
# auf die ReGa HSS Logikschicht hat.
# - Je CCU muss auf dem IPS System eine eventuelle Firewall so eingerichtet werden,
# dass die CCU IPS auf den Port 5544 (fortlaufend für jede CCU ein Port) erreichen kann.
# - Alle Bezeichnungen in der CCU dürfen keines der folgenden Zeichen enthalten:
# <, >, ', ", &, $, [, ], {, } und \
# Dies ist aber schon Vorgabe von der CCU ! Wer es dennoch schafft solche Zeichen einzugeben
# muss mit Fehlern (auch auf der CCU!) rechnen.
#
# Verwendung:
#
# - Es muss wenigstens im Abschnitt Konfiguration eine CCU eingetragen werden.
# - Zusätzliche Einstellungen sind jeweils separat beschrieben.
# - Das Script ausführen.
# Sollte das Script mit einem Fehler beendet werden; einfach noch mal
# ausführen. Bereits angelegte Geräte werden übersprungen!
# Getestet mit ein recht umfangreichen Installation. Es waren am Ende über
# 2000 neue Variablen entstanden.
#
# ChangeLog:
#
# 15.02.2021
# Bugfix: Wenn Mapping zum Gewerk leer war, wurde der aktueller Status mit HM_RequestStatus nicht abgefragt.
# Bugfix: Wenn Mapping zum Gewerk leer war, wurde die Einstellung EmulateStatus nicht gesetzt.
# Neu: ROTARY_HANDLE_TRANSCEIVER für HmIP Drehgriffsensoren.
# Neu: SWITCH_TRANSMITTER für HmIP Schaltaktoren (nur Anzeige).
# Neu: MAINTENANCE für HmIP erweitert um LOW_BAT, SABOTAGE und OPERATING_VOLTAGE.
# Neu: CLIMATECONTROL_FLOOR_TRANSCEIVER für HmIP ergänzt..
# Neu: Alle Geräte von HmIP mit *CLIMATECONTROL* erweitert um:
# - Profilumschaltung
# - Temperatur Status
# - Frostschutz
# - Ventilöffnung
# - Adaptionsfahrt Status
# - Ventil Status
# - Notbetrieb
#
# 19.11.2017
# Neu: Homematic-IP wird unterstützt (sofern IPS-Version passt !)
# Neu: Verlinkung auf Gewerke (GewerkCat) kann deaktiviert werden.
# Neu: Erstellen von Hilfsvariablen und angepassten Aktions-Scripten kann
# deaktiviert werden. (ScriptCat)
# Bugfix: Es wurden Variablen falsch benannt und Fehler im Script erzeugt,
# wenn das Mapping unvollständig war (z.B. die ganzen TODO Einträge)
#
# 20.04.2017
# Bugfix: CURL-Sendet einen Header welche die CCU nicht unterstützt.
#
# 20.08.2015
# Neu: Diverse Geräte-Typen und Kanäle im Mapping ergänzt. Teilweise
# nur vorbereitet. Es fehlen bei den neuen Geräten noch viele Profile.
# Im Mapping an dem Kommentar // TODO zu erkennen.
#
# 29.07.2015
# Bugfix: Auf der CCU2 sind alle internen Interface-IDs der BidCos-Dienste
# nicht fest vergeben. Außer dem immer vorhandenen BidCos-RF.
# Wired-Geräte wurden darum nicht immer zuverlässig angelegt.
#
# 26.07.2015
# Bugfix: Enthält ein Kanal oder Gerät ein < oder > Zeichen im Namen,
# schlug das Laden der Daten von der CCU fehl.
#
# 02.07.2015
# Neu: Zusätzliche Variablen und Aktions-Scripte für die einfache Bedienung
# von bestimmen Geräten implementiert:
# - DIMMER & VIRTUAL_DIMMER
#
# Bugfix: Alle veralteten IPS_* PHP-Funktionen entfernt.
# Kleiner Anpassungen, damit das Script auf IPS 4.x besser läuft.
#
# 30.06.2015
# Neu: Mehr Profile (Neue Wand & Heizkörperthermostaten, BLIND-Geräte)
# Zusätzliche Variablen und Aktions-Scripte für die einfache Bedienung
# von bestimmen Geräten implementiert:
# - Neue Wand & Heizkörperthermostaten
# - BLIND-Geräte (Jalousie-Aktoren)
#
# BugFix: Die neuen Wand & Heizkörperthermostaten senden einige Statusvariablen
# erst nach einiger Zeit oder wenn der Modus umgeschaltet wurde.
# Ein neues Feld 'forceDP' im Mapping-Array erzwingt jetzt das Anlegen
# von Statusvariablen und fragt anschließend den Wert aus der CCU ab.
#
# ToDo:
# Fertige Aktions-Scripte für...
# die Party Modi-Umschaltung der Thermostaten.
# ....
#
#
# Konfiguration (1.CCU):
$HMCcuAddress[] = 'x.x.x.x'; // IP oder DNS Name
# Konfiguration (2.CCU):
//$HMCcuAddress[] = 'ccu'; // IP oder DNS Name
# Konfiguration IPS:
$OhneRaum = true; // true = alle Geräte anlegen, auch wenn kein Raum zugeordnet wurde.
// false = nur Geräte anlegen, welche in der CCU einem Raum zugeordnet wurden.
$MitStatusmeldungen= true; // true = Auch MAINTENANCE Kanäle anlegen.
// false = Keine MAINTENANCE Kanäle anlegen.
$RaumCat = 0; // ID für Kategorie der Räume // 0 = neu anlegen oder vorhandene im root suchen
$GewerkCat = 0; // ID für Kategorie Gewerke // 0 = neu anlegen oder vorhandene im root suchen // -1 = für nicht anlegen
$GewerkTyp = 1; // Gewerke anlegen als Kategorie (0) oder als Dummy-Instanz (1)
$ScriptCat = 0; // ID für HomeMatic Aktions-Scripte // 0 = neu anlegen oder im root suchen // -1= für nicht anlegen
// Datenpunkte wo 'Status emulieren' aktiv sein soll.
$Emulate = array('SET_TEMPERATURE', 'SETPOINT', 'LED_STATUS');
# MAPPING
#
# Hier werden die Kanaltypen mit ihren Datenpunkten konfiguriert.
# IPS legt bei vielen Datenpunkten (Variablen) automatisch ein
# richtiges Profil an. Jedoch entsprechen die Namen immer den
# Datenpunkt (z.B. STATE, LEVEL etc...)
#
# Die erste Ebene enthält alle Kanaltypen welche angelegt werden sollen.
# Ist ein Kanaltyp hier nicht angelegt und wird in der CCU gefunden,
# wird er nicht in IPS angelegt und dafür eine Meldung ausgegeben.
#
# Das Array innerhalb der Kanaltypen enthält alle Datenpunkte,
# welche nach den erzeugen in IPS noch weiter bearbeitet werden sollen.
#
# Folgende Felder müssen dafür vorhanden sein:
#
# 'Profil' : IPS kennt nicht für jeden Homematic Datenpunkt das korrekte Profil.
# Hier kann ein eigenen Profil erzwungen werden.
#
# 'Action' : IPS aktiviert für bestimme Datenpunkte automatisch eine Standardaktion.
# Leider auch für Geräte welche gar nicht schaltbar sind, wie Rauchmelder
# oder TKF. Mit false / true kann dieses Verhalten korrigiert werden.
#
# 'Name Raum' = Name der Variable unterhalb vom Gerät.
# Es stehen folgende Platzhalter zur Verfügung:
# %1$s = Name vom Gerät
# %2$s = Name vom Raum
#
# 'Name Gewerk' = Name des erzeugen Links innerhalb des Gewerkes, welcher auf die Variable zeigt.
# Es stehen folgende Platzhalter zur Verfügung:
# %1$s = Name vom Gerät
# %2$s = Name vom Raum
# %3$s = Name vom Gewerk
$TypMappingProfil = array(
'VIRTUAL_KEY' => array(),
'SMOKE_DETECTOR' => array(
'STATE' => array(
'Name Raum' => 'Auslösung',
'Name Gewerk' => '%1$s',
'Profil' => '~Alert',
'Action' => false
)
),
'SMOKE_DETECTOR_TEAM' => array(
'STATE' => array(
'Name Raum' => 'Auslösung',
'Name Gewerk' => '%1$s',
'Profil' => '~Alert',
'Action' => false
)
),
'KEY' => array(), // kein Zuordnung aber anlegen
'KEY_TRANSCEIVER' => array(), // kein Zuordnung aber anlegen
'RAINDETECTOR' => array(
'STATE' => array(
'Name Raum' => 'Regen',
'Name Gewerk' => 'Regen %2$s',
'Profil' => '~Raining', // ~Raining
'Action' => false
)
),
'RAINDETECTOR_HEAT' => array(
'STATE' => array(
'Name Raum' => 'Heizung Regensensor',
'Name Gewerk' => 'Heizung Regensensor %2$s',
'Profil' => '', // ~Switch
'Action' => true
)
),
'WEATHER' => array(
'TEMPERATURE' => array(
'Name Raum' => 'Temperatur',
'Name Gewerk' => 'Temperatur %2$s',
'Profil' => '', // ~Temperature
'Action' => false
),
'HUMIDITY' => array(
'Name Raum' => 'Luftfeuchte',
'Name Gewerk' => 'Luftfeuchte %2$s',
'Profil' => '', // ~Humidity
'Action' => false
),
'RAINING' => array(
'Name Raum' => 'Regen',
'Name Gewerk' => 'Regen %2$s',
'Profil' => '', // ~Raining
'Action' => false
),
'RAIN_COUNTER' => array(
'Name Raum' => 'Regenmenge',
'Name Gewerk' => 'Regenmenge %2$s',
'Profil' => '', // ~Rainfall
'Action' => false
),
'WIND_SPEED' => array(
'Name Raum' => 'Windgeschwindigkeit',
'Name Gewerk' => 'Windgeschwindigkeit %2$s',
'Profil' => '', // ~WindSpeed.kmh
'Action' => false
),
'WIND_DIRECTION' => array(
'Name Raum' => 'Windrichtung',
'Name Gewerk' => 'Windrichtung %2$s',
'Profil' => '', // ~WindDirection
'Action' => false
),
'WIND_DIRECTION_RANGE' => array(
'Name Raum' => 'Windrichtungsschwankung',
'Name Gewerk' => 'Windrichtungsschwankung %2$s',
'Profil' => '', // ~WindDirection
'Action' => false
),
'SUNSHINEDURATION' => array(
'Name Raum' => 'Sonnenscheindauer',
'Name Gewerk' => 'Sonnenscheindauer %2$s',
'Profil' => '', // OFFEN
'Action' => false
),
'BRIGHTNESS' => array(
'Name Raum' => 'Helligkeit',
'Name Gewerk' => 'Helligkeit %2$s',
'Profil' => '', // ~Brightness.HM
'Action' => false
),
'LOWBAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Battery
'Action' => false
),
'AIR_PRESSURE' => array(
'Name Raum' => 'Luftdruck',
'Name Gewerk' => 'Luftdruck %2$s',
'Profil' => '', // TODO int hPa
'Action' => false
)
),
'ROTARY_HANDLE_SENSOR' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '', // Window.HM
'Action' => false
),
'ERROR' => array(
'Name Raum' => 'Fehler',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // FEHLT
'Action' => false
),
'LOWBAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Battery
'Action' => false
)
),
'ROTARY_HANDLE_TRANSCEIVER' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '', // Window.HM
'Action' => false
)
),
'SWITCH_SENSOR' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '',
'Action' => true
),
'ERROR' => array(
'Name Raum' => 'Fehler',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // FEHLT
'Action' => false
),
'ERROR_SABOTAGE' => array(
'Name Raum' => 'Sabotage',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // FEHLT
'Action' => false
),
'LOWBAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Battery
'Action' => false
)
),
'SWITCH_PANIC' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '',
'Action' => true
),
'ERROR' => array(
'Name Raum' => 'Fehler',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // FEHLT
'Action' => false
),
'ERROR_SABOTAGE' => array(
'Name Raum' => 'Sabotage',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // FEHLT
'Action' => false
),
'LOWBAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Battery
'Action' => false
)
),
'ARMING' => array(
'STATE' => array(
'Name Raum' => 'Zustand Scharf',
'Name Gewerk' => '%1$s',
'Profil' => '', // FEHLT
'Action' => false
),
'ERROR_SABOTAGE' => array(
'Name Raum' => 'Sabotage',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // FEHLT
'Action' => false
),
'LOWBAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Battery
'Action' => false
)
),
'SWITCH_TRANSMITTER' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Switch
'Action' => false
)
),
'SWITCH_VIRTUAL_RECEIVER' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Switch
'Action' => true
)
),
'SWITCH' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Switch
'Action' => true
)
),
'DIGITAL_OUTPUT' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Switch
'Action' => true
)
),
'MAINTENANCE' => array(
/* 'RSSI_DEVICE'
'CONFIG_PENDING'
'UNREACH' */
'LOWBAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Battery
'Action' => false
),
'LOW_BAT' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '%1$s',
'Profil' => '~Battery',
'Action' => false
),
'OPERATING_VOLTAGE' => array(
'Name Raum' => 'Batteriespannung',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '~Volt',
'Action' => false
),
'SABOTAGE' => array(
'Name Raum' => 'Sabotage',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '~Alert',
'Action' => false
),
/* 'STICKY_UNREACH'
'RSSI_PEER' */
),
'CLIMATECONTROL_REGULATOR' => array(
'SETPOINT' => array(
'Name Raum' => 'Soll Temperatur',
'Name Gewerk' => 'Soll Temperatur %2$s',
'Profil' => '', // ~Temperature.HM
'Action' => true
)
),
'MOTION_DETECTOR' => array(
'MOTION' => array(
'Name Raum' => 'Bewegung',
'Name Gewerk' => 'Bewegung %2$s',
'Profil' => '', // ~Motion.HM
'Action' => false
),
'BRIGHTNESS' => array(
'Name Raum' => 'Helligkeit',
'Name Gewerk' => 'Helligkeit %2$s',
'Profil' => '', // ~Brightness.HM
'Action' => false
)
),
'DIMMER' => array(
'LEVEL' => array(
'Name Raum' => 'Level',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Intensity.1
'Action' => true
)
),
'VIRTUAL_DIMMER' => array(
'LEVEL' => array(
'Name Raum' => 'Level',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Intensity.1
'Action' => true
)
),
'CLIMATECONTROL_VENT_DRIVE' => array(
'VALVE_STATE' => array(
'Name Raum' => 'Ventilöffnung',
'Name Gewerk' => 'Ventilöffnung %2$s',
'Profil' => '', // ~Intensity.1
'Action' => false
)
),
'SHUTTER_CONTACT' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '~Window', // ~Window
'Action' => false
)
),
'SIGNAL_LED' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Switch
'Action' => true
)
),
'SIGNAL_CHIME' => array(
'STATE' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '', // ~Switch
'Action' => true
)
),
'BLIND' => array(
'LEVEL' => array(
'Name Raum' => 'Level',
'Name Gewerk' => '%1$s',
'Profil' => '', // ~Intensity.1
'Action' => true
)
),
'SENSOR' => array(
'SENSOR' => array(
'Name Raum' => 'Zustand',
'Name Gewerk' => '%1$s',
'Profil' => '~Alert',
'Action' => false
)
),
'CENTRAL_KEY' => array(), // kein Zuordnung aber anlegen
'DISPLAY' => array(), // kein Zuordnung aber anlegen
'ENERGIE_METER_TRANSMITTER' => array(
'CURRENT' => array(
'Name Raum' => 'Strom',
'Name Gewerk' => '%1$s Strom',
'Profil' => 'mAmpere.F',
'Action' => false
),
'ENERGY_COUNTER' => array(
'Name Raum' => 'Gesamter Verbrauch',
'Name Gewerk' => '%1$s Gesamter Verbrauch',
'Profil' => 'Wh.F',
'Action' => false
),
'FREQUENCY' => array(
'Name Raum' => 'Frequenz',
'Name Gewerk' => '%1$s Frequenz',
'Profil' => '~Hertz',
'Action' => false
),
'POWER' => array(
'Name Raum' => 'Leistung',
'Name Gewerk' => '%1$s Leistung',
'Profil' => '~Watt.3680',
'Action' => false
),
'VOLTAGE' => array(
'Name Raum' => 'Spannung',
'Name Gewerk' => '%1$s Spannung',
'Profil' => '~Volt',
'Action' => false
)
),
'POWERMETER' => array(
'CURRENT' => array(
'Name Raum' => 'Strom',
'Name Gewerk' => '%1$s Strom',
'Profil' => 'mAmpere.F',
'Action' => false
),
'ENERGY_COUNTER' => array(
'Name Raum' => 'Gesamter Verbrauch',
'Name Gewerk' => '%1$s Gesamter Verbrauch',
'Profil' => 'Wh.F',
'Action' => false
),
'FREQUENCY' => array(
'Name Raum' => 'Frequenz',
'Name Gewerk' => '%1$s Frequenz',
'Profil' => '~Hertz',
'Action' => false
),
'POWER' => array(
'Name Raum' => 'Leistung',
'Name Gewerk' => '%1$s Leistung',
'Profil' => '~Watt.3680',
'Action' => false
),
'VOLTAGE' => array(
'Name Raum' => 'Spannung',
'Name Gewerk' => '%1$s Spannung',
'Profil' => '~Volt',
'Action' => false
)
),
'LUXMETER' => array(
'LUX' => array(
'Name Raum' => 'Helligkeit',
'Name Gewerk' => 'Helligkeit %2$s',
'Profil' => '~Illumination.F',
'Action' => false
)
),
'DIGITAL_ANALOG_OUTPUT' => array(
'FREQUENCY' => array() // TODO float mHz
),
'DIGITAL_INPUT' => array(
'FREQUENCY' => array() // TODO float mHz
),
'DIGITAL_ANALOG_INPUT' => array(
'VALUE' => array() // TODO float
),
'INPUT_OUTPUT' => array(), // nur anlegen
'POWERMETER_IGL' => array( // TODO
'GAS_ENERGY_COUNTER' => array(), // TODO m³ float
'GAS_POWER' => array(), // TODO m³ float
'ENERGY_COUNTER' => array(), // TODO Wh float
'POWER' => array() // TODO W float
),
'POWERMETER_IEC1' => array( // TODO
'GAS_ENERGY_COUNTER' => array(), // TODO m³ float
'GAS_POWER' => array(), // TODO m³ float
'ENERGY_COUNTER' => array(), // TODO Wh float
'IEC_ENERGY_COUNTER' => array(), // TODO Wh float
'IEC_POWER' => array(), // TODO W float
'POWER' => array() // TODO W float
),
'POWERMETER_IEC2' => array( // TODO
'IEC_ENERGY_COUNTER' => array(), // TODO Wh float
'IEC_POWER' => array() // TODO W float
),
'STATUS_INDICATOR' => array( // TODO
'STATE' => array()
),
'KEYMATIC' => array( // TODO
'STATE' => array(), // OPEN = action RELOCK_DELAY =float write only
'STATE_UNCERTAIN' => array(),
),
'SENSOR_FOR_CARBON_DIOXIDE' => array(
'STATE' => array() // TODO
# 0 = LEVEL_NORMAL
# 1 = LEVEL_ADDED
# 2 = LEVEL_ADDED_STRONG
),
'ALARMACTUATOR' => array(
'STATE' => array() // TODO
),
'PULSE_SENSOR' => array(),
'TILT_SENSOR' => array(
'STATE' => array(
'Name Raum' => 'Neigung',
'Name Gewerk' => '%1$s',
'Profil' => '~Alert',
'Action' => false
)
),
'WINMATIC' => array(
'LEVEL' => array( // TODO
),
'STATE_UNCERTAIN' => array( // TODO bool
)
),
'AKKU' => array(
'LEVEL' => array( // TODO float
),
'STATUS' => array( // TODO int
# 0 = TRICKLE_CHARGE
# 1 = CHARGE
# 2 = DISCHARGE
# 3 = STATE_UNKNOWN
)
),
'WATERDETECTIONSENSOR' => array(
'STATE' => array(
'Name Raum' => 'Wasserstand',
'Name Gewerk' => '%1$s',
'Profil' => '', // TODO
# 0 = DRY
# 1 = WET
# 2 = WATER
'Action' => false
)
),
'CAPACITIVE_FILLING_LEVEL_SENSOR' => array(
'FILLING_LEVEL' => array(
'Name Raum' => 'Füllstand',
'Name Gewerk' => '%1$s',
'Profil' => '~Intensity.1',
'Action' => false
)
),
'WEATHER_TRANSMIT' => array(
'TEMPERATURE' => array(
'Name Raum' => 'Temperatur',
'Name Gewerk' => 'Temperatur %2$s',
'Profil' => '', // ~Temperature
'Action' => false
),
'HUMIDITY' => array(
'Name Raum' => 'Luftfeuchte',
'Name Gewerk' => 'Luftfeuchte %2$s',
'Profil' => '', // ~Humidity
'Action' => false
)
),
'THERMALCONTROL_TRANSMIT' => array(
'CONTROL_MODE' => array(
'Name Raum' => 'Betriebsmodus',
'Name Gewerk' => 'Betriebsmodus %2$s',
'Profil' => 'ControlMode.HM', // ~Mode.HM
'Action' => 'CLIMATECONTROL_SCRIPT'
),
'LOWBAT_REPORTING' => array(
'Name Raum' => 'Batterie',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '~Battery',
'Action' => false
),
// 'COMMUNICATION_REPORTING'
'WINDOW_OPEN_REPORTING' => array(
'Name Raum' => 'Fenster offen',
'Name Gewerk' => 'Fenster offen %2$s',
'Profil' => '~Window',
'Action' => false
),
'BATTERY_STATE' => array(
'Name Raum' => 'Batteriespannung',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '~Volt',
'Action' => false
),
'BOOST_STATE' => array(
'Name Raum' => 'Boost Status',
'Name Gewerk' => 'Boost Status %2$s',
'Profil' => '', // TODO
'Action' => false
),
'ACTUAL_TEMPERATURE' => array(
'Name Raum' => 'Temperatur',
'Name Gewerk' => 'Temperatur %2$s',
'Profil' => '', // ~Temperature
'Action' => false
),
'ACTUAL_HUMIDITY' => array(
'Name Raum' => 'Luftfeuchte',
'Name Gewerk' => 'Luftfeuchte %2$s',
'Profil' => '~Humidity.F',
'Action' => false
),
'SET_TEMPERATURE' => array(
'Name Raum' => 'Soll Temperatur',
'Name Gewerk' => 'Soll Temperatur %2$s',
'Profil' => '', // ~Temperature.HM
'Action' => true
),
'PARTY_TEMPERATURE' => array(
'Name Raum' => 'Party Temperatur',
'Name Gewerk' => 'Party Temperatur %2$s',
'Profil' => '~Temperature',
'Action' => false
),
'forceDP' => array('PARTY_START_DAY' => 1, 'PARTY_START_MONTH' => 1, 'PARTY_START_TIME' => 1, 'PARTY_START_YEAR' => 1, 'PARTY_STOP_DAY' => 1, 'PARTY_STOP_MONTH' => 1, 'PARTY_STOP_TIME' => 1, 'PARTY_STOP_YEAR' => 1, 'PARTY_TEMPERATURE' => 2)
),
'CLIMATECONTROL_RT_TRANSCEIVER' => array(
'CONTROL_MODE' => array(
'Name Raum' => 'Betriebsmodus',
'Name Gewerk' => 'Betriebsmodus %2$s',
'Profil' => 'ControlMode.HM', // ~Mode.HM
'Action' => 'CLIMATECONTROL_SCRIPT'
),
'BATTERY_STATE' => array(
'Name Raum' => 'Batteriespannung',
'Name Gewerk' => '', // nicht verlinken
'Profil' => '~Volt',
'Action' => false
),
'BOOST_STATE' => array(
'Name Raum' => 'Boost Status',
'Name Gewerk' => 'Boost Status %2$s',
'Profil' => '', // TODO
'Action' => false
),
'ACTUAL_TEMPERATURE' => array(
'Name Raum' => 'Temperatur',
'Name Gewerk' => 'Temperatur %2$s',
'Profil' => '', // ~Temperature
'Action' => false
),
'SET_TEMPERATURE' => array(
'Name Raum' => 'Soll Temperatur',
'Name Gewerk' => 'Soll Temperatur %2$s',
'Profil' => '', // ~Temperature.HM
'Action' => true
),
'PARTY_TEMPERATURE' => array(
'Name Raum' => 'Party Temperatur',
'Name Gewerk' => 'Party Temperatur %2$s',
'Profil' => '~Temperature',
'Action' => false
),
'VALVE_STATE' => array(
'Name Raum' => 'Ventilöffnung',
'Name Gewerk' => 'Ventilöffnung %2$s',
'Profil' => '', // ~Intensity.1
'Action' => false
),
'forceDP' => array('PARTY_START_DAY' => 1, 'PARTY_START_MONTH' => 1, 'PARTY_START_TIME' => 1, 'PARTY_START_YEAR' => 1, 'PARTY_STOP_DAY' => 1, 'PARTY_STOP_MONTH' => 1, 'PARTY_STOP_TIME' => 1, 'PARTY_STOP_YEAR' => 1, 'PARTY_TEMPERATURE' => 2)
//'FAULT_REPORTING' //fehlt
),
'CLIMATE_TRANSCEIVER' => array(
'ACTUAL_TEMPERATURE' => array(
'Name Raum' => 'Temperatur',
'Name Gewerk' => 'Temperatur %2$s',
'Profil' => '', // ~Temperature
'Action' => false
),
'HUMIDITY' => array(
'Name Raum' => 'Luftfeuchte',
'Name Gewerk' => 'Luftfeuchte %2$s',
'Profil' => '', // ~Humidity
'Action' => false
)
),
'BRIGHTNESS_TRANSMITTER' => array(
'CURRENT_ILLUMINATION' => array(
'Name Raum' => 'Aktuelle Helligkeit',
'Name Gewerk' => '%1$s aktuelle Helligkeit',
'Profil' => '~Illumination.F',
'Action' => false
),
'AVERAGE_ILLUMINATION' => array(
'Name Raum' => 'Durchschnittliche Helligkeit',
'Name Gewerk' => '%1$s durchschnittliche Helligkeit',
'Profil' => '~Illumination.F',
'Action' => false
),
'HIGHEST_ILLUMINATION' => array(
'Name Raum' => 'Maximale Helligkeit',
'Name Gewerk' => '%1$s maximale Helligkeit',
'Profil' => '~Illumination.F',
'Action' => false
),
'LOWEST_ILLUMINATION' => array(
'Name Raum' => 'Minimale Helligkeit',
'Name Gewerk' => '%1$s minimale Helligkeit',
'Profil' => '~Illumination.F',
'Action' => false
),
),
'WATER_DETECTION_TRANSMITTER' => array(
'WATERLEVEL_DETECTED' => array(
'Name Raum' => 'Wasserstand erkannt',
'Name Gewerk' => '%1$s Wasserstand erkannt',
'Profil' => '~Alert',
'Action' => false
),
'MOISTURE_DETECTED' => array(
'Name Raum' => 'Feuchtigkeit erkannt',
'Name Gewerk' => '%1$s Feuchtigkeit erkannt',
'Profil' => '~Alert',
'Action' => false
),
),
'SHUTTER_TRANSMITTER' => array(
'LEVEL' => array(
'Name Raum' => 'Rollladenhöhe',
'Name Gewerk' => '%1$s Rollladenhöhe',
'Profil' => '',
'Action' => false
),
'ACTIVITY_STATE' => array(
'Name Raum' => 'Fahraktivität',
'Name Gewerk' => '%1$s Fahraktivität',
'Profil' => 'BlindActivity.HM',
'Action' => false
),
),
'SHUTTER_VIRTUAL_RECEIVER' => array(
'LEVEL' => array(
'Name Raum' => 'Rollladenhöhe',
'Name Gewerk' => '%1$s Rollladenhöhe',
'Profil' => '',
'Action' => true
),
),
'HEATING_CLIMATECONTROL_TRANSCEIVER' => array(
'ACTIVE_PROFILE'=> array(
'Name Raum' => 'Aktives Zeitprofil',
'Name Gewerk' => 'aktives Zeitprofil %2$s',
'Profil' => 'HeatingControlProfile.HM',
'Action' => true
),
'ACTUAL_TEMPERATURE' => array(
'Name Raum' => 'Temperatur',
'Name Gewerk' => 'Temperatur %2$s',
'Profil' => '', // ~Temperature
'Action' => false
),
'ACTUAL_TEMPERATURE_STATUS' => array(
'Name Raum' => 'Temperatur Status',
'Name Gewerk' => 'Temperatur Status %2$s',
'Profil' => 'TemperaturState.HM',
'Action' => false
),
'FROST_PROTECTION' => array(
'Name Raum' => 'Frostschutz',
'Name Gewerk' => 'Frostschutz %2$s',
'Profil' => '~Switch',
'Action' => false
),
'HUMIDITY' => array(
'Name Raum' => 'Luftfeuchte',
'Name Gewerk' => 'Luftfeuchte %2$s',
'Profil' => '~Humidity',
'Action' => false
),
'SET_POINT_MODE' => array(
'Name Raum' => 'Betriebsmodus',
'Name Gewerk' => 'Betriebsmodus %2$s',
'Profil' => 'HeatingControlMode.HM',
'Action' => 'HEATING_CLIMATECONTROL_SCRIPT'
),
'SET_POINT_TEMPERATURE' => array(
'Name Raum' => 'Soll Temperatur',
'Name Gewerk' => 'Soll Temperatur %2$s',
'Profil' => '', // ~Temperature.HM
'Action' => true
),
'BOOST_MODE' => array(
'Name Raum' => 'Boost',
'Name Gewerk' => 'Boost %2$s',
'Profil' => '~Switch',
'Action' => 'WRITE_BOOLEAN_SCRIPT'
),
'WINDOW_STATE' => array(
'Name Raum' => 'Fenster',
'Name Gewerk' => 'Fenster %2$s',
'Profil' => 'WindowState.HM',
'Action' => 'WRITE_INTEGER_SCRIPT'
),
'HEATING_COOLING' => array(
'Name Raum' => 'Betriebsart',
'Name Gewerk' => 'Betriebsart %2$s',
'Profil' => 'HeatingCooling.HM',
'Action' => 'WRITE_INTEGER_SCRIPT'
),
'LEVEL' => array(
'Name Raum' => 'Ventilöffnung',
'Name Gewerk' => 'Ventilöffnung %2$s',
'Profil' => '~Intensity.1',
'Action' => true
),
'VALVE_ADAPTION' => array(
'Name Raum' => 'Adaptionsfahrt aktiv',
'Name Gewerk' => 'Adaptionsfahrt aktiv %2$s',
'Profil' => '~Switch',
'Action' => true
),
'VALVE_STATE' => array(
'Name Raum' => 'Status Ventil',
'Name Gewerk' => 'Status Ventil %2$s',
'Profil' => 'ValveError.HM',
'Action' => false
),
),
'CLIMATECONTROL_FLOOR_DIRECT_TRANSMITTER' => array(
'EMERGENCY_OPERATION' => array(
'Name Raum' => 'Verbindung',
'Name Gewerk' => 'Verbindung %2$s',
'Profil' => '~Alert',
'Action' => false
),
'FROST_PROTECTION' => array(
'Name Raum' => 'Frostschutz',
'Name Gewerk' => 'Frostschutz %2$s',
'Profil' => '~Alert',
'Action' => false
),
'HUMIDITY_ALARM' => array(
'Name Raum' => 'Luftfeuchte',
'Name Gewerk' => 'Luftfeuchte %2$s',
'Profil' => '~Alert',
'Action' => false
),
'STATE' => array(
'Name Raum' => 'Schaltzustand',
'Name Gewerk' => 'Schaltzustand %2$s',
'Profil' => '~Switch',
'Action' => false
),
),
'CLIMATECONTROL_FLOOR_TRANSCEIVER' => array(
'EMERGENCY_OPERATION' => array(
'Name Raum' => 'Notbetrieb',
'Name Gewerk' => 'Notbetrieb %2$s',
'Profil' => '~Alert',
'Action' => false
),
'FROST_PROTECTION' => array(
'Name Raum' => 'Frostschutz',
'Name Gewerk' => 'Frostschutz %2$s',
'Profil' => '~Switch',
'Action' => false
),
'LEVEL' => array(
'Name Raum' => 'Ventilöffnung',
'Name Gewerk' => 'Ventilöffnung %2$s',
'Profil' => '~Intensity.1',
'Action' => true
),
'VALVE_STATE' => array(
'Name Raum' => 'Status Ventil',
'Name Gewerk' => 'Status Ventil %2$s',
'Profil' => 'ValveError.HM',
'Action' => false
),
),
'SWITCH_INTERFACE' => array() // kein Zuordnung aber anlegen
);
$RequestState = array(
'STATE',
'LEVEL',
'SENSOR',
'SET_TEMPERATURE',
'SETPOINT',
'LOWBAT',
'HUMIDITY',
'TEMPERATURE',
'MOTION',
'BRIGHTNESS',
'ACTUAL_HUMIDITY',
'ACTUAL_TEMPERATURE',
'BATTERY_STATE',
'BOOST_STATE',
'CONTROL_MODE',
'LOWBAT_REPORTING',
'WINDOW_OPEN_REPORTING',
'VALVE_STATE',
'CURRENT',
'ENERGY_COUNTER',
'FREQUENCY',
'POWER',
'VOLTAGE',
'RAINING',
'RAIN_COUNTER',
'SUNSHINEDURATION',
'WIND_DIRECTION',
'WIND_DIRECTION_RANGE',
'WIND_SPEED',
'LED_STATUS',
'PARTY_TEMPERATURE',
'LUX',
'ACTIVITY_STATE',
'HEATING_COOLING',
'SET_POINT_TEMPERATURE',
'ACTUAL_TEMPERATURE_STATUS',
'FROST_PROTECTION',
'WINDOW_STATE',
'BOOST_MODE',
'SET_POINT_MODE',
'ACTIVE_PROFILE',
'OPERATING_VOLTAGE',
'LOW_BAT',
'SABOTAGE'
);
# ENDE Konfig MAPPING
// Nicht Standardprofile anlegen
if (!IPS_VariableProfileExists('Wh.F'))
{
IPS_CreateVariableProfile('Wh.F', 2);
IPS_SetVariableProfileDigits('Wh.F', 2);
IPS_SetVariableProfileText('Wh.F', '', ' Wh');
}
if (!IPS_VariableProfileExists('mAmpere.F'))
{
IPS_CreateVariableProfile('mAmpere.F', 2);
IPS_SetVariableProfileDigits('mAmpere.F', 2);
IPS_SetVariableProfileText('mAmpere.F', '', ' mA');
}
if ($ScriptCat != -1)
{
if (!IPS_VariableProfileExists('BlindControl.HM'))
{
IPS_CreateVariableProfile('BlindControl.HM', 1);
IPS_SetVariableProfileAssociation('BlindControl.HM', -1, 'Ab', '', 0x0000FF);
IPS_SetVariableProfileAssociation('BlindControl.HM', 0, 'Stop', '', 0x000000);
IPS_SetVariableProfileAssociation('BlindControl.HM', 1, 'Auf', '', 0x0000FF);
}
if (!IPS_VariableProfileExists('BlindActivity.HM'))
{
IPS_CreateVariableProfile('BlindActivity.HM', 1);
IPS_SetVariableProfileAssociation('BlindActivity.HM', 0, 'unbekannt', '', -1);
IPS_SetVariableProfileAssociation('BlindActivity.HM', 1, 'aufwärts', '', -1);
IPS_SetVariableProfileAssociation('BlindActivity.HM', 2, 'abwärts', '', -1);
IPS_SetVariableProfileAssociation('BlindActivity.HM', 3, 'steht', '', -1);
}
if (!IPS_VariableProfileExists('ControlTemp.HM'))
{
IPS_CreateVariableProfile('ControlTemp.HM', 1);
IPS_SetVariableProfileIcon('ControlTemp.HM', 'Temperature');
IPS_SetVariableProfileAssociation('ControlTemp.HM', 1, 'Absenk Temp', '', 0xff0000);
IPS_SetVariableProfileAssociation('ControlTemp.HM', 2, 'Komfort Temp', '', 0xff9900);
}
if (!IPS_VariableProfileExists('ControlMode.HM'))
{
IPS_CreateVariableProfile('ControlMode.HM', 1);
IPS_SetVariableProfileAssociation('ControlMode.HM', 0, 'Automatik', '', 0x339966);
IPS_SetVariableProfileAssociation('ControlMode.HM', 1, 'Manuell', '', 0xFF0000);
IPS_SetVariableProfileAssociation('ControlMode.HM', 2, 'Urlaub', '', 0x3366FF);
IPS_SetVariableProfileAssociation('ControlMode.HM', 3, 'Boost', '', 0xFFFF99);
}
if (!IPS_VariableProfileExists('HeatingControlMode.HM'))
{
IPS_CreateVariableProfile('HeatingControlMode.HM', 1);
IPS_SetVariableProfileAssociation('HeatingControlMode.HM', 0, 'Automatik', '', 0x339966);
IPS_SetVariableProfileAssociation('HeatingControlMode.HM', 1, 'Manuell', '', 0xFF0000);
}
if (!IPS_VariableProfileExists('DimmerControl.HM'))
{
IPS_CreateVariableProfile('DimmerControl.HM', 1);
IPS_SetVariableProfileIcon('DimmerControl.HM', 'Intensity');
IPS_SetVariableProfileAssociation('DimmerControl.HM', -2, '0 %', '', 0x0000FF);
IPS_SetVariableProfileAssociation('DimmerControl.HM', -1, 'Dunkler', '', 0x339966);
IPS_SetVariableProfileAssociation('DimmerControl.HM', 0, 'Stop', '', 0x000000);
IPS_SetVariableProfileAssociation('DimmerControl.HM', 1, 'Zurück', '', 0xFF0000);
IPS_SetVariableProfileAssociation('DimmerControl.HM', 2, 'Heller', '', 0x339966);
IPS_SetVariableProfileAssociation('DimmerControl.HM', 3, '100 %', '', 0x0000FF);
}
if (!IPS_VariableProfileExists('DimmerSpeed.HM'))
{
IPS_CreateVariableProfile('DimmerSpeed.HM', 2);
IPS_SetVariableProfileIcon('DimmerSpeed.HM', 'Intensity');
IPS_SetVariableProfileValues('DimmerSpeed.HM', 0, 30, 2);
IPS_SetVariableProfileText('DimmerSpeed.HM', '', ' s');
}
if (!IPS_VariableProfileExists('WindowState.HM'))
{
IPS_CreateVariableProfile('WindowState.HM', 1);
IPS_SetVariableProfileAssociation('WindowState.HM', 0, 'geschlossen', '', -1);
IPS_SetVariableProfileAssociation('WindowState.HM', 1, 'offen', '', -1);
}
if (!IPS_VariableProfileExists('HeatingCooling.HM'))
{
IPS_CreateVariableProfile('HeatingCooling.HM', 1);
IPS_SetVariableProfileAssociation('HeatingCooling.HM', 0, 'Heizen', '', -1);
IPS_SetVariableProfileAssociation('HeatingCooling.HM', 1, 'Kühlen', '', -1);
}
if (!IPS_VariableProfileExists('TemperaturState.HM'))
{
IPS_CreateVariableProfile('TemperaturState.HM', 1);
IPS_SetVariableProfileAssociation('TemperaturState.HM', 0, 'OK', '', -1);
IPS_SetVariableProfileAssociation('TemperaturState.HM', 1, 'unbekannt', '', -1);
IPS_SetVariableProfileAssociation('TemperaturState.HM', 2, 'überheizt', '', 0xFF0000);
IPS_SetVariableProfileAssociation('TemperaturState.HM', 3, 'unterkühlt', '', 0x0000FF);
}
if (!IPS_VariableProfileExists('ValveError.HM'))
{
IPS_CreateVariableProfile('ValveError.HM', 1);
IPS_SetVariableProfileAssociation('ValveError.HM', 0, 'unbekannt', '', -1);
IPS_SetVariableProfileAssociation('ValveError.HM', 1, 'nicht installiert', '', -1);
IPS_SetVariableProfileAssociation('ValveError.HM', 2, 'wartet auf Adaptionsfahrt', '', -1);
IPS_SetVariableProfileAssociation('ValveError.HM', 3, 'Adaptionsfahrt läuft', '', -1);
IPS_SetVariableProfileAssociation('ValveError.HM', 4, 'fertig', '', -1);
IPS_SetVariableProfileAssociation('ValveError.HM', 5, 'Ventil schwergängig', '', 0x339966);
IPS_SetVariableProfileAssociation('ValveError.HM', 6, 'Stellbereich zu groß', '', 0x339966);
IPS_SetVariableProfileAssociation('ValveError.HM', 7, 'Stellbereich zu klein', '', 0x339966);
IPS_SetVariableProfileAssociation('ValveError.HM', 8, 'Notbetrieb', '', 0xFF0000);
}
if (!IPS_VariableProfileExists('HeatingControlProfile.HM'))
{
IPS_CreateVariableProfile('HeatingControlProfile.HM', 1);
IPS_SetVariableProfileValues('HeatingControlProfile.HM',1,3,0);
}
$AddOnMappings = array(
'BLIND' => array(
'CONTROL' => array(
'Name Raum' => 'Steuerung',
'Name Gewerk' => 'Steuerung %2$s',
'Profil' => 'BlindControl.HM',
'Action' => 'BLIND_SCRIPT',
'VarTyp' => 1
)
),
'SHUTTER_VIRTUAL_RECEIVER' => array(
'CONTROL' => array(
'Name Raum' => 'Steuerung',
'Name Gewerk' => 'Steuerung %2$s',
'Profil' => 'BlindControl.HM',
'Action' => 'BLIND_SCRIPT',
'VarTyp' => 1
)
),
'THERMALCONTROL_TRANSMIT' => array(
'CONTROL_TEMP' => array(
'Name Raum' => 'Soll Temperatur Vorwahl',
'Name Gewerk' => 'Soll Temperatur Vorwahl %2$s',
'Profil' => 'ControlTemp.HM',
'Action' => 'CONTROL_TEMP_SCRIPT',
'VarTyp' => 1
)
),
'CLIMATECONTROL_RT_TRANSCEIVER' => array(
'CONTROL_TEMP' => array(
'Name Raum' => 'Soll Temperatur Vorwahl',
'Name Gewerk' => 'Soll Temperatur Vorwahl %2$s',
'Profil' => 'ControlTemp.HM',
'Action' => 'CONTROL_TEMP_SCRIPT',
'VarTyp' => 1
)
),
'DIMMER' => array(
'DIMMER_CONTROL' => array(
'Name Raum' => 'Steuerung',
'Name Gewerk' => 'Steuerung %2$s',
'Profil' => 'DimmerControl.HM',
'Action' => 'DIMMER_SCRIPT',
'VarTyp' => 1
),
'RAMP_TIME' => array(
'Name Raum' => 'Geschwindigkeit',
'Name Gewerk' => 'Geschwindigkeit %2$s',
'Profil' => 'DimmerSpeed.HM',
'Action' => 'DIMMER_SCRIPT',
'VarTyp' => 2
)
),
'VIRTUAL_DIMMER' => array(
'DIMMER_CONTROL' => array(
'Name Raum' => 'Steuerung',
'Name Gewerk' => 'Steuerung %2$s',
'Profil' => 'DimmerControl.HM',
'Action' => 'DIMMER_SCRIPT',
'VarTyp' => 1
),
'RAMP_TIME' => array(
'Name Raum' => 'Geschwindigkeit',
'Name Gewerk' => 'Geschwindigkeit %2$s',
'Profil' => 'DimmerSpeed.HM',
'Action' => 'DIMMER_SCRIPT',
'VarTyp' => 2
)
),
);
}
if ($RaumCat == 0) // neu anlegen oder im root suchen
{
$RaumCat = GetOrCreateCategoryByName(0, "Räume");
}
else // vorhanden ?
{
$parent = @IPS_GetObject($RaumCat);
if ($parent === false)
die("Manuelle Angabe der ID für Räume fehlerhaft!");
}
if ($GewerkCat == 0) // neu anlegen oder im root suchen
{
$GewerkCat = GetOrCreateCategoryByName(0, "Gewerke");
}
elseif ($GewerkCat >0) // vorhanden ?
{
$parent = @IPS_GetObject($GewerkCat);
if ($parent === false)
die("Manuelle Angabe der ID für Gewerke fehlerhaft!");
}
if ($ScriptCat == 0) // neu anlegen oder im root suchen
{
$ScriptCat = GetOrCreateCategoryByName(0, "Aktions-Scripte");
}
elseif ($ScriptCat >0) // vorhanden ?
{
$parent = @IPS_GetObject($ScriptCat);
if ($parent === false)
die("Manuelle Angabe der ID für Scripte fehlerhaft!");
}
ini_set('max_execution_time', count($HMCcuAddress) * 120);
//HM Sockets prüfen und einrichten
$nextPort = 5544;
$HMSockets = array_flip($HMCcuAddress);
$HMSocketsOld = IPS_GetInstanceListByModuleID("{A151ECE9-D733-4FB9-AA15-7F7DD10C58AF}");
if (count($HMSocketsOld) > 0)
{
foreach ($HMSocketsOld as $HMSocket)
{
$HMSocketIDsOld[IPS_GetProperty($HMSocket, 'Host')] = $HMSocket;
$Port = IPS_GetProperty($HMSocket, 'Port');
if ($Port >= $nextPort)
$nextPort = $Port + 1;
}
$HMSockets = array_merge($HMSockets, $HMSocketIDsOld); //IDs von Old zu Sockets mappen
}
foreach ($HMCcuAddress as $key => $IP)
{
if ($HMSockets[$IP] < 10000)
{ //neu anlegen und port berechnen ?
$xml = ReadCCUInterfaces($IP);
if ($xml[0] === false)
die($xml[1]);
$OpenRF = (count($xml->xpath('//Interface[@Name="BidCos-RF"]')) > 0);
$OpenHmIP = (count($xml->xpath('//Interface[@Name="HmIP-RF"]')) > 0);
$OpenWired = (count($xml->xpath('//Interface[@Name="BidCos-Wired"]')) > 0);
# "Erzeuge HomeMatic-Socket für CCU mit der Adresse " . $IP . PHP_EOL." Und lege den Ereignis-Server in IPS auf Port " . $nextPort.PHP_EOL;
echo "--------------------------------------------------------------------" . PHP_EOL;
$ObjID = IPS_CreateInstance("{A151ECE9-D733-4FB9-AA15-7F7DD10C58AF}");
usleep(50000 /* [Objekt #50000 existiert nicht] */);
IPS_SetName($ObjID, "HomeMatic Socket - " . $IP);
$Config = json_decode(IPS_GetConfiguration($ObjID),true);
$Config['Host']= $IP;
$Config['Open']= true;
$Config['Port']= $nextPort;
if (array_key_exists('Mode', $Config))
{
$Config['Mode']= $OpenWired ? 0 : 1;
if ($OpenHmIP)
echo "--------ACHTUNG HOMEMATIC IP INTERFACE GEFUNDEN ! IPS VERSION IST ABER ZU ALT ! -----".PHP_EOL;
} else {
$Config['RFOpen'] = $OpenRF;
$Config['WROpen'] = $OpenWired;
$Config['IPOpen'] = $OpenHmIP;
}
IPS_SetConfiguration($ObjID,json_encode($Config));
usleep(50000 /* [Objekt #50000 existiert nicht] */);
@IPS_ApplyChanges($ObjID);
$nextPort++;
$HMSockets[$IP] = $ObjID;
}
}
$HMDevices = IPS_GetInstanceListByModuleID("{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}");
$HMAdresses = array();
foreach ($HMDevices as $HMDevice) // vorhandene HM-Instanzen einlesen
{
$HMAdresses[] = IPS_GetProperty($HMDevice, "Address");
}
foreach ($HMCcuAddress as $Key)
{
$HMParent = $HMSockets[$Key];
if (IPS_GetInstance($HMParent)['InstanceStatus'] <> 102)
{
if (IPS_GetInstance($HMParent)['InstanceStatus'] >= 200)
{
if (@IPS_ApplyChanges($HMSocket) === false)
echo "Homematic-Socket (" . IPS_GetName($HMParent) . ") mit der InstanzID " . $HMParent . " konnte nicht reaktiviert werden." . PHP_EOL;
}
if (IPS_GetInstance($HMParent)['InstanceStatus'] <> 102)
{
echo "Homematic-Socket (" . IPS_GetName($HMParent) . ") mit der InstanzID " . $HMParent . " ist nicht aktiv." . PHP_EOL;
echo " Überspringe alle Geräte dieser CCU" . PHP_EOL;
echo "--------------------------------------------------------------------" . PHP_EOL;
continue;
}
}
$xml = ReadCCUDevices($Key);
if ($xml[0] === false)
die($xml[1]);
foreach ($xml->Room as $Room)
{
$Rooms[(string) $Room['Name']] = GetOrCreateCategoryByName($RaumCat, (string) $Room['Name']);
}
if ($OhneRaum)
$Rooms['# Ohne Raum'] = GetOrCreateCategoryByName($RaumCat, '# Ohne Raum');
if ($MitStatusmeldungen)
$Rooms['# Statusmeldungen'] = GetOrCreateCategoryByName($RaumCat, '# Statusmeldungen');
if ($GewerkCat != -1)
{
foreach ($xml->{'Function'} as $Function) // Gewerke erzeugen
{
if ($GewerkTyp == 0)
$Functions[(string) $Function['Name']] = GetOrCreateCategoryByName($GewerkCat, (string) $Function['Name']);
elseif ($GewerkTyp == 1)
$Functions[(string) $Function['Name']] = GetOrCreateDummyByName($GewerkCat, (string) $Function['Name']);
}
}
foreach ($xml->Device as $Device)
{
foreach ($Device->Channel as $Channel)
{
// Device nicht erzeugen, wenn...
//schon vorhanden
if (in_array((string) $Channel['Address'], $HMAdresses))
continue;
// kein Raum zugeordnet und ohne Raumzuordnung soll nicht erzeugt werden
if (!isset($Channel->Room[0]['Name']) and ! $OhneRaum)
continue;
// Interface ermitteln
switch ((string) $Device['Interface'])
{
case 'BidCos-RF':
$Protocol = 0;
break;
case 'BidCos-Wired':
$Protocol = 1;
break;
case 'HmIP-RF':
$Protocol = 2;
break;
default: // falsches Interface (nicht HmIP, Radio oder Wired. Wie Enocean oder CUxD)
// echo "Gerät mit der Addresse " . (string) $Channel['Address'] . " hat keine unterstütztes Interface (" . (string) $Device['Interface'] . ")." . PHP_EOL;
// echo " Gerät mit Namen '" . (string) $Channel['Name'] . "' wird nicht erzeugt." . PHP_EOL;
// echo "--------------------------------------------------------------------" . PHP_EOL;
continue 2;
}
// Datenpunkte im XML zählen... wenn 0 nicht anlegen
if (count($Channel->xpath('Point')) == 0)
continue;
// Typ vom Gerät aus der XML auswerten... für passendes Profil bestimmter DPs
if (!array_key_exists((string) $Channel['ChnLabel'], $TypMappingProfil))
{
echo "Gerät mit der Adresse " . (string) $Channel['Address'] . " hat keinen bekannten Kanaltyp (" . (string) $Channel['ChnLabel'] . ")." . PHP_EOL;
echo " Gerät mit Namen '" . (string) $Channel['Name'] . "' wird nicht erzeugt." . PHP_EOL;
echo "--------------------------------------------------------------------" . PHP_EOL;
continue;
}
$Mapping = $TypMappingProfil[(string) $Channel['ChnLabel']];
// Für Geräte ohne Raum den Pseudo-Raumnamen angeben.
if (!isset($Channel->Room[0]['Name']))
{
$Room = $Channel->addChild('Room');
if ((string) $Channel['ChnLabel'] == 'MAINTENANCE')
{
if (!$MitStatusmeldungen)
continue;
$Room->addAttribute('Name', '# Statusmeldungen');
}
else
$Room->addAttribute('Name', '# Ohne Raum');
}
$HMDevice = GetOrCreateHMDevice($Rooms[(string) $Channel->Room[0]['Name']], (string) $Channel['Name'], (string) $Channel['Address'], $Protocol, $HMParent);
// Jetzt zusätzliche Elemente Erzeugen
if ($ScriptCat != -1)
{
if (array_key_exists((string) $Channel['ChnLabel'], $AddOnMappings))
{
$AddOnMapping = $AddOnMappings[(string) $Channel['ChnLabel']];
foreach ($AddOnMapping as $ident => $Var)
{
$VarId = IPS_CreateVariable($Var['VarTyp']);
IPS_SetParent($VarId, $HMDevice);
IPS_SetName($VarId, $ident);
IPS_SetIdent($VarId, $ident);
}
$Mapping = array_merge($Mapping, $AddOnMapping);
}
}
if (array_key_exists('forceDP', $Mapping))
{
foreach ($Mapping['forceDP'] as $ident => $VarTyp)
{
if (@IPS_GetObjectIDByIdent($ident, $HMDevice) === false)
{
$VarId = IPS_CreateVariable($VarTyp);
IPS_SetParent($VarId, $HMDevice);
IPS_SetName($VarId, $ident);
IPS_SetIdent($VarId, $ident);
}
@HM_RequestStatus($HMDevice, $ident);
}
}
$Childs = IPS_GetChildrenIDs($HMDevice);
if (count($Childs) == 0)
{
echo "Gerät mit der Adresse " . (string) $Channel['Address'] . " hat keine Datenpunkte." . PHP_EOL;
echo " Gerät mit Namen '" . (string) $Channel['Name'] . "' wird wieder gelöscht." . PHP_EOL;
echo "--------------------------------------------------------------------" . PHP_EOL;
IPS_DeleteInstance($HMDevice);
continue;
}
$DeviceHidden = true;
foreach ($Childs as $Var)
{
$Obj = IPS_GetObject($Var);
if (!array_key_exists($Obj['ObjectIdent'], $Mapping))
{
IPS_SetHidden($Var, true);
continue;
}
if (array_key_exists('Name Raum',$Mapping[$Obj['ObjectIdent']]))
{
$Name = sprintf($Mapping[$Obj['ObjectIdent']]['Name Raum'], (string) $Channel['Name'], (string) $Channel->Room[0]['Name']);
IPS_SetName($Var, $Name);
}
if (array_key_exists('Profil',$Mapping[$Obj['ObjectIdent']]))
{
// Profil ändern, wenn nicht leer im Mapping
if ($Mapping[$Obj['ObjectIdent']]['Profil'] <> '')
{
if (!@IPS_SetVariableCustomProfile($Var, $Mapping[$Obj['ObjectIdent']]['Profil']))
{
echo "Fehler bei Gerät mit der Adresse " . (string) $Channel['Address'] . " und Datenpunkt " . $Obj['ObjectIdent'] . PHP_EOL;
echo " Profil '" . $Mapping[$Obj['ObjectIdent']]['Profil'] . "' konnte nicht zugewiesen werden." . PHP_EOL;
echo "--------------------------------------------------------------------" . PHP_EOL;
}
}
}
if (array_key_exists('Action',$Mapping[$Obj['ObjectIdent']]))
{
if (IPS_GetVariable($Var)['VariableAction'] > 0)
{ // Standardaktion möglich
if ($Mapping[$Obj['ObjectIdent']]['Action'] === true)
IPS_SetVariableCustomAction($Var, 0);
elseif ($Mapping[$Obj['ObjectIdent']]['Action'] === false)
IPS_SetVariableCustomAction($Var, 1);
} else
{
if ($Mapping[$Obj['ObjectIdent']]['Action'] === true)
{
echo "Gerät mit der Adresse " . (string) $Channel['Address'] . " hat keine Standardaktion," . PHP_EOL;
echo " für den Datenpunkt " . $Obj['ObjectIdent'] . " des Gerätes mit Namen '" . (string) $Channel['Name'] . "'." . PHP_EOL;
echo "--------------------------------------------------------------------" . PHP_EOL;
}
}
if (is_string($Mapping[$Obj['ObjectIdent']]['Action']) && ($ScriptCat != -1))
{
IPS_SetVariableCustomAction($Var, GetOrCreateScript($ScriptCat, $Mapping[$Obj['ObjectIdent']]['Action']));
}
}
if (in_array($Obj['ObjectIdent'], $Emulate))
{
IPS_SetProperty($HMDevice, 'EmulateStatus', true);
usleep(50000 /* [Objekt #50000 existiert nicht] */);
IPS_ApplyChanges($HMDevice);
}
if (in_array($Obj['ObjectIdent'], $RequestState)) {
@HM_RequestStatus($HMDevice, $Obj['ObjectIdent']);
}
$DeviceHidden = false;
if ($GewerkCat != -1)
{
if (array_key_exists('Name Gewerk',$Mapping[$Obj['ObjectIdent']]))
{
// Link erzeugen zu Gewerk wenn Mapping nicht leer ist
if ($Mapping[$Obj['ObjectIdent']]['Name Gewerk'] == '') {
continue;
}
//
// Schleife Gewerk
foreach ($Channel->{'Function'} as $Function)
{
$Name = sprintf($Mapping[$Obj['ObjectIdent']]['Name Gewerk'], (string) $Channel['Name'], (string) $Channel->Room[0]['Name'], (string) $Function['Name']);
$LnkID = IPS_CreateLink();
IPS_SetLinkTargetID($LnkID, $Var);
IPS_SetName($LnkID, $Name);
IPS_SetParent($LnkID, $Functions[(string) $Function['Name']]);
}
}
}
}
if ($DeviceHidden)
IPS_SetHidden($HMDevice, true);
}
$HMNewAdresses[] = (string) $Channel['Address'];
}
/* if (!isset($HMNewAdresses))
die("Keine neuen Geräte gefunden!");
var_dump($HMNewAdresses); */
}
function ReadCCUInterfaces($ip)
{
$Script = '
string index; ! Indexvariable
WriteLine("");
string SysVars=dom.GetObject(ID_INTERFACES).EnumUsedIDs();
foreach (index, SysVars)
{
Write("");
}
WriteLine("");
';
$rawdata = LoadHMScript($ip, $Script);
if ($rawdata === false)
return array(false, "Konnte HM-Daten nicht laden.");
$pos = strrpos($rawdata, '');
$data = utf8_encode(substr($rawdata, 0, $pos));
$xml = @new SimpleXMLElement("" . $data);
if ($xml === false)
return array(false, "XML malformed");
return $xml;
}
function ReadCCUDevices($ip)
{
$Script = 'string index; ! Indexvariable
string index2;
string index3;
WriteLine("");
string SysVars=dom.GetObject(ID_ROOMS).EnumUsedIDs();
foreach (index, SysVars)
{
Write("");
}
string SysVars=dom.GetObject(ID_FUNCTIONS).EnumUsedIDs();
foreach (index, SysVars)
{
Write("");
}
string SysVars=dom.GetObject(ID_DEVICES).EnumUsedIDs();
foreach (index, SysVars)
{
Write("");
Write("Name=\"" # Name # "\" ");
Write("Interface=\"" # dom.GetObject(oitemID.Interface()));
WriteLine("\">");
foreach (index2, oitemID.Channels())
{
Write("");
Write("Name=\"" # Name2 # "\" ");
Write("Address=\"" # oitemID2.Address() # "\" ");
Write("ChnLabel=\"" # oitemID2.ChnLabel() # "\"");
WriteLine(">");
foreach (index3, oitemID2.ChnFunction())
{
Write("");
WriteLine("Name=\"" # Name3 # "\" />");
}
foreach (index3, oitemID2.ChnRoom())
{
Write("");
}
foreach (index3, oitemID2.DPs())
{
Write("");
}
WriteLine("");
}
WriteLine("");
}
WriteLine("");';
$rawdata = LoadHMScript($ip, $Script);
if ($rawdata === false)
return array(false, "Konnte HM-Daten nicht laden.");
$pos = strrpos($rawdata, '');
$data = utf8_encode(substr($rawdata, 0, $pos));
// var_dump($data);
// die;
$xml = @new SimpleXMLElement("" . $data);
if ($xml === false)
return array(false, "XML malformed");
return $xml;
}
function GetOrCreateHMDevice($Parent, $Name, $Address, $Protocol, $HMParent)
{
$ObjID = IPS_CreateInstance("{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}");
if (IPS_GetInstance($ObjID)['ConnectionID'] <> $HMParent)
{
IPS_DisconnectInstance($ObjID);
IPS_ConnectInstance($ObjID, $HMParent);
}
IPS_SetParent($ObjID, $Parent);
IPS_SetName($ObjID, $Name);
IPS_SetProperty($ObjID, 'Address', $Address);
IPS_SetProperty($ObjID, 'Protocol', $Protocol);
IPS_SetProperty($ObjID, 'EmulateStatus', false);
usleep(50000 /* [Objekt #50000 existiert nicht] */);
@IPS_ApplyChanges($ObjID);
return $ObjID;
}
function GetOrCreateCategoryByName($Parent, $Name)
{
$ObjID = @IPS_GetObjectIDByName($Name, $Parent);
if ($ObjID == 0)
{
$ObjID = IPS_CreateCategory();
IPS_SetParent($ObjID, $Parent);
IPS_SetName($ObjID, $Name);
}
return $ObjID;
}
function GetOrCreateDummyByName($Parent, $Name)
{
$ObjID = @IPS_GetObjectIDByName($Name, $Parent);
if ($ObjID == 0)
{
$ObjID = IPS_CreateInstance("{485D0419-BE97-4548-AA9C-C083EB82E61E}");
IPS_SetParent($ObjID, $Parent);
IPS_SetName($ObjID, $Name);
}
return $ObjID;
}
function LoadHMScript($HMAddress, $HMScript)
{
$header[] = "Accept: text/plain,text/xml,application/xml,application/xhtml+xml,text/html";
$header[] = "Cache-Control: max-age=0";
$header[] = "Connection: close";
$header[] = "Accept-Charset: UTF-8";
$header[] = "Content-type: text/plain;charset=\"UTF-8\"";
$ch = curl_init('http://' . $HMAddress . ':8181/ReadAll.exe');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $HMScript);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 20000);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 20000);
$result = curl_exec($ch);
curl_close($ch);
if ($result === false)
{
return false;
}
return $result;
}
function GetOrCreateScript($parent, $ident)
{
$ObjId = @IPS_GetObjectIDByIdent($ident, $parent);
if ($ObjId === false)
{
$ObjId = IPS_CreateScript(0);
IPS_SetParent($ObjId, $parent);
IPS_SetIdent($ObjId, $ident);
IPS_SetName($ObjId, $ident);
IPS_SetScriptContent($ObjId, ScriptContent($ident));
}
return $ObjId;
}
function ScriptContent($ident)
{
$data = array(
'BLIND_SCRIPT' =>
'
$target = IPS_GetParent($_IPS[\'VARIABLE\']);
switch ($_IPS[\'VALUE\'])
{
case -1:
HM_WriteValueFloat($target,\'LEVEL\',0);
break;
case 0:
HM_WriteValueBoolean($target,\'STOP\',true);
break;
case 1:
HM_WriteValueFloat($target,\'LEVEL\',1);
break;
}
?>',
'CLIMATECONTROL_SCRIPT' =>
'
$target = IPS_GetParent($_IPS[\'VARIABLE\']);
switch ($_IPS[\'VALUE\'])
{
case 0:
HM_WriteValueBoolean($target,\'AUTO_MODE\',true);
break;
case 1:
HM_WriteValueFloat($target,\'MANU_MODE\',GetValueFloat(IPS_GetObjectIDByIdent(\'SET_TEMPERATURE\',$target)));
break;
case 2:
//\'PARTY_MODE_SUBMIT\' fehlt noch
break;
case 3:
HM_WriteValueBoolean($target,\'BOOST_MODE\',true);
break;
}
?>',
'HEATING_CLIMATECONTROL_SCRIPT' =>
'
$target = IPS_GetParent($_IPS[\'VARIABLE\']);
switch ($_IPS[\'VALUE\'])
{
case 0:
HM_WriteValueInteger($target,\'CONTROL_MODE\', 0);
break;
case 1:
HM_WriteValueInteger($target,\'CONTROL_MODE\', 1);
break;
}
?>',
'WRITE_BOOLEAN_SCRIPT' =>
'
$r = IPS_GetObject($_IPS[\'VARIABLE\']);
$ident = $r[\'ObjectIdent\'];
$target = $r[\'ParentID\'];
HM_WriteValueBoolean($target,$ident, $_IPS[\'VALUE\']);
?>',
'WRITE_INTEGER_SCRIPT' =>
'
$r = IPS_GetObject($_IPS[\'VARIABLE\']);
$ident = $r[\'ObjectIdent\'];
$target = $r[\'ParentID\'];
HM_WriteValueInteger($target,$ident, $_IPS[\'VALUE\']);
?>',
'WRITE_FLOAT_SCRIPT' =>
'
$r = IPS_GetObject($_IPS[\'VARIABLE\']);
$ident = $r[\'ObjectIdent\'];
$target = $r[\'ParentID\'];
HM_WriteValueFloat($target,$ident, $_IPS[\'VALUE\']);
?>',
'CONTROL_TEMP_SCRIPT' =>
'
$target = IPS_GetParent($_IPS[\'VARIABLE\']);
switch ($_IPS[\'VALUE\'])
{
case 1:
HM_WriteValueBoolean($target,\'LOWERING_MODE\',true);
break;
case 2:
HM_WriteValueBoolean($target,\'COMFORT_MODE\',true);
break;
}
?>',
'DIMMER_SCRIPT' =>
'
$target = IPS_GetParent($_IPS[\'VARIABLE\']);
switch (IPS_GetObject($_IPS[\'VARIABLE\'])[\'ObjectIdent\'])
{
case \'DIMMER_CONTROL\':
switch ($_IPS[\'VALUE\'])
{
case -2:
HM_WriteValueFloat($target,\'LEVEL\',0);
break;
case -1:
HM_WriteValueFloat($target,\'RAMP_TIME\',GetValueFloat(IPS_GetObjectIDByIdent(\'RAMP_TIME\',$target)));
HM_WriteValueFloat($target,\'LEVEL\',0);
break;
case 0:
HM_WriteValueBoolean($target,\'RAMP_STOP\',true);
HM_WriteValueBoolean($target,\'OLD_LEVEL\',true);
break;
case 1:
HM_WriteValueBoolean($target,\'OLD_LEVEL\',true);
break;
case 2:
HM_WriteValueFloat($target,\'RAMP_TIME\',GetValueFloat(IPS_GetObjectIDByIdent(\'RAMP_TIME\',$target)));
HM_WriteValueFloat($target,\'LEVEL\',1);
break;
case 3:
HM_WriteValueFloat($target,\'LEVEL\',1);
break;
}
break;
case \'RAMP_TIME\':
SetValueFloat($_IPS[\'VARIABLE\'],$_IPS[\'VALUE\']);
break;
}
?>'
);
return $data[$ident];
}