diff --git a/README.md b/README.md new file mode 100644 index 0000000..3425719 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Emergency Stop + +Add a big ugly emergency stop to your sidebar. It's big, it's yellow, it's red, it's impossible to miss. That's the point. +![](/extras/assets/img/plugins/estop/enabled.PNG) +## Setup + +Install via the bundled [Plugin Manager](https://github.com/foosel/OctoPrint/wiki/Plugin:-Plugin-Manager) +or manually using this URL: + + https://github.com/ntoff/OctoPrint-Estop/archive/master.zip + +## Position + +Once installed, you may wish to move the button to the top of the sidebar, you can do so by modifying the [config.yaml](http://docs.octoprint.org/en/master/configuration/config_yaml.html) file as follows: + +Find the "appearance" section, and add the plugin to the top of the sidebar order. If no other components have been previously rearranged, you may end up with only the plugin in the order list, this is fine, you don't need to add every item to the list (not adding them won't stop them from showing up). + + appearance: + color: violet + components: + order: + sidebar: + - plugin_estop + +Please note: White spaces are critical inside the config.yaml file, special care must be taken when adding or removing entries that the correct layout is maintained. For more information on config.yaml and its appearance section, see here: http://docs.octoprint.org/en/master/configuration/config_yaml.html#appearance diff --git a/extras/assets/img/plugins/estop/disabled.PNG b/extras/assets/img/plugins/estop/disabled.PNG new file mode 100644 index 0000000..b168ffa Binary files /dev/null and b/extras/assets/img/plugins/estop/disabled.PNG differ diff --git a/extras/assets/img/plugins/estop/enabled.PNG b/extras/assets/img/plugins/estop/enabled.PNG new file mode 100644 index 0000000..86017a4 Binary files /dev/null and b/extras/assets/img/plugins/estop/enabled.PNG differ diff --git a/extras/estop.md b/extras/estop.md new file mode 100644 index 0000000..c4e71d5 --- /dev/null +++ b/extras/estop.md @@ -0,0 +1,45 @@ +--- +layout: plugin + +id: estop +title: Emergency STOP! button +description: Adds an emergency stop (gcode M112) button to the sidebar. +author: ntoff +license: AGPLv3 + +date: 2017-03-23 + +homepage: https://github.com/ntoff/OctoPrint-Estop +source: https://github.com/ntoff/OctoPrint-Estop +archive: https://github.com/ntoff/OctoPrint-Estop/archive/master.zip + +follow_dependency_links: false + +tags: +- emergency stop +- M112 + + +screenshots: +- /assets/img/plugins/estop/enabled.PNG + alt: enabled + caption: Enabled (logged in and operational) +- /assets/img/plugins/estop/disabled.PNG + alt: disabled + caption: Disabled (logged out or non operational) + + +featuredimage: /assets/img/plugins/estop/enabled.PNG + +compatibility: + octoprint: + - 1.2.0 + + + os: + - linux + - windows + - macos +--- + +Adds a nice big emergency stop button that sends M112 to the printer in the case of an emergency. \ No newline at end of file diff --git a/octoprint_estop/__init__.py b/octoprint_estop/__init__.py new file mode 100644 index 0000000..38c24d2 --- /dev/null +++ b/octoprint_estop/__init__.py @@ -0,0 +1,23 @@ +# coding=utf-8 +from __future__ import absolute_import + +import octoprint.plugin + +class EstopPlugin(octoprint.plugin.AssetPlugin, + octoprint.plugin.TemplatePlugin): + + def get_assets(self): + return dict( + js=["js/estop.js"], + css=["css/estop.css"] + ) + def get_template_configs(self): + return [dict(type="sidebar", name="Emergency STOP!", icon="fa fa-times")] + +__plugin_name__ = "Emergency Stop Button" + +def __plugin_load__(): + global __plugin_implementation__ + __plugin_implementation__ = EstopPlugin() + + \ No newline at end of file diff --git a/octoprint_estop/static/css/estop.css b/octoprint_estop/static/css/estop.css new file mode 100644 index 0000000..ed5a20f --- /dev/null +++ b/octoprint_estop/static/css/estop.css @@ -0,0 +1,63 @@ +.estop_sidebar { + width:100%; + height:28px; + background-image: repeating-linear-gradient( + -45deg, + #000, + #000 4px, + #ff0 4px, + #ff0 8px + ); + text-align: center; + vertical-align: middle; +} +.btn-estop { + width: 80%; + height: 28px; + color: #ffffff; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25); + background-color: #eb0000; + background-image: -moz-linear-gradient(top, #ff0000, #cc0000); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0000), to(#cc0000)); + background-image: -webkit-linear-gradient(top, #ff0000, #cc0000); + background-image: -o-linear-gradient(top, #ff0000, #cc0000); + background-image: linear-gradient(to bottom, #ff0000, #cc0000); + background-repeat: repeat-x; + border-color: #cc0000 #cc0000 #800000; + border-width: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0000', endColorstr='#ffcc0000', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + display: inline-block; + padding: 0px; + margin-bottom: 0; + font-size: 14px; + font-weight: bold; + line-height: 20px; + color: #fff; + text-align: center; + vertical-align: middle; +} +.btn-estop:hover { + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.8); + background-color: #eb0000; + background-image: -moz-linear-gradient(top, #dd0000, #cc0000); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd0000), to(#cc0000)); + background-image: -webkit-linear-gradient(top, #dd0000, #cc0000); + background-image: -o-linear-gradient(top, #dd0000, #cc0000); + background-image: linear-gradient(to bottom, #dd0000, #cc0000); + background-repeat: repeat-x; + border-color: #cc0000 #cc0000 #800000; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0000', endColorstr='#ffcc0000', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + text-decoration: none; + +} +.btn-estop:active { + text-decoration: overline underline; +} +.btn-estop:disabled { + text-shadow: 0px 0px 0 rgba(0, 0, 0, 0.0); + color: #555; + opacity: 0.8; + cursor: not-allowed; +} \ No newline at end of file diff --git a/octoprint_estop/static/js/estop.js b/octoprint_estop/static/js/estop.js new file mode 100644 index 0000000..8ee5edb --- /dev/null +++ b/octoprint_estop/static/js/estop.js @@ -0,0 +1,25 @@ +/* + * Author: ntoff + * License: AGPLv3 + */ +$(function() { + function EstopViewModel(parameters) { + var self = this; + //see if we're logged in and the printer is operational (for en/disable of button) + self.loginState = parameters[0]; + self.terminal = parameters[1]; + + self.sendEstopCommand = function () { + OctoPrint.control.sendGcode("M112"); //should this ever be a variable? M112 universal? + }; + } + + OCTOPRINT_VIEWMODELS.push({ + construct: EstopViewModel, + dependencies: [ + "loginStateViewModel", + "terminalViewModel", + ], + elements: ["#sidebar_plugin_estop"] + }); +}); diff --git a/octoprint_estop/templates/estop_sidebar.jinja2 b/octoprint_estop/templates/estop_sidebar.jinja2 new file mode 100644 index 0000000..cc384c9 --- /dev/null +++ b/octoprint_estop/templates/estop_sidebar.jinja2 @@ -0,0 +1,4 @@ +
+ +
+ diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..5a6a482 --- /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 = "estop" + +# The plugin's python package, should be "octoprint_", has to be unique +plugin_package = "octoprint_estop" + +# The plugin's human readable name. Can be overwritten within OctoPrint's internal data via __plugin_name__ in the +# plugin module +plugin_name = "OctoPrint-Estop" + +# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module +plugin_version = "0.1.0" + +# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin +# module +plugin_description = """Emergency Stop button""" + +# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module +plugin_author = "ntoff" + +# 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/ntoff/OctoPrint-Estop" + +# 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 contained in .* +plugin_additional_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_additional_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) diff --git a/translations/README.txt b/translations/README.txt new file mode 100644 index 0000000..74fd329 --- /dev/null +++ b/translations/README.txt @@ -0,0 +1,28 @@ +Your plugin's translations will reside here. The provided setup.py supports a +couple of additional commands to make managing your translations easier: + +babel_extract + Extracts any translateable messages (marked with Jinja's `_("...")` or + JavaScript's `gettext("...")`) and creates the initial `messages.pot` file. +babel_refresh + Reruns extraction and updates the `messages.pot` file. +babel_new --locale= + Creates a new translation folder for locale ``. +babel_compile + Compiles the translations into `mo` files, ready to be used within + OctoPrint. +babel_pack --locale= [ --author= ] + Packs the translation for locale `` up as an installable + language pack that can be manually installed by your plugin's users. This is + interesting for languages you can not guarantee to keep up to date yourself + with each new release of your plugin and have to depend on contributors for. + +If you want to bundle translations with your plugin, create a new folder +`octoprint_skeleton/translations`. When that folder exists, +an additional command becomes available: + +babel_bundle --locale= + Moves the translation for locale `` to octoprint_skeleton/translations, + effectively bundling it with your plugin. This is interesting for languages + you can guarantee to keep up to date yourself with each new release of your + plugin.