|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<meta name="description" content="Home Assistant Dashboard using WebSocket API"> |
|
<title>Home Assistant using WebSocket</title> |
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> |
|
<link href="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.css" rel="stylesheet"> |
|
<style> |
|
.button { |
|
background-color: #03A9F4; |
|
border: none; |
|
color: white; |
|
padding: 24px 24px; |
|
text-align: center; |
|
text-decoration: none; |
|
display: inline-block; |
|
font-size: 16px; |
|
margin: 4px 2px; |
|
cursor: pointer; |
|
} |
|
.button-on { |
|
background-color: green; |
|
} |
|
.button-off { |
|
background-color: red; |
|
} |
|
</style> |
|
|
|
<script src='http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'></script> |
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js'></script> |
|
<script src='https://cdn.jsdelivr.net/npm/home-assistant-js-websocket@1.1.2/dist/haws.umd.min.js'></script> |
|
<script> |
|
|
|
///// Modify to suit your configeration ///// |
|
var URL = 'ws://' + window.location.hostname + ':8123/api/websocket'; |
|
var PASSWORD = 'XXXXXX'; // Your HA password if any |
|
var groups = ["group.all_switches","group.all_lights","group.living_room","group.power","group.battery_levels"]; |
|
///////////////////////////////////////////// |
|
|
|
var wsconn; |
|
|
|
String.prototype.format = function () { |
|
var args = arguments; |
|
return this.replace(/\{(\d+)\}/g, function (m, n) { return args[n]; }); |
|
}; |
|
|
|
String.prototype.capitalize = function() { |
|
return this.charAt(0).toUpperCase() + this.slice(1); |
|
} |
|
|
|
CallCommand = function(domain, service, obj) { |
|
var service_data = { |
|
entity_id: domain + "." + obj.id |
|
}; |
|
wsconn.callService(domain, service, service_data); |
|
}; |
|
|
|
UpdateSwitchButton = function(key, state) { |
|
id = '#' + key; |
|
if(state == "on") { |
|
$( id ).removeClass( "button-off" ).addClass( "button-on" ); |
|
} else { |
|
$( id ).removeClass( "button-on" ).addClass( "button-off" ); |
|
} |
|
}; |
|
|
|
UpdateSensorButton = function(key, state) { |
|
//$( '#lr_pir_battery > span').text(" foo"); |
|
var id = '#' + key + '>span'; |
|
if(state < 0) state = "0"; |
|
$( id ).html( "<br>" + state ); |
|
}; |
|
|
|
var states = {}; |
|
var buttons_created = false; |
|
|
|
$(document).ready(function() { |
|
|
|
const status = document.getElementById('status'); |
|
|
|
var CreateAllButtons = function(groups, entities) { |
|
for (var i = 0, len = groups.length; i < len; i++) { |
|
var group_name = groups[i]; |
|
// TODO: handle group within group |
|
// TODO: get subgroups and CreateButtons |
|
var gentities = HAWS.getGroupEntities(entities, entities[group_name]); |
|
CreateButtons(group_name, gentities); |
|
} |
|
} |
|
|
|
var CreateButtons = function(group_name, entities) { |
|
console.log("CreateButtons", group_name); |
|
var name = group_name.replace("_", " ").split(".")[1].capitalize(); |
|
$( 'div#buttons' ).append( "<h3>" + name + "</h3>" ); |
|
var btn, button; |
|
_.forEach(entities, function(entity, entity_id) { |
|
var domain = entity_id.split(".")[0]; |
|
var id = entity_id.split(".")[1]; |
|
var name = entity.attributes.friendly_name |
|
switch(domain) { |
|
case "switch": |
|
button = |
|
"<button id = \"{0}\" class=\"button switch\"><i class=\"fa fa-lightbulb-o\"></i> {1}</button>"; |
|
break; |
|
case "light": |
|
button = |
|
"<button id = \"{0}\" class=\"button light\"><i class=\"fa fa-lightbulb-o\"></i> {1}</button>"; |
|
break; |
|
case "sensor": |
|
case "binary_sensor": |
|
default: |
|
button = |
|
"<button id = \"{0}\" class=\"button sensor\"><i class=\"fa thermometer-full\"></i> {1}<span class=\"value\">?</span></button>"; |
|
}; |
|
var btn = button.format(id, name); |
|
$( 'div#buttons' ).append( btn ); |
|
}); |
|
$('button.switch').click(function() { |
|
CallCommand("switch", "toggle", this); |
|
}); |
|
$('button.light').click(function() { |
|
CallCommand("light", "toggle", this); |
|
}); |
|
}; |
|
|
|
function render(entities) { |
|
if( ! buttons_created) { |
|
CreateAllButtons(groups, entities); |
|
buttons_created = true; |
|
} |
|
for (var i = 0, len = groups.length; i < len; i++) { |
|
var group_name = groups[i]; |
|
var gentities = HAWS.getGroupEntities(entities, entities[group_name]); |
|
_.forEach(gentities, function(entity, id) { |
|
domain = id.split(".")[0]; |
|
key = id.split(".")[1]; |
|
switch(domain) { |
|
case "switch": |
|
case "light": |
|
UpdateSwitchButton(key, entity.state); |
|
break; |
|
default: |
|
UpdateSensorButton(key, entity.state); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
function GetErrorCode(err) { |
|
if(err == 1) return 'ERR_CANNOT_CONNECT'; |
|
if(err == 2) return 'ERR_INVALID_AUTH'; |
|
return 'UNKNOWN_ERROR'; |
|
} |
|
|
|
//add authentation with options parameter |
|
var options = {authToken: PASSWORD}; |
|
HAWS.createConnection(URL, options).then(conn => { |
|
wsconn = conn; |
|
status.innerHTML = 'Connected'; |
|
HAWS.subscribeEntities(conn, render); |
|
}, err => { status.innerHTML = "Connection error: " + GetErrorCode(err); }); |
|
|
|
}); |
|
</script> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
<div class="page-header"> |
|
<h1>Home Assistant Dashboard using WebSocket API</h1> |
|
</div> |
|
<div class="container-fluid" style="margin-top: 20px;"> |
|
<div id="status"></div> |
|
<div class="panel panel-default"> |
|
<div class="panel-body"> |
|
<div id="buttons"></div> |
|
</div> |
|
<div class="panel-body"> |
|
<div id="samplebuttons" style="display:none"> |
|
<button class="button"><i class="fa fa-reply"></i></button> |
|
<button class="button button-on"><i class="fa fa-star"></i></button> |
|
<button class="button button-off"><i class="fa fa-trash-o"></i></button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</body> |
|
</html> |
Add authentication and error messages.