diff --git a/kodi-plugin.coffee b/kodi-plugin.coffee old mode 100644 new mode 100755 index f68b7db..00808df --- a/kodi-plugin.coffee +++ b/kodi-plugin.coffee @@ -29,7 +29,7 @@ module.exports = (env) -> @framework.deviceManager.registerDeviceClass("KodiPlayer", { configDef: deviceConfigDef.KodiPlayer, - createCallback: (config) => new KodiPlayer(config) + createCallback: (config, lastState) => new KodiPlayer(config, @, lastState) }) @framework.ruleManager.addActionProvider( @@ -38,7 +38,6 @@ module.exports = (env) -> @framework.ruleManager.addActionProvider( new KodiShowToastActionProvider(@framework,@config) ) - @framework.ruleManager.addPredicateProvider(new PlayingPredicateProvider(@framework)) prepareConfig: (config) -> base = commons.base @, 'KodiPlugin' @@ -90,14 +89,14 @@ module.exports = (env) -> _type: "" _connectionProvider : null - constructor: (@config) -> + constructor: (@config, @plugin, lastState) -> @name = @config.name @id = @config.id - @debug = kodiPlugin.config.debug ? false + @debug = @plugin.config.debug ? false @base = commons.base @, @config.class - @interval = 60000 + @interval = 10000 - @_state = 'stop' + @_state = lastState?.state?.value @actions = _.cloneDeep @actions @attributes = _.cloneDeep @attributes @@ -225,7 +224,11 @@ module.exports = (env) -> _updateInfo: -> Promise.all([@_updatePlayerStatus(), @_updatePlayer()]) .catch (error) => - @base.rejectWithErrorString null, error, "Unable to update player" + + # Changed code to prevent log flooding with EHOSTUNREACH errors when mediaplayer is turned off + + #@base.rejectWithErrorString null, error, "Unable to update player" # OLD + Promise.resolve() # NEW .finally () => @base.scheduleUpdate @_updateInfo, @interval @@ -252,7 +255,7 @@ module.exports = (env) -> else @base.debug 'Kodi Stopped' @_setState 'stop' - @emit 'state', @_state + #@emit 'state', @_state return Promise.resolve() _updatePlayer: () -> @@ -274,7 +277,7 @@ module.exports = (env) -> info.label else '' ) - @_setCurrentArtist(if info.artist? then info.artist else "") + @_setCurrentArtist(if info.artist.length > 0 then info.artist[0] else "") else @_setCurrentArtist '' @_setCurrentTitle '' @@ -325,14 +328,14 @@ module.exports = (env) -> return { token: match nextInput: input.substring(match.length) - actionHandler: new KodiExecuteOpenActionHandler(device, @config, state) + actionHandler: new KodiExecuteOpenActionHandler(@framework, device, @config, state) } else return null class KodiExecuteOpenActionHandler extends env.actions.ActionHandler - constructor: (@device, @config, @name) -> + constructor: (@framework, @device, @config, @name) -> @debug = kodiPlugin.config.debug ? false @base = commons.base @, "KodiExecuteOpenActionHandler" @@ -345,78 +348,20 @@ module.exports = (env) -> for command in @config.customOpenCommands @base.debug "checking for (1): #{command.name} == #{@name}" if command.name is @name - return @device.executeOpenCommand( - command.command).then( => __("executed %s", @device.name) - ) - - class PlayingPredicateProvider extends env.predicates.PredicateProvider - constructor: (@framework) -> - @debug = kodiPlugin.config.debug ? false - @base = commons.base @, "PlayingPredicateProvider" - - parsePredicate: (input, context) -> - kodiDevices = _(@framework.deviceManager.devices).values() - .filter((device) => device.hasAttribute( 'state')).value() - - device = null - state = null - negated = null - match = null - - M(input, context) - .matchDevice(kodiDevices, (next, d) => - next.match([' is', ' reports', ' signals']) - .match([' playing', ' stopped',' paused', ' not playing'], (m, s) => - if device? and device.id isnt d.id - context?.addError(""""#{input.trim()}" is ambiguous.""") - return - device = d - mapping = {'playing': 'play', 'stopped': 'stop', 'paused': 'pause', 'not playing': 'not play'} - state = mapping[s.trim()] # is one of 'playing', 'stopped', 'paused', 'not playing' - - match = m.getFullMatch() + + {variables, functions} = @framework.variableManager.getVariablesAndFunctions() + input = __('"%s"', command.command) + context = M.createParseContext(variables, functions) + match = null + m = M(input, context) + parseCommand = (m, tokens) => match = tokens + m.matchStringWithVars(parseCommand) + + return @framework.variableManager.evaluateStringExpression(match).then( (cmd) => + @device.executeOpenCommand(cmd).then( => + __("executed %s on %s", command.name, @device.name) + ) ) - ) - - if match? - assert device? - assert state? - assert typeof match is "string" - return { - token: match - nextInput: input.substring(match.length) - predicateHandler: new PlayingPredicateHandler(device, state) - } - else - return null - - class PlayingPredicateHandler extends env.predicates.PredicateHandler - - constructor: (@device, @state) -> - @debug = kodiPlugin.config.debug ? false - @base = commons.base @, "PlayingPredicateHandler" - @dependOnDevice(@device) - - setup: -> - @playingListener = (p) => - @base.debug "checking whether current state #{p} matches #{@state}" - if @state is p or (@state is 'not play' and p isnt 'play') - @emit 'change', true - - @device.on 'state', @playingListener - super() - - getValue: -> - return @device.getUpdatedAttributeValue('state').then( - (p) => - @state is p or (@state is 'not play' and p isnt 'play') - ) - - destroy: -> - @device.removeListener 'state', @playingListener - super() - - getType: -> 'state' class KodiShowToastActionProvider extends env.actions.ActionProvider constructor: (@framework, @config) ->