Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

Commit

Permalink
Merge pull request #51 from DewGew/beta
Browse files Browse the repository at this point in the history
CheckForUpdates, Sort devices
  • Loading branch information
DewGew authored Dec 5, 2019
2 parents 847ec04 + 9c6a22a commit 27efe02
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 22 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Based on Pawcio's script at [domoticz forum](https://www.domoticz.com/forum/view
Required:
- public url
- python >= 3.5
- reverse proxy for establishing secure connection (if not using Ngrok)
- Make local deployment available trough HTTPS with valid certificate:
- Use ngrok for a secure SSL tunnel with valid public HTTPS URL
- Configure reverse proxy with domain name and valid certificate using Lets Encrypt

Domoticz-Google-Assistant delivers:
- The oauth authorization and smarthome endpoint for the google assistant.
Expand Down
111 changes: 99 additions & 12 deletions const.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,11 @@
<i class="material-icons" style="vertical-align: middle;">timelapse</i><small class="text-muted"> Sytem Uptime:<br>{uptime}</small>
</div>
<div class="col">
<small class="text-muted">DZGA Version:<br>V""" + VERSION + """</small>
<small class="text-muted">DZGA Version:<br>V""" + VERSION + """</small><br>
<small class="text-muted" id="updates"></small>
</div>
<div class="col">
<div class="col" id="buttonUpdate">
</div>
<div class="col">
<small class="text-muted"><a href="https://github.com/DewGew/Domoticz-Google-Assistant">Source Code at Github</a></small><br>
Expand All @@ -267,14 +269,15 @@
<div id="menu1" class="tab-pane fade" role="tabpanel">
<br>
<h5>Device list</h5>
<small class="text-muted">List of devices the server recived from domoticz.<br>NOTE: If you don't see any device check your connection to domoticz.</small>
<table class="table">
<small class="text-muted">List of devices the server recived from domoticz. Room and Nicknames added in configuration. <b>Click on Header to sort asc or desc</b><br><b>NOTE:</b> If you don't see any device check your connection to domoticz.</small>
<table class="table" id="deviceTable">
<thead>
<tr>
<th scope="col">Idx</th>
<th scope="col">Name</th>
<th scope="col">Type</th>
<th scope="col">State</th>
<th scope="col" onclick="sortIdxTable(0)">Idx</th>
<th scope="col" onclick="sortTable(0)">Name <small><i>(Nicknames)</i></small></th>
<th scope="col" onclick="sortTable(1)">Type</th>
<th scope="col" onclick="sortTable(2)">State</th>
<th scope="col" onclick="sortTable(3)">Room</th>
</tr>
</thead>
<tbody id="deviceList_idx" ></tbody>
Expand Down Expand Up @@ -360,6 +363,7 @@
<p><b>loglevel:</b><br>Set log level <code>Debug</code>, <code>Info</code> or <code>Error</code>. Default is <code>Info</code></p>
<p><b>logtofile:</b><br>Enable or disable write log to file. If 'false' logs will not show in the LOG tab.</p>
<p><b>userinterface:</b><br>Enable or disable UI</p>
<p><b>CheckForUpates:</b><br>Enable or disable check for updates</p>
<p><b>ngrok_tunnel:</b><br>Use Ngrok tunnel true or false. Instantly create a public HTTPS URL.<br>Don't have to open any port on router and do not require a reverse proxy.<br><b>NOTE:</b>Ngrok assigns random urls. When server restart the server gets a new url</p>
<p><b>auth_user/auth_pass:</b><br>Set the authorization username and password.</p>
Expand Down Expand Up @@ -463,7 +467,7 @@
<button class="btn btn-raised btn-primary" name="reload" value="reload"><i class="material-icons" style="vertical-align: middle;">sync</i> Reload logs</button>
<button class="btn btn-raised btn-primary" name="deletelogs" value="deletelogs"><i class="material-icons" style="vertical-align: middle;">delete</i> Remove logs</button>
</form>
<p class="text-muted">Log file will be overwrite when dzga server restarts</p>
<p class="text-muted">Log file will be overwritten when dzga server restarts</p>
</div>
</div>
</div>
Expand All @@ -479,9 +483,86 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/mode/yaml/yaml.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.48.4/addon/display/autorefresh.js"></script>
<script>
function sortTable(n) {{
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("deviceTable");
switching = true;
dir = "asc";
while (switching) {{
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {{
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
if (dir == "asc") {{
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {{
shouldSwitch = true;
break;
}}
}} else if (dir == "desc") {{
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {{
shouldSwitch = true;
break;
}}
}}
}}
if (shouldSwitch) {{
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
switchcount ++;
}} else {{
if (switchcount == 0 && dir == "asc") {{
dir = "desc";
switching = true;
}}
}}
}}
}}
function sortIdxTable(n) {{
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("deviceTable");
switching = true;
dir = "asc";
while (switching) {{
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {{
shouldSwitch = false;
x = rows[i].getElementsByTagName("TH")[n];
y = rows[i + 1].getElementsByTagName("TH")[n];
if (dir == "asc") {{
if (Number(x.innerHTML) > Number(y.innerHTML)) {{
shouldSwitch = true;
break;
}}
}} else if (dir == "desc") {{
if (Number(x.innerHTML) < Number(y.innerHTML)) {{
shouldSwitch = true;
break;
}}
}}
}}
if (shouldSwitch) {{
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
switchcount ++;
}} else {{
if (switchcount == 0 && dir == "asc") {{
dir = "desc";
switching = true;
}}
}}
}}
}}
$(document).ready(function() {{
var config = {conf}
var updates = {update}
if (updates) {{
document.getElementById("updates").innerHTML = "Updates are Availible.";
$('#buttonUpdate').append('<br><form action="/settings" method="post"><button class="btn btn-raised btn-primary" name="update" value="update"><i class="material-icons" style="vertical-align: middle;">update</i> Update</button></form>');
}}
$('body').bootstrapMaterialDesign();
$(function () {{
Expand All @@ -491,12 +572,18 @@
if (config.auth_user == 'admin' || config.auth_pass == 'admin'){{
$('#messageModal').modal('show')
}}
var devicelist = {list}
var x,i = "";
var x,i, nicknames = "";
for (i in devicelist){{
x += "<tr><th scope='row'>" + devicelist[i][1] + "</th><td>" + devicelist[i][0] + "</td><td>" + devicelist[i][2] + "</td><td>" + devicelist[i][3] + "</td></tr>";
if (devicelist[i][4] == undefined) {{
devicelist[i][4] = " "
}}
if (devicelist[i][5] == undefined) {{
nicknames = " ";
}}else{{ nicknames = " <small><i>(" + devicelist[i][5] + ")</i></small>"}}
x += "<tr><th scope='row'>" + devicelist[i][1] + "</th><td>" + devicelist[i][0] + nicknames + "</td><td>" + devicelist[i][2] + "</td><td>" + devicelist[i][3] + "</td><td>" + devicelist[i][4] + "</td></tr>";
}}
if (typeof x !== "undefined"){{
Expand Down
2 changes: 2 additions & 0 deletions default_config
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ loglevel: 'Info'
logtofile: false
# Enable or disable UI
userinterface: true
# Check for updates
CheckForUpdates: true

# Instantly create a public HTTPS URL. Don't have to open any port on router and do not require a reverse proxy.
# Ngrok assigns random urls. When server restart the server gets a new url
Expand Down
37 changes: 37 additions & 0 deletions scripts/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit

scripts_dir="$(dirname "${BASH_SOURCE[0]}")"
GIT_DIR="$(realpath $(dirname ${BASH_SOURCE[0]})/..)"

# make sure we're running as the owner of the checkout directory
RUN_AS="$(ls -ld "$scripts_dir" | awk 'NR==1 {print $3}')"
if [ "$USER" != "$RUN_AS" ]
then
echo ""
echo " This script must run as $RUN_AS, trying to change user..."
exec sudo -u $RUN_AS $0
fi
cd /home/${USER}/

echo "!-----------------------------------!"
echo " Check for update..."
echo ""
cd Domoticz-Google-Assistant
git reset --hard
git pull
echo ""
echo "*-----------------------------------*"
49 changes: 40 additions & 9 deletions smarthome.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,26 @@
except Exception as e:
logger.error('Connection to Domoticz refused!. Check configuration')

update = 0
confJSON = json.dumps(configuration)
public_url = PUBLIC_URL

def checkupdate():
try:
r = requests.get('https://raw.githubusercontent.com/DewGew/Domoticz-Google-Assistant/master/const.py')
text = r.text
if VERSION not in text:
update = 1
logger.info("========")
logger.info(" New version is availible on Github!")
else:
update = 0
return update
except Exception as e:
logger.error('Connection to Github refused!. Check configuration')

if 'CheckForUpdates' in configuration and configuration['CheckForUpdates'] == True:
update = checkupdate()
#some way to convert a domain type: Domoticz to google
def AogGetDomain(device):
if device["Type"] in ['Light/Switch', 'Lighting 1', 'Lighting 2', 'RFY']:
Expand Down Expand Up @@ -72,8 +90,11 @@ def AogGetDomain(device):
return tempDOMAIN
elif 'Temp + Humidity + Baro' == device['Type']:
return tempDOMAIN
elif 'Color Switch' == device["Type"]:
elif 'Color Switch' == device["Type"] and "Dimmer" == device["SwitchType"]:
return colorDOMAIN
elif 'Color Switch' == device["Type"] and "On/Off" == device["SwitchType"]:
logger.info(device["Name"] + " (Idx: " + device["idx"] + ") is a color switch. To get all functions, set this device as Dimmer in Domoticz")
return lightDOMAIN
elif 'Security' == device["Type"]:
return securityDOMAIN
return None
Expand Down Expand Up @@ -494,7 +515,7 @@ def settings(self, s):
meta = '<!-- <meta http-equiv="refresh" content="5"> -->'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)

s.send_message(200, template)

Expand All @@ -510,7 +531,7 @@ def settings_post(self, s):
meta = '<!-- <meta http-equiv="refresh" content="5"> -->'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)

s.send_message(200, template)

Expand All @@ -523,7 +544,7 @@ def settings_post(self, s):
meta = '<!-- <meta http-equiv="refresh" content="5"> -->'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)

s.send_message(200, template)

Expand All @@ -532,27 +553,27 @@ def settings_post(self, s):
meta = '<meta http-equiv="refresh" content="5">'
code = ''
logs = ''
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)

s.send_message(200, template)
restartServer()

if (s.form.get("sync")):
r = self.forceDevicesSync()
time.sleep(1)
time.sleep(0.5)
message = 'Devices syncronized'
meta = '<!-- <meta http-equiv="refresh" content="10"> -->'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)
s.send_message(200, template)

if (s.form.get("reload")):
message = ''
meta = '<!-- <meta http-equiv="refresh" content="10"> -->'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)
s.send_message(200, template)

if (s.form.get("deletelogs")):
Expand All @@ -565,8 +586,18 @@ def settings_post(self, s):
meta = '<!-- <meta http-equiv="refresh" content="10"> -->'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)
s.send_message(200, template)

if (s.form.get("update")):
os.system('bash ~/Domoticz-Google-Assistant/scripts/update.sh')
message = 'Updated, Restarting Server, please wait!'
meta = '<meta http-equiv="refresh" content="5">'
code = readFile(CONFIGFILE)
logs = readFile(LOGFILE)
template = TEMPLATE.format(message=message, uptime=uptime(), list=deviceList, meta=meta, code=code, conf=confJSON, public_url=public_url, logs=logs, update=update)
s.send_message(200, template)
restartServer()


def smarthome_sync(self, payload, token):
Expand Down

0 comments on commit 27efe02

Please sign in to comment.