From e266509f32ede521f5e4c1ce1d6c012fe35466fd Mon Sep 17 00:00:00 2001 From: SenTzu01 Date: Sat, 3 Feb 2018 21:56:48 +0100 Subject: [PATCH 1/5] Added feature allowing use of Pimatic functions and variables in custom Player.Open commands --- kodi-plugin.coffee | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) mode change 100644 => 100755 kodi-plugin.coffee diff --git a/kodi-plugin.coffee b/kodi-plugin.coffee old mode 100644 new mode 100755 index f68b7db..fe12de4 --- a/kodi-plugin.coffee +++ b/kodi-plugin.coffee @@ -325,14 +325,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,8 +345,19 @@ 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) + + {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) + ) ) class PlayingPredicateProvider extends env.predicates.PredicateProvider From 2f4021b79f1f87379e6b529317dd462f7e7da7d6 Mon Sep 17 00:00:00 2001 From: SenTzu01 Date: Sat, 28 Apr 2018 10:16:29 +0200 Subject: [PATCH 2/5] Bugfix: When info update object from kodi has an empty artist, @_setCurrentArtist() causes Pimatic to crash while attempting to insert attribute value into the database Plugin only checked for key not null, should check for array not empty --- kodi-plugin.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kodi-plugin.coffee b/kodi-plugin.coffee index fe12de4..e0a7787 100755 --- a/kodi-plugin.coffee +++ b/kodi-plugin.coffee @@ -274,7 +274,7 @@ module.exports = (env) -> info.label else '' ) - @_setCurrentArtist(if info.artist? then info.artist else "") + @_setCurrentArtist(if info.artist.lenght > 0 then info.artist[0] else "") else @_setCurrentArtist '' @_setCurrentTitle '' From b014366956ebf0f28d368091006d4b4908f4914b Mon Sep 17 00:00:00 2001 From: SenTzu01 Date: Fri, 22 Feb 2019 12:47:10 +0100 Subject: [PATCH 3/5] Corrected typo lenght -> length on line 277 --- kodi-plugin.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kodi-plugin.coffee b/kodi-plugin.coffee index e0a7787..3fb15b3 100755 --- a/kodi-plugin.coffee +++ b/kodi-plugin.coffee @@ -274,7 +274,7 @@ module.exports = (env) -> info.label else '' ) - @_setCurrentArtist(if info.artist.lenght > 0 then info.artist[0] else "") + @_setCurrentArtist(if info.artist.length > 0 then info.artist[0] else "") else @_setCurrentArtist '' @_setCurrentTitle '' From 9487180bd12a423328db4d70c4542bab303a779a Mon Sep 17 00:00:00 2001 From: SenTzu01 Date: Fri, 25 Oct 2019 12:28:12 +0200 Subject: [PATCH 4/5] Bugfix on state --- kodi-plugin.coffee | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/kodi-plugin.coffee b/kodi-plugin.coffee index 3fb15b3..1c8b4cd 100755 --- 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( @@ -90,14 +90,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 +225,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 +256,7 @@ module.exports = (env) -> else @base.debug 'Kodi Stopped' @_setState 'stop' - @emit 'state', @_state + #@emit 'state', @_state return Promise.resolve() _updatePlayer: () -> From a803c38e2d3becc035652cf17d4dac8ad496016c Mon Sep 17 00:00:00 2001 From: SenTzu01 Date: Fri, 28 Jan 2022 17:26:37 +0100 Subject: [PATCH 5/5] Removed predicates, added them to lib/predicates.coffee in Pimatic repo --- kodi-plugin.coffee | 70 ---------------------------------------------- 1 file changed, 70 deletions(-) diff --git a/kodi-plugin.coffee b/kodi-plugin.coffee index 1c8b4cd..00808df 100755 --- a/kodi-plugin.coffee +++ b/kodi-plugin.coffee @@ -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' @@ -364,75 +363,6 @@ module.exports = (env) -> ) ) - 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() - ) - ) - - 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) -> @debug = kodiPlugin.config.debug ? false