From c57cd04a247ba918703470a6bb8e64844f2c514e Mon Sep 17 00:00:00 2001 From: Vitor de Miranda Henrique Date: Tue, 19 Oct 2021 23:17:51 -0500 Subject: [PATCH] linking helper started --- octoprint_enclosure/__init__.py | 73 ++--- octoprint_enclosure/static/js/enclosure.js | 252 ++++++++++++++++-- .../templates/enclosure_settings.jinja2 | 24 +- .../templates/ifttt/general_info.jinja2 | 37 +++ .../templates/ifttt/io_trigger.jinja2 | 59 ++++ .../templates/ifttt/main_screen.jinja2 | 62 +++++ .../templates/ifttt/printer_event.jinja2 | 21 ++ .../templates/ifttt/set_output_value.jinja2 | 28 ++ .../templates/ifttt_logic_table.jinja2 | 33 +++ 9 files changed, 523 insertions(+), 66 deletions(-) create mode 100644 octoprint_enclosure/templates/ifttt/general_info.jinja2 create mode 100644 octoprint_enclosure/templates/ifttt/io_trigger.jinja2 create mode 100644 octoprint_enclosure/templates/ifttt/main_screen.jinja2 create mode 100644 octoprint_enclosure/templates/ifttt/printer_event.jinja2 create mode 100644 octoprint_enclosure/templates/ifttt/set_output_value.jinja2 create mode 100644 octoprint_enclosure/templates/ifttt_logic_table.jinja2 diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 4baf4d9..77d902f 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -1,47 +1,49 @@ # coding=utf-8 from __future__ import absolute_import -import octoprint.plugin -import octoprint.util +import json from abc import ABC from enum import Enum from uuid import UUID, uuid4 -import json -from flask import jsonify, request, make_response, Response + +import flask +import octoprint.plugin +import octoprint.util +from flask import Response, jsonify, make_response, request, abort +# class OutputType(Enum): +# ACTION_BASED_INPUT = 0 +# STATE_BASED_INPUT = 1 -class OutputType(Enum): - ACTION_BASED_INPUT = 0 - STATE_BASED_INPUT = 1 -class OutputPeripheral(ABC): - def __init__(self, id: UUID ,name:str, type:OutputType) -> None: - super().__init__() +# class OutputPeripheral(ABC): +# def __init__(self, id: UUID, name: str, type: OutputType) -> None: +# super().__init__() - def run_action(self): - """ - Output peripheral can be action based when it's: - - GCODE command - - Shell script +# def run_action(self): +# """ +# Output peripheral can be action based when it's: +# - GCODE command +# - Shell script - Returns: - Bool: Success - """ - pass +# Returns: +# Bool: Success +# """ +# pass - def set_state(self, state): - """ - Output peripheral can be state based when it's: - - GPIO: it can be set to on / off / toggle - - Led Strip: it can be set to a color in RGB - - Neopixel - - PWM +# def set_state(self, state): +# """ +# Output peripheral can be state based when it's: +# - GPIO: it can be set to on / off / toggle +# - Led Strip: it can be set to a color in RGB +# - Neopixel +# - PWM - Returns: - Bool: Success - """ - pass +# Returns: +# Bool: Success +# """ +# pass class EnclosurePlugin(octoprint.plugin.StartupPlugin, @@ -57,7 +59,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, self._ids = [] - @octoprint.plugin.BlueprintPlugin.route("/available_id", methods=["GET"]) + @octoprint.plugin.BlueprintPlugin.route("/uuid", methods=["GET"]) def get_available_id(self): return Response(json.dumps(str(uuid4())), mimetype='application/json') @@ -106,7 +108,6 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, if v == implementation: return k - def register_plugin(self, implementation): k = self._get_plugin_key(implementation) @@ -145,8 +146,8 @@ def __plugin_load__(): global __plugin_helpers__ __plugin_helpers__ = dict( # get_id = __plugin_implementation__.get_id, - output_peripheral_set_state = __plugin_implementation__.output_peripheral_set_state, - register_plugin = __plugin_implementation__.register_plugin, - register_output_peripheral = __plugin_implementation__.register_output_peripheral, - register_input_peripheral = __plugin_implementation__.register_input_peripheral, + output_peripheral_set_state= __plugin_implementation__.output_peripheral_set_state, + register_plugin= __plugin_implementation__.register_plugin, + register_output_peripheral= __plugin_implementation__.register_output_peripheral, + register_input_peripheral= __plugin_implementation__.register_input_peripheral, ) diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index f4df1b9..9f355c6 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -1,42 +1,236 @@ - $(function () { - function EnclosureViewModel(parameters) { - var self = this; - - self.settingsViewModel = parameters[0]; - self.connectionViewModel = parameters[1]; - self.printerStateViewModel = parameters[2]; - - self.enclosureOutputs = ko.observableArray(); - self.enclosureInputs = ko.observableArray(); - - self.settings_unsaved = ko.observable(false); - - self.onBeforeBinding = function () { + var cleanIFTTT = function (index_id) { + return { + index_id: index_id, + trigger_type: "io_trigger", + linked_input_id: "", + input_logic: "equals", + input_value: "", + action_type: "set_output_value", + linked_output: "", + output_set_value: "" + } }; - self.onSettingsBeforeSave = function () { + function generate_random_uuid() { + return ([1e2] + 1e2).replace(/[018]/g, c => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); + } + + function IFTTTEditorViewModel(parameters) { + var self = this; + + self.isNew = ko.observable(false); + self.index_id = ko.observable(); + self.trigger_type = ko.observable(); + self.action_type = ko.observable(); + self.linked_input_id = ko.observable(); + self.linked_output = ko.observable(); + self.output_set_value = ko.observable(); + + self.ifttt_logic = undefined; + self.enclosureOutputs = undefined; + self.enclosureInputs = undefined; + + + self.validInput = ko.pureComputed(function () { + return true; + }); + + self.linked_input = ko.pureComputed(function () { + if (self.trigger_type() == 'io_trigger') { + var _linked_input = ko.utils.arrayFilter(self.enclosureInputs(), function (item) { + return (self.linked_input_id() == item.index_id()); + }).pop(); + if(_linked_input){ + return _linked_input + } + } + return undefined + }); + + // self.linked_input_type = ko.pureComputed(function () { + // if (self.linked_input()) { + // return self.linked_input.category; + // } + // return ko.observable("none"); + // }); + + self.fromIFTTTData = function (data) { + + self.isNew(data === undefined); + + if (data === undefined) { + var arrRelaysLength = self.ifttt_logic().length; + var nextIndex = arrRelaysLength == 0 ? 1 : self.ifttt_logic()[arrRelaysLength - 1].index_id() + 1; + data = cleanIFTTT(nextIndex); + } else { + objIndex = self.ifttt_logic().findIndex((obj => obj.index_id == data.index_id)); + data = ko.mapping.toJS(self.ifttt_logic()[objIndex]); + } + + self.index_id(data.index_id); + self.trigger_type(data.trigger_type) + self.action_type(data.action_type) + self.linked_input_id(data.linked_input_id) + self.linked_output(data.linked_output) + self.output_set_value(data.output_set_value) + + }; + + self.toIFTTTData = function (data) { + var output_data = { + index_id: self.index_id(), + trigger_type: self.trigger_type(), + action_type: self.action_type(), + linked_input_id: self.linked_input_id(), + linked_output: self.linked_output(), + output_set_value: self.output_set_value(), + } + + return output_data; + }; + // end of IFTTTEditorViewModel }; - self.onEventSettingsUpdated = function () { + + function EnclosureViewModel(parameters) { + var self = this; + + self.pluginName = "enclosure"; + + self.settingsViewModel = parameters[0]; + self.connectionViewModel = parameters[1]; + self.printerStateViewModel = parameters[2]; + + self.settings_unsaved = ko.observable(false); + + self.ifttt_logic = ko.observableArray(); + self.enclosureOutputs = ko.observableArray(); + self.enclosureInputs = ko.observableArray(); + self.settings_unsaved = ko.observable(false); + + // self.settings_outputs_regular = ko.pureComputed(function () { + // return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) { + // return (item.output_type() === "regular_gpio" && !item.toggle_timer()); + // }); + // }); + + self.createIFTTTEditor = function (data) { + var inputEditor = new IFTTTEditorViewModel(); + return inputEditor; + }; + + self.inputEditor = self.createIFTTTEditor(); + self.inputEditor.ifttt_logic = self.ifttt_logic; + self.inputEditor.enclosureOutputs = self.enclosureOutputs; + self.inputEditor.enclosureInputs = self.enclosureInputs; + + self.removeLogic = function (data) { + self.ifttt_logic.remove(data); + self.settings_unsaved(true); + } + + self.buildPluginUrl = function (path) { + return window.PLUGIN_BASEURL + self.pluginName + path; + }; + + self.get_uuid = function () { + + while (true) { + uuid_test = generate_random_uuid(); + var used_id_output = ko.utils.arrayFilter(self.enclosureOutputs(), function (item) { + return (uuid_test == item.index_id()); + }).pop(); + + var used_id_input = ko.utils.arrayFilter(self.enclosureInputs(), function (item) { + return (uuid_test == item.index_id()); + }).pop(); + + if (!used_id_output && !used_id_input) { + return uuid_test + } + } + + // response = $.ajax({ + // type: "GET", + // url: self.buildPluginUrl("/uuid"), + // async: false + // }).responseText; + + // return JSON.parse(response); + } + + self.addLogic = function (callback) { + var isNew = self.inputEditor.isNew(); + + self.settings_unsaved(true); + + var input = ko.mapping.fromJS(self.inputEditor.toIFTTTData()); + + if (isNew) { + self.ifttt_logic.push(input); + } else { + objIndex = self.ifttt_logic().findIndex((obj => obj.index_id() == input.index_id())); + var _old_input = self.ifttt_logic()[objIndex]; + self.ifttt_logic.replace(_old_input, input); + } + + if (callback !== undefined) { + callback(); + } + }; + + self.confirmEditLogic = function () { + + if (self.inputEditor.validInput()) { + var callback = function () { + $("#settings_ifttt_edit_dialog").modal("hide"); + }; + + self.addLogic(callback); + } + }; + + self.showIFTTTDialog = function (data) { + + self.inputEditor.fromIFTTTData(data); + + var editDialog = $("#settings_ifttt_edit_dialog"); + + $('ul.nav-pills a[data-toggle="tab"]:first', editDialog).tab("show"); + editDialog.modal({ + minHeight: function () { + return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); + } + }).css({ + width: 'auto', + 'margin-left': function () { + return -($(this).width()); + } + }); + }; + + self.onBeforeBinding = function () { + + }; + + self.onSettingsBeforeSave = function () {}; + + self.onEventSettingsUpdated = function () { + + }; }; - - self.print_data = function () { - }; - - }; - - - - OCTOPRINT_VIEWMODELS.push({ - construct: EnclosureViewModel, - dependencies: ["settingsViewModel", "connectionViewModel", "printerStateViewModel"], - elements: ["#settings_plugin_enclosure"] - }); + OCTOPRINT_VIEWMODELS.push({ + construct: EnclosureViewModel, + dependencies: ["settingsViewModel", "connectionViewModel", "printerStateViewModel"], + elements: ["#settings_plugin_enclosure"] + }); }) \ No newline at end of file diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index 8c5de87..2d78f80 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -1,8 +1,30 @@
-

{{ _('Enclosure Plugin') }}

+

{{ _('Enclosure Plugin Logic') }}

+ + + {% include "ifttt_logic_table.jinja2" %} + + + +
+ +{% include "ifttt/main_screen.jinja2" %} \ No newline at end of file diff --git a/octoprint_enclosure/templates/ifttt/general_info.jinja2 b/octoprint_enclosure/templates/ifttt/general_info.jinja2 new file mode 100644 index 0000000..7220f4a --- /dev/null +++ b/octoprint_enclosure/templates/ifttt/general_info.jinja2 @@ -0,0 +1,37 @@ +
+ +
+ +
+ + Auto generated ID for Input +
+
+ +
+ +
+ + +
+
+ + +
+ +
+ +
+
+ + +
\ No newline at end of file diff --git a/octoprint_enclosure/templates/ifttt/io_trigger.jinja2 b/octoprint_enclosure/templates/ifttt/io_trigger.jinja2 new file mode 100644 index 0000000..b6017b9 --- /dev/null +++ b/octoprint_enclosure/templates/ifttt/io_trigger.jinja2 @@ -0,0 +1,59 @@ +
+ + +
+ +
+ +
+
+ + + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + +
+
+ + + +
\ No newline at end of file diff --git a/octoprint_enclosure/templates/ifttt/main_screen.jinja2 b/octoprint_enclosure/templates/ifttt/main_screen.jinja2 new file mode 100644 index 0000000..00bf276 --- /dev/null +++ b/octoprint_enclosure/templates/ifttt/main_screen.jinja2 @@ -0,0 +1,62 @@ + \ No newline at end of file diff --git a/octoprint_enclosure/templates/ifttt/printer_event.jinja2 b/octoprint_enclosure/templates/ifttt/printer_event.jinja2 new file mode 100644 index 0000000..7ddcf1d --- /dev/null +++ b/octoprint_enclosure/templates/ifttt/printer_event.jinja2 @@ -0,0 +1,21 @@ +
+ +
+ +
+ + + +
+
+ +
\ No newline at end of file diff --git a/octoprint_enclosure/templates/ifttt/set_output_value.jinja2 b/octoprint_enclosure/templates/ifttt/set_output_value.jinja2 new file mode 100644 index 0000000..d1518ab --- /dev/null +++ b/octoprint_enclosure/templates/ifttt/set_output_value.jinja2 @@ -0,0 +1,28 @@ +
+ +
+ +
+ +
+
+ +
+ + +
+ + values should be "on", "off" or "toggle" or anything that the linked output supports +
+ + +
+ +
\ No newline at end of file diff --git a/octoprint_enclosure/templates/ifttt_logic_table.jinja2 b/octoprint_enclosure/templates/ifttt_logic_table.jinja2 new file mode 100644 index 0000000..dede5c2 --- /dev/null +++ b/octoprint_enclosure/templates/ifttt_logic_table.jinja2 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + +
IdTriggerInputActionOutputSet Value{{ _('Edit') }}
+  |  + +
+ +
+ +
\ No newline at end of file