mirror of https://github.com/sfeakes/AqualinkD.git
246 lines
7.2 KiB
JavaScript
246 lines
7.2 KiB
JavaScript
|
|
|
|
/*
|
|
Below is the basic premise of the file if you need to create something for a different home automation
|
|
|
|
exampleCreateTile()
|
|
|
|
function exampleCreateTile() {
|
|
var tile = {};
|
|
tile["id"] = "my.unique.id";
|
|
tile["name"] = "Example Switch";
|
|
tile["display"] = "true";
|
|
tile["type"] = "switch"; // switch or value
|
|
tile["state"] = 'on';
|
|
tile["status"] = tile["state"]; // status and state are different for AqualinkD, but for purposes of a switch or sensor they are the same.
|
|
|
|
// Call AqualinkD function to create the tile and add to display.
|
|
createTile(tile);
|
|
// Make sure we use our own callback for button press. (only needed for a switch)
|
|
var subdiv = document.getElementById(tile["id"]);
|
|
subdiv.setAttribute('onclick', "exampleTilePressedCallback('" + tile["id"] + "')");
|
|
}
|
|
|
|
// use this function to update the state or value of a tile
|
|
function exampleUpdateTileStatus() {
|
|
// For Switch
|
|
setTileOn("my.unique.id", 'on'); // valid values are 'on' and 'off'
|
|
// For value
|
|
setTileValue("my.unique.id", "0.00");
|
|
}
|
|
|
|
// This will be called when a tile is clicked in the UI.
|
|
function exampleTilePressedCallback() {
|
|
// Get the state of the tile
|
|
var state = (document.getElementById("my.unique.id").getAttribute('status') == 'off') ? 'on' : 'off';
|
|
// Action what needs to happen. ie send request to home automation hub.
|
|
// Change / re-set the tile in teh display.
|
|
setTileOn("my.unique.id", state);
|
|
}
|
|
*/
|
|
|
|
// Add your HA API token
|
|
var HA_TOKEN = '<YOUR LONG HA TOKEN HERE>';
|
|
// Change to your HA server IP
|
|
var HA_SERVER = 'http://192.168.1.255:8123';
|
|
|
|
|
|
setupTiles();
|
|
|
|
|
|
// Only use asunv to garantee order, also why homeassistantAction() function returns a promise.
|
|
function setupTiles() {
|
|
// If we have specific user agents setup, make sure one matches.
|
|
if (_config?.HA_tilePlugin && _config?.HA_tilePlugin?.userAgents) {
|
|
var found=false;
|
|
for (const agent of _config.HA_tilePlugin.userAgents) {
|
|
if (navigator.userAgent.search(agent) != -1) {
|
|
found = true;
|
|
}
|
|
}
|
|
// User agent doesn't match the list, return and tdo nothing.
|
|
if (!found) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// If aqualinkd has not added tiles, wait.
|
|
if ( document.getElementById("Filter_Pump") === null) {
|
|
setTimeout(setupTiles, 100);
|
|
return;
|
|
}
|
|
|
|
if (!_config?.HA_tilePlugin) {
|
|
// If you are not using config.json to add them, Add your HA ID's below. replace the below examples.
|
|
/* ###########################################################
|
|
#
|
|
# Add manual entries here
|
|
#
|
|
########################################################### */
|
|
//homeassistantAction("light.back_floodlights");
|
|
} else {
|
|
HA_TOKEN = _config.HA_tilePlugin.HA_token;
|
|
HA_SERVER = _config.HA_tilePlugin.HA_server;
|
|
for (const id of _config.HA_tilePlugin.HA_entity_ids) {
|
|
homeassistantAction(id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*. Some helper / formating functions */
|
|
function getStringAfterCharacter(mainString, character) {
|
|
const index = mainString.indexOf(character);
|
|
if (index === -1) {
|
|
// Character not found, return the original string or an empty string as desired
|
|
return mainString;
|
|
}
|
|
return mainString.slice(index + 1);
|
|
}
|
|
function getStringBeforeCharacter(mainString, character) {
|
|
const index = mainString.indexOf(character);
|
|
if (index === -1) {
|
|
// Character not found, return the original string or an empty string as desired
|
|
return mainString;
|
|
}
|
|
return mainString.slice(0, index);
|
|
}
|
|
|
|
function formatTwoDecimalsOrInteger(num) {
|
|
const roundedNum = Math.round(num * 100) / 100;
|
|
let result = String(roundedNum);
|
|
|
|
// Check if the string ends with '.00' and remove it if present
|
|
if (result.endsWith('.00')) {
|
|
result = result.slice(0, -3); // Remove the last 3 characters (".00")
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
function HA_switchTileState(id) {
|
|
state = (document.getElementById(id).getAttribute('status') == 'off') ? 'on' : 'off';
|
|
|
|
homeassistantAction(id, state);
|
|
|
|
setTileOn(id, state);
|
|
}
|
|
|
|
|
|
function HA_updateDevice(data) {
|
|
var tile
|
|
var name
|
|
|
|
if (!data || !data.state) {
|
|
console.log("Error, missing JSON values ID="+data?.entity_id+", Name="+data?.attributes?.friendly_name+", State="+data?.state);
|
|
return;
|
|
} else if (!data.attributes.friendly_name) {
|
|
name = getStringAfterCharacter(data.entity_id, ".");
|
|
} else {
|
|
name = data.attributes.friendly_name;
|
|
}
|
|
|
|
const service = getStringBeforeCharacter(data.entity_id, ".");
|
|
|
|
// If the tile doesn't exist, create it.
|
|
if ((tile = document.getElementById(data.entity_id)) == null) {
|
|
var tile = {};
|
|
tile["id"] = data.entity_id;
|
|
tile["name"] = name;
|
|
tile["display"] = "true";
|
|
|
|
if ( service == "sensor" ) {
|
|
tile["type"] = "value";
|
|
tile["value"] = data.state;
|
|
} else {
|
|
tile["type"] = "switch"; // switch or value
|
|
}
|
|
|
|
if ( service == "cover") {
|
|
tile["state"] = ((data.state == 'closed') ? 'off' : 'on')
|
|
} else {
|
|
tile["state"] = ((data.state == 'off') ? 'off' : 'on');
|
|
}
|
|
tile["status"] = tile["state"];
|
|
|
|
createTile(tile);
|
|
|
|
// Make sure we use out own callback for button press.
|
|
subdiv = document.getElementById(data.entity_id);
|
|
subdiv.setAttribute('onclick', "HA_switchTileState('" + data.entity_id + "')");
|
|
tile = document.getElementById(data.entity_id);
|
|
}
|
|
|
|
switch (service) {
|
|
case "sensor":
|
|
setTileValue(data.entity_id, formatTwoDecimalsOrInteger(data.state));
|
|
break;
|
|
case "cover":
|
|
setTileOn(data.entity_id, ((data.state == 'closed') ? 'off' : 'on'), null);
|
|
break;
|
|
case "light":
|
|
case "switch":
|
|
case "input_boolean":
|
|
default:
|
|
setTileOn(data.entity_id, ((data.state == 'off') ? 'off' : 'on'), null);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getURL(service, action) {
|
|
switch (service) {
|
|
case "sensor":
|
|
return "";
|
|
break;
|
|
case "cover":
|
|
return '/api/services/'+service+'/'+(action=="on"?"open":"close")+"_cover";
|
|
break;
|
|
case "light":
|
|
case "switch":
|
|
case "input_boolean":
|
|
default:
|
|
return '/api/services/'+service+'/turn_'+action;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
function homeassistantAction(id, action="status") {
|
|
var http = new XMLHttpRequest();
|
|
if (http) {
|
|
http.onreadystatechange = function() {
|
|
if (http.readyState === 4) {
|
|
if (http.status == 200) {
|
|
var data = JSON.parse(http.responseText);
|
|
// Sending action on/off returns blank from HA, so only bother acting on status messages
|
|
if (action == "status") {
|
|
HA_updateDevice(data);
|
|
}
|
|
} else {
|
|
console.error("Http error "+http.status);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
if (action == "status") {
|
|
http.open('GET', HA_SERVER+'/api/states/' + id, true);
|
|
http.setRequestHeader("Content-Type", "application/json");
|
|
http.setRequestHeader("Authorization", "Bearer "+HA_TOKEN);
|
|
_poller = setTimeout(function() { homeassistantAction(id, action); }, 5000);
|
|
http.send(null);
|
|
} else {
|
|
const service = getStringBeforeCharacter(id, ".");
|
|
// Below should be api/services/cover/open_cover for cover.
|
|
http.open('POST', HA_SERVER+getURL(service,action), true);
|
|
http.setRequestHeader("Content-Type", "application/json");
|
|
http.setRequestHeader("Authorization", "Bearer "+HA_TOKEN);
|
|
http.send('{"entity_id": "'+id+'"}');
|
|
}
|
|
}
|
|
|