Renamed from Printer WebUI to OctoPrint
The location of the config folder has changed. OctoPrint will try to migrate the configuration from its old location (~/.printerwebui, ...) to its new one (~/.octoprint, ...). For this to work the following conditions must be met: 1) the old config folder exists and is a directory 2) the new config folder does not exist at all. The migration functionality will be in the future.master
50
README.md
|
@ -1,7 +1,13 @@
|
||||||
Printer WebUI
|
Attention
|
||||||
=============
|
=========
|
||||||
|
|
||||||
The Printer WebUI provides a responsive web interface for controlling a 3D printer (RepRap, Ultimaker, ...). It currently
|
OctoPrint -- formerly known as Printer WebUI -- will be migrated to a new repository location reflecting its new name on Saturday 26th 2013. It will then
|
||||||
|
be located at http://github.com/foosel/OctoPrint. Please be prepared to upgrade your links and remote refs. Sorry for the inconvenience.
|
||||||
|
|
||||||
|
OctoPrint
|
||||||
|
=========
|
||||||
|
|
||||||
|
OctoPrint provides a responsive web interface for controlling a 3D printer (RepRap, Ultimaker, ...). It currently
|
||||||
allows
|
allows
|
||||||
|
|
||||||
* uploading .gcode files to the server and managing them via the UI
|
* uploading .gcode files to the server and managing them via the UI
|
||||||
|
@ -16,7 +22,7 @@ allows
|
||||||
* optional: visual monitoring of the printer via webcam stream integrated into the UI (using e.g. MJPG-Streamer)
|
* optional: visual monitoring of the printer via webcam stream integrated into the UI (using e.g. MJPG-Streamer)
|
||||||
* optional: creation of timelapse recordings of the printjob via webcam stream (using e.g. MJPG-Streamer) -- currently two timelaspe methods are implemented, triggering a shot on z-layer change or every "n" seconds
|
* optional: creation of timelapse recordings of the printjob via webcam stream (using e.g. MJPG-Streamer) -- currently two timelaspe methods are implemented, triggering a shot on z-layer change or every "n" seconds
|
||||||
|
|
||||||
The intended usecase is to run the Printer WebUI on a single-board computer like the Raspberry Pi and a WiFi module,
|
The intended usecase is to run OctoPrint on a single-board computer like the Raspberry Pi and a WiFi module,
|
||||||
connect the printer to the server and therefore create a WiFi-enabled 3D printer.
|
connect the printer to the server and therefore create a WiFi-enabled 3D printer.
|
||||||
|
|
||||||
If you want to add a webcam for visual monitoring and timelapse support, you'll need a **powered** USB hub.
|
If you want to add a webcam for visual monitoring and timelapse support, you'll need a **powered** USB hub.
|
||||||
|
@ -24,34 +30,34 @@ If you want to add a webcam for visual monitoring and timelapse support, you'll
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Printer WebUI depends on a couple of python modules to do its job. Those are listed in requirements.txt and can be
|
OctoPrint depends on a couple of python modules to do its job. Those are listed in requirements.txt and can be
|
||||||
installed using `pip`:
|
installed using `pip`:
|
||||||
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
Printer WebUI currently only supports Python 2.7.
|
OctoPrint currently only supports Python 2.7.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Just start the server via
|
Just start the server via
|
||||||
|
|
||||||
python -m printer_webui.server
|
python -m octoprint.server
|
||||||
|
|
||||||
By default it binds to all interfaces on port 5000 (so pointing your browser to `http://127.0.0.1:5000`
|
By default it binds to all interfaces on port 5000 (so pointing your browser to `http://127.0.0.1:5000`
|
||||||
will do the trick). If you want to change that, use the additional command line parameters `host` and `port`,
|
will do the trick). If you want to change that, use the additional command line parameters `host` and `port`,
|
||||||
which accept the host ip to bind to and the numeric port number respectively. If for example you want to the server
|
which accept the host ip to bind to and the numeric port number respectively. If for example you want to the server
|
||||||
to only listen on the local interface on port 8080, the command line would be
|
to only listen on the local interface on port 8080, the command line would be
|
||||||
|
|
||||||
python -m printer_webui.server --host=127.0.0.1 --port=8080
|
python -m octoprint.server --host=127.0.0.1 --port=8080
|
||||||
|
|
||||||
Alternatively, the host and port on which to bind can be defined via the configuration.
|
Alternatively, the host and port on which to bind can be defined via the configuration.
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The config-file `config.ini` for Printer WebUI is expected in its settings folder, which is located at `~/.printerwebui`
|
The config-file `config.ini` for OctoPrint is expected in its settings folder, which is located at `~/.octoprint`
|
||||||
on Linux, at `%APPDATA%/PrinterWebUI` on Windows and at `~/Library/Application Support` on MacOS X.
|
on Linux, at `%APPDATA%/OctoPrint` on Windows and at `~/Library/Application Support/OctoPrint` on MacOS.
|
||||||
|
|
||||||
The following example config should explain the available options:
|
The following example config should explain the available options:
|
||||||
|
|
||||||
|
@ -89,21 +95,21 @@ The following example config should explain the available options:
|
||||||
analyzeGcode = True
|
analyzeGcode = True
|
||||||
|
|
||||||
[folder]
|
[folder]
|
||||||
# Absolute path where to store gcode uploads. Defaults to the uploads folder in the Printer WebUI settings folder
|
# Absolute path where to store gcode uploads. Defaults to the uploads folder in the OctoPrint settings folder
|
||||||
uploads = /path/to/upload/folder
|
uploads = /path/to/upload/folder
|
||||||
|
|
||||||
# Absolute path where to store finished timelapse recordings. Defaults to the timelapse folder in the Printer WebUI
|
# Absolute path where to store finished timelapse recordings. Defaults to the timelapse folder in the OctoPrint
|
||||||
# settings dir
|
# settings dir
|
||||||
timelapse = /path/to/timelapse/folder
|
timelapse = /path/to/timelapse/folder
|
||||||
|
|
||||||
# Absolute path where to store temporary timelapse files. Defaults to the timelapse/tmp folder in the Printer WebUI
|
# Absolute path where to store temporary timelapse files. Defaults to the timelapse/tmp folder in the OctoPrint
|
||||||
# settings dir
|
# settings dir
|
||||||
timelapse_tmp = /path/timelapse/tmp/folder
|
timelapse_tmp = /path/timelapse/tmp/folder
|
||||||
|
|
||||||
Setup on a Raspberry Pi running Raspbian
|
Setup on a Raspberry Pi running Raspbian
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
I currently run the Printer WebUI on a Raspberry Pi running Raspbian (http://www.raspbian.org/). I recommend to use
|
I currently run the OctoPrint on a Raspberry Pi running Raspbian (http://www.raspbian.org/). I recommend to use
|
||||||
a maximum baudrate of 115200 baud in your printer firmware, as the used Python serial module does not support
|
a maximum baudrate of 115200 baud in your printer firmware, as the used Python serial module does not support
|
||||||
250000 baud in all Linux distributions yet (Raspbian being not one of them, at least according to my experience).
|
250000 baud in all Linux distributions yet (Raspbian being not one of them, at least according to my experience).
|
||||||
|
|
||||||
|
@ -116,9 +122,9 @@ listed in requirements.txt:
|
||||||
cd PrinterWebUI
|
cd PrinterWebUI
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
You should then be able to start the WebUI server:
|
You should then be able to start the OctoPrint server:
|
||||||
|
|
||||||
pi@raspberrypi ~/PrinterWebUI $ python -m printer_webui.server
|
pi@raspberrypi ~/PrinterWebUI $ python -m octoprint.server
|
||||||
* Running on http://0.0.0.0:5000/
|
* Running on http://0.0.0.0:5000/
|
||||||
|
|
||||||
If you also want webcam and timelapse support, you'll need to download and compile MJPG-Streamer:
|
If you also want webcam and timelapse support, you'll need to download and compile MJPG-Streamer:
|
||||||
|
@ -145,23 +151,23 @@ This should hopefully run through without any compilation errors. You should the
|
||||||
o: commands..........: enabled
|
o: commands..........: enabled
|
||||||
|
|
||||||
If you now point your browser to `http://<your Raspi's IP>:8080/?action=stream`, you should see a moving picture at 5fps.
|
If you now point your browser to `http://<your Raspi's IP>:8080/?action=stream`, you should see a moving picture at 5fps.
|
||||||
Open `~/.printerwebui/config.ini` and add the following lines to it:
|
Open `~/.octoprint/config.ini` and add the following lines to it:
|
||||||
|
|
||||||
[webcam]
|
[webcam]
|
||||||
stream = http://<your Raspi's IP>:8080/?action=stream
|
stream = http://<your Raspi's IP>:8080/?action=stream
|
||||||
snapshot = http://127.0.0.1:8080/?action=snapshot
|
snapshot = http://127.0.0.1:8080/?action=snapshot
|
||||||
ffmpeg = /usr/bin/avconv
|
ffmpeg = /usr/bin/avconv
|
||||||
|
|
||||||
Restart the WebUI server and reload its frontend. You should now see a Webcam tab with content.
|
Restart the OctoPrint server and reload its frontend. You should now see a Webcam tab with content.
|
||||||
|
|
||||||
If everything works, add the startup commands to `/etc/rc.local`.
|
If everything works, add the startup commands to `/etc/rc.local`.
|
||||||
|
|
||||||
Credits
|
Credits
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The Printer WebUI started out as a fork of Cura (https://github.com/daid/Cura) for adding a web interface to its
|
The OctoPrint started out as a fork of Cura (https://github.com/daid/Cura) for adding a web interface to its
|
||||||
printing functionality. It still uses Cura's communication code for talking to the printer, but has been reorganized to
|
printing functionality and was originally named Printer WebUI. It still uses Cura's communication code for talking to
|
||||||
only include those parts of Cura necessary for its targeted usecase.
|
the printer, but has been reorganized to only include those parts of Cura necessary for its targeted usecase.
|
||||||
|
|
||||||
It also uses the following libraries and frameworks for backend and frontend:
|
It also uses the following libraries and frameworks for backend and frontend:
|
||||||
|
|
||||||
|
@ -175,3 +181,5 @@ It also uses the following libraries and frameworks for backend and frontend:
|
||||||
The following software is recommended for Webcam support on the Raspberry Pi:
|
The following software is recommended for Webcam support on the Raspberry Pi:
|
||||||
|
|
||||||
* MJPG-Streamer: http://sourceforge.net/apps/mediawiki/mjpg-streamer/index.php?title=Main_Page
|
* MJPG-Streamer: http://sourceforge.net/apps/mediawiki/mjpg-streamer/index.php?title=Main_Page
|
||||||
|
|
||||||
|
I also want to thank [Janina Himmen](http://jhimmen.de/) for providing the kick-ass logo!
|
||||||
|
|
|
@ -8,10 +8,10 @@ import threading
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import printer_webui.util.comm as comm
|
import octoprint.util.comm as comm
|
||||||
from printer_webui.util import gcodeInterpreter
|
from octoprint.util import gcodeInterpreter
|
||||||
|
|
||||||
from printer_webui.settings import settings
|
from octoprint.settings import settings
|
||||||
|
|
||||||
def getConnectionOptions():
|
def getConnectionOptions():
|
||||||
"""
|
"""
|
|
@ -10,16 +10,16 @@ import os
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from printer_webui.printer import Printer, getConnectionOptions, PrinterCallback
|
from octoprint.printer import Printer, getConnectionOptions, PrinterCallback
|
||||||
from printer_webui.settings import settings
|
from octoprint.settings import settings
|
||||||
import printer_webui.timelapse as timelapse
|
import octoprint.timelapse as timelapse
|
||||||
|
|
||||||
BASEURL = "/ajax/"
|
BASEURL = "/ajax/"
|
||||||
SUCCESS = {}
|
SUCCESS = {}
|
||||||
|
|
||||||
UPLOAD_FOLDER = settings().getBaseFolder("uploads")
|
UPLOAD_FOLDER = settings().getBaseFolder("uploads")
|
||||||
|
|
||||||
app = Flask("printer_webui")
|
app = Flask("octoprint")
|
||||||
printer = Printer()
|
printer = Printer()
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
|
@ -6,7 +6,8 @@ import ConfigParser
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
APPNAME="PrinterWebUI"
|
APPNAME="OctoPrint"
|
||||||
|
OLD_APPNAME="PrinterWebUI"
|
||||||
|
|
||||||
instance = None
|
instance = None
|
||||||
|
|
||||||
|
@ -52,18 +53,12 @@ class Settings(object):
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
def init_settings_dir(self):
|
def init_settings_dir(self):
|
||||||
# taken from http://stackoverflow.com/questions/1084697/how-do-i-store-desktop-application-data-in-a-cross-platform-way-for-python
|
self.settings_dir = _resolveSettingsDir(APPNAME)
|
||||||
if sys.platform == "darwin":
|
|
||||||
from AppKit import NSSearchPathForDirectoriesInDomains
|
# migration due to rename
|
||||||
# http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
|
old_settings_dir = _resolveSettingsDir(OLD_APPNAME)
|
||||||
# NSApplicationSupportDirectory = 14
|
if os.path.exists(old_settings_dir) and os.path.isdir(old_settings_dir) and not os.path.exists(self.settings_dir):
|
||||||
# NSUserDomainMask = 1
|
os.rename(old_settings_dir, self.settings_dir)
|
||||||
# True for expanding the tilde into a fully qualified path
|
|
||||||
self.settings_dir = os.path.join(NSSearchPathForDirectoriesInDomains(14, 1, True)[0], APPNAME)
|
|
||||||
elif sys.platform == "win32":
|
|
||||||
self.settings_dir = os.path.join(os.environ["APPDATA"], APPNAME)
|
|
||||||
else:
|
|
||||||
self.settings_dir = os.path.expanduser(os.path.join("~", "." + APPNAME.lower()))
|
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
self._config = ConfigParser.ConfigParser(allow_no_value=True)
|
self._config = ConfigParser.ConfigParser(allow_no_value=True)
|
||||||
|
@ -144,3 +139,16 @@ class Settings(object):
|
||||||
sectionConfig[key] = value
|
sectionConfig[key] = value
|
||||||
self._changes[section] = sectionConfig
|
self._changes[section] = sectionConfig
|
||||||
|
|
||||||
|
def _resolveSettingsDir(applicationName):
|
||||||
|
# taken from http://stackoverflow.com/questions/1084697/how-do-i-store-desktop-application-data-in-a-cross-platform-way-for-python
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
from AppKit import NSSearchPathForDirectoriesInDomains
|
||||||
|
# http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
|
||||||
|
# NSApplicationSupportDirectory = 14
|
||||||
|
# NSUserDomainMask = 1
|
||||||
|
# True for expanding the tilde into a fully qualified path
|
||||||
|
return os.path.join(NSSearchPathForDirectoriesInDomains(14, 1, True)[0], applicationName)
|
||||||
|
elif sys.platform == "win32":
|
||||||
|
return os.path.join(os.environ["APPDATA"], applicationName)
|
||||||
|
else:
|
||||||
|
return os.path.expanduser(os.path.join("~", "." + applicationName.lower()))
|
|
@ -57,6 +57,14 @@ table th.gcode_files_action, table td.gcode_files_action {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#temperature-graph {
|
||||||
|
height: 350px;
|
||||||
|
width: 100%;
|
||||||
|
background-image: url("/static/img/graph-background.png");
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
#temp {
|
#temp {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 815 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
|
@ -1,9 +1,9 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Printer WebUI</title>
|
<title>OctoPrint</title>
|
||||||
|
|
||||||
<!--<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}">-->
|
<link rel="shortcut icon" href="{{ url_for('static', filename='img/tentacle-32x32.png') }}">
|
||||||
|
|
||||||
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet" media="screen">
|
||||||
<link href="{{ url_for('static', filename='css/jquery.fileupload-ui.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/jquery.fileupload-ui.css') }}" rel="stylesheet" media="screen">
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="brand" href="#">Printer WebUI</a>
|
<a class="brand" href="#"><img src="{{ url_for('static', filename='img/tentacle-20x20.png') }}"> OctoPrint</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane active" id="temp">
|
<div class="tab-pane active" id="temp">
|
||||||
<div class="row" style="padding-left: 20px">
|
<div class="row" style="padding-left: 20px">
|
||||||
<div id="temperature-graph" style="height: 350px; width: 100%"></div>
|
<div id="temperature-graph"></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="form-horizontal" style="width: 49%; float: left; margin-bottom: 20px;">
|
<div class="form-horizontal" style="width: 49%; float: left; margin-bottom: 20px;">
|
|
@ -2,7 +2,7 @@
|
||||||
__author__ = "Gina Häußge <osd@foosel.net>"
|
__author__ = "Gina Häußge <osd@foosel.net>"
|
||||||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
||||||
|
|
||||||
from printer_webui.settings import settings
|
from octoprint.settings import settings
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
|
@ -12,10 +12,10 @@ import Queue as queue
|
||||||
|
|
||||||
import serial
|
import serial
|
||||||
|
|
||||||
from printer_webui.util.avr_isp import stk500v2
|
from octoprint.util.avr_isp import stk500v2
|
||||||
from printer_webui.util.avr_isp import ispBase
|
from octoprint.util.avr_isp import ispBase
|
||||||
|
|
||||||
from printer_webui.settings import settings
|
from octoprint.settings import settings
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import _winreg
|
import _winreg
|
|
@ -5,7 +5,7 @@ import math
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from printer_webui.util import util3d
|
from octoprint.util import util3d
|
||||||
|
|
||||||
preferences = {
|
preferences = {
|
||||||
"extruder_offset_x1": -22.0,
|
"extruder_offset_x1": -22.0,
|