Kodi Remote

I want to share with you the Kodi remote as I couldn’t find it here.

If someone wants to develop this with me, put your own version here.

To-do list

  • Playlist button (shows songs from the current playlist or album)
  • Volume adjustment (for amplifier)
  • Fast forward and backward
  • Current track information and picture
  • Keyboard button

Here’s the code
ui-lovelace.yaml

# Kodi Remote
- title: Kodi
  cards:
   - type: vertical-stack
     cards:
      - type: entities
        entities:
          - media_player.kodi
      - type: horizontal-stack
        cards:
        #PREVIUOS
          - type: entity-button
            icon: mdi:skip-previous
            name: ''
            entity: script.kr_prev
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_prev
            hold_action:
              action: none
        #STOP
          - type: entity-button
            icon: mdi:stop
            name: ''
            entity: script.kr_stop
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_stop
            hold_action:
              action: none
        #PLAY PAUSE
          - type: entity-button
            icon: mdi:play-pause
            name: ''
            entity: script.kr_play_pause
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_play_pause
            hold_action:
              action: none
        #NEXT
          - type: entity-button
            icon: mdi:skip-next
            name: ''
            entity: script.kr_next
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_next
            hold_action:
              action: none
      - type: horizontal-stack
        cards:
        #HOME
          - type: entity-button
            icon: mdi:home
            name: 
            entity: script.kr_home
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_home
            hold_action:
              action: none
        # UP
          - type: entity-button
            icon: mdi:menu-up-outline
            name: 
            entity: script.kr_up
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_up
            hold_action:
              action: none
        # EMPTY
          - type: entity-button
            icon: mdi:file-excel-box
            name: 
            entity: script.kr_down
            tap_action:
              action: none
            hold_action:
              action: none
      - type: horizontal-stack
        cards:
        # LEFT
          - type: entity-button
            icon: mdi:menu-left-outline
            name: 
            entity: script.kr_left
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_left
            hold_action:
              action: none
        #SELECT
          - type: entity-button
            icon: mdi:circle-outline
            name: 
            entity: script.kr_select
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_select
            hold_action:
              action: none
        #RIGHT
          - type: entity-button
            icon: mdi:menu-right-outline
            name: 
            entity: script.kr_right
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_right
            hold_action:
              action: none
      - type: horizontal-stack
        cards:
        #BACK
          - type: entity-button
            icon: mdi:undo-variant
            name: 
            entity: script.kr_back
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_back
            hold_action:
              action: none
        # DOWN
          - type: entity-button
            icon: mdi:menu-down-outline
            name: 
            entity: script.kr_down
            tap_action:
              action: call-service
              service: script.turn_on
              service_data:
                entity_id: script.kr_down
            hold_action:
              action: none
        # EMPTY
          - type: entity-button
            icon: mdi:skip-next
            name: ''
            entity: script.kr_playlist
            tap_action:
              action: more-info
              service: script.turn_on
              service_data:
                entity_id: script.kr_playlist
            hold_action:
              action: none

script.yaml

# Kodi Remote
kr_up:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Up'
      data:
        entity_id: media_player.kodi
        method: Input.Up
      service: media_player.kodi_call_method

kr_down:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Down'
      data:
        entity_id: media_player.kodi
        method: Input.Down
      service: media_player.kodi_call_method

kr_left:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Left'
      data:
        entity_id: media_player.kodi
        method: Input.Left
      service: media_player.kodi_call_method

kr_right:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Right'
      data:
        entity_id: media_player.kodi
        method: Input.Right
      service: media_player.kodi_call_method

 kr_select:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Select'
      data:
         entity_id: media_player.kodi
         method: Input.Select
       service: media_player.kodi_call_method

kr_home:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Home'
      data:
        entity_id: media_player.kodi
        method: Input.Home
      service: media_player.kodi_call_method

kr_back:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Back'
      data:
        entity_id: media_player.kodi
        method: Input.Back
      service: media_player.kodi_call_method

kr_next:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Next'
      data:
        entity_id: media_player.kodi
      service: media_player.media_next_track

kr_prev:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Prev'
      data:
        entity_id: media_player.kodi
      service: media_player.media_previous_track

kr_play_pause:
  alias: ''
  sequence:
    - alias: 'Kodi Remote PlayPause'
      data:
        entity_id: media_player.kodi
      service: media_player.media_play_pause

kr_stop:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Stop'
      data:
        entity_id: media_player.kodi
      service: media_player.media_stop

kr_playlist:
  alias: ''
  sequence:
    - alias: 'Kodi Remote Playlist'
      data:
         entity_id: media_player.kodi
         method: Audio.Details.Album
      service: media_player.kodi_call_method
10 Likes

could you use the formating tool make easyer to read and see your great work

…and some screen shots?? (Photo or it didn’t happen :wink:)

2 Likes

Is better now?

I take it that the whole Input.Action schema list isn’t implemented in the component?

lounge_kodi_player_fast_fwd:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.FastForward

ERROR (MainThread) [homeassistant.components.media_player.kodi] Run API method media_player.lounge_osmc_kodi.Input.FastForward({}) error: {'code': -32601, 'message': 'Method not found.'}

lounge_kodi_player_fast_fwd:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.StepForward

ERROR (MainThread) [homeassistant.components.media_player.kodi] Run API method media_player.lounge_osmc_kodi.Input.StepForward({}) error: {'code': -32601, 'message': 'Method not found.'}

Full action list at section 6.10.1 https://kodi.wiki/view/JSON-RPC_API/v9

I think the fault is lounge_kodi_player_fast_fwd:. It occurs in both.

No, there is only one lounge_kodi_player_fast_fwd. It’s the same script I just tried two different input.actions.

This brings up a similar error:

cinema_kodi_input_next_subtitle:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.cinema_kodi
        method: Input.NextSubtitle

On my IR remote this action cycles through the available subtitles and disabled.

Here’s the problem: https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/media_player/kodi.py

REQUIREMENTS = ['jsonrpc-async==0.6', 'jsonrpc-websocket==0.6']

I was using API version 0.9 not 0.6.

It only supports these input.action commands (section 5.6):

https://kodi.wiki/view/JSON-RPC_API/v6

Thanks for sharing.

ok, this is not a nice thing. I look into the matter and try to come up with someone’s solution.

I put here an update when I get more done

I give up. This curl command used to work:

'curl -u "kodi:mypwd" --header "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"Player.SetSpeed\",\"params\":{\"playerid\":1,\"speed\":\"increment\"}}" "http://10.1.1.14:8080/jsonrpc"'

So I tried:

lounge_kodi_player_fast_fwd:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.SetSpeed
        playerid: 1
        speed: Increment

and this

lounge_kodi_player_fast_fwd:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.SetSpeed
        params:
          playerid: 1
          speed: Increment

and even

lounge_kodi_player_fast_fwd:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.SetSpeed
        params: { playerid: 1, speed: Increment }

But I keep getting this error:

ERROR (MainThread) [homeassistant.components.media_player.kodi] Run API method media_player.lounge_osmc_kodi.Player.SetSpeed({'params': OrderedDict([('playerid', 1), ('speed', 'Increment')])}) error: {'code': -32602, 'data': {'method': 'Player.SetSpeed', 'stack': {'message': 'Missing parameter', 'name': 'playerid', 'type': 'integer'}}, 'message': 'Invalid params.'}

So this is the right method. I just cant work out how to pass the parameters, playerid and speed.

It’s far too late and I’m going to bed. Hopefully someone that knows what they are doing can spot my mistake.

  1. Can anyone verify that HA is using correct version of jsonrpc libraries?
    If not, can anyone try to install required versions by enabling HA virtualenv with HA user and then running following:

pip install jsonrpc-async==0.6
pip install jsonrpc-websocket==0.6

  1. What if You just give up with complex rpc system by defining rest command on Kodi and execute that by your script?

I mean something like this:

rest_command:
  kodi_set_speed:
    username: kodi
    password: mypwd
    url: http://10.1.1.14:8080/jsonrpc
    method: POST
    headers:
      accept: 'application/json, text/html'
    payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"Player.SetSpeed\",\"params\":{\"playerid\":1,\"speed\":\"increment\"}}"
    content_type:  'Content-Type: application/json'
    verify_ssl: false

Edit:

And sure someone is so talented that he/she finds out that it is possible to pass method and params as a parameter to your rest command like this:

rest_command:
  kodi_call:
    username: kodi
    password: mypwd
    url: http://10.1.1.14:8080/jsonrpc
    method: POST
    headers:
      accept: 'application/json, text/html'
    payload: '{"jsonrpc":"2.0","id":1,"method":"Player.{{method}}","params":{{params}}}'
    content_type:  'Content-Type: application/json'
    verify_ssl: false

And in your service definition do something like this:

......
  - service: rest_command.kodi_call
    data:
      method: SetSpeed
      params: '{"playerid":1, "speed": "increment"}'

The following is working for me

koditestscript:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.kodi 
        method: Player.SetSpeed
        playerid: 1
        speed: "increment"
1 Like

Works perfectly. Thank you.

For anyone wanting them, the skip back and forward 10s or 30s follow this format:

lounge_kodi_player_skip_back_30:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.Seek
        playerid: 1
        value: "bigbackward" # "bigforward" for the other way
lounge_kodi_player_skip_fwd_10:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.Seek
        playerid: 1
        value: "smallforward" # "smallbackward" for the other way

My remote was almost complete. Except the MDI icons for back 30s and forward 10s have only just been released and did not make this last update. These place holders will do until the next update:

Well not quite complete. I just discovered this handy service:

lounge_update_kodi_library:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: VideoLibrary.Scan

But that can wait until tomorrow. It’s far too late on a work night.

EDIT:

I remembered that custom ui tiles can use local icons:

full config:

lounge_kodi_input_back:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Back

lounge_kodi_input_contectx_menu:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.ContextMenu

lounge_kodi_input_down:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Down

lounge_kodi_input_next_subtitle:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.SetSubtitle
        playerid: 1
        subtitle: "next"
        enable: true

lounge_kodi_input_home:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Home

lounge_kodi_input_info:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Info

lounge_kodi_input_left:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Left

lounge_kodi_input_right:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Right

lounge_kodi_input_select:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Select

lounge_kodi_input_up:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Input.Up

lounge_kodi_player_fast_fwd:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.SetSpeed
        playerid: 1
        speed: "increment"

lounge_kodi_player_play_pause:
  sequence:
    - service: media_player.media_play_pause
      data:
        entity_id: media_player.lounge_osmc_kodi

lounge_kodi_player_rewind:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.SetSpeed
        playerid: 1
        speed: "decrement"

lounge_kodi_player_skip_back:
  sequence:
    - service: media_player.media_previous_track
      data:
        entity_id: media_player.lounge_osmc_kodi

lounge_kodi_player_skip_back_10:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.Seek
        playerid: 1
        value: "smallbackward"

lounge_kodi_player_skip_back_30:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.Seek
        playerid: 1
        value: "bigbackward"

lounge_kodi_player_skip_fwd:
  sequence:
    - service: media_player.media_next_track
      data:
        entity_id: media_player.lounge_osmc_kodi

lounge_kodi_player_skip_fwd_10:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.Seek
        playerid: 1
        value: "smallforward"

lounge_kodi_player_skip_fwd_30:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: Player.Seek
        playerid: 1
        value: "bigforward"

lounge_kodi_player_stop:
  sequence:
    - service: media_player.media_stop
      data:
        entity_id: media_player.lounge_osmc_kodi

lounge_update_kodi_library:
  sequence:
    - service: media_player.kodi_call_method
      data:
        entity_id: media_player.lounge_osmc_kodi
        method: VideoLibrary.Scan
3 Likes

That looks awesome! Could you post the ui-lovelace.yaml code as well?

1 Like

Sure, here you go:

type: 'custom:tiles-card'
card_settings:
  title: Kodi
  title_align: left
  columns: 4
  column_width: calc(97%/4)
  row_height: 75px
  background: var(--paper-card-background-color)
global_settings:
  label_sec:
    color:
      value: white
  icon:
    color:
      value: white
  shadow: 'elevation: 6dp'
  border:
    size: 3px
    radius: 5px
    color:
      value: black
entities:
  - column: 1
    entity: script.lounge_kodi_input_home
    icon:
      value: 'mdi:home'
    row: 1
  - column: 2
    entity: script.lounge_kodi_input_contectx_menu
    icon:
      value: 'mdi:menu'
    label_sec:
      value: Menu
    row: 1
  - column: 3
    entity: script.lounge_kodi_input_up
    icon:
      value: 'mdi:arrow-up-bold-circle'
    background:
      value: '#2576da'
    row: 1
  - column: 4
    entity: script.lounge_kodi_input_info
    icon:
      value: 'mdi:information-outline'
    label_sec:
      value: Info
    row: 1
  - column: 1
    entity: script.lounge_kodi_player_play_pause
    icon:
      value: 'mdi:play-pause'
    row: 2
  - column: 2
    entity: script.lounge_kodi_input_left
    icon:
      value: 'mdi:arrow-left-bold-circle'
    background:
      value: '#2576da'
    row: 2
  - column: 3
    entity: script.lounge_kodi_input_select
    icon:
      value: 'mdi:check-circle-outline'
    row: 2
  - column: 4
    entity: script.lounge_kodi_input_right
    icon:
      value: 'mdi:arrow-right-bold-circle'
    background:
      value: '#2576da'
    row: 2
  - column: 1
    entity: script.lounge_kodi_player_stop
    icon:
      value: 'mdi:stop'
    row: 3
  - column: 2
    entity: script.lounge_kodi_input_back
    icon:
      value: 'mdi:backburger'
    label_sec:
      value: Return
    row: 3
  - column: 3
    entity: script.lounge_kodi_input_down
    icon:
      value: 'mdi:arrow-down-bold-circle'
    background:
      value: '#2576da'
    row: 3
  - column: 4
    entity: script.lounge_kodi_input_next_subtitle
    icon:
      value: 'mdi:subtitles-outline'
    label_sec:
      value: Subtitle
    row: 3
  - column: 1
    entity: script.lounge_kodi_player_rewind
    icon:
      value: 'mdi:rewind'
    row: 4
  - column: 2
    entity: script.lounge_kodi_player_fast_fwd
    icon:
      value: 'mdi:fast-forward'
    row: 4
  - column: 3
    entity: script.lounge_kodi_player_skip_back
    icon:
      value: 'mdi:skip-previous'
    row: 4
  - column: 4
    entity: script.lounge_kodi_player_skip_fwd
    icon:
      value: 'mdi:skip-next'
    row: 4
  - column: 1
    entity: script.lounge_kodi_player_skip_back_30
    icon:
      value: /local/icons/rewind-30.png
    row: 5
  - column: 2
    entity: script.lounge_kodi_player_skip_back_10
    icon:
      value: 'mdi:rewind-10'
    row: 5
  - column: 3
    entity: script.lounge_kodi_player_skip_fwd_10
    icon:
      value: /local/icons/fast-forward-10.png
    row: 5
  - column: 4
    entity: script.lounge_kodi_player_skip_fwd_30
    icon:
      value: 'mdi:fast-forward-30'
    row: 5
2 Likes