Kodi Remote

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?

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

Awesome, thanks a ton! This has some things in it I’ve never seen before so this is a great way to learn.

I’ve got 1 of my 3 kodi’s all set up now and it works great. Now to do the other 2. I’m thinking there should be a way to use the same script but change the entity id based on the card that’s pulling it. For now I’ll just do some find/replace and have more code in the files.

Thanks again!

What does your config look like for Kodi? I have a similar set up.

thankyou for sharing this, works perfectly and just what I was after!

quick question on those 2 mdi icons, is this reliant on a new Hassio release to incorporate these icons? Thanks again for sharing this remote! Very cool

They are not available in 0.88.2 (the version I’m currently running) so I downloaded them and am using them from local storage (www folder).

1 Like

Thanks Tom!

Thank you for sharing, this is something I wanted to do !!!

Thanks. Did the same but with custom button card
image

      - type: vertical-stack
        cards:
          - type: 'custom:button-card'
            color_type: label-card
            template: remote_button_round
            color: rgba(150, 150, 150, 0.1)
            name: Kodi Remote
          - type: horizontal-stack
            cards:
              - type: 'custom:button-card'
                name: Menu
                size: 30%
                show_name: true
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ContextMenu
                    entity_id: media_player.kodi
                template: remote_button_round
                icon: 'mdi:menu'
              - type: 'custom:button-card'
                template: remote_button_round
                hold_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Up
                    entity_id: media_player.kodi
                  repeat: 100
                icon: 'mdi:arrow-up-bold-circle'
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Up
                    entity_id: media_player.kodi
              - icon: 'mdi:chevron-double-up'
                type: 'custom:button-card'
                template: remote_button_round
                hold_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    entity_id: media_player.kodi
                    action: pageup
                  repeat: 100
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    entity_id: media_player.kodi
                    action: pageup
          - type: horizontal-stack
            cards:
              - icon: 'mdi:arrow-left-bold-circle'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Left
                    entity_id: media_player.kodi
              - icon: 'mdi:check-circle-outline'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Select
                    entity_id: media_player.kodi
              - icon: 'mdi:arrow-right-bold-circle'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Right
                    entity_id: media_player.kodi
          - type: horizontal-stack
            cards:
              - icon: 'mdi:backburger'
                type: 'custom:button-card'
                template: remote_button_round
                show_name: true
                name: Return
                size: 30%
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Back
                    entity_id: media_player.kodi
              - icon: 'mdi:arrow-down-bold-circle'
                type: 'custom:button-card'
                template: remote_button_round
                hold_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Down
                    entity_id: media_player.kodi
                  repeat: 100
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Down
                    entity_id: media_player.kodi
              - icon: 'mdi:chevron-double-down'
                type: 'custom:button-card'
                template: remote_button_round
                hold_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    entity_id: media_player.kodi
                    action: pagedown
                  repeat: 100
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    entity_id: media_player.kodi
                    action: pagedown
          - type: horizontal-stack
            cards:
              - icon: 'mdi:chevron-double-left'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    entity_id: media_player.kodi
                    action: stepback
              - icon: 'mdi:pause'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    action: playpause
                    entity_id: media_player.kodi
              - icon: 'mdi:chevron-double-right'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    action: stepforward
                    entity_id: media_player.kodi
          - type: horizontal-stack
            cards:
              - icon: 'mdi:home'
                type: 'custom:button-card'
                template: remote_button_round
                name: Home
                size: 30%
                show_name: true
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Home
                    entity_id: media_player.kodi
              - icon: 'mdi:stop'
                type: 'custom:button-card'
                template: remote_button_round
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.ExecuteAction
                    entity_id: media_player.kodi
                    action: stop
              - icon: 'mdi:information-outline'
                type: 'custom:button-card'
                template: remote_button_round
                name: Info
                size: 30%
                show_name: true
                tap_action:
                  service: media_player.kodi_call_method
                  action: call-service
                  service_data:
                    method: Input.Info
                    entity_id: media_player.kodi
5 Likes

just doing some reading

read your post had a brain fart

what about have a input_select

  kodi_machine:
    name: "Select Kodi Box"
    options:
      - kodi_main
    initial: kodi_main
    icon: mdi:kodi  

then couldnt you use the data_template

kodi_left:
  alias: "Kodi Left"
  sequence:
    data_template:
      entity_id: media_player.{{ states.input_select.kodi_machine.state}}
      method: Input.Left
    service: media_player.kodi_call_method    
media_player.kodi_call_method

Does this need replacing with the local service name? Or is this a custom service?

I’ve copied your scripts & lovelace code but not getting any response on Kodi.

I’m getting this in the log:

homeassistant.exceptions.ServiceNotFound: Unable to find service media_player/kodi_call_method
2019-09-07 23:28:35 ERROR (MainThread) [homeassistant.components.script] Error executing script script.kr_home. Service not found for call_service at pos 1: Unable to find service media_player/kodi_call_method
2019-09-07 23:28:35 ERROR (MainThread) [homeassistant.core] Error executing service <ServiceCall script.kr_home (c:71fb774cf04f49d2ab7b9d4978533daf)>
Traceback (most recent call last):

Thanks.

The way you call kodi methods was changed in the recent HA update. Documented in the release notes

The only info I can find in the integrations docs is limited and doesn’t appear to actually give an example of using the call method. It just mentions it but then doesn’t give any obvious details.

Could you possibly share some code samples?

Thanks.