// Philips HUE Steuerung // // Steuert bis zu 12 HUE-Geräte (RGB, RGBW, Dimmer, // LivingWhites-Schalter) oder Gruppen an. // AI13 auf 1 triggern -> "Alles aus" // // (c) Andreas Lackner luke@friedensflotte.org // based on work of Romy Glauser // // 2015-05-07: // Unterstütz LUMITECH-Parameter aus Lichtsteuerung // Kleine Bugfixes (Log korrigiert, Verbesserung Handling Szene 0 int DEBUG_LEVEL=3; // Diese Werte haengen von den Einstellungen des Vorangeschaltenen Lichtbausteins ab! int DIMMER_MIN=35; int DIMMER_MAX=100; // IP der HUE-Bridge char* IP_ADDRESS = "192.168.20.30"; // Port (80=http) char* PORT = "80"; // siehe http://www.developers.meethue.com/documentation/getting-started char* USERNAME = "BJDGw9Y"; int inputType[12]; inputType[0] = 3; // -1=unbenutzt, 0=rgb/lumitech, 1=dimmer, 2=on/off, 3=gruppe inputType[1] = 3; inputType[2] = 3; inputType[3] = 3; inputType[4] = 3; inputType[5] = 3; inputType[6] = 3; inputType[7] = 3; inputType[8] = 3; inputType[9] = 3; inputType[10] = 3; inputType[11] = 3; int lightOrGroupID[12]; // Zuweisung der Lampen- oder GruppenIDs. // Definiert welcher Eingang des Bausteins welche Lampe/Gruppe ansteuert: lightOrGroupID[0] = 1; lightOrGroupID[1] = 2; lightOrGroupID[2] = 3; lightOrGroupID[3] = 4; lightOrGroupID[4] = 5; lightOrGroupID[5] = 6; lightOrGroupID[6] = 7; lightOrGroupID[7] = 8; lightOrGroupID[8] = 9; lightOrGroupID[9] = 10; lightOrGroupID[10] = 11; lightOrGroupID[11] = 12; // ENDE der Konfiguration char streamname[100]; sprintf(streamname, "/dev/tcp/%s/%s/", IP_ADDRESS, PORT); int nEvents; int LIGHT = 1; int GROUP = 2; void updateLamp(int idx, float value) { if (inputType[idx] == -1) { //ignorieren } else if (inputType[idx] == 0) { if (value < 200000000) { // RGB setColor(lightOrGroupID[idx], value, LIGHT); } else { // LUMITECH setCtBri(lightOrGroupID[idx], value); } } else if (inputType[idx] == 1) { setBrightness(lightOrGroupID[idx], value); } else if (inputType[idx] == 2) { setOnOff(lightOrGroupID[idx], value); } else if (inputType[idx] == 3) { setColor(lightOrGroupID[idx], value, GROUP); } } void setBrightness(int lightID, float bri) { char command[30]; char selector[20]; // Normieren von 35-100 -> 1-255 if (bri > 0) { bri = (bri- DIMMER_MIN )/( DIMMER_MAX - DIMMER_MIN )*254+1; } sprintf(selector,"lights/%d/state", lightID); if (bri == 0) { sprintf(command, "{\"on\": false}"); if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID); } else { sprintf(command, "{\"on\": true, \"bri\": %d}", (int) (bri)); if (DEBUG_LEVEL > 0) printf("Light %d ON %d%%", lightID, (int) ((bri-1)/2.55)+1); } sendCommand(selector, command); } void setCtBri(int lightID, float ctbrivalue) { char command[50]; char selector[20]; float bri, ct; int briNorm, miredNorm; bri = floor((ctbrivalue-200000000) / 10000); // 0-100 ct = floor((ctbrivalue-200000000) - (bri * 10000)); // Wert in Kelvin, von 2700 - 6500 briNorm = (int) round(bri*2.55); // 0-255 miredNorm = (int) round(1000000/ct); // Wert von 154 - 370 sprintf(selector,"lights/%d/state", lightID); if (bri == 0) { sprintf(command, "{\"on\": false}"); if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID); } else { sprintf(command, "{\"on\": true, \"bri\": %d, \"ct\": %d}", briNorm, miredNorm); if (DEBUG_LEVEL > 0) printf("Light %d ON %d%% %dK", lightID, (int) bri, (int) ct); } sendCommand(selector, command); } void setOnOff(int lightID, float bri) { char command[30]; char selector[20]; sprintf(selector,"lights/%d/state", lightID); if (bri == 0) { sprintf(command, "{\"on\": false}"); if (DEBUG_LEVEL > 0) printf("Light %d OFF", lightID); } else { sprintf(command, "{\"on\": true}"); if (DEBUG_LEVEL > 0) printf("Light %d ON", lightID); } sendCommand(selector, command); } void setColor(int lightOrGroupID, float rgbvalue, int type) { char buffer[256]; float red,green,blue; float hue,sat,bri; char command[100]; char selector[50]; // Hinweis: rgbvalue ist red + green*1000 + blue*1000000 blue = floor(rgbvalue/1000000); green = floor((rgbvalue-blue*1000000)/1000); red = rgbvalue-blue*1000000-green*1000; // nochmal umrechnen nach hue irgendwie, weil die Living Colors Gen2 irgendwie nich gehen mit xy hue = 0; sat = 0; bri = 0; if (blue > 0 || green > 0 || red > 0) { if ((red >= green) && (green >= blue)) { if (red == blue) { hue = 0; } else { hue = 60*(green-blue)/(red-blue); } sat = (red - blue) / red; bri = red; } else if ((green > red) && (red >= blue)) { hue = 60*(2 - (red-blue)/(green-blue)); sat = (green - blue) / green; bri = green; } else if ((green >= blue) && (blue > red)) { hue = 60*(2 + (blue-red)/(green-red)); sat = (green - red) / green; bri = green; } else if ((blue > green) && (green > red)) { hue = 60*(4 - (green-red)/(blue-red)); sat = (blue - red) / blue; bri = blue; } else if ((blue > red) && (red >= green)) { hue = 60*(4 + (red-green)/(blue-green)); sat = (blue - green) / blue; bri = blue; } else if ((red >= blue) && (blue > green)) { hue = 60*(6 - (blue-green)/(red-green)); sat = (red - green) / red; bri = red; } // Werte f¸r HUE normieren (hue = 0-65535, sat 0-255, bri 0-255) hue = hue / 360 * 65535; sat = sat * 255; bri = bri * 2.55; } // Ausgeben ins Log if (DEBUG_LEVEL > 1) printf("value:%09d, b:%d, g:%d, r: %d, hue:%d, sat: %d, bri: %d\n", rgbvalue, blue, green, red, (int)hue, (int)sat, (int)bri); if (bri == 0) { sprintf(command, "{\"on\": false}"); if (DEBUG_LEVEL > 0 && type==LIGHT ) printf("Light %d OFF", lightOrGroupID); if (DEBUG_LEVEL > 0 && type==GROUP ) printf("Group %d OFF", lightOrGroupID); } else { sprintf(command, "{\"bri\": %d, \"hue\": %d, \"sat\": %d, \"on\": true}", (int)bri, (int)hue, (int)sat); if (DEBUG_LEVEL > 0 && type==LIGHT ) printf("Light %d ON %d%%, %d∞ %d%%", lightOrGroupID, (int) ((bri-1)/2.55)+1, (int) (hue / 65535 * 360), (int)(sat/2.55)); if (DEBUG_LEVEL > 0 && type==GROUP ) printf("Group %d ON %d%%, %d∞ %d%%", lightOrGroupID, (int) ((bri-1)/2.55)+1, (int) (hue / 65535 * 360), (int)(sat/2.55)); } if (type==LIGHT) { sprintf(selector,"lights/%d/state", lightOrGroupID); } else if (type==GROUP) { sprintf(selector,"groups/%d/action", lightOrGroupID); } sendCommand(selector, command); } void sendCommand(char* selector, char* command) { STREAM* TcpStream = stream_create(streamname,0,0); if (TcpStream == NULL) { printf("Creating Stream failed"); stream_close(TcpStream); return; } char buffer[1024]; sprintf(buffer, "PUT /api/%s/%s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\nContent-Length: %d\r\n\r\n%s", USERNAME, selector, IP_ADDRESS, strlen(command), command); if (DEBUG_LEVEL > 1) printf(buffer); stream_write(TcpStream,buffer,sizeof(buffer)); stream_flush(TcpStream); stream_close(TcpStream); } while (1==1) { nEvents = getinputevent(); if (nEvents & 0x8 << 12 && getinput(12)==1) { if (DEBUG_LEVEL > 0) printf("All Lights OFF"); sendCommand( "groups/0/action", "{\"on\":false}"); } else { int i; for (i = 0; i < 12; i++) { if (nEvents & 0x8 << i) { updateLamp(i, getinput(i)); sleep(150); } } } sleep(3000); }