Finalized decoupling of timelapse from printer module, made sure timelapse is properly unregistered from eventbus on change

master
Gina Häußge 2013-06-16 22:42:18 +02:00
parent 236e26979f
commit 0e56952913
3 changed files with 57 additions and 37 deletions

View File

@ -73,9 +73,6 @@ class Printer():
self._selectedFile = None
# timelapse
self._timelapse = None
# comm
self._comm = None
@ -215,15 +212,6 @@ class Printer():
self._gcodeManager.printFailed(self._selectedFile["filename"])
eventManager().fire("PrintFailed", self._filename)
def setTimelapse(self, timelapse):
if self._timelapse is not None and self.isPrinting():
self._timelapse.stopTimelapse()
del self._timelapse
self._timelapse = timelapse
def getTimelapse(self):
return self._timelapse
#~~ state monitoring
def _setCurrentZ(self, currentZ):

View File

@ -15,7 +15,7 @@ import subprocess
from octoprint.printer import Printer, getConnectionOptions
from octoprint.settings import settings, valid_boolean_trues
import octoprint.timelapse as timelapse
import octoprint.timelapse
import octoprint.gcodefiles as gcodefiles
import octoprint.util as util
import octoprint.users as users
@ -28,7 +28,9 @@ BASEURL = "/ajax/"
app = Flask("octoprint")
# Only instantiated by the Server().run() method
# In order that threads don't start too early when running as a Daemon
printer = None
printer = None
timelapse = None
gcodeManager = None
userManager = None
eventManager = None
@ -60,8 +62,8 @@ class PrinterStateConnection(tornadio2.SocketConnection):
def on_open(self, info):
self._logger.info("New connection from client")
# Use of global here is smelly
printer.registerCallback(self)
gcodeManager.registerCallback(self)
self._printer.registerCallback(self)
self._gcodeManager.registerCallback(self)
self._eventManager.fire("ClientOpened")
self._eventManager.subscribe("MovieDone", self._onMovieDone)
@ -69,8 +71,8 @@ class PrinterStateConnection(tornadio2.SocketConnection):
def on_close(self):
self._logger.info("Closed client connection")
# Use of global here is smelly
printer.unregisterCallback(self)
gcodeManager.unregisterCallback(self)
self._printer.unregisterCallback(self)
self._gcodeManager.unregisterCallback(self)
self._eventManager.fire("ClientClosed")
self._eventManager.unsubscribe("MovieDone", self._onMovieDone)
@ -352,19 +354,19 @@ def refreshFiles():
@app.route(BASEURL + "timelapse", methods=["GET"])
def getTimelapseData():
lapse = printer.getTimelapse()
global timelapse
type = "off"
additionalConfig = {}
if lapse is not None and isinstance(lapse, timelapse.ZTimelapse):
if timelapse is not None and isinstance(timelapse, octoprint.timelapse.ZTimelapse):
type = "zchange"
elif lapse is not None and isinstance(lapse, timelapse.TimedTimelapse):
elif timelapse is not None and isinstance(timelapse, octoprint.timelapse.TimedTimelapse):
type = "timed"
additionalConfig = {
"interval": lapse.interval()
"interval": timelapse.interval()
}
files = timelapse.getFinishedTimelapses()
files = octoprint.timelapse.getFinishedTimelapses()
for file in files:
file["url"] = url_for("downloadTimelapse", filename=file["name"])
@ -391,11 +393,17 @@ def deleteTimelapse(filename):
@app.route(BASEURL + "timelapse", methods=["POST"])
@login_required
def setTimelapseConfig():
global timelapse
if request.values.has_key("type"):
type = request.values["type"]
lapse = None
if type in ["zchange", "timed"]:
# valid timelapse type, check if there is an old one we need to stop first
if timelapse is not None:
timelapse.unload()
timelapse = None
if "zchange" == type:
lapse = timelapse.ZTimelapse()
timelapse = octoprint.timelapse.ZTimelapse()
elif "timed" == type:
interval = 10
if request.values.has_key("interval"):
@ -403,8 +411,7 @@ def setTimelapseConfig():
interval = int(request.values["interval"])
except ValueError:
pass
lapse = timelapse.TimedTimelapse(interval)
printer.setTimelapse(lapse)
timelapse = octoprint.timelapse.TimedTimelapse(interval)
return getTimelapseData()
@ -802,6 +809,12 @@ class Server():
}
},
"loggers": {
#"octoprint.timelapse": {
# "level": "DEBUG"
#},
#"octoprint.events": {
# "level": "DEBUG"
#}
},
"root": {
"level": "INFO",

View File

@ -47,10 +47,23 @@ class Timelapse(object):
self._renderThread = None
self._captureMutex = threading.Lock()
# subscribe events
eventManager().subscribe("PrintStarted", self.onPrintStarted)
eventManager().subscribe("PrintFailed", self.onPrintDone)
eventManager().subscribe("PrintDone", self.onPrintDone)
self.subscribeToEvents()
for (event, callback) in self.eventSubscriptions():
eventManager().subscribe(event, callback)
def unload(self):
if self._inTimelapse:
self.stopTimelapse(doCreateMovie=False)
# unsubscribe events
eventManager().unsubscribe("PrintStarted", self.onPrintStarted)
eventManager().unsubscribe("PrintFailed", self.onPrintDone)
eventManager().unsubscribe("PrintDone", self.onPrintDone)
for (event, callback) in self.eventSubscriptions():
eventManager().unsubscribe(event, callback)
def onPrintStarted(self, event, payload):
"""
@ -64,14 +77,16 @@ class Timelapse(object):
"""
self.stopTimelapse()
def subscribeToEvents(self):
def eventSubscriptions(self):
"""
Override this method to subscribe to additional events. Events that are already subscribed:
Override this method to subscribe to additional events by returning an array of (event, callback) tuples.
Events that are already subscribed:
* PrintStarted - self.onPrintStarted
* PrintFailed - self.onPrintDone
* PrintDone - self.onPrintDone
"""
pass
return []
def startTimelapse(self, gcodeFile):
self._logger.debug("Starting timelapse for %s" % gcodeFile)
@ -81,11 +96,13 @@ class Timelapse(object):
self._inTimelapse = True
self._gcodeFile = os.path.basename(gcodeFile)
def stopTimelapse(self):
def stopTimelapse(self, doCreateMovie=True):
self._logger.debug("Stopping timelapse")
self._renderThread = threading.Thread(target=self._createMovie)
self._renderThread.daemon = True
self._renderThread.start()
if doCreateMovie:
self._renderThread = threading.Thread(target=self._createMovie)
self._renderThread.daemon = True
self._renderThread.start()
self._imageNumber = None
self._inTimelapse = False
@ -157,8 +174,10 @@ class ZTimelapse(Timelapse):
Timelapse.__init__(self)
self._logger.debug("ZTimelapse initialized")
def subscribeToEvents(self):
eventManager().subscribe("ZChange", self._onZChange)
def eventSubscriptions(self):
return [
("ZChange", self._onZChange)
]
def _onZChange(self, event, payload):
self.captureImage()