Skip to content
This repository has been archived by the owner on Aug 21, 2019. It is now read-only.

Commit

Permalink
add RGB Multiplexer module
Browse files Browse the repository at this point in the history
  • Loading branch information
paresy committed Mar 22, 2018
1 parent 0e16aec commit 955a9e0
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ Folgende Module beinhaltet das SymconMisc Repository:
- __Rechen-Modul__ ([Dokumentation](Rechenmodul))
Berechnung verschiedener Hilfswerte auf Basis einer Gruppe von Variablen, z.B. Summer oder Durchschnitt.

- __RGB-Multiplexer__ ([Dokumentation](RGBMultiplexer))
Verbindet einzelne R, G, B Kanäle zu einer Variable, welche mit dem Farbrad angesteuert werden kann.

- __Szenen-Steuerung__ ([Dokumentation](SzenenSteuerung))
Speichert den Zustand einer belieben Anzahl an Aktoren und macht diese via WebFront/PHP-Funktion abrufbar.

Expand Down
71 changes: 71 additions & 0 deletions RGBMultiplexer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# RGB-Multiplexer

### Inhaltverzeichnis

1. [Funktionsumfang](#1-funktionsumfang)
2. [Voraussetzungen](#2-voraussetzungen)
3. [Software-Installation](#3-software-installation)
4. [Einrichten der Instanzen in IP-Symcon](#4-einrichten-der-instanzen-in-ip-symcon)
5. [Statusvariablen und Profile](#5-statusvariablen-und-profile)
6. [WebFront](#6-webfront)
7. [PHP-Befehlsreferenz](#7-php-befehlsreferenz)

### 1. Funktionsumfang

* Bietet ein Farbrad an, welches im Hintergrund drei einzelne R, G, B Kanäle ansteuert
* Sollten die R, G, B Kanäle den Wert ändern wird der neue Zustand auch ins Farbrad übertragen

### 2. Voraussetzungen

- IP-Symcon ab Version 4.x

### 3. Software-Installation

Über das Modul-Control folgende URL hinzufügen.
`git://github.com/paresy/SymconMisc.git`

### 4. Einrichten der Instanzen in IP-Symcon

- Unter "Instanz hinzufügen" ist das 'RGB Multiplexer'-Modul unter dem Hersteller '(Sonstige)' aufgeführt.

__Konfigurationsseite__:

Name | Beschreibung
------------------- | ---------------------------------
Variable (R) | Variable für den Rot Kanal
Variable (G) | Variable für den Grün Kanal
Variable (B) | Variable für den Blau Kanal
Button "RGB setzen" | Sendet den RGB-Wert an die Kanäle


### 5. Statusvariablen und Profile

Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.

##### Statusvariablen

Name | Typ | Beschreibung
----- | ------- | ----------------
Color | Integer | Beinhaltet Wert passend zum Farbrad

##### Profile:

Es werden keine zusätzlichen Profile hinzugefügt

### 6. WebFront

Über das WebFront werden die Variablen angezeigt. Über das Farbrad kann die Farbe eingestellt werden.

### 7. PHP-Befehlsreferenz

`boolean RGBM_SetRGB(integer $InstanzID, integer $Rot, integer $Gruen, integer, $Blau);`
Sendet die R, G, B Werte an die einzelnen Kanäle und aktualisiert die Color Variable
Die Funktion liefert keinerlei Rückgabewert.
Beispiel:
`RGBM_SetRGB(12345, 255, 255, 255);`

`boolean RGBM_RequestStatus(integer $InstanzID);`
Ermittelt den Wert der einzelnen R, G, B Kanäle und setzt die Color Variable. Diese Funktion muss nicht aufgerufen werden. Dies passiert bei Änderung einer der Variable der R, G, B Kanäle automatisch.
Die Funktion liefert keinerlei Rückgabewert.
Beispiel:
`RGBM_RequestStatus(12345);`
15 changes: 15 additions & 0 deletions RGBMultiplexer/form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"elements":
[
{ "name": "SourceVariableR", "type": "SelectVariable", "caption": "Variable (R)" },
{ "name": "SourceVariableG", "type": "SelectVariable", "caption": "Variable (G)" },
{ "name": "SourceVariableB", "type": "SelectVariable", "caption": "Variable (B)" }
],
"actions":
[
{ "name": "ValueR", "type": "NumberSpinner", "caption": "R" },
{ "name": "ValueG", "type": "NumberSpinner", "caption": "G" },
{ "name": "ValueB", "type": "NumberSpinner", "caption": "B" },
{ "type": "Button", "label": "Set RGB", "onClick": "RGBM_SetRGB($id, $ValueR, $ValueG, $ValueB);" }
]
}
13 changes: 13 additions & 0 deletions RGBMultiplexer/locale.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"translations": {
"de": {
"Variable (R)": "Variable (R)",
"Variable (G)": "Variable (G)",
"Variable (B)": "Variable (B)",
"R": "R",
"G": "G",
"B": "B",
"Set RGB": "RGB setzen"
}
}
}
14 changes: 14 additions & 0 deletions RGBMultiplexer/module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "{49886D87-74B7-49E5-8C56-DD2BF058AB9D}",
"name": "RGBMultiplexer",
"type": 3,
"vendor": "",
"aliases":
[
"RGB Multiplexer"
],
"parentRequirements": [],
"childRequirements": [],
"implemented": [],
"prefix": "RGBM"
}
182 changes: 182 additions & 0 deletions RGBMultiplexer/module.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?
if (!defined('IPS_BASE')) {
define("IPS_BASE", 10000);
}
if (!defined('VM_UPDATE')) {
define("VM_UPDATE", IPS_BASE + 603);
}

class RGBMultiplexer extends IPSModule
{

public function Create()
{
//Never delete this line!
parent::Create();

$this->RegisterPropertyInteger("SourceVariableR", 0);
$this->RegisterPropertyInteger("SourceVariableG", 0);
$this->RegisterPropertyInteger("SourceVariableB", 0);

$this->RegisterVariableInteger("Color", "Color", "HexColor", 0);
$this->EnableAction("Color");

$this->RegisterTimer("Update", 0, "RGBM_RequestStatus(\$_IPS['TARGET']);");

}

public function ApplyChanges()
{

//Never delete this line!
parent::ApplyChanges();

if($this->ReadPropertyInteger("SourceVariableR") > 0) {
$this->RegisterMessage($this->ReadPropertyInteger("SourceVariableR"), VM_UPDATE);
}
if($this->ReadPropertyInteger("SourceVariableG") > 0) {
$this->RegisterMessage($this->ReadPropertyInteger("SourceVariableG"), VM_UPDATE);
}
if($this->ReadPropertyInteger("SourceVariableB") > 0) {
$this->RegisterMessage($this->ReadPropertyInteger("SourceVariableB"), VM_UPDATE);
}

}

public function MessageSink($TimeStamp, $SenderID, $Message, $Data) {

//Kick off a timer. This will prevent multiple calls to SetValue and a visual "color" jumping
$this->SetTimerInterval("Update", 250);

}

public function RequestAction($Ident, $Value) {

switch($Ident) {
case "Color":
$this->SetRGB(($Value >> 16) & 0xFF, ($Value >> 8) & 0xFF, $Value & 0xFF);
break;
default:
throw new Exception("Invalid Ident");
}

}

public function RequestStatus() {

$R = $this->getDimValue($this->ReadPropertyInteger("SourceVariableR")) / 100 * 255;
$G = $this->getDimValue($this->ReadPropertyInteger("SourceVariableG")) / 100 * 255;
$B = $this->getDimValue($this->ReadPropertyInteger("SourceVariableB")) / 100 * 255;

SetValue($this->GetIDForIdent("Color"), ($R << 16) + ($G << 8) + $B);

$this->SetTimerInterval("Update", 0);
}

public function SetRGB(int $R, int $G, int $B) {

$this->dimDevice($this->ReadPropertyInteger("SourceVariableR"), $R / 255 * 100);
$this->dimDevice($this->ReadPropertyInteger("SourceVariableG"), $G / 255 * 100);
$this->dimDevice($this->ReadPropertyInteger("SourceVariableB"), $B / 255 * 100);

SetValue($this->GetIDForIdent("Color"), ($R << 16) + ($G << 8) + $B);

}

//Remove this in the future and reference our submodule
private static function getDimValue($variableID)
{
$targetVariable = IPS_GetVariable($variableID);

if ($targetVariable['VariableCustomProfile'] != '') {
$profileName = $targetVariable['VariableCustomProfile'];
} else {
$profileName = $targetVariable['VariableProfile'];
}

$profile = IPS_GetVariableProfile($profileName);

if (($profile['MaxValue'] - $profile['MinValue']) <= 0) {
return 0;
}

$valueToPercent = function ($value) use ($profile) {
return (($value - $profile['MinValue']) / ($profile['MaxValue'] - $profile['MinValue'])) * 100;
};

$value = $valueToPercent(GetValue($variableID));

// Revert value for reversed profile
if (preg_match('/\.Reversed$/', $profileName)) {
$value = 100 - $value;
}

return $value;
}

//Remove this in the future and reference our submodule
private static function dimDevice($variableID, $value)
{
if (!IPS_VariableExists($variableID)) {
return false;
}

$targetVariable = IPS_GetVariable($variableID);

if ($targetVariable['VariableCustomProfile'] != '') {
$profileName = $targetVariable['VariableCustomProfile'];
} else {
$profileName = $targetVariable['VariableProfile'];
}

if (!IPS_VariableProfileExists($profileName)) {
return false;
}

// Revert value for reversed profile
if (preg_match('/\.Reversed$/', $profileName)) {
$value = 100 - $value;
}

$profile = IPS_GetVariableProfile($profileName);

if (($profile['MaxValue'] - $profile['MinValue']) <= 0) {
return false;
}

if ($targetVariable['VariableCustomAction'] != 0) {
$profileAction = $targetVariable['VariableCustomAction'];
} else {
$profileAction = $targetVariable['VariableAction'];
}

if ($profileAction < 10000) {
return false;
}

$percentToValue = function ($value) use ($profile) {
return (max(0, min($value, 100)) / 100) * ($profile['MaxValue'] - $profile['MinValue']) + $profile['MinValue'];
};

if ($targetVariable['VariableType'] == 1 /* Integer */) {
$value = intval($percentToValue($value));
} elseif ($targetVariable['VariableType'] == 2 /* Float */) {
$value = floatval($percentToValue($value));
} else {
return false;
}

if (IPS_InstanceExists($profileAction)) {
IPS_RunScriptText('IPS_RequestAction(' . var_export($profileAction, true) . ', ' . var_export(IPS_GetObject($variableID)['ObjectIdent'], true) . ', ' . var_export($value, true) . ');');
} elseif (IPS_ScriptExists($profileAction)) {
IPS_RunScriptEx($profileAction, ['VARIABLE' => $variableID, 'VALUE' => $value, 'SENDER' => 'RGBMultiplexer']);
} else {
return false;
}

return true;
}

}

?>

0 comments on commit 955a9e0

Please sign in to comment.