From 5b5e0b3c64ad1a78ff7f72455264fd0cd45fc9eb Mon Sep 17 00:00:00 2001 From: Kai Wansart Date: Fri, 2 Feb 2018 17:23:44 +0100 Subject: [PATCH] progress --- app/devices/ssh.py | 25 ++++ app/devices/wol.py | 16 ++- app/devices/yeelight.py | 75 +++++++++++ app/webserver.py | 81 ++++++++---- config/devices.json.example | 29 +++-- readme.md | 6 +- www/html/devices.html | 2 +- www/html/yeelight.html | 0 www/js/cm.js | 245 ++++++++++++++++++++++++++++-------- 9 files changed, 395 insertions(+), 84 deletions(-) create mode 100644 www/html/yeelight.html diff --git a/app/devices/ssh.py b/app/devices/ssh.py index 4d6fdcf..34c567d 100644 --- a/app/devices/ssh.py +++ b/app/devices/ssh.py @@ -6,6 +6,7 @@ class SSH(object): ##-----------------------------------------------------------------------------------## def __init__(self, devices): ##-----------------------------------------------------------------------------------## + self.devices = {} for device in devices: self.devices[device] = {} self.devices[device]['user'] = devices[device]['user'] @@ -25,6 +26,30 @@ class SSH(object): if(command=="upgrade"): self.upgrade(device) + ##-----------------------------------------------------------------------------------## + def config(self): + ##-----------------------------------------------------------------------------------## + config = { + "device" : { + "name" : "", + "ip" : "", + "user" : "" + }, + "shutdown" : { + "device" : "name", + "state" : "button" + }, + "reboot" : { + "device" : "name", + "state" : "button" + }, + "upgrade" : { + "device" : "name", + "state" : "button" + } + } + return config + ##-----------------------------------------------------------------------------------## def shutdown(self, device): ##-----------------------------------------------------------------------------------## diff --git a/app/devices/wol.py b/app/devices/wol.py index c146c16..d611b7f 100644 --- a/app/devices/wol.py +++ b/app/devices/wol.py @@ -7,9 +7,23 @@ class WOL(object): def __init__(self, devices): ##-----------------------------------------------------------------------------------## count = 0 + self.devices= {} for device in devices: self.devices[device] = devices[device]['mac'] - + ##-----------------------------------------------------------------------------------## + def config(self): + ##-----------------------------------------------------------------------------------## + config = { + "device" : { + "name" : "", + "mac" : "" + }, + "wake" : { + "device" : "name", + "state" : "button" + } + } + return config ##-----------------------------------------------------------------------------------## def wakeDevice(self, device): ##-----------------------------------------------------------------------------------## diff --git a/app/devices/yeelight.py b/app/devices/yeelight.py index d814fdb..c4c8267 100644 --- a/app/devices/yeelight.py +++ b/app/devices/yeelight.py @@ -26,6 +26,81 @@ class Yeelight(object): except: print(bulb + " ist in keiner Gruppe") + ##-----------------------------------------------------------------------------------## + def config(self): + ##-----------------------------------------------------------------------------------## + config = { + "rgb" : { + "device" : { + "name" : "", + "ip" : "", + "type" : "rgb" + }, + "power" : { + "device" : "name", + "state" : "switch" + }, + "brightness" : { + "device" : "name", + "state" : "dimmer" + }, + "temperature" : { + "device" : "name", + "state" : "dimmer" + }, + "color" : { + "device" : "name", + "r" : "dimmer", + "g" : "dimmer", + "b" : "dimmer" + } + }, + "white" : { + "device" : { + "name": "", + "ip" : "", + "type" : "white" + }, + "power" : { + "device" : "name", + "state" : "switch" + }, + "brightness" : { + "device" : "name", + "state" : "dimmer" + }, + "temperature" : { + "device" : "name", + "state" : "dimmer" + } + } + } + return config + + ##-----------------------------------------------------------------------------------## + def state(self): + ##-----------------------------------------------------------------------------------## + state = {} + for bulb in self.bulbs: + state[bulb] = {} + try: + properties = self.bulbs[bulb].get_properties() + except: + state[bulb]['offline'] = True + finally: + state[bulb]['offline'] = False + state[bulb]['power'] = properties['power'] + state[bulb]['brightness'] = properties['bright'] + state[bulb]['temperature'] = properties['ct'] + state[bulb]['color'] = properties['rgb'] + state[bulb]['groups'] = {} + for group in self.groups: + if(bulb in self.groups[group]): + state[bulb]['groups'][group] = "" + #r, g, b = tuple(int(properties['rgb'][i:i+2], 16) for i in (0, 2 ,4)) + #print("r:" + str(r) + " g: " + str(g) + " b: " + str(b)) + return state + ##-----------------------------------------------------------------------------------## def command(self, data): ##-----------------------------------------------------------------------------------## diff --git a/app/webserver.py b/app/webserver.py index 6297782..2ac70fa 100644 --- a/app/webserver.py +++ b/app/webserver.py @@ -1,4 +1,4 @@ -from flask import Flask, request +from flask import Flask, request, jsonify ##---------------------------------------------------------------------------------------## @@ -10,6 +10,29 @@ class Webserver(object): print("Webserver initialisiert") self.settings = config.read("settings") self.devices = config.read("devices") + self.config = {} + + ##-----------------------------------------------------------------------------------## + def createConfig(self, module, devices, config): + ##-----------------------------------------------------------------------------------## + #print("Module: " + str(module)) + #print("Devices: " + str(devices)) + #print("Config: " + str(config)) + self.config[module] = {} + if(module == "yeelight"): + for device in devices: + self.config[module][device] = {} + self.config[module][device] = self.devices[module][device] + if(devices[device]['type'] == "rgb"): + self.config[module][device]['config'] = config['rgb'] + if(devices[device]['type'] == "white"): + self.config[module][device]['config'] = config['white'] + return + + for device in devices: + self.config[module][device] = {} + self.config[module][device] = self.devices[module][device] + self.config[module][device]['config'] = config ##-----------------------------------------------------------------------------------## def run(self): @@ -20,8 +43,11 @@ class Webserver(object): print("Enabled Yeelight") from app.devices import yeelight self.yeelight = yeelight.Yeelight(self.devices['yeelight']) + devices = self.devices['yeelight'] + config = self.yeelight.config() + self.createConfig("yeelight", devices, config) - @app.route('/yeelight', methods=['POST']) + @app.route('/rest/yeelight', methods=['POST']) def yeelight(): app.logger.debug("JSON received...") app.logger.debug(request.json) @@ -38,8 +64,11 @@ class Webserver(object): print("Enabled SSH") from app.devices import ssh self.ssh = ssh.SSH(self.devices['ssh']) + devices = self.devices['ssh'] + config = self.ssh.config() + self.createConfig("ssh", devices, config) - @app.route('/ssh', methods=['POST']) + @app.route('/rest/ssh', methods=['POST']) def ssh(): app.logger.debug("JSON received...") app.logger.debug(request.json) @@ -56,8 +85,11 @@ class Webserver(object): print("Enabled WOL") from app.devices import wol self.wol = wol.WOL(self.devices['wol']) + devices = self.devices['wol'] + config = self.wol.config() + self.createConfig("wol", devices, config) - @app.route('/wol', methods=['POST']) + @app.route('/rest/wol', methods=['POST']) def wol(): app.logger.debug("JSON received...") app.logger.debug(request.json) @@ -70,22 +102,29 @@ class Webserver(object): else: print("Disabled SSH") - if(self.devices['denon'] != None): - print("Enabled Denon") - from app.devices import denon - self.denon = wol.WOL(self.devices['denon']) + #if(self.devices['denon'] != None): + # print("Enabled Denon") + # from app.devices import denon + # self.denon = denon.Denon(self.devices['denon']) + # devices = self.devices['denon'] + # config = self.denon.config() + # self.createConfig("denon", devices, config) - @app.route('/denon', methods=['POST']) - def denon(): - app.logger.debug("JSON received...") - app.logger.debug(request.json) - if request.json: - data = request.get_json(force=True) - self.denon.command(data) - return '200' - else: - return '500' - else: - print("Disabled Denon") + # @app.route('/rest/denon', methods=['POST']) + # def denon(): + # app.logger.debug("JSON received...") + # app.logger.debug(request.json) + # if request.json: + # data = request.get_json(force=True) + # self.denon.command(data) + # return '200' + # else: + # return '500' + #else: + # print("Disabled Denon") - app.run(debug=False, host='0.0.0.0') \ No newline at end of file + @app.route('/rest/config', methods=['GET']) + def config(): + return jsonify(self.config) + + app.run(debug=True, host='0.0.0.0') \ No newline at end of file diff --git a/config/devices.json.example b/config/devices.json.example index 5f77a7a..af498a0 100644 --- a/config/devices.json.example +++ b/config/devices.json.example @@ -2,20 +2,35 @@ "yeelight" : { "fernseher" : { "ip" : "192.168.178.127", - "type" : "rgb" - }, + "type" : "rgb", + "groups" : { + "zimmer" : "zimmer", + "passiv" : "passiv" + } + }, "regal" : { "ip" : "192.168.178.128", - "type" : "rgb" - }, + "type" : "rgb", + "groups" : { + "zimmer" : "zimmer", + "passiv" : "passiv" + } + }, "monitor" : { "ip" : "192.168.178.126", - "type" : "rgb" - }, + "type" : "rgb", + "groups" : { + "zimmer" : "zimmer", + "passiv" : "passiv" + } + }, "bett" : { "ip" : "192.168.178.122", - "type" : "rgb" + "type" : "rgb", + "groups" : { + "zimmer" : "zimmer" } + } }, "ssh" : { "nas" : { diff --git a/readme.md b/readme.md index 809123e..2bde5fa 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,8 @@ # TODO -1. Return available commands -2. Presets (Yeelight) -3. Website..... +1. ~~Return available commands~~ +2. Presets (Yeelight) .... Progress +3. Website..... Progress 4. Yamaha Receiver 5. Yeelight Flow 6. Wecker diff --git a/www/html/devices.html b/www/html/devices.html index dc722ac..a46115a 100644 --- a/www/html/devices.html +++ b/www/html/devices.html @@ -1,4 +1,4 @@ -
+

Lampen

diff --git a/www/html/yeelight.html b/www/html/yeelight.html new file mode 100644 index 0000000..e69de29 diff --git a/www/js/cm.js b/www/js/cm.js index 651edf0..39e131b 100644 --- a/www/js/cm.js +++ b/www/js/cm.js @@ -2,61 +2,204 @@ // CM - Hauptfunktion //------------------------------------------------------------------------------ -class CM +var config = {} + +//-----------------------------------------------------------------------------------// +function bodyDataAction () +//-----------------------------------------------------------------------------------// { - constructor () - { - this.BodyDataAction(); - - console.log("CM LOADED"); - } - - BodyDataAction () - { - var menuButtons = document.getElementById("navbarBtn"). - getElementsByTagName("button"); - for (var i = 0; i < menuButtons.length; i++) { - menuButtons[i].onclick = function(evt) { - var res = evt.target.id; - CM_o.Menu(res); - }; - } - } - - Menu (message) - { - var selectedId = $(".selected").attr('id'); - switch (message) - { - case 'pageDevices': - console.log( "pageDevices") - this.LoadContent('html/devices.html'); - document.getElementById('pageDevices').className = "btn btn-outline-light text-dark active"; - document.getElementById('pageSettings').className = "btn btn-outline-light text-dark"; - break; - case 'pageSettings': - console.log( "pageDevices") - this.LoadContent('html/settings.html'); - document.getElementById('pageDevices').className = "btn btn-outline-light text-dark"; - document.getElementById('pageSettings').className = "btn btn-outline-light text-dark active"; - break; - default: - alert ('[CM] Unbekannte Anfrage: ' + message); - } - } - - LoadContent ( path ) - { - $.get( path, function( data ) { - $( ".content" ).html( data ); - console.log( "Load was performed." ); - }); + var menuButtons = document.getElementById("navbarBtn"). + getElementsByTagName("button"); + for (var i = 0; i < menuButtons.length; i++) { + menuButtons[i].onclick = function(evt) { + var res = evt.target.id; + menu(res); + }; } } +//-----------------------------------------------------------------------------------// +function menu (message, request=null) +//-----------------------------------------------------------------------------------// +{ + var selectedId = $(".selected").attr('id'); + switch (message) + { + case 'pageDevices': + console.log( "pageDevices") + //loadContent('html/devices.html'); + generateDevices(); + document.getElementById('pageDevices').className = "btn btn-outline-light text-dark active"; + document.getElementById('pageSettings').className = "btn btn-outline-light text-dark"; + break; + case 'pageSettings': + console.log( "pageDevices") + //loadContent('html/settings.html'); + document.getElementById('pageDevices').className = "btn btn-outline-light text-dark"; + document.getElementById('pageSettings').className = "btn btn-outline-light text-dark active"; + break; + case 'switchRequest': + console.log( request ) + switchRequest(request); + break; + default: + alert ('[CM] Unbekannte Anfrage: ' + message); + } +} +//-----------------------------------------------------------------------------------// +function switchRequest (request) +//-----------------------------------------------------------------------------------// +{ + var req = request.split("."); + switch (req[0]) + { + case 'yeelight': + var bulb = req[1] + var type = req[2] + var value = req[3] + var cmd = {}; + cmd[bulb] = {}; + cmd[bulb][type] = value; + postYeelight(cmd); + break; + default: + alert ('[POST] Unbekannte Anfrage: ' + req[0]); + } +} + +//-----------------------------------------------------------------------------------// +function generateYeelightBulbs ( data , type) +//-----------------------------------------------------------------------------------// +{ + $( ".content" ).append($('
')); + $( ".yeelight"+type ).append($("

").text("Yeelight " + type)); + $( ".yeelight"+type ).append($('
')); + for (bulb in data) + { + $( ".yeelight"+type+"row" ).append($('
')); + $( "." + bulb + "col" ).append($("

").text(bulb)); + $( "." + bulb + "col" ).append($('
')); + var configBulb = data[bulb]['config'] + for (setting in configBulb) + { + if (configBulb[setting]['state'] == "switch") + { + var command = "on"; + $( "." + bulb + "btn" ).append($('')); + var buttonOn = document.getElementById('yeelight.'+bulb+'.'+setting+'.on'); + buttonOn.onclick = function(evt) { + var res = evt.target.id; + menu('switchRequest', res);} + var command = "off"; + $( "." + bulb + "btn" ).append($('')); + var buttonOff = document.getElementById('yeelight.'+bulb+'.'+setting+'.off'); + buttonOff.onclick = function(evt) { + var res = evt.target.id; + menu('switchRequest', res);} + } + } + } +} + +//-----------------------------------------------------------------------------------// +function generateYeelightGroups ( data ) +//-----------------------------------------------------------------------------------// +{ + console.log(data); + var groups = {} + for (bulb in data) + { + for (group in data[bulb]['groups']) + { + if (group in groups) + { + //groups[group] = data[bulb]; + } + else + { + groups[group] = {}; + groups[group] = data[bulb]; + } + } + }; + console.log(groups); + generateYeelightBulbs(groups,"Gruppen"); +} + +//-----------------------------------------------------------------------------------// +function generateYeelight ( data ) +//-----------------------------------------------------------------------------------// +{ + generateYeelightBulbs(data,"Bulbs"); + generateYeelightGroups(data); +} + +//-----------------------------------------------------------------------------------// +function generateDevices ( ) +//-----------------------------------------------------------------------------------// +{ + for (module in config) + { + if(module == "yeelight") + { + generateYeelight(config[module]); + } + } + + return 0; +} + +//-----------------------------------------------------------------------------------// +function getConfig ( ) +//-----------------------------------------------------------------------------------// +{ + $.ajax('/rest/config', { + type : 'GET', + dataType: "json", + success : function(data) { + config = data; + bodyDataAction(); + menu("pageDevices"); + } + }); +} + +//-----------------------------------------------------------------------------------// +function postYeelight ( cmd ) +//-----------------------------------------------------------------------------------// +{ + $.ajax('/rest/yeelight', { + type : 'POST', + dataType: "json", + contentType: 'application/json', + data : JSON.stringify(cmd), + success : function(data) { + console.log(data); + } + }); +} + +//-----------------------------------------------------------------------------------// +function loadContent ( content ) +//-----------------------------------------------------------------------------------// +{ + $.get( content, function( data ) { + $( ".content" ).html( data ); + console.log( "Load was performed." ); + }); +} + +//-----------------------------------------------------------------------------------// $(function() { console.log("ONLOAD"); - CM_o = new CM(); - CM_o.Menu("pageDevices"); -}); \ No newline at end of file + + getConfig(); + + console.log("CM LOADED"); +}); +//-----------------------------------------------------------------------------------// \ No newline at end of file