Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
Printrun
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
Printrun
Commits
d89ac8db
Commit
d89ac8db
authored
Aug 08, 2013
by
Guillaume Seguin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move prontserve module to printrun/
parent
cba60a34
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
333 additions
and
326 deletions
+333
-326
prontserve.py
printrun/prontserve.py
+331
-0
prontserve.py
prontserve.py
+2
-326
No files found.
printrun/prontserve.py
0 → 100755
View file @
d89ac8db
#!/usr/bin/env python
import
glob
,
os
,
time
,
datetime
,
sys
,
codecs
,
random
,
textwrap
,
re
,
traceback
import
logging
,
tornado
.
ioloop
,
printcore
,
pronsole
from
.
import
printcore
from
.
import
pronsole
# Allow construct protocol developers to use a specific lib for dev purposes
c_path
=
os
.
getenv
(
'PY_CONSTRUCT_PATH'
)
if
c_path
!=
None
:
print
"$PY_CONSTRUCT_PATH detected, loading server lib from:
\n
%
s"
%
c_path
sys
.
path
.
insert
(
1
,
c_path
)
from
construct_server.construct_server
import
ConstructServer
from
construct_server.event_emitter
import
EventEmitter
from
pprint
import
pprint
from
.
import
gcoder
sys
.
stdout
=
codecs
.
getwriter
(
'utf8'
)(
sys
.
stdout
)
log
=
logging
.
getLogger
(
"root"
)
# Routes
# -------------------------------------------------
class
RootHandler
(
tornado
.
web
.
RequestHandler
):
def
get
(
self
):
self
.
render
(
"index.html"
)
class
InspectHandler
(
tornado
.
web
.
RequestHandler
):
def
prepare
(
self
):
construct_auth
(
self
,
None
)
def
get
(
self
):
self
.
render
(
"inspect.html"
)
# Faster GCoder implementation without any parsing
# -------------------------------------------------
class
Line
(
object
):
__slots__
=
(
'raw'
,
'command'
,
'is_move'
)
def
__init__
(
self
,
l
):
self
.
raw
=
l
def
__getattr__
(
self
,
name
):
return
None
class
FastGCode
(
object
):
def
__init__
(
self
,
data
):
self
.
lines
=
[
Line
(
l2
)
for
l2
in
(
l
.
strip
()
for
l
in
data
)
if
l2
]
self
.
all_layers
=
[
self
.
lines
]
def
__len__
(
self
):
return
len
(
self
.
lines
)
def
__iter__
(
self
):
return
self
.
lines
.
__iter__
()
def
idxs
(
self
,
index
):
return
(
0
,
index
)
# Prontserve: Server-specific functionality
# -------------------------------------------------
class
Prontserve
(
pronsole
.
pronsole
,
EventEmitter
):
def
__init__
(
self
,
**
kwargs
):
self
.
initializing
=
True
self
.
max_w_val
=
0
pronsole
.
pronsole
.
__init__
(
self
)
EventEmitter
.
__init__
(
self
)
self
.
settings
.
sensor_names
=
{
'T'
:
'extruder'
,
'B'
:
'bed'
}
self
.
settings
.
sensor_poll_rate
=
1
# seconds
self
.
p
.
loud
=
kwargs
[
'loud'
]
self
.
dry_run
=
kwargs
[
'dry_run'
]
==
True
self
.
stdout
=
sys
.
stdout
self
.
load_default_rc
()
self
.
p
.
sendcb
=
self
.
sendcb
self
.
initializing
=
False
dir
=
os
.
path
.
dirname
(
__file__
)
self
.
server
=
ConstructServer
(
printer
=
self
,
settings
=
dict
(
pause_between_prints
=
self
.
settings
.
pause_between_prints
,
sensor_poll_rate
=
self
.
settings
.
sensor_poll_rate
*
1000
),
components
=
dict
(
temps
=
[
"e0"
,
"b"
],
fans
=
[
"f0"
],
conveyors
=
[
"c0"
],
axes
=
[]
# In the far off future we may have axes like these for position data:
# axes= ["x", "y", "z"]
),
server_settings
=
dict
(
template_path
=
os
.
path
.
join
(
dir
,
"printrun"
,
"server"
,
"templates"
),
static_path
=
os
.
path
.
join
(
dir
,
"printrun"
,
"server"
,
"static"
),
debug
=
True
),
routes
=
[
(
r"/"
,
RootHandler
),
(
r"/inspect"
,
InspectHandler
)
]
)
def
display_startup_padding
(
self
):
if
self
.
dry_run
:
for
i
in
range
(
0
,
7
):
sys
.
stdout
.
write
(
"
\x1B
[0;33m Dry Run
\x1B
[0m"
)
print
""
def
display_startup_message
(
self
):
welcome
=
textwrap
.
dedent
(
u"""
+---+
\x1B
[0;32mProntserve: Your printer just got a whole lot better.
\x1B
[0m|
\u2713
| Ready to print.
+---+ More details at http://localhost:8888/"""
)
print
"
\n
"
+
"-"
*
80
self
.
display_startup_padding
()
sys
.
stdout
.
write
(
welcome
)
print
"
\n
"
self
.
display_startup_padding
()
print
"-"
*
80
+
"
\n
"
def
start
(
self
):
try
:
if
self
.
dry_run
==
False
:
# Attempt to connect to the printer
self
.
do_connect
(
""
)
if
self
.
p
.
printer
==
None
:
sys
.
exit
(
1
)
print
"Connecting to printer..."
# Wait for the attempt to succeed or timeout
for
x
in
range
(
0
,
50
-
1
):
if
self
.
p
.
online
==
True
:
break
sys
.
stdout
.
write
(
"."
)
sys
.
stdout
.
flush
()
time
.
sleep
(
0.1
)
print
""
if
self
.
p
.
online
==
False
:
print
"Unable to connect to printer: Connection timed-out."
sys
.
exit
(
1
)
# Wait for the printer to finish connecting and then reset it
time
.
sleep
(
2
)
self
.
reset
()
# Start the server, display the startup message and start the ioloop
self
.
server
.
start
()
self
.
display_startup_message
()
self
.
server
.
ioloop
.
start
()
except
Exception
as
ex
:
print
traceback
.
format_exc
()
if
args
.
heaptrace
:
from
guppy
import
hpy
print
hpy
()
.
heap
()
self
.
p
.
disconnect
()
exit
()
def
is_online
(
self
):
return
self
.
p
.
online
==
True
def
is_printing
(
self
):
return
self
.
p
.
printing
==
False
and
self
.
p
.
online
def
post_process_print_job
(
self
,
filename
,
filebody
):
return
FastGCode
(
filebody
.
split
(
"
\n
"
))
def
get_print_job_memory_footprint
(
self
,
filename
,
filebody
):
return
0
# TODO
def
current_print_line
(
self
):
if
(
self
.
p
.
printing
):
return
(
self
.
p
.
queueindex
)
return
0
def
total_print_lines
(
self
,
job_body
):
return
len
(
job_body
)
def
start_print_job
(
self
,
job
):
self
.
p
.
startprint
(
job
[
'body'
])
self
.
p
.
paused
=
False
def
do_home
(
self
,
*
args
,
**
kwargs
):
pronsole
.
pronsole
.
do_home
(
self
,
" "
.
join
(
args
))
def
do_move
(
self
,
**
kwargs
):
# Convert mm/s to mm/minute
if
"at"
in
kwargs
:
speed_multiplier
=
float
(
kwargs
[
'at'
]
.
replace
(
"
%
"
,
""
))
*
0.01
else
:
speed_multiplier
=
1
for
k
,
v
in
kwargs
.
iteritems
():
if
k
==
"at"
:
continue
# Getting the feedrate
if
k
in
[
"z"
,
"e"
]:
prefix
=
k
else
:
prefix
=
"xy"
speed
=
getattr
(
self
.
settings
,
"
%
s_feedrate"
%
prefix
)
*
speed_multiplier
# Creating the pronsole axial move command
args
=
{
"axis"
:
k
,
"dist"
:
v
,
"speed"
:
speed
}
cmd
=
"
%(axis)
s
%(dist)
s
%(speed)
s"
%
args
print
"move
%
s"
%
cmd
pronsole
.
pronsole
.
do_move
(
self
,
cmd
)
def
do_stop_move
(
self
):
raise
Exception
(
"Continuous movement not supported"
)
def
do_estop
(
self
):
self
.
reset
()
print
"Emergency Stop!"
# Not thread safe; must be run from the ioloop thread.
def
reset
(
self
):
self
.
async
(
self
.
server
.
set_blocking_temps
,
[])
# pause the print job if any is printing
if
self
.
p
.
printing
:
pronsole
.
pronsole
.
do_pause
(
self
,
""
)
# Prevent the sensor from polling for 2 seconds while the firmware
# restarts
self
.
server
.
set_reset_timeout
(
time
.
time
()
+
2
)
self
.
server
.
set_sensor_update_received
(
True
)
# restart the firmware
pronsole
.
pronsole
.
do_reset
(
self
,
""
)
self
.
p
.
printing
=
False
def
on_temp_target_change
(
self
,
parent_path
,
component
,
value
):
target
=
parent_path
[
0
]
gcode
=
"M104"
if
target
==
"b"
:
gcode
=
"M140"
if
not
target
in
[
"b"
,
"e0"
]:
gcode
+=
" p
%
i"
%
(
int
(
target
[
1
:]))
gcode
+=
" S
%
f"
%
float
(
value
)
self
.
p
.
send_now
(
gcode
)
def
on_fan_enabled_change
(
self
,
parent_path
,
component
,
value
):
update_fan
(
component
)
def
on_fan_speed_change
(
self
,
parent_path
,
component
,
value
):
update_fan
(
component
)
def
update_fan
(
self
,
component
):
speed
=
int
(
component
[
'speed'
])
if
component
[
'enabled'
]
==
False
:
speed
=
0
print
"M106 S
%
i"
%
speed
self
.
p
.
send_now
(
"M106 S
%
i"
%
speed
)
def
on_motors_enabled_change
(
self
,
parent_path
,
component
,
value
):
self
.
p
.
send_now
({
True
:
"M17"
,
False
:
"M18"
}[
value
])
def
request_sensor_update
(
self
):
if
self
.
dry_run
:
return
self
.
_receive_sensor_update
(
"ok T:
%
i B:
%
i"
%
(
random
.
randint
(
30
,
60
),
random
.
randint
(
30
,
60
))
)
if
self
.
p
.
online
:
self
.
p
.
send_now
(
"M105"
)
def
recvcb
(
self
,
l
):
""" Parses a line of output from the printer via printcore """
l
=
l
.
rstrip
()
#print l
if
self
.
server
.
waiting_to_reach_temp
and
(
"ok"
in
l
):
self
.
async
(
self
.
server
.
set_blocking_temps
,
[])
if
(
"T:"
in
l
):
self
.
async
(
self
.
_receive_sensor_update
,
l
)
if
l
!=
"ok"
and
not
l
.
startswith
(
"ok T"
)
and
not
l
.
startswith
(
"T:"
):
self
.
async
(
self
.
_receive_printer_error
,
l
)
def
sendcb
(
self
,
l
):
# Monitor the sent commands for new extruder target temperatures
if
(
"M109"
in
l
)
or
(
"M104"
in
l
)
or
(
"M140"
in
l
)
or
(
"M190"
in
l
):
temp
=
float
(
re
.
search
(
'S([0-9]+)'
,
l
)
.
group
(
1
))
if
(
"M109"
in
l
)
or
(
"M104"
in
l
):
target
=
"e0"
if
" P"
in
l
:
target
=
"e
%
i"
%
(
int
(
re
.
search
(
' P([0-9]+)'
,
l
)
.
group
(
1
)))
else
:
target
=
"b"
self
.
async
(
self
.
server
.
c_set
,
[
target
,
"target_temp"
],
temp
,
internal
=
True
)
if
(
"M109"
in
l
)
or
(
"M190"
in
l
)
or
(
"M116"
in
l
):
if
(
"M116"
in
l
):
target
=
"e0"
self
.
async
(
self
.
server
.
set_blocking_temps
,
[
target
])
# Adds a callback to the ioloop to run a method later on in the server thread
def
async
(
self
,
*
args
,
**
kwargs
):
self
.
server
.
ioloop
.
add_callback
(
*
args
,
**
kwargs
)
def
_receive_sensor_update
(
self
,
l
):
try
:
self
.
async
(
self
.
server
.
set_sensor_update_received
,
True
)
words
=
filter
(
lambda
s
:
s
.
find
(
":"
)
>
0
,
l
.
lower
()
.
split
(
" "
))
d
=
dict
([
s
.
split
(
":"
)
for
s
in
words
])
for
key
,
value
in
d
.
iteritems
():
if
key
==
"t"
:
key
=
"e0"
if
not
key
in
self
.
server
.
components
:
continue
self
.
server
.
c_set
([
key
,
"current_temp"
],
float
(
value
),
internal
=
True
)
# Fire a event if the extruder is giving us a countdown till it's online
# see: TEMP_RESIDENCY_TIME (via the googles)
# see: https://github.com/ErikZalm/Marlin/blob/Marlin_v1/Marlin/Marlin_main.cpp#L1191
if
(
"w"
in
d
)
and
(
not
d
[
"w"
]
==
"?"
):
w
=
float
(
d
[
"w"
])
*
1000
for
target
in
(
self
.
server
.
blockers
):
self
.
server
.
c_set
([
target
,
"target_temp_countdown"
],
w
,
internal
=
True
)
except
Exception
as
ex
:
print
traceback
.
format_exc
()
def
log
(
self
,
*
msg
):
msg
=
''
.
join
(
str
(
i
)
for
i
in
msg
)
msg
.
replace
(
"
\r
"
,
""
)
print
msg
# self.server.broadcast([
# dict(type= "log", data= dict(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
):
None
def
confirm
(
self
):
True
prontserve.py
100755 → 100644
View file @
d89ac8db
#!/usr/bin/env python
import
glob
,
os
,
time
,
datetime
,
sys
,
codecs
,
random
,
textwrap
,
re
,
traceback
import
logging
,
argparse
,
tornado
.
ioloop
,
printcore
,
pronsole
# Allow construct protocol developers to use a specific lib for dev purposes
c_path
=
os
.
getenv
(
'PY_CONSTRUCT_PATH'
)
if
c_path
!=
None
:
print
"$PY_CONSTRUCT_PATH detected, loading server lib from:
\n
%
s"
%
c_path
sys
.
path
.
insert
(
1
,
c_path
)
from
construct_server.construct_server
import
ConstructServer
from
construct_server.event_emitter
import
EventEmitter
from
pprint
import
pprint
from
printrun
import
gcoder
sys
.
stdout
=
codecs
.
getwriter
(
'utf8'
)(
sys
.
stdout
)
log
=
logging
.
getLogger
(
"root"
)
import
argparse
from
printrun.prontserve
import
Prontserve
# Args
# -------------------------------------------------
...
...
@@ -39,317 +26,6 @@ if __name__ == "__main__":
)
args
=
parser
.
parse_args
()
if
args
.
heaptrace
:
from
guppy
import
hpy
# Routes
# -------------------------------------------------
class
RootHandler
(
tornado
.
web
.
RequestHandler
):
def
get
(
self
):
self
.
render
(
"index.html"
)
class
InspectHandler
(
tornado
.
web
.
RequestHandler
):
def
prepare
(
self
):
construct_auth
(
self
,
None
)
def
get
(
self
):
self
.
render
(
"inspect.html"
)
# Faster GCoder implementation without any parsing
# -------------------------------------------------
class
Line
(
object
):
__slots__
=
(
'raw'
,
'command'
,
'is_move'
)
def
__init__
(
self
,
l
):
self
.
raw
=
l
def
__getattr__
(
self
,
name
):
return
None
class
FastGCode
(
object
):
def
__init__
(
self
,
data
):
self
.
lines
=
[
Line
(
l2
)
for
l2
in
(
l
.
strip
()
for
l
in
data
)
if
l2
]
self
.
all_layers
=
[
self
.
lines
]
def
__len__
(
self
):
return
len
(
self
.
lines
)
def
__iter__
(
self
):
return
self
.
lines
.
__iter__
()
def
idxs
(
self
,
index
):
return
(
0
,
index
)
# Prontserve: Server-specific functionality
# -------------------------------------------------
class
Prontserve
(
pronsole
.
pronsole
,
EventEmitter
):
def
__init__
(
self
,
**
kwargs
):
self
.
initializing
=
True
self
.
max_w_val
=
0
pronsole
.
pronsole
.
__init__
(
self
)
EventEmitter
.
__init__
(
self
)
self
.
settings
.
sensor_names
=
{
'T'
:
'extruder'
,
'B'
:
'bed'
}
self
.
settings
.
sensor_poll_rate
=
1
# seconds
self
.
p
.
loud
=
kwargs
[
'loud'
]
self
.
dry_run
=
kwargs
[
'dry_run'
]
==
True
self
.
stdout
=
sys
.
stdout
self
.
load_default_rc
()
self
.
p
.
sendcb
=
self
.
sendcb
self
.
initializing
=
False
dir
=
os
.
path
.
dirname
(
__file__
)
self
.
server
=
ConstructServer
(
printer
=
self
,
settings
=
dict
(
pause_between_prints
=
self
.
settings
.
pause_between_prints
,
sensor_poll_rate
=
self
.
settings
.
sensor_poll_rate
*
1000
),
components
=
dict
(
temps
=
[
"e0"
,
"b"
],
fans
=
[
"f0"
],
conveyors
=
[
"c0"
],
axes
=
[]
# In the far off future we may have axes like these for position data:
# axes= ["x", "y", "z"]
),
server_settings
=
dict
(
template_path
=
os
.
path
.
join
(
dir
,
"printrun"
,
"server"
,
"templates"
),
static_path
=
os
.
path
.
join
(
dir
,
"printrun"
,
"server"
,
"static"
),
debug
=
True
),
routes
=
[
(
r"/"
,
RootHandler
),
(
r"/inspect"
,
InspectHandler
)
]
)
def
display_startup_padding
(
self
):
if
self
.
dry_run
:
for
i
in
range
(
0
,
7
):
sys
.
stdout
.
write
(
"
\x1B
[0;33m Dry Run
\x1B
[0m"
)
print
""
def
display_startup_message
(
self
):
welcome
=
textwrap
.
dedent
(
u"""
+---+
\x1B
[0;32mProntserve: Your printer just got a whole lot better.
\x1B
[0m|
\u2713
| Ready to print.
+---+ More details at http://localhost:8888/"""
)
print
"
\n
"
+
"-"
*
80
self
.
display_startup_padding
()
sys
.
stdout
.
write
(
welcome
)
print
"
\n
"
self
.
display_startup_padding
()
print
"-"
*
80
+
"
\n
"
def
start
(
self
):
try
:
if
self
.
dry_run
==
False
:
# Attempt to connect to the printer
self
.
do_connect
(
""
)
if
self
.
p
.
printer
==
None
:
sys
.
exit
(
1
)
print
"Connecting to printer..."
# Wait for the attempt to succeed or timeout
for
x
in
range
(
0
,
50
-
1
):
if
self
.
p
.
online
==
True
:
break
sys
.
stdout
.
write
(
"."
)
sys
.
stdout
.
flush
()
time
.
sleep
(
0.1
)
print
""
if
self
.
p
.
online
==
False
:
print
"Unable to connect to printer: Connection timed-out."
sys
.
exit
(
1
)
# Wait for the printer to finish connecting and then reset it
time
.
sleep
(
2
)
self
.
reset
()
# Start the server, display the startup message and start the ioloop
self
.
server
.
start
()
self
.
display_startup_message
()
self
.
server
.
ioloop
.
start
()
except
Exception
as
ex
:
print
traceback
.
format_exc
()
if
args
.
heaptrace
:
print
hpy
()
.
heap
()
self
.
p
.
disconnect
()
exit
()
def
is_online
(
self
):
return
self
.
p
.
online
==
True
def
is_printing
(
self
):
return
self
.
p
.
printing
==
False
and
self
.
p
.
online
def
post_process_print_job
(
self
,
filename
,
filebody
):
return
FastGCode
(
filebody
.
split
(
"
\n
"
))
def
get_print_job_memory_footprint
(
self
,
filename
,
filebody
):
return
0
# TODO
def
current_print_line
(
self
):
if
(
self
.
p
.
printing
):
return
(
self
.
p
.
queueindex
)
return
0
def
total_print_lines
(
self
,
job_body
):
return
len
(
job_body
)
def
start_print_job
(
self
,
job
):
self
.
p
.
startprint
(
job
[
'body'
])
self
.
p
.
paused
=
False
def
do_home
(
self
,
*
args
,
**
kwargs
):
pronsole
.
pronsole
.
do_home
(
self
,
" "
.
join
(
args
))
def
do_move
(
self
,
**
kwargs
):
# Convert mm/s to mm/minute
if
"at"
in
kwargs
:
speed_multiplier
=
float
(
kwargs
[
'at'
]
.
replace
(
"
%
"
,
""
))
*
0.01
else
:
speed_multiplier
=
1
for
k
,
v
in
kwargs
.
iteritems
():
if
k
==
"at"
:
continue
# Getting the feedrate
if
k
in
[
"z"
,
"e"
]:
prefix
=
k
else
:
prefix
=
"xy"
speed
=
getattr
(
self
.
settings
,
"
%
s_feedrate"
%
prefix
)
*
speed_multiplier
# Creating the pronsole axial move command
args
=
{
"axis"
:
k
,
"dist"
:
v
,
"speed"
:
speed
}
cmd
=
"
%(axis)
s
%(dist)
s
%(speed)
s"
%
args
print
"move
%
s"
%
cmd
pronsole
.
pronsole
.
do_move
(
self
,
cmd
)
def
do_stop_move
(
self
):
raise
Exception
(
"Continuous movement not supported"
)
def
do_estop
(
self
):
self
.
reset
()
print
"Emergency Stop!"
# Not thread safe; must be run from the ioloop thread.
def
reset
(
self
):
self
.
async
(
self
.
server
.
set_blocking_temps
,
[])
# pause the print job if any is printing
if
self
.
p
.
printing
:
pronsole
.
pronsole
.
do_pause
(
self
,
""
)
# Prevent the sensor from polling for 2 seconds while the firmware
# restarts
self
.
server
.
set_reset_timeout
(
time
.
time
()
+
2
)
self
.
server
.
set_sensor_update_received
(
True
)
# restart the firmware
pronsole
.
pronsole
.
do_reset
(
self
,
""
)
self
.
p
.
printing
=
False
def
on_temp_target_change
(
self
,
parent_path
,
component
,
value
):
target
=
parent_path
[
0
]
gcode
=
"M104"
if
target
==
"b"
:
gcode
=
"M140"
if
not
target
in
[
"b"
,
"e0"
]:
gcode
+=
" p
%
i"
%
(
int
(
target
[
1
:]))
gcode
+=
" S
%
f"
%
float
(
value
)
self
.
p
.
send_now
(
gcode
)
def
on_fan_enabled_change
(
self
,
parent_path
,
component
,
value
):
update_fan
(
component
)
def
on_fan_speed_change
(
self
,
parent_path
,
component
,
value
):
update_fan
(
component
)
def
update_fan
(
self
,
component
):
speed
=
int
(
component
[
'speed'
])
if
component
[
'enabled'
]
==
False
:
speed
=
0
print
"M106 S
%
i"
%
speed
self
.
p
.
send_now
(
"M106 S
%
i"
%
speed
)
def
on_motors_enabled_change
(
self
,
parent_path
,
component
,
value
):
self
.
p
.
send_now
({
True
:
"M17"
,
False
:
"M18"
}[
value
])
def
request_sensor_update
(
self
):
if
self
.
dry_run
:
return
self
.
_receive_sensor_update
(
"ok T:
%
i B:
%
i"
%
(
random
.
randint
(
30
,
60
),
random
.
randint
(
30
,
60
))
)
if
self
.
p
.
online
:
self
.
p
.
send_now
(
"M105"
)
def
recvcb
(
self
,
l
):
""" Parses a line of output from the printer via printcore """
l
=
l
.
rstrip
()
#print l
if
self
.
server
.
waiting_to_reach_temp
and
(
"ok"
in
l
):
self
.
async
(
self
.
server
.
set_blocking_temps
,
[])
if
(
"T:"
in
l
):
self
.
async
(
self
.
_receive_sensor_update
,
l
)
if
l
!=
"ok"
and
not
l
.
startswith
(
"ok T"
)
and
not
l
.
startswith
(
"T:"
):
self
.
async
(
self
.
_receive_printer_error
,
l
)
def
sendcb
(
self
,
l
):
# Monitor the sent commands for new extruder target temperatures
if
(
"M109"
in
l
)
or
(
"M104"
in
l
)
or
(
"M140"
in
l
)
or
(
"M190"
in
l
):
temp
=
float
(
re
.
search
(
'S([0-9]+)'
,
l
)
.
group
(
1
))
if
(
"M109"
in
l
)
or
(
"M104"
in
l
):
target
=
"e0"
if
" P"
in
l
:
target
=
"e
%
i"
%
(
int
(
re
.
search
(
' P([0-9]+)'
,
l
)
.
group
(
1
)))
else
:
target
=
"b"
self
.
async
(
self
.
server
.
c_set
,
[
target
,
"target_temp"
],
temp
,
internal
=
True
)
if
(
"M109"
in
l
)
or
(
"M190"
in
l
)
or
(
"M116"
in
l
):
if
(
"M116"
in
l
):
target
=
"e0"
self
.
async
(
self
.
server
.
set_blocking_temps
,
[
target
])
# Adds a callback to the ioloop to run a method later on in the server thread
def
async
(
self
,
*
args
,
**
kwargs
):
self
.
server
.
ioloop
.
add_callback
(
*
args
,
**
kwargs
)
def
_receive_sensor_update
(
self
,
l
):
try
:
self
.
async
(
self
.
server
.
set_sensor_update_received
,
True
)
words
=
filter
(
lambda
s
:
s
.
find
(
":"
)
>
0
,
l
.
lower
()
.
split
(
" "
))
d
=
dict
([
s
.
split
(
":"
)
for
s
in
words
])
for
key
,
value
in
d
.
iteritems
():
if
key
==
"t"
:
key
=
"e0"
if
not
key
in
self
.
server
.
components
:
continue
self
.
server
.
c_set
([
key
,
"current_temp"
],
float
(
value
),
internal
=
True
)
# Fire a event if the extruder is giving us a countdown till it's online
# see: TEMP_RESIDENCY_TIME (via the googles)
# see: https://github.com/ErikZalm/Marlin/blob/Marlin_v1/Marlin/Marlin_main.cpp#L1191
if
(
"w"
in
d
)
and
(
not
d
[
"w"
]
==
"?"
):
w
=
float
(
d
[
"w"
])
*
1000
for
target
in
(
self
.
server
.
blockers
):
self
.
server
.
c_set
([
target
,
"target_temp_countdown"
],
w
,
internal
=
True
)
except
Exception
as
ex
:
print
traceback
.
format_exc
()
def
log
(
self
,
*
msg
):
msg
=
''
.
join
(
str
(
i
)
for
i
in
msg
)
msg
.
replace
(
"
\r
"
,
""
)
print
msg
# self.server.broadcast([
# dict(type= "log", data= dict(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
):
None
def
confirm
(
self
):
True
# Server Start Up
# -------------------------------------------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment