From 6daeefa71c80728d9e76e5e4cda276df69b3c0d8 Mon Sep 17 00:00:00 2001 From: David Zingg Date: Tue, 19 Nov 2019 21:29:32 +0100 Subject: [PATCH] first commit --- .idea/MyStromSwitchPlugin.iml | 12 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/workspace.xml | 37 ++ MANIFEST.in | 1 + README.md | 5 + babel.cfg | 6 + octoprint_mystromswitch/__init__.py | 441 ++++++++++++++++++ .../static/css/shutdownprinter.css | 38 ++ .../static/js/shutdownprinter.js | 292 ++++++++++++ .../templates/shutdownprinter_settings.jinja2 | 181 +++++++ .../templates/shutdownprinter_sidebar.jinja2 | 6 + requirements.txt | 9 + setup.py | 94 ++++ 16 files changed, 1149 insertions(+) create mode 100644 .idea/MyStromSwitchPlugin.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 MANIFEST.in create mode 100644 README.md create mode 100644 babel.cfg create mode 100644 octoprint_mystromswitch/__init__.py create mode 100644 octoprint_mystromswitch/static/css/shutdownprinter.css create mode 100644 octoprint_mystromswitch/static/js/shutdownprinter.js create mode 100644 octoprint_mystromswitch/templates/shutdownprinter_settings.jinja2 create mode 100644 octoprint_mystromswitch/templates/shutdownprinter_sidebar.jinja2 create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/.idea/MyStromSwitchPlugin.iml b/.idea/MyStromSwitchPlugin.iml new file mode 100644 index 0000000..6f63a63 --- /dev/null +++ b/.idea/MyStromSwitchPlugin.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d3b7f65 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e0cf972 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..9228c10 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + 1574193087583 + + + + \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..bb3ec5f --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..14feab0 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# OctoPrint MyStrom Switch Plugin + +This OctoPrint plugin enables the system to control the myStrom switch and read the current Powerconsumption of your system + + diff --git a/babel.cfg b/babel.cfg new file mode 100644 index 0000000..b6f5945 --- /dev/null +++ b/babel.cfg @@ -0,0 +1,6 @@ +[python: */**.py] +[jinja2: */**.jinja2] +extensions=jinja2.ext.autoescape, jinja2.ext.with_ + +[javascript: */**.js] +extract_messages = gettext, ngettext diff --git a/octoprint_mystromswitch/__init__.py b/octoprint_mystromswitch/__init__.py new file mode 100644 index 0000000..ea3e757 --- /dev/null +++ b/octoprint_mystromswitch/__init__.py @@ -0,0 +1,441 @@ +# coding=utf-8 +from __future__ import absolute_import + +import ssl +import urllib2 + +import octoprint.plugin +from flask import make_response +from octoprint.events import eventManager, Events +from octoprint.server import user_permission +from octoprint.util import RepeatedTimer + + +class shutdownprinterPlugin(octoprint.plugin.SettingsPlugin, + octoprint.plugin.AssetPlugin, + octoprint.plugin.TemplatePlugin, + octoprint.plugin.SimpleApiPlugin, + octoprint.plugin.EventHandlerPlugin, + octoprint.plugin.StartupPlugin): + + def __init__(self): + self.url = "" + self.previousEventIsCancel = False + self.gcode = "M81" + self._mode_shutdown_gcode = True + self._mode_shutdown_api = False + self._mode_shutdown_api_custom = False + self.api_custom_GET = False + self.api_custom_POST = False + self.api_custom_PUT = False + self.api_custom_url = "" + self.api_custom_json_header = "" + self.api_custom_body = "" + self.api_key_plugin = "" + self.api_json_command = "" + self.api_plugin_name = "" + self.api_plugin_port = 5000 + self.extraCommand = "" + self.abortTimeout = 0 + self.temperatureValue = 0 + self.temperatureTarget = False + self.printFailed = False + self.printCancelled = False + self.rememberCheckBox = False + self.lastCheckBoxValue = False + self._shutdown_printer_enabled = True + self._timeout_value = None + self._abort_timer = None + self._abort_timer_temp = None + self.ctx = ssl.create_default_context() + self.ctx.check_hostname = False + self.ctx.verify_mode = ssl.CERT_NONE + + def initialize(self): + self.gcode = self._settings.get(["gcode"]) + self._logger.debug("gcode: %s" % self.gcode) + + self.url = self._settings.get(["url"]) + self._logger.debug("url: %s" % self.url) + + self.api_key_plugin = self._settings.get(["api_key_plugin"]) + self._logger.debug("api_key_plugin: %s" % self.api_key_plugin) + + self._mode_shutdown_gcode = self._settings.get_boolean(["_mode_shutdown_gcode"]) + self._logger.debug("_mode_shutdown_gcode: %s" % self._mode_shutdown_gcode) + + self._mode_shutdown_api = self._settings.get_boolean(["_mode_shutdown_api"]) + self._logger.debug("_mode_shutdown_api: %s" % self._mode_shutdown_api) + + self._mode_shutdown_api_custom = self._settings.get_boolean(["_mode_shutdown_api_custom"]) + self._logger.debug("_mode_shutdown_api_custom: %s" % self._mode_shutdown_api_custom) + + self.api_custom_POST = self._settings.get_boolean(["api_custom_POST"]) + self._logger.debug("api_custom_POST: %s" % self.api_custom_POST) + + self.api_custom_GET = self._settings.get_boolean(["api_custom_GET"]) + self._logger.debug("api_custom_GET: %s" % self.api_custom_GET) + + self.api_custom_PUT = self._settings.get_boolean(["api_custom_PUT"]) + self._logger.debug("api_custom_PUT: %s" % self.api_custom_PUT) + + self.api_custom_url = self._settings.get(["api_custom_url"]) + self._logger.debug("api_custom_url: %s" % self.api_custom_url) + + self.api_custom_json_header = self._settings.get(["api_custom_json_header"]) + self._logger.debug("api_custom_json_header: %s" % self.api_custom_json_header) + + self.api_custom_body = self._settings.get(["api_custom_body"]) + self._logger.debug("api_custom_body: %s" % self.api_custom_body) + + self.api_json_command = self._settings.get(["api_json_command"]) + self._logger.debug("api_json_command: %s" % self.api_json_command) + + self.api_plugin_name = self._settings.get(["api_plugin_name"]) + self._logger.debug("api_plugin_name: %s" % self.api_plugin_name) + + self.api_plugin_port = self._settings.get_int(["api_plugin_port"]) + self._logger.debug("api_plugin_port: %s" % self.api_plugin_port) + + self.temperatureValue = self._settings.get_int(["temperatureValue"]) + self._logger.debug("temperatureValue: %s" % self.temperatureValue) + + self.temperatureTarget = self._settings.get_boolean(["temperatureTarget"]) + self._logger.debug("temperatureTarget: %s" % self.temperatureTarget) + + self.extraCommand = self._settings.get(["extraCommand"]) + self._logger.debug("extraCommand: %s" % self.extraCommand) + + self.abortTimeout = self._settings.get_int(["abortTimeout"]) + self._logger.debug("abortTimeout: %s" % self.abortTimeout) + + self.printFailed = self._settings.get_boolean(["printFailed"]) + self._logger.debug("printFailed: %s" % self.printFailed) + + self.printCancelled = self._settings.get_boolean(["printCancelled"]) + self._logger.debug("printCancelled: %s" % self.printCancelled) + + self.rememberCheckBox = self._settings.get_boolean(["rememberCheckBox"]) + self._logger.debug("rememberCheckBox: %s" % self.rememberCheckBox) + + self.lastCheckBoxValue = self._settings.get_boolean(["lastCheckBoxValue"]) + self._logger.debug("lastCheckBoxValue: %s" % self.lastCheckBoxValue) + if self.rememberCheckBox: + self._shutdown_printer_enabled = self.lastCheckBoxValue + + def get_assets(self): + return dict(js=["js/shutdownprinter.js"], css=["css/shutdownprinter.css"]) + + def get_template_configs(self): + return [dict(type="sidebar", + name="Shutdown Printer", + custom_bindings=False, + icon="power-off"), + dict(type="settings", custom_bindings=False)] + + def get_api_commands(self): + return dict(enable=["eventView"], + status=[], + update=["eventView"], + disable=["eventView"], + shutdown=["mode", "eventView"], + abort=["eventView"]) + + def on_api_command(self, command, data): + if not user_permission.can(): + return make_response("Insufficient rights", 403) + + if command == "status": + return make_response(str(self._shutdown_printer_enabled), 200) + elif command == "enable": + self._shutdown_printer_enabled = True + elif command == "disable": + self._shutdown_printer_enabled = False + elif command == "shutdown": + self._shutdown_printer_API_CMD(data["mode"]) # mode 1 = gcode, mode 2 = api, mode 3 = custom api + elif command == "abort": + if self._abort_timer is not None: + self._abort_timer.cancel() + self._abort_timer = None + if self._abort_timer_temp is not None: + self._abort_timer_temp.cancel() + self._abort_timer_temp = None + self._timeout_value = None + self._logger.info("Shutdown aborted.") + + if command == "enable" or command == "disable": + self.lastCheckBoxValue = self._shutdown_printer_enabled + if self.rememberCheckBox: + self._settings.set_boolean(["lastCheckBoxValue"], self.lastCheckBoxValue) + self._settings.save() + eventManager().fire(Events.SETTINGS_UPDATED) + if data["eventView"] == True: + self._plugin_manager.send_plugin_message(self._identifier, + dict(shutdownprinterEnabled=self._shutdown_printer_enabled, + type="timeout", timeout_value=self._timeout_value)) + + def on_event(self, event, payload): + + # if event == Events.CLIENT_OPENED: + # self._plugin_manager.send_plugin_message(self._identifier, dict(shutdownprinterEnabled=self._shutdown_printer_enabled, type="timeout", timeout_value=self._timeout_value)) + # return + + if not self._shutdown_printer_enabled: + return + + if event == Events.PRINT_STARTED: + # self._logger.info("Print started") + self.previousEventIsCancel = False + + if event not in [Events.PRINT_DONE, Events.PRINT_FAILED, Events.PRINT_CANCELLED]: + return + + return + if event == Events.PRINT_DONE: + self._temperature_target() + return + elif event == Events.PRINT_CANCELLED and self.printCancelled: + # self._logger.info("Print cancelled") + self.previousEventIsCancel = True + self._temperature_target() + return + elif event == Events.PRINT_CANCELLED: + # self._logger.info("Print cancelled") + self.previousEventIsCancel = True + return + + elif event == Events.PRINT_FAILED and self.printFailed: + if self.previousEventIsCancel == True: + self.previousEventIsCancel = False + return; + # self._logger.info("Print failed") + self._temperature_target() + return + else: + self.previousEventIsCancel = False + return + + def _temperature_target(self): + if self._abort_timer_temp is not None: + return + if self.temperatureTarget: + self._abort_timer_temp = RepeatedTimer(2, self._temperature_task) + self._abort_timer_temp.start() + else: + self._timer_start() + + def _temperature_task(self): + if self._printer.get_state_id() == "PRINTING" and self._printer.is_printing() == True: + self._abort_timer_temp.cancel() + self._abort_timer_temp = None + return + self._temp = self._printer.get_current_temperatures() + tester = 0; + number = 0; + for tool in self._temp.keys(): + if not tool == "bed": + if self._temp[tool]["actual"] <= self.temperatureValue: + tester += 1 + number += 1 + if tester == number: + self._abort_timer_temp.cancel() + self._abort_timer_temp = None + self._timer_start() + + def _timer_start(self): + if self._abort_timer is not None: + return + + self._logger.info("Starting abort shutdown printer timer.") + + self._timeout_value = self.abortTimeout + self._abort_timer = RepeatedTimer(1, self._timer_task) + self._abort_timer.start() + + def _timer_task(self): + if self._timeout_value is None: + return + + self._timeout_value -= 1 + self._plugin_manager.send_plugin_message(self._identifier, + dict(shutdownprinterEnabled=self._shutdown_printer_enabled, + type="timeout", timeout_value=self._timeout_value)) + if self._printer.get_state_id() == "PRINTING" and self._printer.is_printing() == True: + self._timeout_value = 0 + self._plugin_manager.send_plugin_message(self._identifier, + dict(shutdownprinterEnabled=self._shutdown_printer_enabled, + type="timeout", timeout_value=self._timeout_value)) + self._abort_timer.cancel() + self._abort_timer = None + return + if self._timeout_value <= 0: + if self._abort_timer is not None: + self._abort_timer.cancel() + self._abort_timer = None + self._shutdown_printer() + + def _shutdown_printer(self): + if self._mode_shutdown_gcode == True: + self._shutdown_printer_by_gcode() + elif self._mode_shutdown_api == True: + self._shutdown_printer_by_API() + else: + self._shutdown_printer_by_API_custom() + + def _shutdown_printer_API_CMD(self, mode): + if mode == 1: + self._shutdown_printer_by_gcode() + elif mode == 2: + self._shutdown_printer_by_API() + elif mode == 3: + self._shutdown_printer_by_API_custom() + + def _extraCommand(self): + if self.extraCommand != "": + process = subprocess.Popen(mCmdFound, shell=True, stdin=None, stdout=subprocess.PIPE) + self.extraCommand = process.communicate() + self._logger.info("response extraCommand: %s" % mCmdFound.rstrip().strip()) + + def _shutdown_printer_by_API(self): + url = "http://127.0.0.1:" + str(self.api_plugin_port) + "/api/plugin/" + self.api_plugin_name + headers = {'Content-Type': 'application/json', 'X-Api-Key': self.api_key_plugin} + data = self.api_json_command + self._logger.info("Shutting down printer with API") + try: + request = urllib2.Request(url, data=data, headers=headers) + request.get_method = lambda: "POST" + contents = urllib2.urlopen(request, timeout=30, context=self.ctx).read() + self._logger.debug("call response (POST API octoprint): %s" % contents) + self._extraCommand() + except Exception as e: + self._logger.error("Failed to connect to call api: %s" % e.message) + return + + def _shutdown_printer_by_API_custom(self): + headers = {} + if self.api_custom_json_header != "": + headers = eval(self.api_custom_json_header) + if self.api_custom_PUT == True: + data = self.api_custom_body + self._logger.info("Shutting down printer with API custom (PUT)") + try: + request = urllib2.Request(self.api_custom_url, data=data, headers=headers) + request.get_method = lambda: "PUT" + contents = urllib2.urlopen(request, timeout=30, context=self.ctx).read() + self._logger.debug("call response (PUT): %s" % contents) + self._extraCommand() + except Exception as e: + self._logger.error("Failed to connect to call api: %s" % e.message) + return + if self.api_custom_POST == True: + data = self.api_custom_body + self._logger.info("Shutting down printer with API custom (POST)") + try: + request = urllib2.Request(self.api_custom_url, data=data, headers=headers) + request.get_method = lambda: "POST" + contents = urllib2.urlopen(request, timeout=30, context=self.ctx).read() + self._logger.debug("call response (POST): %s" % contents) + self._extraCommand() + except Exception as e: + self._logger.error("Failed to connect to call api: %s" % e.message) + return + elif self.api_custom_GET == True: + self._logger.info("Shutting down printer with API custom (GET)") + try: + request = urllib2.Request(self.api_custom_url, headers=headers) + contents = urllib2.urlopen(request, timeout=30, context=self.ctx).read() + self._logger.debug("call response (GET): %s" % contents) + self._extraCommand() + except Exception as e: + self._logger.error("Failed to connect to call api: %s" % e.message) + return + + def _shutdown_printer_by_gcode(self): + self._printer.commands(self.gcode + " " + self.url) + self._logger.info("Shutting down printer with command: " + self.gcode + " " + self.url) + self._extraCommand() + + def on_after_startup(self): + self._logger.info("Hello World!") + + def get_settings_defaults(self): + return dict( + gcode="M81", + url="", + api_key_plugin="", + abortTimeout=30, + extraCommand="", + _mode_shutdown_gcode=True, + _mode_shutdown_api=False, + _mode_shutdown_api_custom=False, + api_custom_POST=False, + api_custom_GET=False, + api_custom_PUT=False, + api_custom_url="", + api_custom_json_header="", + api_custom_body="", + api_plugin_port=5000, + temperatureValue=110, + _shutdown_printer_enabled=True, + printFailed=False, + printCancelled=False, + rememberCheckBox=False, + lastCheckBoxValue=False + ) + + def on_settings_save(self, data): + octoprint.plugin.SettingsPlugin.on_settings_save(self, data) + + self.gcode = self._settings.get(["gcode"]) + self.url = self._settings.get(["url"]) + self.api_key_plugin = self._settings.get(["api_key_plugin"]) + self._mode_shutdown_gcode = self._settings.get_boolean(["_mode_shutdown_gcode"]) + self._mode_shutdown_api = self._settings.get_boolean(["_mode_shutdown_api"]) + self._mode_shutdown_api_custom = self._settings.get_boolean(["_mode_shutdown_api_custom"]) + self.api_custom_POST = self._settings.get_boolean(["api_custom_POST"]) + self.api_custom_GET = self._settings.get_boolean(["api_custom_GET"]) + self.api_custom_PUT = self._settings.get_boolean(["api_custom_PUT"]) + self.api_custom_url = self._settings.get(["api_custom_url"]) + self.api_custom_json_header = self._settings.get(["api_custom_json_header"]) + self.api_custom_body = self._settings.get(["api_custom_body"]) + self.api_json_command = self._settings.get(["api_json_command"]) + self.api_plugin_name = self._settings.get(["api_plugin_name"]) + self.api_plugin_port = self._settings.get_int(["api_plugin_port"]) + self.temperatureValue = self._settings.get_int(["temperatureValue"]) + self.temperatureTarget = self._settings.get_int(["temperatureTarget"]) + self.extraCommand = self._settings.get(["extraCommand"]) + self.printFailed = self._settings.get_boolean(["printFailed"]) + self.printCancelled = self._settings.get_boolean(["printCancelled"]) + self.abortTimeout = self._settings.get_int(["abortTimeout"]) + self.rememberCheckBox = self._settings.get_boolean(["rememberCheckBox"]) + self.lastCheckBoxValue = self._settings.get_boolean(["lastCheckBoxValue"]) + + def get_update_information(self): + return dict( + shutdownprinter=dict( + displayName="Shutdown Printer", + displayVersion=self._plugin_version, + + # version check: github repository + type="github_release", + user="devildant", + repo="OctoPrint-ShutdownPrinter", + current=self._plugin_version, + + # update method: pip w/ dependency links + pip="https://github.com/devildant/OctoPrint-ShutdownPrinter/archive/{target_version}.zip" + ) + ) + + +__plugin_name__ = "Shutdown Printer" + + +def __plugin_load__(): + global __plugin_implementation__ + __plugin_implementation__ = shutdownprinterPlugin() + + global __plugin_hooks__ + __plugin_hooks__ = { + "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information + } diff --git a/octoprint_mystromswitch/static/css/shutdownprinter.css b/octoprint_mystromswitch/static/css/shutdownprinter.css new file mode 100644 index 0000000..464f526 --- /dev/null +++ b/octoprint_mystromswitch/static/css/shutdownprinter.css @@ -0,0 +1,38 @@ +/* #touch body #sidebar_plugin_shutdownprinter_wrapper .accordion-heading { */ + /* display: block !important; */ + /* pointer-events: none; */ + /* margin: 40px -30px 0; */ + /* padding: .5rem 30px; */ + /* background-color: #00B0FF; */ + /* color: black; */ +/* } */ +/* #touch body #sidebar_plugin_shutdownprinter_wrapper .accordion-heading>a, #touch body #sidebar_plugin_shutdownprinter_wrapper .accordion-heading>a i { */ + /* color: black; */ + /* font-size: 1.4375rem; */ + /* padding-right: 0; */ + /* padding-left: 0; */ +/* } */ + +/* #touch body #sidebar_plugin_shutdownprinter > label { */ + /* display: block; */ + /* background:#333; */ + /* padding-left: 50px; */ + /* padding-top: 15px; */ + /* padding-bottom: 15px; */ +/* } */ + +/* #touch body #sidebar_plugin_shutdownprinter { */ + /* pointer-events: auto; */ + /* margin: 0px -30px 0; */ + /* padding-right: 15px; */ + /* padding-left: 15px; */ +/* } */ + +.shutdownPrinterHideCancelBtnConfirm { + display:none; +} + +#touch body #tabs #sidebar_plugin_shutdownprinter_wrapper_link a:before, #touch body #navbar #all_touchui_settings #sidebar_plugin_shutdownprinter_wrapper_link a:before,#touch body #tabs #sidebar_plugin_shutdownprinter_wrapper_link2 a:before, #touch body #navbar #all_touchui_settings #sidebar_plugin_shutdownprinter_wrapper_link2 a:before { + content: "\f011"; +} + diff --git a/octoprint_mystromswitch/static/js/shutdownprinter.js b/octoprint_mystromswitch/static/js/shutdownprinter.js new file mode 100644 index 0000000..88e032e --- /dev/null +++ b/octoprint_mystromswitch/static/js/shutdownprinter.js @@ -0,0 +1,292 @@ +$(function() { + function ShutdownPrinterViewModel(parameters) { + var self = this; + + self.loginState = parameters[0]; + self.settings = parameters[1]; + self.printer = parameters[2]; + + + self.shutdownprinterEnabled = ko.observable(); + + self.testButtonChangeStatus = function (stat) { + $("#tester_shutdownprinter_gcode").prop("disabled", stat); + $("#tester_shutdownprinter_api").prop("disabled", stat); + $("#tester_shutdownprinter_api_custom").prop("disabled", stat); + } + + self.eventChangeCheckToRadio = function (id, listOff) { + $(id).on("change", function () { + if ($(this).prop("checked") == true) + { + listOff.forEach(function(element) { + if (id != element.id) + { + if ($(element.id).prop("checked") == true) + { + $(element.id).unbind("change"); + $(element.id).trigger("click"); + self.eventChangeCheckToRadio(element.id, listOff); + } + } + }); + } + }) + } + + $("#tester_shutdownprinter_gcode").on("click", function () { + self.settings.saveData(); + $(this).children("i").show(); + setTimeout(function (current) { + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "shutdown", + mode: 1, + eventView : true + }), + contentType: "application/json; charset=UTF-8" + }).done(function() { + current.children("i").hide(); + }); + + }, 1000, $(this)); + + }); + $("#tester_shutdownprinter_api").on("click", function () { + self.settings.saveData(); + $(this).children("i").show(); + setTimeout(function (current) { + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "shutdown", + mode: 2, + eventView : true + }), + contentType: "application/json; charset=UTF-8" + }).done(function() { + current.children("i").hide(); + }); + }, 1000, $(this)); + + }); + + $("#tester_shutdownprinter_api_custom").on("click", function () { + self.settings.saveData(); + $(this).children("i").show(); + setTimeout(function (current) { + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "shutdown", + mode: 3, + eventView : true + }), + contentType: "application/json; charset=UTF-8" + }).done(function() { + current.children("i").hide(); + }); + }, 1000, $(this)); + + }); + self.listOffMode = [ + {"id" : "#shutdownprinter_mode_shutdown_gcode"}, + {"id" : "#shutdownprinter_mode_shutdown_api"}, + {"id" : "#shutdownprinter_mode_shutdown_api_custom"}, + ] + self.listOffHTTPMethode = [ + {"id" : "#shutdownprinter_api_custom_GET"}, + {"id" : "#shutdownprinter_api_custom_POST"}, + {"id" : "#shutdownprinter_api_custom_PUT"} + ] + self.eventChangeCheckToRadio("#shutdownprinter_mode_shutdown_gcode", self.listOffMode); + self.eventChangeCheckToRadio("#shutdownprinter_mode_shutdown_api", self.listOffMode); + self.eventChangeCheckToRadio("#shutdownprinter_mode_shutdown_api_custom", self.listOffMode); + + self.eventChangeCheckToRadio("#shutdownprinter_api_custom_GET", self.listOffHTTPMethode); + self.eventChangeCheckToRadio("#shutdownprinter_api_custom_POST", self.listOffHTTPMethode); + self.eventChangeCheckToRadio("#shutdownprinter_api_custom_PUT", self.listOffHTTPMethode); + + // Hack to remove automatically added Cancel button + // See https://github.com/sciactive/pnotify/issues/141 + //PNotify.prototype.options.confirm.buttons = []; + //another way use, add custom style class for hide cancel button + self.timeoutPopupText = gettext('Shutting down printer in '); + self.timeoutPopupOptions = { + title: gettext('Shutdown Printer'), + type: 'notice', + icon: true, + hide: false, + confirm: { + confirm: true, + buttons: [{ + text: 'Abort Shutdown Printer', + addClass: 'btn-block btn-danger', + promptTrigger: true, + click: function(notice, value){ + notice.remove(); + notice.get().trigger("pnotify.cancel", [notice, value]); + } + }, { + addClass: 'shutdownPrinterHideCancelBtnConfirm', + promptTrigger: true, + click: function(notice, value){ + notice.remove(); + + } + }] + }, + buttons: { + closer: false, + sticker: false, + }, + history: { + history: false + } + }; + + //for touch ui + self.touchUIMoveElement = function (self, counter) { + var hash = window.location.hash; + if (hash != "" && hash != "#printer" && hash != "#touch") + { + return; + } + if (counter < 10) { + if (document.getElementById("touch") != null && document.getElementById("printer") != null && document.getElementById("printer") != null && document.getElementById("touch").querySelector("#printer").querySelector("#files_wrapper")) { + var newParent = document.getElementById("files_wrapper").parentNode; + newParent.insertBefore(document.getElementById('sidebar_plugin_shutdownprinter_wrapper'), document.getElementById("files_wrapper")); + } else { + setTimeout(self.touchUIMoveElement, 1000, self, ++counter); + } + } + } + //add octoprint event for check finish + self.onStartupComplete = function () { + //self.touchUIMoveElement(self, 0); + if (self.printer.isPrinting()) + { + self.testButtonChangeStatus(true); + } else { + self.testButtonChangeStatus(false); + } + + + }; + + self.onUserLoggedIn = function() { + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "update", + eventView : false + }), + contentType: "application/json; charset=UTF-8" + }) + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + data: JSON.stringify({ + command: "status" + }), + context:self, + contentType: "application/json; charset=UTF-8" + }).done(function(data, textStatus, jqXHR ){ + this.shutdownprinterEnabled(data == "True" ? true : false); + }) + } + + self.onUserLoggedOut = function() { + } + + self.onEventPrinterStateChanged = function(payload) { + if (payload.state_id == "PRINTING" || payload.state_id == "PAUSED"){ + self.testButtonChangeStatus(true); + } else { + self.testButtonChangeStatus(false); + } + } + + self.onShutdownPrinterEvent = function() { + if (self.shutdownprinterEnabled()) { + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "enable", + eventView : false + }), + contentType: "application/json; charset=UTF-8" + }) + } else { + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "disable", + eventView : false + }), + contentType: "application/json; charset=UTF-8" + }) + } + } + + self.shutdownprinterEnabled.subscribe(self.onShutdownPrinterEvent, self); + + self.onDataUpdaterPluginMessage = function(plugin, data) { + if (plugin != "shutdownprinter" && plugin != "octoprint_shutdownprinter") { + return; + } + + self.shutdownprinterEnabled(data.shutdownprinterEnabled); + if (data.type == "timeout") { + if ((data.timeout_value != null) && (data.timeout_value > 0)) { + self.timeoutPopupOptions.text = self.timeoutPopupText + data.timeout_value; + if (typeof self.timeoutPopup != "undefined") { + self.timeoutPopup.update(self.timeoutPopupOptions); + } else { + self.timeoutPopup = new PNotify(self.timeoutPopupOptions); + self.timeoutPopup.get().on('pnotify.cancel', function() {self.abortShutdown(true);}); + } + } else { + if (typeof self.timeoutPopup != "undefined") { + self.timeoutPopup.remove(); + self.timeoutPopup = undefined; + } + } + } + } + + self.abortShutdown = function(abortShutdownValue) { + self.timeoutPopup.remove(); + self.timeoutPopup = undefined; + $.ajax({ + url: API_BASEURL + "plugin/shutdownprinter", + type: "POST", + dataType: "json", + data: JSON.stringify({ + command: "abort", + eventView : true + }), + contentType: "application/json; charset=UTF-8" + }) + } + } + + OCTOPRINT_VIEWMODELS.push([ + ShutdownPrinterViewModel, + ["loginStateViewModel", "settingsViewModel", "printerStateViewModel"], + $(".sidebar_plugin_shutdownprinter").get(0) + ]); +}); diff --git a/octoprint_mystromswitch/templates/shutdownprinter_settings.jinja2 b/octoprint_mystromswitch/templates/shutdownprinter_settings.jinja2 new file mode 100644 index 0000000..cdc092c --- /dev/null +++ b/octoprint_mystromswitch/templates/shutdownprinter_settings.jinja2 @@ -0,0 +1,181 @@ +
+

General

+
+
Mode GCODE
+
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+ +
+
Mode API
+
+
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+
+ + +
+
+
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+
+
+
Mode API Custom
+
+
+ +
+
+
+
+ + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
Common options
+
+ +
+
+ + sec +
+
+
+
+
+ +
+
+
+

Events catch

+
+
+ +
+
+
+
+ +
+
+
+

Nozzle temperature target

+
+
+ +
+
+

Extra command/script

+
+
+ +
+
+
+ +
+
+ + °C +
+
+
+
diff --git a/octoprint_mystromswitch/templates/shutdownprinter_sidebar.jinja2 b/octoprint_mystromswitch/templates/shutdownprinter_sidebar.jinja2 new file mode 100644 index 0000000..85720ae --- /dev/null +++ b/octoprint_mystromswitch/templates/shutdownprinter_sidebar.jinja2 @@ -0,0 +1,6 @@ + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a1dc463 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +### +# This file is only here to make sure that something like +# +# pip install -e . +# +# works as expected. Requirements can be found in setup.py. +### + +. diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..307caa7 --- /dev/null +++ b/setup.py @@ -0,0 +1,94 @@ +# coding=utf-8 + +######################################################################################################################## +### Do not forget to adjust the following variables to your own plugin. + +# The plugin's identifier, has to be unique +plugin_identifier = "mystromswitch" + +# The plugin's python package, should be "octoprint_", has to be unique +plugin_package = "octoprint_mystromswitch" + +# The plugin's human readable name. Can be overwritten within OctoPrint's internal data via __plugin_name__ in the +# plugin module +plugin_name = "OctoPrint-MyStromSwitch" + +# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module +plugin_version = "1.0.7" + +# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin +# module +plugin_description = "Plugin to Control myStrom Switch" + +# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module +plugin_author = "David Zingg" + +# The plugin's author's mail address. +plugin_author_email = "" + +# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module +plugin_url = "https://github.com/devildant/OctoPrint-ShutdownPrinter" + +# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module +plugin_license = "AGPLv3" + +# Any additional requirements besides OctoPrint should be listed here +plugin_requires = [] + +### -------------------------------------------------------------------------------------------------------------------- +### More advanced options that you usually shouldn't have to touch follow after this point +### -------------------------------------------------------------------------------------------------------------------- + +# Additional package data to install for this plugin. The subfolders "templates", "static" and "translations" will +# already be installed automatically if they exist. +plugin_additional_data = [] + +# Any additional python packages you need to install with your plugin that are not contains in .* +plugin_addtional_packages = [] + +# Any python packages within .* you do NOT want to install with your plugin +plugin_ignored_packages = [] + +# Additional parameters for the call to setuptools.setup. If your plugin wants to register additional entry points, +# define dependency links or other things like that, this is the place to go. Will be merged recursively with the +# default setup parameters as provided by octoprint_setuptools.create_plugin_setup_parameters using +# octoprint.util.dict_merge. +# +# Example: +# plugin_requires = ["someDependency==dev"] +# additional_setup_parameters = {"dependency_links": ["https://github.com/someUser/someRepo/archive/master.zip#egg=someDependency-dev"]} +additional_setup_parameters = {} + +######################################################################################################################## + +from setuptools import setup + +try: + import octoprint_setuptools +except: + print("Could not import OctoPrint's setuptools, are you sure you are running that under " + "the same python installation that OctoPrint is installed under?") + import sys + sys.exit(-1) + +setup_parameters = octoprint_setuptools.create_plugin_setup_parameters( + identifier=plugin_identifier, + package=plugin_package, + name=plugin_name, + version=plugin_version, + description=plugin_description, + author=plugin_author, + mail=plugin_author_email, + url=plugin_url, + license=plugin_license, + requires=plugin_requires, + additional_packages=plugin_addtional_packages, + ignored_packages=plugin_ignored_packages, + additional_data=plugin_additional_data +) + +if len(additional_setup_parameters): + from octoprint.util import dict_merge + setup_parameters = dict_merge(setup_parameters, additional_setup_parameters) + +setup(**setup_parameters)