Commit 66c6f8d5 authored by Guillaume Seguin's avatar Guillaume Seguin

Merge branch 'experimental' of github.com:kliment/Printrun into experimental

parents f3fff426 871edba8
...@@ -102,6 +102,9 @@ class printcore(): ...@@ -102,6 +102,9 @@ class printcore():
self.stop_read_thread = True self.stop_read_thread = True
self.read_thread.join() self.read_thread.join()
self.read_thread = None self.read_thread = None
if self.print_thread:
self.printing = False
self.print_thread.join()
self._stop_sender() self._stop_sender()
try: try:
self.printer.close() self.printer.close()
......
...@@ -25,7 +25,7 @@ gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|[a-z][-+]?[0-9]*\.?[0-9]*") ...@@ -25,7 +25,7 @@ gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|[a-z][-+]?[0-9]*\.?[0-9]*")
m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|[A-Z]:?[-+]?[0-9]*\.?[0-9]*") m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|[A-Z]:?[-+]?[0-9]*\.?[0-9]*")
move_gcodes = ["G0", "G1", "G2", "G3"] move_gcodes = ["G0", "G1", "G2", "G3"]
class Line(object): class PyLine(object):
__slots__ = ('x','y','z','e','f','i','j','s','p', __slots__ = ('x','y','z','e','f','i','j','s','p',
'raw','split_raw', 'raw','split_raw',
...@@ -34,15 +34,26 @@ class Line(object): ...@@ -34,15 +34,26 @@ class Line(object):
'current_x', 'current_y', 'current_z', 'extruding', 'current_tool', 'current_x', 'current_y', 'current_z', 'extruding', 'current_tool',
'gcview_end_vertex') 'gcview_end_vertex')
def __getattr__(self, name):
return None
try:
import gcoder_line
LineBase = gcoder_line.GLine
except ImportError:
LineBase = PyLine
class Line(LineBase):
__slots__ = ()
def __init__(self, l): def __init__(self, l):
super(Line, self).__init__()
self.raw = l self.raw = l
self.split_raw = gcode_exp.findall(self.raw.lower()) self.split_raw = gcode_exp.findall(self.raw.lower())
self.command = self.split_raw[0].upper() if not self.split_raw[0].startswith("n") else self.split_raw[1].upper() self.command = self.split_raw[0].upper() if not self.split_raw[0].startswith("n") else self.split_raw[1].upper()
self.is_move = self.command in move_gcodes self.is_move = self.command in move_gcodes
def __getattr__(self, name):
return None
def parse_coordinates(self, imperial = False, force = False): def parse_coordinates(self, imperial = False, force = False):
# Not a G-line, we don't want to parse its arguments # Not a G-line, we don't want to parse its arguments
if not force and not self.command[0] == "G": if not force and not self.command[0] == "G":
...@@ -407,6 +418,5 @@ def main(): ...@@ -407,6 +418,5 @@ def main():
print "Number of layers: %d" % gcode.num_layers() print "Number of layers: %d" % gcode.num_layers()
print "Estimated duration: %s" % gcode.estimate_duration() print "Estimated duration: %s" % gcode.estimate_duration()
if __name__ == '__main__': if __name__ == '__main__':
main() main()
# This file is copied from GCoder.
#
# GCoder is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GCoder is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
from libc.stdlib cimport malloc, free
from libc.stdint cimport uint32_t
cdef extern from "string.h":
char *strncpy(char *dest, char *src, size_t n)
size_t strlen(const char *s)
cdef char* copy_string(object value):
cdef char* orig = value
str_len = len(orig)
cdef char* array = <char *>malloc(str_len + 1)
strncpy(array, orig, str_len)
array[str_len] = 0;
return array
cdef enum BitPos:
pos_x = 1 << 0
pos_y = 1 << 1
pos_z = 1 << 2
pos_e = 1 << 3
pos_f = 1 << 4
pos_i = 1 << 5
pos_j = 1 << 6
pos_s = 1 << 7
pos_p = 1 << 8
pos_is_move = 1 << 9
pos_relative = 1 << 10
pos_relative_e = 1 << 11
pos_extruding = 1 << 12
pos_current_x = 1 << 13
pos_current_y = 1 << 14
pos_current_z = 1 << 15
pos_current_tool = 1 << 16
pos_raw = 1 << 17
pos_split_raw = 1 << 18
pos_command = 1 << 19
pos_gcview_end_vertex = 1 << 20
cdef inline uint32_t has_var(uint32_t status, uint32_t pos):
return status & pos
cdef inline uint32_t set_has_var(uint32_t status, uint32_t pos):
return status | pos
cdef inline uint32_t unset_has_var(uint32_t status, uint32_t pos):
return status & ~pos
cdef class GLine(object):
cdef char* _raw
cdef char* _command
cdef object _split_raw
cdef float _x, _y, _z, _e, _f, _i, _j, _s, _p
cdef float _current_x, _current_y, _current_z
cdef uint32_t _gcview_end_vertex
cdef uint32_t _status
cdef char _current_tool
__slots__ = ()
def __cinit__(self):
self._status = 0
self._raw = NULL
self._command = NULL
def __dealloc__(self):
if self._raw != NULL: free(self._raw)
if self._command != NULL: free(self._command)
property x:
def __get__(self):
if has_var(self._status, pos_x): return self._x
else: return None
def __set__(self, value):
self._x = value
self._status = set_has_var(self._status, pos_x)
property y:
def __get__(self):
if has_var(self._status, pos_y): return self._y
else: return None
def __set__(self, value):
self._y = value
self._status = set_has_var(self._status, pos_y)
property z:
def __get__(self):
if has_var(self._status, pos_z): return self._z
else: return None
def __set__(self, value):
self._z = value
self._status = set_has_var(self._status, pos_z)
property e:
def __get__(self):
if has_var(self._status, pos_e): return self._e
else: return None
def __set__(self, value):
self._e = value
self._status = set_has_var(self._status, pos_e)
property f:
def __get__(self):
if has_var(self._status, pos_f): return self._f
else: return None
def __set__(self, value):
self._f = value
self._status = set_has_var(self._status, pos_f)
property i:
def __get__(self):
if has_var(self._status, pos_i): return self._i
else: return None
def __set__(self, value):
self._i = value
self._status = set_has_var(self._status, pos_i)
property j:
def __get__(self):
if has_var(self._status, pos_j): return self._j
else: return None
def __set__(self, value):
self._j = value
self._status = set_has_var(self._status, pos_j)
property s:
def __get__(self):
if has_var(self._status, pos_s): return self._s
else: return None
def __set__(self, value):
self._s = value
self._status = set_has_var(self._status, pos_s)
property p:
def __get__(self):
if has_var(self._status, pos_p): return self._p
else: return None
def __set__(self, value):
self._p = value
self._status = set_has_var(self._status, pos_p)
property is_move:
def __get__(self):
if has_var(self._status, pos_is_move): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_is_move)
else: self._status = unset_has_var(self._status, pos_is_move)
property relative:
def __get__(self):
if has_var(self._status, pos_relative): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_relative)
else: self._status = unset_has_var(self._status, pos_relative)
property relative_e:
def __get__(self):
if has_var(self._status, pos_relative_e): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_relative_e)
else: self._status = unset_has_var(self._status, pos_relative_e)
property extruding:
def __get__(self):
if has_var(self._status, pos_extruding): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_extruding)
else: self._status = unset_has_var(self._status, pos_extruding)
property current_x:
def __get__(self):
if has_var(self._status, pos_current_x): return self._current_x
else: return None
def __set__(self, value):
self._current_x = value
self._status = set_has_var(self._status, pos_current_x)
property current_y:
def __get__(self):
if has_var(self._status, pos_current_y): return self._current_y
else: return None
def __set__(self, value):
self._current_y = value
self._status = set_has_var(self._status, pos_current_y)
property current_z:
def __get__(self):
if has_var(self._status, pos_current_z): return self._current_z
else: return None
def __set__(self, value):
self._current_z = value
self._status = set_has_var(self._status, pos_current_z)
property current_tool:
def __get__(self):
if has_var(self._status, pos_current_tool): return self._current_tool
else: return None
def __set__(self, value):
self._current_tool = value
self._status = set_has_var(self._status, pos_current_tool)
property gcview_end_vertex:
def __get__(self):
if has_var(self._status, pos_gcview_end_vertex): return self._gcview_end_vertex
else: return None
def __set__(self, value):
self._gcview_end_vertex = value
self._status = set_has_var(self._status, pos_gcview_end_vertex)
property split_raw:
def __get__(self):
if has_var(self._status, pos_split_raw): return self._split_raw
else: return None
def __set__(self, value):
self._split_raw = value
self._status = set_has_var(self._status, pos_split_raw)
def __del__(self):
self._split_raw = None
property raw:
def __get__(self):
if has_var(self._status, pos_raw): return self._raw
else: return None
def __set__(self, value):
self._raw = copy_string(value)
self._status = set_has_var(self._status, pos_raw)
property command:
def __get__(self):
if has_var(self._status, pos_command): return self._command
else: return None
def __set__(self, value):
self._command = copy_string(value)
self._status = set_has_var(self._status, pos_command)
...@@ -269,7 +269,8 @@ class VizPane(wx.BoxSizer): ...@@ -269,7 +269,8 @@ class VizPane(wx.BoxSizer):
root.gviz = gviz.gviz(parentpanel, (300, 300), root.gviz = gviz.gviz(parentpanel, (300, 300),
build_dimensions = root.build_dimensions_list, build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2), grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width) extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gviz.SetToolTip(wx.ToolTip("Click to examine / edit\n layers of loaded file")) root.gviz.SetToolTip(wx.ToolTip("Click to examine / edit\n layers of loaded file"))
root.gviz.showall = 1 root.gviz.showall = 1
root.gviz.Bind(wx.EVT_LEFT_DOWN, root.showwin) root.gviz.Bind(wx.EVT_LEFT_DOWN, root.showwin)
...@@ -290,7 +291,8 @@ class VizPane(wx.BoxSizer): ...@@ -290,7 +291,8 @@ class VizPane(wx.BoxSizer):
root.gwindow = gviz.window([], root.gwindow = gviz.window([],
build_dimensions = root.build_dimensions_list, build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2), grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width) extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide()) root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide())
if not isinstance(root.gviz, NoViz): if not isinstance(root.gviz, NoViz):
self.Add(root.gviz.widget, 1, flag = wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL) self.Add(root.gviz.widget, 1, flag = wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL)
......
...@@ -23,14 +23,14 @@ from printrun_utils import imagefile ...@@ -23,14 +23,14 @@ from printrun_utils import imagefile
ID_ABOUT = 101 ID_ABOUT = 101
ID_EXIT = 110 ID_EXIT = 110
class window(wx.Frame): class window(wx.Frame):
def __init__(self, f, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5): def __init__(self, f, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000"):
wx.Frame.__init__(self, None, title = "Gcode view, shift to move view, mousewheel to set layer", size = size) wx.Frame.__init__(self, None, title = "Gcode view, shift to move view, mousewheel to set layer", size = size)
self.CreateStatusBar(1); self.CreateStatusBar(1);
self.SetStatusText("Layer number and Z position show here when you scroll"); self.SetStatusText("Layer number and Z position show here when you scroll");
panel = wx.Panel(self, -1) panel = wx.Panel(self, -1)
self.p = gviz(panel, size = size, build_dimensions = build_dimensions, grid = grid, extrusion_width = extrusion_width, realparent = self) self.p = gviz(panel, size = size, build_dimensions = build_dimensions, grid = grid, extrusion_width = extrusion_width, bgcolor = bgcolor, realparent = self)
vbox = wx.BoxSizer(wx.VERTICAL) vbox = wx.BoxSizer(wx.VERTICAL)
toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER) toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER)
...@@ -128,10 +128,12 @@ class gviz(wx.Panel): ...@@ -128,10 +128,12 @@ class gviz(wx.Panel):
self._showall = showall self._showall = showall
showall = property(_get_showall, _set_showall) showall = property(_get_showall, _set_showall)
def __init__(self, parent, size = (200, 200), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, realparent = None): def __init__(self, parent, size = (200, 200), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000", realparent = None):
wx.Panel.__init__(self, parent, -1, size = size) wx.Panel.__init__(self, parent, -1)
self.widget = self self.widget = self
self.SetMinSize((150, 150)) size = [max(1.0, x) for x in size]
ratio = size[0] / size[1]
self.SetMinSize((150, 150/ratio))
self.parent = realparent if realparent else parent self.parent = realparent if realparent else parent
self.size = size self.size = size
self.build_dimensions = build_dimensions self.build_dimensions = build_dimensions
...@@ -163,7 +165,9 @@ class gviz(wx.Panel): ...@@ -163,7 +165,9 @@ class gviz(wx.Panel):
self.hilightqueue = Queue(0) self.hilightqueue = Queue(0)
self.hilightarcsqueue = Queue(0) self.hilightarcsqueue = Queue(0)
self.dirty = 1 self.dirty = 1
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1],-1) self.bgcolor = wx.Colour()
self.bgcolor.SetFromName(bgcolor)
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1], -1)
def inject(self): def inject(self):
#import pdb; pdb.set_trace() #import pdb; pdb.set_trace()
...@@ -217,11 +221,10 @@ class gviz(wx.Panel): ...@@ -217,11 +221,10 @@ class gviz(wx.Panel):
float(self.size[1] - 1)/self.build_dimensions[1])] float(self.size[1] - 1)/self.build_dimensions[1])]
def resize(self, event): def resize(self, event):
oldside = max(1.0, min(self.size)) old_basescale = self.basescale
self.size = self.GetClientSizeTuple() self.size = self.GetClientSizeTuple()
self.update_basescale() self.update_basescale()
newside = max(1.0, min(self.size)) zoomratio = float(self.basescale[0]) / old_basescale[0]
zoomratio = float(newside) / oldside
wx.CallLater(200, self.zoom, 0, 0, zoomratio) wx.CallLater(200, self.zoom, 0, 0, zoomratio)
def zoom(self, x, y, factor): def zoom(self, x, y, factor):
...@@ -230,8 +233,8 @@ class gviz(wx.Panel): ...@@ -230,8 +233,8 @@ class gviz(wx.Panel):
x = y = side / 2 x = y = side / 2
self.scale = [s * factor for s in self.scale] self.scale = [s * factor for s in self.scale]
self.translate = [ x - (x-self.translate[0]) * factor, self.translate = [x - (x - self.translate[0]) * factor,
y - (y-self.translate[1]) * factor] y - (y - self.translate[1]) * factor]
penwidth = max(1.0, self.filament_width*((self.scale[0]+self.scale[1])/2.0)) penwidth = max(1.0, self.filament_width*((self.scale[0]+self.scale[1])/2.0))
for pen in self.penslist: for pen in self.penslist:
pen.SetWidth(penwidth) pen.SetWidth(penwidth)
...@@ -239,18 +242,18 @@ class gviz(wx.Panel): ...@@ -239,18 +242,18 @@ class gviz(wx.Panel):
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
def _line_scaler(self, x): def _line_scaler(self, x):
return (self.scale[0]*x[0]+self.translate[0], return (self.scale[0]*x[0],
self.scale[1]*x[1]+self.translate[1], self.scale[1]*x[1],
self.scale[0]*x[2]+self.translate[0], self.scale[0]*x[2],
self.scale[1]*x[3]+self.translate[1],) self.scale[1]*x[3],)
def _arc_scaler(self, x): def _arc_scaler(self, x):
return (self.scale[0]*x[0]+self.translate[0], return (self.scale[0]*x[0],
self.scale[1]*x[1]+self.translate[1], self.scale[1]*x[1],
self.scale[0]*x[2]+self.translate[0], self.scale[0]*x[2],
self.scale[1]*x[3]+self.translate[1], self.scale[1]*x[3],
self.scale[0]*x[4]+self.translate[0], self.scale[0]*x[4],
self.scale[1]*x[5]+self.translate[1],) self.scale[1]*x[5],)
def _drawlines(self, dc, lines, pens): def _drawlines(self, dc, lines, pens):
scaled_lines = map(self._line_scaler, lines) scaled_lines = map(self._line_scaler, lines)
...@@ -264,7 +267,9 @@ class gviz(wx.Panel): ...@@ -264,7 +267,9 @@ class gviz(wx.Panel):
dc.DrawArc(*scaled_arcs[i]) dc.DrawArc(*scaled_arcs[i])
def repaint_everything(self): def repaint_everything(self):
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1],-1) width = self.scale[0]*self.build_dimensions[0]
height = self.scale[1]*self.build_dimensions[1]
self.blitmap = wx.EmptyBitmap(width + 1, height + 1, -1)
dc = wx.MemoryDC() dc = wx.MemoryDC()
dc.SelectObject(self.blitmap) dc.SelectObject(self.blitmap)
dc.SetBackground(wx.Brush((250, 250, 200))) dc.SetBackground(wx.Brush((250, 250, 200)))
...@@ -273,9 +278,11 @@ class gviz(wx.Panel): ...@@ -273,9 +278,11 @@ class gviz(wx.Panel):
for grid_unit in self.grid: for grid_unit in self.grid:
if grid_unit > 0: if grid_unit > 0:
for x in xrange(int(self.build_dimensions[0]/grid_unit)+1): for x in xrange(int(self.build_dimensions[0]/grid_unit)+1):
dc.DrawLine(self.translate[0]+x*self.scale[0]*grid_unit, self.translate[1], self.translate[0]+x*self.scale[0]*grid_unit, self.translate[1]+self.scale[1]*self.build_dimensions[1]) draw_x = self.scale[0]*x*grid_unit
dc.DrawLine(draw_x, 0, draw_x, height)
for y in xrange(int(self.build_dimensions[1]/grid_unit)+1): for y in xrange(int(self.build_dimensions[1]/grid_unit)+1):
dc.DrawLine(self.translate[0], self.translate[1]+y*self.scale[1]*grid_unit, self.translate[0]+self.scale[0]*self.build_dimensions[0], self.translate[1]+y*self.scale[1]*grid_unit) draw_y = self.scale[1]*(self.build_dimensions[1]-y*grid_unit)
dc.DrawLine(0, draw_y, width, draw_y)
dc.SetPen(wx.Pen(wx.Colour(0, 0, 0))) dc.SetPen(wx.Pen(wx.Colour(0, 0, 0)))
if not self.showall: if not self.showall:
...@@ -327,7 +334,9 @@ class gviz(wx.Panel): ...@@ -327,7 +334,9 @@ class gviz(wx.Panel):
self.repaint_everything() self.repaint_everything()
self.paint_hilights() self.paint_hilights()
dc = wx.PaintDC(self) dc = wx.PaintDC(self)
dc.DrawBitmap(self.blitmap, 0, 0) dc.SetBackground(wx.Brush(self.bgcolor))
dc.Clear()
dc.DrawBitmap(self.blitmap, self.translate[0], self.translate[1])
def addfile(self, gcode): def addfile(self, gcode):
self.clear() self.clear()
......
This diff is collapsed.
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
import tornado.ioloop import tornado.ioloop
import tornado.web import tornado.web
import tornado.websocket import tornado.websocket
from tornado.web import asynchronous
from tornado import gen from tornado import gen
import tornado.httpserver import tornado.httpserver
import uuid
import time import time
import base64 import base64
import logging import logging
...@@ -90,12 +92,51 @@ class StopHandler(tornado.web.RequestHandler): ...@@ -90,12 +92,51 @@ class StopHandler(tornado.web.RequestHandler):
prontserve.do_stop() prontserve.do_stop()
self.finish("ACK") self.finish("ACK")
@tornado.web.stream_body
class JobsHandler(tornado.web.RequestHandler): class JobsHandler(tornado.web.RequestHandler):
def post(self): def post(self):
self.read_bytes = 0
self.total_bytes = self.request.content_length
self.body = ''
print self.request
session_uuid = self.get_argument("session_uuid", None)
print "me"
print session_uuid
print "them"
self.websocket = None
for c in ConstructSocketHandler.clients:
print c.session_uuid
if c.session_uuid == session_uuid: self.websocket = c
self.request.request_continue()
self.read_chunks()
def read_chunks(self, chunk=''):
self.read_bytes += len(chunk)
self.body += chunk
if chunk: self.process_chunk()
chunk_length = min(100000, self.request.content_length - self.read_bytes)
if chunk_length > 0:
self.request.connection.stream.read_bytes(
chunk_length, self.read_chunks)
else:
self.request._on_request_body(self.body, self.uploaded)
def process_chunk(self):
print self.get_argument("session_uuid", None)
print "bytes: (%i / %i)"%(self.read_bytes, self.total_bytes)
msg = {'uploaded': self.read_bytes, 'total': self.total_bytes}
if self.websocket != None:
self.websocket.send(job_upload_progress_changed = msg)
def uploaded(self):
fileinfo = self.request.files['job'][0] fileinfo = self.request.files['job'][0]
prontserve.do_add_job(fileinfo['filename'], fileinfo['body']) prontserve.do_add_job(fileinfo['filename'], fileinfo['body'])
self.finish("ACK") self.finish("ACK")
class JobHandler(tornado.web.RequestHandler): class JobHandler(tornado.web.RequestHandler):
def delete(self, job_id): def delete(self, job_id):
prontserve.do_rm_job(job_id) prontserve.do_rm_job(job_id)
...@@ -116,6 +157,7 @@ class InspectHandler(tornado.web.RequestHandler): ...@@ -116,6 +157,7 @@ class InspectHandler(tornado.web.RequestHandler):
#class EchoWebSocketHandler(tornado.web.RequestHandler): #class EchoWebSocketHandler(tornado.web.RequestHandler):
class ConstructSocketHandler(tornado.websocket.WebSocketHandler): class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
clients = []
def on_sensor_changed(self): def on_sensor_changed(self):
for name in ['bed', 'extruder']: for name in ['bed', 'extruder']:
...@@ -141,6 +183,8 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler): ...@@ -141,6 +183,8 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
return "construct.text.0.0.1" return "construct.text.0.0.1"
def open(self): def open(self):
self.session_uuid = str(uuid.uuid4())
self.clients.append(self)
prontserve.listeners.add(self) prontserve.listeners.add(self)
self.write_message({'headers': { self.write_message({'headers': {
'jobs': prontserve.jobs.public_list(), 'jobs': prontserve.jobs.public_list(),
...@@ -151,6 +195,7 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler): ...@@ -151,6 +195,7 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
for k, v in prontserve.target_values.iteritems(): for k, v in prontserve.target_values.iteritems():
self.on_uncaught_event("target_temp_changed", {k: v}) self.on_uncaught_event("target_temp_changed", {k: v})
self.on_uncaught_event("job_progress_changed", prontserve.previous_job_progress) self.on_uncaught_event("job_progress_changed", prontserve.previous_job_progress)
self.send(initialized= {'session_uuid': self.session_uuid} )
print "WebSocket opened. %i sockets currently open." % len(prontserve.listeners) print "WebSocket opened. %i sockets currently open." % len(prontserve.listeners)
def send(self, dict_args = {}, **kwargs): def send(self, dict_args = {}, **kwargs):
...@@ -196,15 +241,15 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler): ...@@ -196,15 +241,15 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
try: try:
if cmd == "set": cmd = "construct_set" if cmd == "set": cmd = "construct_set"
response = getattr(prontserve, "do_%s"%cmd)(*args, **kwargs) response = getattr(prontserve, "do_%s"%cmd)(*args, **kwargs)
print response self.write_message({"ack": response})
if response is not None: self.write_message(response) except Exception as ex:
except:
print traceback.format_exc() print traceback.format_exc()
self.write_message({"error": "bad command."}) self.write_message({"error": str(ex)})
else: else:
self.write_message({"error": "%s command does not exist."%cmd}) self.write_message({"error": "%s command does not exist."%cmd})
def on_close(self): def on_close(self):
self.clients.remove(self)
prontserve.listeners.remove(self) prontserve.listeners.remove(self)
print "WebSocket closed. %i sockets currently open." % len(prontserve.listeners) print "WebSocket closed. %i sockets currently open." % len(prontserve.listeners)
...@@ -253,6 +298,7 @@ class EventEmitter(object): ...@@ -253,6 +298,7 @@ class EventEmitter(object):
class Prontserve(pronsole.pronsole, EventEmitter): class Prontserve(pronsole.pronsole, EventEmitter):
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.initializing = True
pronsole.pronsole.__init__(self) pronsole.pronsole.__init__(self)
EventEmitter.__init__(self) EventEmitter.__init__(self)
self.settings.sensor_names = {'T': 'extruder', 'B': 'bed'} self.settings.sensor_names = {'T': 'extruder', 'B': 'bed'}
...@@ -270,8 +316,10 @@ class Prontserve(pronsole.pronsole, EventEmitter): ...@@ -270,8 +316,10 @@ class Prontserve(pronsole.pronsole, EventEmitter):
self.current_job = None self.current_job = None
self.previous_job_progress = 0 self.previous_job_progress = 0
self.silent = True self.silent = True
self._sensor_update_received = True
self.init_mdns() self.init_mdns()
self.jobs.listeners.add(self) self.jobs.listeners.add(self)
self.initializing = False
def init_mdns(self): def init_mdns(self):
sdRef = pybonjour.DNSServiceRegister(name = None, sdRef = pybonjour.DNSServiceRegister(name = None,
...@@ -284,7 +332,7 @@ class Prontserve(pronsole.pronsole, EventEmitter): ...@@ -284,7 +332,7 @@ class Prontserve(pronsole.pronsole, EventEmitter):
sdRef.close() sdRef.close()
def do_print(self): def do_print(self):
if not self.p.online: raise "not online" if not self.p.online: raise Exception("not online")
self.printing_jobs = True self.printing_jobs = True
def do_home(self, *args, **kwargs): def do_home(self, *args, **kwargs):
...@@ -315,7 +363,7 @@ class Prontserve(pronsole.pronsole, EventEmitter): ...@@ -315,7 +363,7 @@ class Prontserve(pronsole.pronsole, EventEmitter):
pronsole.pronsole.do_move(self, cmd ) pronsole.pronsole.do_move(self, cmd )
def do_stop_move(self): def do_stop_move(self):
raise "Continuous movement not supported" raise Exception("Continuous movement not supported")
def do_estop(self): def do_estop(self):
pronsole.pronsole.do_pause(self, "") pronsole.pronsole.do_pause(self, "")
...@@ -403,7 +451,16 @@ class Prontserve(pronsole.pronsole, EventEmitter): ...@@ -403,7 +451,16 @@ class Prontserve(pronsole.pronsole, EventEmitter):
self.previous_job_progress = progress self.previous_job_progress = progress
self.fire("job_progress_changed", progress) self.fire("job_progress_changed", progress)
def print_progress(self):
if(self.p.printing):
return 100*float(self.p.queueindex)/len(self.p.mainqueue)
if(self.sdprinting):
return self.percentdone
return 0
def run_sensor_loop(self): def run_sensor_loop(self):
if self._sensor_update_received:
self._sensor_update_received = False
if self.dry_run: if self.dry_run:
self._receive_sensor_update("ok T:%i"%random.randint(20, 50)) self._receive_sensor_update("ok T:%i"%random.randint(20, 50))
else: else:
...@@ -423,20 +480,11 @@ class Prontserve(pronsole.pronsole, EventEmitter): ...@@ -423,20 +480,11 @@ class Prontserve(pronsole.pronsole, EventEmitter):
if l!="ok" and not l.startswith("ok T") and not l.startswith("T:"): if l!="ok" and not l.startswith("ok T") and not l.startswith("T:"):
self._receive_printer_error(l) self._receive_printer_error(l)
def print_progress(self):
if(self.p.printing):
return 100*float(self.p.queueindex)/len(self.p.mainqueue)
if(self.sdprinting):
return self.percentdone
return 0
def _receive_sensor_update(self, l): def _receive_sensor_update(self, l):
self._sensor_update_received = True
words = filter(lambda s: s.find(":") > 0, l.split(" ")) words = filter(lambda s: s.find(":") > 0, l.split(" "))
d = dict([ s.split(":") for s in words]) d = dict([ s.split(":") for s in words])
# print "sensor update received!"
for key, value in d.iteritems(): for key, value in d.iteritems():
self.__update_sensor(key, value) self.__update_sensor(key, value)
...@@ -457,9 +505,17 @@ class Prontserve(pronsole.pronsole, EventEmitter): ...@@ -457,9 +505,17 @@ class Prontserve(pronsole.pronsole, EventEmitter):
print msg print msg
self.fire("log", {'msg': msg, 'level': "debug"}) self.fire("log", {'msg': msg, 'level': "debug"})
def logError(self, *msg):
print u"".join(unicode(i) for i in msg)
if self.initializing == False:
raise Exception(u"".join(unicode(i) for i in msg))
def write_prompt(self): def write_prompt(self):
None None
def confirm(self):
True
class PrintJobQueue(EventEmitter): class PrintJobQueue(EventEmitter):
...@@ -548,6 +604,10 @@ if __name__ == "__main__": ...@@ -548,6 +604,10 @@ if __name__ == "__main__":
help='Does not connect to the 3D printer' help='Does not connect to the 3D printer'
) )
parser.add_argument('--loud', default=False, action='store_true',
help='Enables verbose printer output'
)
args = parser.parse_args() args = parser.parse_args()
dry_run = args.dry_run dry_run = args.dry_run
...@@ -557,9 +617,23 @@ if __name__ == "__main__": ...@@ -557,9 +617,23 @@ if __name__ == "__main__":
sys.stdout.write("\x1B[0;33m Dry Run \x1B[0m") sys.stdout.write("\x1B[0;33m Dry Run \x1B[0m")
print "" print ""
print "Prontserve is starting..."
prontserve = Prontserve(dry_run=dry_run) prontserve = Prontserve(dry_run=dry_run)
if dry_run==False: prontserve.do_connect("") prontserve.p.loud = args.loud
try:
if dry_run==False:
prontserve.do_connect("")
if prontserve.p.printer == None: sys.exit(1)
print "Connecting to printer..."
for x in range(0,50-1):
if prontserve.p.online == True: break
sys.stdout.write(".")
sys.stdout.flush()
time.sleep(0.1)
print ""
if prontserve.p.online == False:
print "Unable to connect to printer: Connection timed-out."
sys.exit(1)
time.sleep(1) time.sleep(1)
prontserve.run_sensor_loop() prontserve.run_sensor_loop()
...@@ -577,7 +651,6 @@ if __name__ == "__main__": ...@@ -577,7 +651,6 @@ if __name__ == "__main__":
warn_if_dry_run() warn_if_dry_run()
print "-"*80 + "\n" print "-"*80 + "\n"
try:
prontserve.ioloop.start() prontserve.ioloop.start()
except: except:
prontserve.p.disconnect() prontserve.p.disconnect()
...@@ -89,5 +89,3 @@ def interceptor(func): ...@@ -89,5 +89,3 @@ def interceptor(func):
cls._execute = wrapper(cls._execute) cls._execute = wrapper(cls._execute)
return cls return cls
return classwrapper return classwrapper
print "moo"
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
.morris-hover{position:absolute;z-index:1000;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);font-family:sans-serif;font-size:12px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;}
.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -10,12 +10,12 @@ ...@@ -10,12 +10,12 @@
<div class="lead-box"> <div class="lead-box">
<h1> <h1>
Your printer just got a whole lot better. Prontserve BETA is Online
</h1> </h1>
<p class="lead"> <p class="lead">
Prontserve is ready to print. Why not try it out with Prontserve is ready to print. Why not try it out with
<a href="/inspect">Inspector</a> or <a href="/inspect">Inspector</a> or
<a href="https://github.com/D1plo1d/ctrlpanel">Ctrl Panel</a>? <a href="https://github.com/D1plo1d/tegh">Tegh</a>?
</p> </p>
</div> </div>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<html> <html>
<head> <head>
<title>Prontserve Inspector</title> <title>Prontserve Inspector</title>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"> <link href="/static/vendor/css/bootstrap-combined.min.css" rel="stylesheet">
<link rel="stylesheet" href="http://cdn.oesmith.co.uk/morris-0.4.1.min.css"> <link href="/static/vendor/css/morris-0.4.1.min.css" rel="stylesheet">
<link href="/static/css/inspect.css" rel="stylesheet"> <link href="/static/css/inspect.css" rel="stylesheet">
</head> </head>
...@@ -46,11 +46,11 @@ ...@@ -46,11 +46,11 @@
<div class="focus-lost-overlay modal-backdrop fade out hide"></div> <div class="focus-lost-overlay modal-backdrop fade out hide"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="/static/vendor/js/jquery-1.9.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script> <script src="/static/vendor/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sugar/1.3.9/sugar.min.js"></script> <script src="/static/vendor/js/sugar.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script> <script src="/static/vendor/js/raphael-min.js"></script>
<script src="http://cdn.oesmith.co.uk/morris-0.4.1.min.js"></script> <script src="/static/vendor/js/morris-0.4.1.min.js"></script>
<script src="/static/js/inspect.js"></script> <script src="/static/js/inspect.js"></script>
</body> </body>
......
...@@ -21,6 +21,11 @@ from stat import * ...@@ -21,6 +21,11 @@ from stat import *
from distutils.core import setup from distutils.core import setup
from distutils.command.install import install as _install from distutils.command.install import install as _install
from distutils.command.install_data import install_data as _install_data from distutils.command.install_data import install_data as _install_data
try:
from Cython.Build import cythonize
extensions = cythonize("printrun/gcoder_line.pyx")
except ImportError:
extensions = None
INSTALLED_FILES = "installed_files" INSTALLED_FILES = "installed_files"
...@@ -84,7 +89,7 @@ class uninstall (_install): ...@@ -84,7 +89,7 @@ class uninstall (_install):
except: except:
self.warn ("Could not remove file %s" % file) self.warn ("Could not remove file %s" % file)
ops = ("install", "build", "sdist", "uninstall", "clean") ops = ("install", "build", "sdist", "uninstall", "clean", "build_ext")
if len (sys.argv) < 2 or sys.argv[1] not in ops: if len (sys.argv) < 2 or sys.argv[1] not in ops:
print "Please specify operation : %s" % " | ".join (ops) print "Please specify operation : %s" % " | ".join (ops)
...@@ -148,5 +153,6 @@ setup ( ...@@ -148,5 +153,6 @@ setup (
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"], scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = {"uninstall" : uninstall, cmdclass = {"uninstall" : uninstall,
"install" : install, "install" : install,
"install_data" : install_data} "install_data" : install_data},
ext_modules = extensions,
) )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment