def register():
    """ Register plugins.
    """
    PluginsManager().register(PanoduinoAxis,
                              PanoduinoAxisController,
                              capacity='yawAxis',
                              name=NAME)
    PluginsManager().register(PanoduinoAxis,
                              PanoduinoAxisController,
                              capacity='pitchAxis',
                              name=NAME)
    PluginsManager().register(PanoduinoShutter,
                              PanoduinoShutterController,
                              capacity='shutter',
                              name=NAME)
Beispiel #2
0
def register():
    """ Register plugins.
    """
    PluginsManager().register(SimulationAxis,
                              SimulationAxisController,
                              capacity='yawAxis',
                              name=NAME)
    PluginsManager().register(SimulationAxis,
                              SimulationAxisController,
                              capacity='pitchAxis',
                              name=NAME)
    PluginsManager().register(SimulationShutter,
                              SimulationShutterController,
                              capacity='shutter',
                              name=NAME)
Beispiel #3
0
def register():
    """ Register plugins.
    """
    PluginsManager().register(GigaPanBotAxis,
                              GigaPanBotAxisController,
                              capacity='yawAxis',
                              name=NAME)
    PluginsManager().register(GigaPanBotAxis,
                              GigaPanBotAxisController,
                              capacity='pitchAxis',
                              name=NAME)
    PluginsManager().register(GigaPanBotShutter,
                              GigaPanBotShutterController,
                              capacity='shutter',
                              name=NAME)
Beispiel #4
0
def register():
    """ Register plugins.
    """
    PluginsManager().register(OwlAxis,
                              OwlAxisController,
                              capacity='yawAxis',
                              name=NAME)
    PluginsManager().register(OwlAxis,
                              OwlAxisController,
                              capacity='pitchAxis',
                              name=NAME)
    PluginsManager().register(OwlShutter,
                              OwlShutterController,
                              capacity='shutter',
                              name=NAME)
def register():
    """ Register plugins.
    """
    PluginsManager().register(GenericTetheredShutter,
                              GenericTetheredShutterController,
                              capacity='shutter',
                              name=NAME)
Beispiel #6
0
def register():
    """ Register plugins.
    """
    PluginsManager().register(TimelordShutter,
                              TimelordShutterController,
                              capacity='shutter',
                              name=NAME)
def register():
    """ Register plugins.
    """
    PluginsManager().register(NkRemoteShutter,
                              NkRemoteShutterController,
                              capacity='shutter',
                              name=NAME)
def register():
    """ Register plugins.
    """
    PluginsManager().register(GphotoBracketShutter,
                              GphotoBracketShutterController,
                              capacity='shutter',
                              name=NAME)
Beispiel #9
0
 def __onShutterConfigurePushButtonClicked(self):
     """ Shutter plugin configure push button clicked.
     """
     selectedPluginName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
     model, controllerClass = PluginsManager ().get('shutter', selectedPluginName)
     controller = controllerClass(self, model)
     controller.exec_()
Beispiel #10
0
 def __onPitchAxisConfigurePushButtonClicked(self):
     """ Pitch axis plugin configure push button clicked.
     """
     selectedPluginName = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
     model, controllerClass = PluginsManager ().get('pitchAxis', selectedPluginName)
     controller = controllerClass(self, model)
     controller.exec_()
def register():
    """ Register plugins.
    """
    PluginsManager().register(UrsaMinorBt2Shutter,
                              UrsaMinorBt2ShutterController,
                              capacity='shutter',
                              name=NAME)
Beispiel #12
0
def register():
    """ Register plugins.
    """
    PluginsManager().register(EOSUtilityShutter,
                              EOSUtilityShutterController,
                              capacity='shutter',
                              name=NAME)
 def __onShutterComboBoxActivated(self, pluginName):
     """ Shutter combo box.
     """
     Logger().debug("PluginsController.__onShutterComboBoxActivated(): plugin=%s" % pluginName)
     model, controllerClass = PluginsManager ().get('shutter', pluginName)
     if hasattr(model, '_driver'):
         self._view.shutterDriverComboBox.setEnabled(True)
         self._view.shutterDriverComboBox.setCurrentIndex(self._view.shutterDriverComboBox.findText(model._config['DRIVER_TYPE']))
     else:
         self._view.shutterDriverComboBox.setEnabled(False)
    def _onAccepted(self):
        """ Ok button has been clicked.

        Save back values to model.
        """
        Logger().trace("PluginsController._onAccepted()")

        # Plugins tab
        previousPluginName = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
        ConfigManager().set('Plugins/PLUGIN_YAW_AXIS', unicode(self._view.yawAxisComboBox.currentText()))
        newPluginName = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
        newPlugin = PluginsManager().get('yawAxis', newPluginName)[0]
        if previousPluginName != newPluginName:
            previousPlugin = PluginsManager ().get('yawAxis', previousPluginName)[0]
            previousPlugin.deactivate()
            newPlugin.activate()
        if hasattr(newPlugin, '_driver'):
            newPlugin._config['DRIVER_TYPE'] = config.DRIVER_INDEX[self._view.yawAxisDriverComboBox.currentIndex()]
        # todo: set config in a callback
        newPlugin._saveConfig()

        previousPluginName = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
        ConfigManager().set('Plugins/PLUGIN_PITCH_AXIS', unicode(self._view.pitchAxisComboBox.currentText()))
        newPluginName = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
        newPlugin = PluginsManager().get('pitchAxis', newPluginName)[0]
        if previousPluginName != newPluginName:
            previousPlugin = PluginsManager ().get('pitchAxis', previousPluginName)[0]
            previousPlugin.deactivate()
            newPlugin.activate()
        if hasattr(newPlugin, '_driver'):
            newPlugin._config['DRIVER_TYPE'] = config.DRIVER_INDEX[self._view.pitchAxisDriverComboBox.currentIndex()]
        # todo: set config in a callback
        newPlugin._saveConfig()

        previousPluginName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
        ConfigManager().set('Plugins/PLUGIN_SHUTTER', unicode(self._view.shutterComboBox.currentText()))
        newPluginName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
        newPlugin = PluginsManager().get('shutter', newPluginName)[0]
        if previousPluginName != newPluginName:
            previousPlugin = PluginsManager ().get('shutter', previousPluginName)[0]
            previousPlugin.deactivate()
            newPlugin.activate()
        if hasattr(newPlugin, '_driver'):
            newPlugin._config['DRIVER_TYPE'] = config.DRIVER_INDEX[self._view.shutterDriverComboBox.currentIndex()]
        # todo: set config in a callback
        newPlugin._saveConfig()

        # Drivers tab
        ConfigManager().set('Plugins/HARDWARE_BLUETOOTH_DEVICE_ADDRESS', unicode(self._view.bluetoothDeviceAddressLineEdit.text()))
        ConfigManager().set('Plugins/HARDWARE_SERIAL_PORT', unicode(self._view.serialPortLineEdit.text()))
        ConfigManager().setInt('Plugins/HARDWARE_SERIAL_BAUDRATE', config.SERIAL_BAUDRATE_INDEX[self._view.serialBaudrateComboBox.currentIndex()])
        ConfigManager().set('Plugins/HARDWARE_ETHERNET_HOST', unicode(self._view.ethernetHostLineEdit.text()))
        ConfigManager().setInt('Plugins/HARDWARE_ETHERNET_PORT', self._view.ethernetPortSpinBox.value())

        # Communication tab
        ConfigManager().setFloat('Plugins/HARDWARE_COM_TIMEOUT', self._view.comTimeoutDoubleSpinBox.value(), 1)
        ConfigManager().setInt('Plugins/HARDWARE_COM_RETRY', self._view.comRetrySpinBox.value())

        ConfigManager().save()
    def refreshView(self):

        # Plugins tab
        yawAxisPlugins = PluginsManager ().getList('yawAxis')
        if yawAxisPlugins:
            for model, controller in yawAxisPlugins:
                self._view.yawAxisComboBox.addItem(model.name)
            selectedPluginName = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
            self._view.yawAxisComboBox.setCurrentIndex(self._view.yawAxisComboBox.findText(selectedPluginName))
            selectedPlugin = PluginsManager().get('yawAxis', selectedPluginName)[0]
            if hasattr(selectedPlugin, '_driver'):
                self._view.yawAxisDriverComboBox.setEnabled(True)
                driverType = selectedPlugin._config['DRIVER_TYPE']
                self._view.yawAxisDriverComboBox.setCurrentIndex(config.DRIVER_INDEX[driverType])
            else:
                self._view.yawAxisDriverComboBox.setEnabled(False)
                #self._view.yawAxisDriverComboBox.setCurrentIndex(-1)

        pitchAxisPlugins = PluginsManager ().getList('pitchAxis')
        if pitchAxisPlugins:
            for model, controller in pitchAxisPlugins:
                self._view.pitchAxisComboBox.addItem(model.name)
            selectedPluginName = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
            self._view.pitchAxisComboBox.setCurrentIndex(self._view.pitchAxisComboBox.findText(selectedPluginName))
            selectedPlugin = PluginsManager ().get('pitchAxis', selectedPluginName)[0]
            if hasattr(selectedPlugin, '_driver'):
                self._view.pitchAxisDriverComboBox.setEnabled(True)
                driverType = selectedPlugin._config['DRIVER_TYPE']
                self._view.pitchAxisDriverComboBox.setCurrentIndex(config.DRIVER_INDEX[driverType])
            else:
                self._view.pitchAxisDriverComboBox.setEnabled(False)
                #self._view.pitchAxisDriverComboBox.setCurrentIndex(-1)

        shutterPlugins = PluginsManager ().getList('shutter')
        if shutterPlugins:
            for model, controller in shutterPlugins:
                self._view.shutterComboBox.addItem(model.name)
            selectedPluginName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
            self._view.shutterComboBox.setCurrentIndex(self._view.shutterComboBox.findText(selectedPluginName))
            selectedPlugin = PluginsManager ().get('shutter', selectedPluginName)[0]
            if hasattr(selectedPlugin, '_driver'):
                self._view.shutterDriverComboBox.setEnabled(True)
                driverType = selectedPlugin._config['DRIVER_TYPE']
                self._view.shutterDriverComboBox.setCurrentIndex(config.DRIVER_INDEX[driverType])
            else:
                self._view.shutterDriverComboBox.setEnabled(False)
                #self._view.shutterDriverComboBox.setCurrentIndex(-1)

        # Drivers tab
        self._view.bluetoothDeviceAddressLineEdit.setText(ConfigManager().get('Plugins/HARDWARE_BLUETOOTH_DEVICE_ADDRESS'))
        self._view.serialPortLineEdit.setText(ConfigManager().get('Plugins/HARDWARE_SERIAL_PORT'))
        self._view.serialBaudrateComboBox.setCurrentIndex(config.SERIAL_BAUDRATE_INDEX[ConfigManager().getInt('Plugins/HARDWARE_SERIAL_BAUDRATE')])
        self._view.ethernetHostLineEdit.setText(ConfigManager().get('Plugins/HARDWARE_ETHERNET_HOST'))
        self._view.ethernetPortSpinBox.setValue(ConfigManager().getInt('Plugins/HARDWARE_ETHERNET_PORT'))

        # Communication tab
        self._view.comTimeoutDoubleSpinBox.setValue(ConfigManager().getFloat('Plugins/HARDWARE_COM_TIMEOUT'))
        self._view.comRetrySpinBox.setValue(ConfigManager().getInt('Plugins/HARDWARE_COM_RETRY'))
Beispiel #16
0
    def stop(self, pluginsStatus):
        """ Stop connection.
        """

        # Stop 'yawAxis' plugin connection
        pluginName = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
        plugin = PluginsManager ().get('yawAxis', pluginName)[0]
        if pluginsStatus['yawAxis']['init']:
            Logger().debug("PluginsConnector.start(): 'yawAxis' shutdown")
            try:
                plugin.shutdown()
            except:
                Logger().exception("MainController.__stopConnection()")
            else:
                pluginsStatus['yawAxis']['init'] = False
        if pluginsStatus['yawAxis']['connect']:
            Logger().debug("PluginsConnector.start(): 'yawAxis' stop connection")
            try:
                plugin.stopConnection()
            except:
                Logger().exception("MainController.__stopConnection()")
            else:
                pluginsStatus['yawAxis']['connect'] = False

        # Stop 'pitchAxis' plugin connection
        pluginName = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
        plugin = PluginsManager ().get('pitchAxis', pluginName)[0]
        if pluginsStatus['pitchAxis']['init']:
            Logger().debug("PluginsConnector.start(): 'pitchAxis' shutdown")
            try:
                plugin.shutdown()
            except:
                Logger().exception("MainController.__stopConnection()")
            else:
                pluginsStatus['pitchAxis']['init'] = False
        if pluginsStatus['pitchAxis']['connect']:
            Logger().debug("PluginsConnector.start(): 'pitchAxis' stop connection")
            try:
                plugin.stopConnection()
            except:
                Logger().exception("MainController.__stopConnection()")
            else:
                pluginsStatus['pitchAxis']['connect'] = False

        # Stop 'shutter' plugin connection
        pluginName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
        plugin = PluginsManager ().get('shutter', pluginName)[0]
        if pluginsStatus['shutter']['init']:
            Logger().debug("PluginsConnector.start(): 'shutter' shutdown")
            try:
                plugin.shutdown()
            except:
                Logger().exception("MainController.__stopConnection()")
            else:
                pluginsStatus['shutter']['init'] = False
        if pluginsStatus['shutter']['connect']:
            Logger().debug("PluginsConnector.start(): 'shutter' stop connection")
            try:
                plugin.stopConnection()
            except:
                Logger().exception("MainController.__stopConnection()")
            else:
                pluginsStatus['shutter']['connect'] = False

        return pluginsStatus
Beispiel #17
0
 def __getYawAxis(self):
     """
     """
     yawAxisPlugin = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
     return PluginsManager().get('yawAxis',
                                 yawAxisPlugin)[0]  # Use getModel()?
Beispiel #18
0
 def __getPitchAxis(self):
     """
     """
     pitchAxisPlugin = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
     return PluginsManager().get('pitchAxis', pitchAxisPlugin)[0]
Beispiel #19
0
def main():
    try:
        # Give a name to the main trhead
        threading.currentThread().setName("Main")

        # Init the logger
        if hasattr(sys, "frozen"):

            # Forbid all console outputs
            sys.stderr = BlackHole()
            Logger(defaultStreamHandler=False)
        else:
            Logger()

        # Create the buffer for GUI log
        logStream = LogBuffer()
        Logger().addStreamHandler(logStream, QSpaceColorFormatter)

        Logger().info("Starting Papywizard...")

        # Misc infos
        Logger().debug("main(): platform=%s" % config.platform)

        # Init global Qt application
        qtApp = QtGui.QApplication(sys.argv)
        qtApp.setApplicationName("Papywizard")
        qtApp.setApplicationVersion(config.VERSION)

        # Create the splashscreen
        from papywizard.common import pixmaps
        pixmap = QtGui.QPixmap()
        pixmap.load(":/pixmaps/%s" % config.SPLASHCREEN_FILE)
        splash = QtGui.QSplashScreen(pixmap, QtCore.Qt.WindowStaysOnTopHint)
        splash.show()
        qtApp.processEvents()

        # Addtional imports
        Logger().info("Importing modules...")
        splash.showMessage("Importing modules...")
        qtApp.processEvents()
        from papywizard.common import i18n
        from papywizard.common.configManager import ConfigManager
        #from papywizard.common.publisher import Publisher
        from papywizard.model.shooting import Shooting
        from papywizard.controller.mainController import MainController
        from papywizard.controller.spy import Spy
        from papywizard.view import icons

        # i18n stuff
        Logger().info("Loading i18n files...")
        splash.showMessage("Loading i18n files...")
        qtApp.processEvents()
        locale = QtCore.QLocale.system().name()
        Logger().debug("main(): locale=%s" % locale)
        qtTranslator = QtCore.QTranslator()
        if qtTranslator.load(
                "qt_%s" % locale,
                QtCore.QLibraryInfo.location(
                    QtCore.QLibraryInfo.TranslationsPath)):
            qtApp.installTranslator(qtTranslator)
        else:
            Logger().warning("Can't find qt translation file")
        appTranslator = QtCore.QTranslator()
        if appTranslator.load("papywizard_%s" % locale, ":/i18n"):
            qtApp.installTranslator(appTranslator)
        else:
            Logger().warning("Can't find papywizard translation file")

        # Load Qt stylesheet
        Logger().info("Loading Style Sheets...")
        splash.showMessage("Loading Style Sheets...")
        qtApp.processEvents()
        try:
            styleSheet = file(config.USER_STYLESHEET_FILE)
            qtApp.setStyleSheet(styleSheet.read())
            styleSheet.close()
        except IOError:
            Logger().warning("No user Style Sheet found")
        styleSheet = qtApp.styleSheet()
        if styleSheet:
            if styleSheet.startsWith("file://"):
                Logger().debug("Style Sheet loaded from command line param.")
            else:
                Logger().debug("User Style Sheet loaded")

        # Load user configuration
        Logger().info("Loading configuration...")
        splash.showMessage("Loading configuration...")
        qtApp.processEvents()
        ConfigManager().load()

        # Load plugins (move to shooting?)
        Logger().info("Load plugins...")
        splash.showMessage("Load plugins...")
        from papywizard.plugins.dslrRemoteProPlugins import register
        register()
        from papywizard.plugins.eosUtilityPlugins import register
        register()
        from papywizard.plugins.genericTetheredPlugins import register
        register()
        from papywizard.plugins.gigaPanBotPlugins import register
        register()
        from papywizard.plugins.gphotoBracketPlugins import register
        register()
        from papywizard.plugins.merlinOrionPlugins import register
        register()
        from papywizard.plugins.nkRemotePlugins import register
        register()
        from papywizard.plugins.panoduinoPlugins import register
        register()
        from papywizard.plugins.pixOrbPlugins import register
        register()
        from papywizard.plugins.simulationPlugins import register
        register()
        from papywizard.plugins.timelordPlugins import register
        register()
        from papywizard.plugins.ursaMinorBt2Plugins import register
        register()
        from papywizard.plugins.ursaMinorUsbPlugins import register
        register()
        from papywizard.plugins.claussPlugins import register
        register()
        from papywizard.plugins.owlPlugins import register
        register()
        PluginsManager().load()

        # Activate selected plugins (move to PluginsManager ?)
        Logger().info("Activate plugins...")
        plugin = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
        PluginsManager().get('yawAxis', plugin)[0].activate()
        plugin = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
        PluginsManager().get('pitchAxis', plugin)[0].activate()
        plugin = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
        PluginsManager().get('shutter', plugin)[0].activate()

        # Create model
        Logger().info("Creating model...")
        splash.showMessage("Creating model...")
        qtApp.processEvents()
        model = Shooting()

        # Create spy thread
        Logger().info("Starting Spy...")
        Spy(model).start()

        # Create main controller
        Logger().info("Creating GUI...")
        splash.showMessage("Creating GUI...")
        qtApp.processEvents()
        mainController = MainController(model, logStream)

        # Set user logger level
        Logger().setLevel(ConfigManager().get('Configuration/LOGGER_LEVEL'))

        # Terminate splashscreen
        splash.finish(mainController._view)

        # Check if teh configuration is set
        if not ConfigManager().isConfigured():
            from papywizard.view.messageDialog import InfoMessageDialog
            #dialog = WarningMessageDialog(QtCore.QObject().tr("Configuration"),
            #QtCore.QObject().tr("Papywizard needs to be configured"))
            dialog = InfoMessageDialog(QtGui.QApplication.translate("main", "Plugins selection"),
                                       QtGui.QApplication.translate("main", "Before you can use Papywizard, you must choose what " \
                                                                    "plugins to use to control your hardware.\n\n" \
                                                                    "After closing this dialog, you will be prompt to select " \
                                                                    "these plugins. Once it is done, you can configure them "
                                                                    "in the global Configuration dialog"))
            dialog.exec_()
            from papywizard.controller.pluginsController import PluginsController
            controller = PluginsController(None, model)
            controller.exec_()
            controller.shutdown()

        # Enter Qt main loop
        qtApp.exec_()

        # Shutdown controller
        Logger().info("Shuting down GUI...")
        mainController.shutdown()

        # Stop spy thread
        Logger().info("Shuting down Spy...")
        Spy().stop()
        Logger().debug("Waiting Spy thread to terminate...")
        Spy().wait()

        # Shutdown model
        Logger().info("Shuting down model...")
        model.shutdown()

        # Cleanup resources
        Logger().info("Cleaning up resources...")
        i18n.qCleanupResources()
        pixmaps.qCleanupResources()
        icons.qCleanupResources()

        Logger().info("Papywizard stopped")

    except Exception, msg:
        Logger().exception("main()")
        if 'splash' in locals():
            splash.finish(None)
        from papywizard.view.messageDialog import ExceptionMessageDialog
        try:
            msg = msg.message  # Windows exception?
        except AttributeError:
            pass
        dialog = ExceptionMessageDialog("Unhandled exception", unicode(msg))
        dialog.exec_()
Beispiel #20
0
    def start(self):
        """ Start connection.
        """
        pluginsStatus = {'yawAxis': {'connect': False, 'init': False},
                         'pitchAxis': {'connect': False, 'init': False},
                         'shutter': {'connect': False, 'init': False}
                         }

        # Start 'yawAxis' plugin connection
        pluginName = ConfigManager().get('Plugins/PLUGIN_YAW_AXIS')
        plugin = PluginsManager ().get('yawAxis', pluginName)[0]
        Logger().debug("PluginsConnector.start(): 'yawAxis' establish connection")
        try:
            plugin.establishConnection()
        except:
            Logger().exception("PluginsConnector.connectPlugins()")
        else:
            pluginsStatus['yawAxis']['connect'] = True
            Logger().debug("PluginsConnector.start(): 'yawAxis' init")
            try:
                plugin.init()
            except:
                Logger().exception("PluginsConnector.connectPlugins()")
            else:
                pluginsStatus['yawAxis']['init'] = True

        # Start 'pitchAxis' plugin connection
        pluginName = ConfigManager().get('Plugins/PLUGIN_PITCH_AXIS')
        plugin = PluginsManager ().get('pitchAxis', pluginName)[0]
        Logger().debug("PluginsConnector.start(): 'pitchAxis' establish connection")
        try:
            plugin.establishConnection()
        except:
            Logger().exception("PluginsConnector.connectPlugins()")
            pluginsStatus['pitchAxis']['connect'] = False
        else:
            pluginsStatus['pitchAxis']['connect'] = True
            Logger().debug("PluginsConnector.start(): 'pitchAxis' init")
            try:
                plugin.init()
            except:
                Logger().exception("PluginsConnector.connectPlugins()")
            else:
                pluginsStatus['pitchAxis']['init'] = True

        # Start 'shutter' plugin connection
        pluginName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
        plugin = PluginsManager ().get('shutter', pluginName)[0]
        Logger().debug("PluginsConnector.start(): 'shutter' establish connection")
        try:
            plugin.establishConnection()
        except:
            Logger().exception("PluginsConnector.connectPlugins()")
        else:
            pluginsStatus['shutter']['connect'] = True
            Logger().debug("PluginsConnector.start(): 'shutter' init")
            try:
                plugin.init()
            except:
                Logger().exception("PluginsConnector.connectPlugins()")
            else:
                pluginsStatus['shutter']['init'] = True

        return pluginsStatus
Beispiel #21
0
 def __getShutter(self):
     """
     """
     shutterName = ConfigManager().get('Plugins/PLUGIN_SHUTTER')
     return PluginsManager ().get('shutter', shutterName)[0] # Use getModel()?