Skip to content

Instantly share code, notes, and snippets.

@bplaat
Created August 17, 2021 15:37
Show Gist options
  • Save bplaat/d233c7417c816be0d635be36bc4bdc0c to your computer and use it in GitHub Desktop.
Save bplaat/d233c7417c816be0d635be36bc4bdc0c to your computer and use it in GitHub Desktop.
PlaatLight
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="plaatlight"');
}
if ($_SERVER['PHP_AUTH_USER'] != 'plaatlight' || $_SERVER['PHP_AUTH_PW'] != 'plaatlight') {
header('HTTP/1.1 401 Unauthorized');
echo 'Not authorized';
exit;
}
function refresh ($get) { header('Location: ' . (isset($get) ? $get : basename(__FILE__))); exit; }
function get ($key) { return isset($_GET[$key]) ? $_GET[$key] : null; }
$hue_url = 'http://?/api/?'; // Fill in Philips Hue IP and REST API auth token
echo '<!DOCTYPE html>';
echo '<html>';
echo '<head>';
echo '<meta charset="utf-8">';
echo '<title>PlaatLight</title>';
echo '<style>body,table{font-size:16px;line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif}
body{width:1000px;padding:0 16px;margin:auto}a{color:#16c}h1,p,input:not([type=checkbox]),label:not(.for){display:block;margin:16px 0}';
echo 'h1{font-size:32px}.nav{line-height:48px;float:right}.nav>a{margin-left:16px}label{font-weight:700}.on{color:#4a4}.off{color:#e33}.not{color:#f51}';
echo 'table{width:100%;border-collapse:collapse;border:1px solid #ccc}tr{border-bottom:1px solid #ddd}th,td{padding:16px;text-align:left;max-width:200px}';
echo '.color::-webkit-slider-runnable-track{background:linear-gradient(to right, #f00, #ff0 19.5%, #9d5 39.1%, #07c 71.9%, #f0f 85.9%, #f00)}';
echo '.color::-moz-range-track{background:linear-gradient(to right, #f00, #ff0 19.5%, #9d5 39.1%, #07c 71.9%, #f0f 85.9%, #f00)}</style>';
echo '</head>';
echo '<body>';
$hue = json_decode(file_get_contents($hue_url), true);
function req ($url, $json, $method = 'PUT') {
global $hue_url;
file_get_contents($hue_url . $url, false, stream_context_create([
'http' => [
'method' => $method,
'header' => 'Content-Type: application/json',
'content' => json_encode($json)
]
]));
}
echo '<div class="nav">';
echo '<a href="?page=lights">Lights</a>';
echo '<a href="?page=groups">Groups</a>';
echo '</div>';
echo '<h1>PlaatLight</h1>';
switch (get('page')) {
case 'switch':
if (get('light')) {
if (get('light') == 'all') {
foreach ($hue['lights'] as $id => $light) {
req('/lights/' . $id . '/state', ['on' => !$hue['lights'][$id]['state']['on']]);
}
} else {
req('/lights/' . get('light') . '/state', ['on' => !$hue['lights'][get('light')]['state']['on']]);
}
refresh('?page=lights');
}
if (get('group')) {
if (get('group') == 'all') {
foreach ($hue['groups'] as $id => $group) {
req('/groups/' . $id . '/action', ['on' => !$hue['groups'][$id]['action']['on']]);
}
} else {
req('/groups/' . get('group') . '/action', ['on' => !$hue['groups'][get('group')]['action']['on']]);
}
refresh('?page=groups');
}
break;
case 'delete':
if (get('group')) {
req('/groups/' . get('group'), [], 'DELETE');
refresh('?page=groups');
}
break;
case 'apply':
if (get('light')) {
$current = $hue['lights'][get('light')]['state']['on'];
req('/lights/' . get('light') . '/state', ['on' => true, 'bri' => (int)get('bri')]);
req('/lights/' . get('light'), ['name' => get('name')]);
if (isset($_GET['hue'])) req('/lights/' . get('light') . '/state', ['hue' => (int)get('hue')]);
req('/lights/' . get('light') . '/state', ['on' => $current]);
refresh('?page=lights');
}
if (get('group')) {
if (get('group') == 'new') {
req('/groups', ['name' => get('name'), 'lights' => get('lights')], 'POST');
} else {
$current = $hue['groups'][get('group')]['action']['on'];
req('/groups/' . get('group'), ['name' => get('name'), 'lights' => get('lights')]);
req('/groups/' . get('group') . '/action', ['on' => $current]);
}
refresh('?page=groups');
}
break;
case 'settings':
echo '<form>';
echo '<input type="hidden" name="page" value="apply">';
if (get('light')) {
echo '<input type="hidden" name="light" value="' . get('light') . '">';
echo '<label>Name</label>';
echo '<input type="text" name="name" value="' . $hue['lights'][get('light')]['name'] . '">';
echo '<label>Brightness</label>';
echo '<input type="range" name="bri" value="' . $hue['lights'][get('light')]['state']['bri'] . '" max="255">';
if ($hue['lights'][get('light')]['type'] == 'Color light') {
echo '<label>Color</label>';
echo '<input class="color" type="range" name="hue" value="' . $hue['lights'][get('light')]['state']['hue'] . '" max="65280">';
}
}
if (get('group')) {
echo '<input type="hidden" name="group" value="' . get('group') . '">';
echo '<label>Name</label>';
echo '<input type="text" name="name" value="' . (isset($hue['groups'][get('group')]['name']) ? $hue['groups'][get('group')]['name'] : '') . '">';
echo '<label>Lights</label>';
foreach ($hue['lights'] as $id => $light) {
echo '<p><input type="checkbox" id="' . $id . '" name="lights[]" value="' . $id . '"';
if (in_array($id, isset($hue['groups'][get('group')]['lights']) ? $hue['groups'][get('group')]['lights'] : [])) {
echo ' checked';
}
echo '> <label class="for" for="' . $id . '">' . $light['name'] . '</label></p>';
}
}
echo '<input type="submit" value="Save and return">';
echo '</form>';
break;
case 'lights':
echo '<table>';
echo '<thead>';
echo '<tr>';
echo '<th>#</th>';
echo '<th>Name</th>';
echo '<th>Type</th>';
echo '<th>Model</th>';
echo '<th>Vendor</th>';
echo '<th>SW Version</th>';
echo '<th>State</th>';
echo '<th>Actions</th>';
echo '<td><a href="?page=switch&light=all">Switch all</a></td>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
foreach ($hue['lights'] as $id => $light) {
echo '<tr>';
echo '<td>' . $id . '</td>';
echo '<td>' . $light['name'] . '</td>';
echo '<td>' . $light['type'] . '</td>';
echo '<td>' . $light['modelid'] . '</td>';
echo '<td>' . $light['manufacturername'] . '</td>';
echo '<td>' . $light['swversion'] . '</td>';
if ($light['state']['reachable']) {
if ($light['state']['on']) {
echo '<th class="on">ON</th>';
} else {
echo '<th class="off">OFF</th>';
}
echo '<td><a href="?page=switch&light=' . $id . '">Switch</a></td>';
echo '<td><a href="?page=settings&light=' . $id . '">Settings</a></td>';
} else {
echo '<th class="not">NOT</th>';
echo '<td colspan="2"></td>';
}
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
break;
case 'groups':
echo '<table>';
echo '<thead>';
echo '<tr>';
echo '<th>#</th>';
echo '<th>Name</th>';
echo '<th>Type</th>';
echo '<th>Lights</th>';
echo '<th>State</th>';
echo '<th>Actions</th>';
echo '<td><a href="?page=switch&group=all">Switch all</a></td>';
echo '<td><a href="?page=settings&group=new">New</a></td>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
foreach ($hue['groups'] as $id => $group) {
echo '<tr>';
echo '<td>' . $id . '</td>';
echo '<td>' . $group['name'] . '</td>';
echo '<td>' . $group['type'] . '</td>';
echo '<td>';
for ($i = 0, $len = count($group['lights']); $i < $len; $i++) {
echo $hue['lights'][$group['lights'][$i]]['name'] . ($i != $len - 1 ? $i == $len - 2 ? ' and ' : ', ' : '');
}
echo '</td>';
if ($group['action']['on']) {
echo '<th class="on">ON</th>';
} else {
echo '<th class="off">OFF</th>';
}
echo '<td><a href="?page=switch&group=' . $id . '">Switch</a></td>';
echo '<td><a href="?page=settings&group=' . $id . '">Settings</a></td>';
echo '<td><a href="?page=delete&group=' . $id . '">Delete</a></td>';
echo '</tr>';
}
echo '</tbody></table>';
break;
default:
refresh('?page=lights');
}
echo '<p>Made by <a href="http://bastiaan.plaatsoft.nl/">Bastiaan van der Plaat</a></p>';
echo '</body>';
echo '</html>';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment