Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It's a start.
- Loading branch information
Showing
5 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# coding=utf-8 | ||
from __future__ import absolute_import | ||
|
||
import octoprint.plugin | ||
|
||
class GPXPlugin(octoprint.plugin.TemplatePlugin, octoprint.plugin.SettingsPlugin): | ||
def serial_handler(self, comm, port, baudrate, timeout): | ||
if self._settings.get(["protocol"]) != "GPX": | ||
return None | ||
|
||
self._logger.info("Connecting through x3g.") | ||
try: | ||
if port is None or port == 'AUTO': | ||
port = comm.detectPort(True) | ||
if port is None: | ||
return None | ||
self._logger.info("calling constructor %s %ld" % (port, baudrate)) | ||
from .gpxprinter import GpxPrinter | ||
return GpxPrinter(port, baudrate, timeout) | ||
except Exception as e: | ||
self._logger.info("Failed to connect to x3g e = %s." % e); | ||
raise | ||
|
||
def on_after_startup(self): | ||
self._logger.info("GPXPlugin startup!") | ||
|
||
def get_settings_defaults(self): | ||
return dict(protocol="gcode") | ||
|
||
def get_template_configs(self): | ||
return [ | ||
dict(type="settings", custom_bindings=False) | ||
] | ||
|
||
|
||
__plugin_implementation__ = GPXPlugin() | ||
|
||
|
||
def __plugin_init__(): | ||
plugin = GPXPlugin() | ||
|
||
global __plugin_implementation__ | ||
__plugin_implementation__ = plugin | ||
|
||
global __plugin_hooks__ | ||
__plugin_hooks__ = {"octoprint.comm.protocol.serial": plugin.serial_handler} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# coding=utf-8 | ||
from __future__ import absolute_import | ||
__author__ = "Mark Walker <markwal@hotmail.com> based on work by Gina Häußge" | ||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' | ||
|
||
import logging | ||
import time | ||
import Queue | ||
|
||
from octoprint.settings import settings | ||
|
||
gpxAvailable = False | ||
try: | ||
import gpx | ||
gpxAvailable = True | ||
except: | ||
pass | ||
|
||
class GpxPrinter(): | ||
def __init__(self, port = None, baudrate = None, timeout = 0): | ||
self._logger = logging.getLogger(__name__) | ||
if not gpxAvailable: | ||
self._logger.info("Unable to import gpx module") | ||
raise ValueError("Unable to import gpx module") | ||
if baudrate == 0: | ||
raise IOError("AUTO baudrate not currently supported by GPX") | ||
self.port = port | ||
self.baudrate = self._baudrate = baudrate | ||
self.timeout = timeout | ||
self._logger.info("GPXPrinter created, port: %s, baudrate: %s" % (self.port, self.baudrate)) | ||
self.outgoing = Queue.Queue() | ||
self.baudrateError = False; | ||
try: | ||
self._append(gpx.connect(port, baudrate, settings().getBaseFolder("plugins") + "/gpx.ini")) #, settings().getBaseFolder("logs") + "/gpx.log") | ||
except Exception as e: | ||
self._logger.info("gpx.connect raised exception = %s" % e) | ||
raise | ||
|
||
def _append(self, s): | ||
if (s != ''): | ||
for item in s.split('\n'): | ||
self.outgoing.put(item) | ||
|
||
def write(self, data): | ||
data = data.strip() | ||
self._logger.info("%s" % data) | ||
# strip checksum | ||
if "*" in data: | ||
data = data[:data.rfind("*")] | ||
if (self.baudrate != self._baudrate): | ||
try: | ||
self._baudrate = self.baudrate | ||
self._logger.info("new baudrate = %d" % self.baudrate) | ||
gpx.set_baudrate(self.baudrate) | ||
self.baudrateError = False | ||
except ValueError: | ||
self.baudrateError = True | ||
self.outgoing.put('') | ||
pass | ||
return | ||
self._append(gpx.write("%s" % data)) | ||
|
||
def readline(self): | ||
while (self.baudrateError): | ||
if (self._baudrate != self.baudrate): | ||
self.write("M105"); | ||
return '' | ||
try: | ||
s = self.outgoing.get_nowait() | ||
self._logger.info("readline: %s" % s) | ||
return s | ||
except Queue.Empty: | ||
pass | ||
self._append(gpx.readnext()) | ||
try: | ||
s = self.outgoing.get(timeout=self.timeout) | ||
self._logger.info("readline: %s" % s) | ||
return s | ||
except Queue.Empty: | ||
self._logger.info("timeout") | ||
pass | ||
return '' | ||
|
||
def close(self): | ||
gpx.disconnect() | ||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<div class="control-group"> | ||
<label class="control-label">{{ _('Protocol') }}</label> | ||
<select data-bind="uniqueName: console.log($data), value: settings.plugins.GPX.protocol"> | ||
<option value="gcode">{{ _('G-Code') }}</option> | ||
<option value="GPX">{{ _('x3g (via GPX)') }}</option> | ||
</select> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
OctoPrint | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# coding=utf-8 | ||
import setuptools | ||
|
||
######################################################################################################################## | ||
|
||
plugin_identifier = "GPX" | ||
plugin_package = "octoprint_%s" % plugin_identifier | ||
plugin_name = "OctoPrint GPX" | ||
plugin_version = "0.1" | ||
plugin_description = "Emulates the gcode printer protocol by translating to/from x3g." | ||
plugin_author = "Mark Walker" | ||
plugin_author_email = "markwal@hotmail.com" | ||
plugin_url = "http://github.com/markwal/OctoPrint-GPX" | ||
plugin_license = "MIT" | ||
|
||
# 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 = [] | ||
|
||
######################################################################################################################## | ||
|
||
def package_data_dirs(source, sub_folders): | ||
import os | ||
dirs = [] | ||
|
||
for d in sub_folders: | ||
folder = os.path.join(source, d) | ||
if not os.path.exists(folder): | ||
continue | ||
|
||
for dirname, _, files in os.walk(folder): | ||
dirname = os.path.relpath(dirname, source) | ||
for f in files: | ||
dirs.append(os.path.join(dirname, f)) | ||
|
||
return dirs | ||
|
||
def requirements(filename): | ||
return filter(lambda line: line and not line.startswith("#"), map(lambda line: line.strip(), open(filename).read().split("\n"))) | ||
|
||
def params(): | ||
# Our metadata, as defined above | ||
name = plugin_name | ||
version = plugin_version | ||
description = plugin_description | ||
author = plugin_author | ||
author_email = plugin_author_email | ||
url = plugin_url | ||
license = plugin_license | ||
|
||
# we only have our plugin package to install | ||
packages = [plugin_package] | ||
|
||
# we might have additional data files in sub folders that need to be installed too | ||
package_data = {plugin_package: package_data_dirs(plugin_package, ['static', 'templates', 'translations'] + plugin_additional_data)} | ||
include_package_data = True | ||
|
||
# If you have any package data that needs to be accessible on the file system, such as templates or static assets | ||
# this plugin is not zip_safe. | ||
zip_safe = False | ||
|
||
# Read the requirements from our requirements.txt file | ||
install_requires = requirements("requirements.txt") | ||
|
||
# Hook the plugin into the "octoprint.plugin" entry point, mapping the plugin_identifier to the plugin_package. | ||
# That way OctoPrint will be able to find the plugin and load it. | ||
entry_points = { | ||
"octoprint.plugin": ["%s = %s" % (plugin_identifier, plugin_package)] | ||
} | ||
|
||
return locals() | ||
|
||
setuptools.setup(**params()) |