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 #255 from DewGew/beta
Browse files Browse the repository at this point in the history
Merge Beta into Master
  • Loading branch information
DewGew authored Apr 11, 2021
2 parents 8425480 + bc9ed2e commit 21209b7
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 18 deletions.
5 changes: 5 additions & 0 deletions config/default_config
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ auth_pass: 'admin'
# Google Assistant Settings:
ClientID: 'clientid_from aog'
ClientSecret: 'clientsecret_from_aog'

# To play notification/message text or sound from domoticz to chromecast
# usage http://dzga_server:port/say?text-to-speak-sperated-by-minus/nl (specify language after "/", "en" is default if none)
# usage http://dzga_server:port/play?doorbell1.mp3 (mp3 file in directory /sound)
Chromecast_Name: 'add_chromecast_name'

# Domoticz Settings:
Domoticz:
Expand Down
2 changes: 1 addition & 1 deletion const.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-

"""Constants for Google Assistant."""
VERSION = '1.9.6'
VERSION = '1.10.8'
PUBLIC_URL = 'https://[your public url]'
CONFIGFILE = 'config/config.yaml'
LOGFILE = 'dzga.log'
Expand Down
3 changes: 3 additions & 0 deletions requirements/pip-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ GitPython>=3.0.5
google-auth>=1.8.1
wheel>=0.34.2
Jinja2==2.11.3
PyChromecast==0.3.2
gTTS==2.2.1
slugify==0.0.1
122 changes: 108 additions & 14 deletions smarthome.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from collections.abc import Mapping
from itertools import product
from pid import PidFile
from pathlib import Path
import requests

import trait
Expand All @@ -20,13 +21,42 @@
ATTRS_THERMSTATSETPOINT, ATTRS_COLOR_TEMP, ATTRS_PERCENTAGE, VERSION, DOMOTICZ_GET_VERSION)
from helpers import (configuration, readFile, saveFile, SmartHomeError, SmartHomeErrorNoChallenge, AogState, uptime,
getTunnelUrl, FILE_DIR, logger, ReportState, Auth, logfilepath)

try:
from jinja2 import Environment, FileSystemLoader
except ImportError:
logger.info('Installing package jinja2')
subprocess.call(['pip', 'install', 'jinja2'])
subprocess.call(['pip3', 'install', 'jinja2'])
from jinja2 import Environment, FileSystemLoader

if 'Chromecast_Name' in configuration and configuration['Chromecast_Name'] != 'add_chromecast_name':
try:
import pychromecast
import socket ##
from gtts import gTTS
from slugify import slugify
except ImportError as e:
logger.error('Installing package pychromecast, socket, gtts and slugify')
subprocess.call(['pip3', 'install', 'pychromecast'])
subprocess.call(['pip3', 'install', 'socket']) ##
subprocess.call(['pip3', 'install', 'gtts'])
subprocess.call(['pip3', 'install', 'slugify'])
import pychromecast
import socket ##
from gtts import gTTS
from slugify import slugify

logger.info("Starting up chromecasts")
try:
chromecasts, _ = pychromecast.get_chromecasts()
cast = next(cc for cc in chromecasts if cc.device.friendly_name == configuration['Chromecast_Name'])
except Exception as e:
logger.error('chromecasts init not succeeded, error : %s' % e)
t = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
t.connect(("8.8.8.8", 80))
IP_Address = t.getsockname()[0]
t.close
logger.info("IP_Address is : " + IP_Address)

DOMOTICZ_URL = configuration['Domoticz']['ip'] + ':' + configuration['Domoticz']['port']
CREDITS = (configuration['Domoticz']['username'], configuration['Domoticz']['password'])
Expand Down Expand Up @@ -206,7 +236,7 @@ def getAog(device):
aog.temp = device.get("Temp")
aog.humidity = device.get("Humidity")
aog.setpoint = device.get("SetPoint")
if aog.domain is "Color":
if aog.domain is domains['color']:
aog.color = device.get("Color")
aog.protected = device.get("Protected")
aog.maxdimlevel = device.get("MaxDimLevel")
Expand All @@ -217,7 +247,7 @@ def getAog(device):

aog.language = settings.get("Language")
aog.tempunit = settings.get("TempUnit")
if aog.domain is "Security":
if aog.domain == "Security":
aog.seccode = settings.get("SecPassword")
aog.secondelay = settings.get("SecOnDelay")

Expand Down Expand Up @@ -309,7 +339,7 @@ def getAog(device):
aog.attributes = ATTRS_BRIGHTNESS
if domains['color'] == aog.domain and "Dimmer" == device["SwitchType"]:
aog.attributes = ATTRS_BRIGHTNESS
if domains['color'] == aog.domain and device["SubType"] in ["RGBWW", "White"]:
if domains['color'] == aog.domain and device["SubType"] in ["RGBWW", "RGBWZ", "White"]:
aog.attributes = ATTRS_COLOR_TEMP
if domains['thermostat'] == aog.domain and "Thermostat" == device["Type"]:
aog.attributes = ATTRS_THERMSTATSETPOINT
Expand All @@ -322,7 +352,7 @@ def getAog(device):

if aog.room == None:
if aog.domain not in [domains['scene'], domains['group']]:
if aog.plan is not "0":
if aog.plan != "0":
aog.room = getPlans(aog.plan)

return aog
Expand Down Expand Up @@ -727,10 +757,6 @@ def states(self, s):

s.send_message(200, deviceList)

def test(self, s):

s.send_message(200, templatepage.render())

def settings(self, s):
user = self.getSessionUser()
if user is None or user.get('uid', '') == '':
Expand Down Expand Up @@ -898,8 +924,12 @@ def smarthome_query(self, payload, token):
continue

e = _GoogleEntity(state)
devices[devid] = e.query_serialize()

try:
devices[devid] = e.query_serialize()
except Exception:
logger.error("Unexpected error serializing query for %s", state)
devices[devid] = {"online": False}

response = {'devices': devices}
logger.info("Response " + json.dumps(response, indent=2, sort_keys=True, ensure_ascii=False))

Expand Down Expand Up @@ -961,21 +991,85 @@ def smarthome_disconnect(self, payload, token):
https://developers.google.com/assistant/smarthome/develop/process-intents#DISCONNECT
"""
return None

def say(self, s):
itext = s.url.query.replace(" ","-")
itext=itext.split("/")
text = itext[0]
if not text:
return False
if len(itext) > 1:
lang = itext[1].lower()
else:
lang = "en"
slow = False
current_time = time.strftime("%d/%m/%y %H:%M:%S", time.localtime())
message="say command on " + current_time + ", text : " + str(text) + ", lang : " + lang
tts = gTTS(text=text, lang=lang, slow=slow)
filename = slugify(text+"-"+lang+"-"+str(slow)) + ".mp3"
cache_filename = FILE_DIR + "/sound/cache/" + filename
tts_file = Path(cache_filename)
if not tts_file.is_file():
logger.info(tts)
tts.save(cache_filename)
mp3_url = "http://" + IP_Address + ":" + str(s.server.server_port) + "/sound?cache/" + filename
#make a query request for Get /sound
logger.info(message)
SmartHomeReqHandler.play_mp3(mp3_url)
s.send_message(200, "OK " + message + "\n")

def play(self, s):
filename = s.url.query
mp3_filename = FILE_DIR + "/sound/" + filename
mp3 = Path(mp3_filename)
current_time = time.strftime("%d/%m/%y %H:%M:%S", time.localtime())
message = "play command on " + current_time + ", file : " + str(mp3_filename)
logger.info(message)
if mp3.is_file():
mp3_url = "http://" + IP_Address + ":" + str(s.server.server_port) + "/sound?" + filename
#make a query request for Get /sound
SmartHomeReqHandler.play_mp3(mp3_url)
s.send_message(200, "OK " + message + "\n")
else:
s.send_message(200, "File not found\n")

def play_mp3(mp3_url):
cast.wait()
mc = cast.media_controller
mc.play_media(mp3_url, 'audio/mp3')
logger.info("Play mp3 started")

def send_sound(self, s):
filename = s.url.query
cache_filename = FILE_DIR + "/sound/" + filename
logger.info("sound : " + cache_filename)
f = open(cache_filename, 'rb')
s.send_response(200) # send_message (later in server.py)
s.send_header('Content-type', 'audio/mpeg3')
s.end_headers()
s.wfile.write(f.read())
f.close()

if 'userinterface' in configuration and configuration['userinterface'] == True:
smarthomeGetMappings = {"/smarthome": SmartHomeReqHandler.smarthome,
"/sync": SmartHomeReqHandler.syncDevices,
"/settings": SmartHomeReqHandler.settings,
"/log": SmartHomeReqHandler.log,
"/states": SmartHomeReqHandler.states,
"/restart": SmartHomeReqHandler.restartServer}
"/restart": SmartHomeReqHandler.restartServer,
"/say": SmartHomeReqHandler.say,
"/play": SmartHomeReqHandler.play,
"/sound": SmartHomeReqHandler.send_sound}

smarthomePostMappings = {"/smarthome": SmartHomeReqHandler.smarthome_post,
"/settings": SmartHomeReqHandler.settings_post}
else:
smarthomeGetMappings = {"/smarthome": SmartHomeReqHandler.smarthome,
"/sync": SmartHomeReqHandler.syncDevices,
"/restart": SmartHomeReqHandler.restartServer}
"/restart": SmartHomeReqHandler.restartServer,
"/say": SmartHomeReqHandler.say,
"/play": SmartHomeReqHandler.play,
"/sound": SmartHomeReqHandler.send_sound}

smarthomePostMappings = {"/smarthome": SmartHomeReqHandler.smarthome_post}

Expand Down
Binary file added sound/cache/ok-en-false.mp3
Binary file not shown.
Binary file added sound/doorbell1.mp3
Binary file not shown.
Binary file added sound/doorbell2.mp3
Binary file not shown.
4 changes: 2 additions & 2 deletions templates/js/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function sortIdxTable(n) {
function readDevices(devicelist){
$.ajax({
type: 'GET',
url: '/states',
url: './states',
success: function(response) {
devicelist = JSON.parse(response)
var xl, i, nicknames = "";
Expand Down Expand Up @@ -234,7 +234,7 @@ function getlogs(){

$.ajax({
type: 'GET',
url: '/log',
url: './log',
success: function(response) {
$("#logs").html(response);
}
Expand Down
2 changes: 1 addition & 1 deletion trait.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ def query_attributes(self):
colorTemp = (color_rgb["t"] * (255 / 100)) * 10
response['color'] = {'temperatureK': round(colorTemp)}
except ValueError:
response['color'] = {}
response = {}

return response

Expand Down

0 comments on commit 21209b7

Please sign in to comment.