From 65f9610ccedbd2615016f4720f8ff85b0e6f507c Mon Sep 17 00:00:00 2001
From: Fabio Manganiello <blacklight86@gmail.com>
Date: Tue, 26 Jun 2018 22:14:11 +0200
Subject: [PATCH] Added switch.tplink web widget

---
 .../backend/http/static/css/switch.tplink.css | 29 +++++++
 .../backend/http/static/js/switch.tplink.js   | 76 +++++++++++++++++++
 .../backend/http/static/js/switch.wemo.js     |  2 +-
 .../http/templates/plugins/switch.tplink.html |  5 ++
 platypush/plugins/switch/tplink.py            | 12 ++-
 5 files changed, 116 insertions(+), 8 deletions(-)
 create mode 100644 platypush/backend/http/static/css/switch.tplink.css
 create mode 100644 platypush/backend/http/static/js/switch.tplink.js
 create mode 100644 platypush/backend/http/templates/plugins/switch.tplink.html

diff --git a/platypush/backend/http/static/css/switch.tplink.css b/platypush/backend/http/static/css/switch.tplink.css
new file mode 100644
index 000000000..4ab62f912
--- /dev/null
+++ b/platypush/backend/http/static/css/switch.tplink.css
@@ -0,0 +1,29 @@
+#tplink-container {
+    background-color: #f8f8f8;
+    padding: 12px;
+    border: 1px solid #ddd;
+    border-radius: 10px;
+    font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
+    font-weight: 400;
+    line-height: 38px;
+    letter-spacing: .1rem;
+}
+
+.tplink-device {
+    padding: 1.5em 1em .2em .5em;
+    border-radius: 10px;
+}
+
+    .tplink-device:nth-of-type(odd) {
+        background-color: #ececec;
+    }
+
+    .tplink-device:hover {
+        background-color: #daf8e2 !important;
+    }
+
+.toggle-container {
+    text-align: right;
+    padding-right: 1em;
+}
+
diff --git a/platypush/backend/http/static/js/switch.tplink.js b/platypush/backend/http/static/js/switch.tplink.js
new file mode 100644
index 000000000..32e93594a
--- /dev/null
+++ b/platypush/backend/http/static/js/switch.tplink.js
@@ -0,0 +1,76 @@
+$(document).ready(function() {
+    var switches,
+        $tplinkContainer = $('#tplink-container');
+
+    var createPowerToggleElement = function(dev) {
+        var $powerToggle = $('<div></div>').addClass('toggle toggle--push switch-ctrl-container');
+        var $input = $('<input></input>').attr('type', 'checkbox')
+            .data('name', dev.host).attr('name', dev.alias).addClass('toggle--checkbox switch-ctrl');
+
+        var $label = $('<label></label>').attr('for', dev.alias).addClass('toggle--btn');
+
+        $input.appendTo($powerToggle);
+        $label.appendTo($powerToggle);
+
+        if (dev.on) {
+            $input.prop('checked', true);
+        }
+
+        return $powerToggle;
+    };
+
+    var updateDevices = function(devices) {
+        for (var dev of devices) {
+            var $dev = $('<div></div>').addClass('row tplink-device').data('name', dev.alias);
+            var $devName = $('<div></div>').addClass('ten columns name').text(dev.alias);
+            var $toggleContainer = $('<div></div>').addClass('two columns toggle-container');
+            var $toggle = createPowerToggleElement(dev);
+
+            $toggle.appendTo($toggleContainer);
+            $devName.appendTo($dev);
+            $toggleContainer.appendTo($dev);
+            $dev.appendTo($tplinkContainer);
+        }
+    };
+
+    var initWidget = function() {
+        execute(
+            {
+                type: 'request',
+                action: 'switch.tplink.status'
+            },
+
+            onSuccess = function(response) {
+                updateDevices(Object.values(response.response.output.devices));
+            }
+        );
+    };
+
+    var initBindings = function() {
+        $tplinkContainer.on('click touch', '.switch-ctrl-container', function() {
+            var $input = $(this).find('.switch-ctrl');
+            var devAddr = $input.data('name');
+
+            execute(
+                {
+                    type: 'request',
+                    action: 'switch.tplink.toggle',
+                    args: { device: devAddr }
+                },
+
+                onSuccess = function(response) {
+                    var status = response.response.output.status;
+                    $input.prop('checked', status == 'on' ? true : false);
+                }
+            );
+        });
+    };
+
+    var init = function() {
+        initWidget();
+        initBindings();
+    };
+
+    init();
+});
+
diff --git a/platypush/backend/http/static/js/switch.wemo.js b/platypush/backend/http/static/js/switch.wemo.js
index 693eb710b..01b2a93db 100644
--- a/platypush/backend/http/static/js/switch.wemo.js
+++ b/platypush/backend/http/static/js/switch.wemo.js
@@ -7,7 +7,7 @@ $(document).ready(function() {
         var $input = $('<input></input>').attr('type', 'checkbox')
             .attr('name', dev.name).addClass('toggle--checkbox switch-ctrl');
 
-        var $label = $('<label></label>').attr('for', id).addClass('toggle--btn');
+        var $label = $('<label></label>').attr('for', dev.name).addClass('toggle--btn');
 
         $input.appendTo($powerToggle);
         $label.appendTo($powerToggle);
diff --git a/platypush/backend/http/templates/plugins/switch.tplink.html b/platypush/backend/http/templates/plugins/switch.tplink.html
new file mode 100644
index 000000000..ad4c74fbb
--- /dev/null
+++ b/platypush/backend/http/templates/plugins/switch.tplink.html
@@ -0,0 +1,5 @@
+<script type="text/javascript" src="{{ url_for('static', filename='js/switch.tplink.js') }}"></script>
+<link rel="stylesheet" href="{{ url_for('static', filename='css/switch.tplink.css') }}"></script>
+
+<div id="tplink-container" class="row"></div>
+
diff --git a/platypush/plugins/switch/tplink.py b/platypush/plugins/switch/tplink.py
index 6ff94a088..4f7d73b89 100644
--- a/platypush/plugins/switch/tplink.py
+++ b/platypush/plugins/switch/tplink.py
@@ -22,17 +22,15 @@ class SwitchTplinkPlugin(SwitchPlugin):
         :returns: The available device over the network as a
         """
 
-        devices = dict(
-            (ip, {
+        devices = { 'devices': {
+            ip: {
                 'alias': dev.alias,
-                'current_consumption': dev.current_consumption,
+                'current_consumption': dev.current_consumption(),
                 'host': dev.host,
                 'hw_info': dev.hw_info,
                 'on': dev.is_on,
-            })
-
-            for (ip, dev) in self._scan()
-        )
+            } for (ip, dev) in self._scan().items()
+        } }
 
         return Response(output=devices)