Harman Kardon Citation 700

Hello,

Im using a harman and kardon citation multibeam 700 as a soundbar for the tv. I can play tts notifications as well. The only problem; i cant select the source to resume the sound from my tv. (connected by hdmi arc port).

I already tested the harmen kardon integration but it doesnt work.
Done some testing with node-red but nothing… Anyone?

Cheers!

1 Like

Did you figure this out? I would love to know. Thanks!

I’m wondering the same. I have the HK Citation 200 and haven’t found a way to make it work with Home Assistant.
The only proof that it’s possible that I have found is from cristianm.bunte in his comment here: A different take on designing a Lovelace UI - #5148 by cristianm.bunte
In it it refers to media_player.hk_citation_one_d20393

So @cristianm.bunte , if you see this, how’s your setup to get your citation one connected to HA?

I’m looking for an integration for my Harman Kardon Citation MultiBeam™ as well. I haven’t found yet so I reversed engineered the local API a bit. As for source selection I think you have to look in to your TV because the HK 700 only has one input source to my understanding (one HDMI in).

However, for future reference. If someone wants to turn this into a full HA Add-On for HK 700, please feel free to do so.

For now, I added the following to my HA configuration.yaml using the REST integration:

sensor:
  # Harman Kardon Citation Multibeam 700
      # - http://100.127.0.25:4323/api/getData?path=citation%3AsummitInfo&roles=value
      # - http://100.127.0.25:4323/api/getData?path=citation%3AsubLineOutState&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2FsubwooferCrossover&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2Fsurround%2FbassTrimLevel&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2Fsurround%2FtrebleTrimLevel&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fcitation%2FlineOutputModeFixed&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fcitation%2FauxInTrimState&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2Fsurround%2FleftRear&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2Fsurround%2FrightRear&roles=value
      # - http://100.127.0.25:4323/api/getData?path=citation%3AsummitInfo&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2FmediaPlayer%2FmaxVolume&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2FdualMonoMode&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2FlipsyncDelay&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fsound%2FsubwooferFullRangeMode&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fairplay%2FaddedToHome&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2FdeviceName&roles=value
      # - http://100.127.0.25:4323/api/getData?path=airplay%3AstarredPassword&roles=value
      # - http://100.127.0.25:4323/api/getData?path=settings%3A%2Fairplay%2FdeviceName&roles=value
      # - http://100.127.0.25:4323/api/getData?path=network%3Aprofile&roles=value

  # auxInTrimState
  - platform: rest
    name: HK700_auxInTrimState
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fcitation%2FauxInTrimState&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].auxInTrimState }}"
    scan_interval: 120
  # subwooferCrossover
  - platform: rest
    name: HK700_subwooferCrossover
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FsubwooferCrossover&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].i32_ }}"
    scan_interval: 120
  # leftRear speaker trim level
  - platform: rest
    name: HK700_leftRearTrim
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2Fsurround%2FleftRear&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].surroundSpeaker.speakerTrimLevel }}"
    json_attributes:
      - surroundSpeaker
    scan_interval: 120
  # rightRear speaker trim level
  - platform: rest
    name: HK700_rightRearTrim
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2Fsurround%2FrightRear&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].surroundSpeaker.speakerTrimLevel }}"
    json_attributes:
      - surroundSpeaker
    scan_interval: 120
  # trebleTrimLevel
  - platform: rest
    name: HK700_trebleTrimLevel
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FtrebleTrimLevel&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].i32_ }}"
    scan_interval: 120
  # bassTrimLevel
  - platform: rest
    name: HK700_bassTrimLevel
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FbassTrimLevel&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].i32_ }}"
    scan_interval: 120
  # lipsyncDelay
  - platform: rest
    name: HK700_lipsyncDelay
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FlipsyncDelay&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].i32_ }}"
    scan_interval: 120
  # maxVolume
  - platform: rest
    name: HK700_maxVolume
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FmaxVolume&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].i32_ }}"
    scan_interval: 120
  # lineOutputModeFixed
  - platform: rest
    name: HK700_lineOutputModeFixed
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fcitation%2FlineOutputModeFixed&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].bool_ }}"
    scan_interval: 120
  # subwooferFullRangeMode
  - platform: rest
    name: HK700_subwooferFullRangeMode
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FsubwooferFullRangeMode&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].bool_ }}"
    scan_interval: 120
  # dualMonoMode
  - platform: rest
    name: HK700_dualMonoMode
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fsound%2FdualMonoMode&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].bool_ }}"
    scan_interval: 120
  # subLineOutState
  - platform: rest
    name: HK700_subLineOutState
    resource: http://192.168.4.210/api/getData?path=citation%3AsubLineOutState&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].bool_ }}"
    scan_interval: 120
  # summitInfo
  - platform: rest
    name: HK700_summitInfo
    resource: http://192.168.4.210/api/getData?path=citation%3AsummitInfo&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "OK"
    json_attributes_path: "$[0].summitInfo"
    json_attributes:
      - txPoweredOn
      - tx
      - rxSlaves
      - networkRunning
    scan_interval: 120
    # airplayAddedToHome
  - platform: rest
    name: HK700_airplayAddedToHome
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fairplay%2FaddedToHome&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].bool_ }}"
    scan_interval: 120
  # deviceName
  - platform: rest
    name: HK700_deviceName
    resource: http://192.168.4.210/api/getData?path=settings%3A%2FdeviceName&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].string_ }}"
    scan_interval: 120
  # airplayStarredPassword
  - platform: rest
    name: HK700_airplayStarredPassword
    resource: http://192.168.4.210/api/getData?path=airplay%3AstarredPassword&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].string_ }}"
    scan_interval: 120
  # airplayDeviceName
  - platform: rest
    name: HK700_airplayDeviceName
    resource: http://192.168.4.210/api/getData?path=settings%3A%2Fairplay%2FdeviceName&roles=value
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0].string_ }}"
    scan_interval: 120

Then reboot. Just edit the IP address for each resource: http://... The first lines are just comments for reference with all possible GET calls I found to gather information out of the HK 700, ignore port 4323. It runs on 80 by default, this is my internal port forwarding.

Sending changes back should be possible too. It seems to call in a similar format API endpoints /api/setData instead of /api/getData but i didn’t work that out for HA yet.

This information was gathered from the Web GUI that uses this api on the local IP address with paths /webclientAmp/ and /settings.fcgi and /network.fcgi. Path /googlecast.fcgi does not seem to contain any data. Path /main.fcgi contains a JSON object in HTML with information instead of making a REST call. I fetched that using the Node-Red and MQTT (Add-On and integration) by making the following Node-Red flow:

[{"id":"984c3ccbfbe6728b","type":"tab","label":"HK700 FetchMain","disabled":false,"info":"","env":[]},{"id":"217d4adf253aafd4","type":"http request","z":"984c3ccbfbe6728b","name":"Fetch main.fcgi","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.4.210/main.fcgi","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":320,"y":120,"wires":[["b9e6a3476e1bf63b"]]},{"id":"b9e6a3476e1bf63b","type":"html","z":"984c3ccbfbe6728b","name":"Get SCRIPT tags from HTML","property":"payload","outproperty":"payload","tag":"head > script","ret":"html","as":"single","chr":"_","x":540,"y":120,"wires":[["23dd3d8b3f56ac05"]]},{"id":"23dd3d8b3f56ac05","type":"function","z":"984c3ccbfbe6728b","name":"Extract JSON directly from the SCRIPT content","func":"// Join lines and filter empty\nlet lines = msg.payload.filter(line => line.trim() !== '');\nlet input = lines.join('\\n');\n\nif (typeof input !== 'string') {\n    node.warn(\"Payload after join is not string\");\n    return null;\n}\n\n// Extract JSON string inside JSON.parse()\nlet regex = /var profile = JSON\\.parse\\(&apos;(.+?)&apos;\\)/s;\nlet match = input.match(regex);\n\nif (!match) {\n    node.warn(\"No JSON.parse(...) match found\");\n    return null;\n}\n\nlet escapedJson = match[1];\n\n// Unescape HTML entities\nfunction htmlUnescape(str) {\n    return str.replace(/&quot;/g, '\"')\n              .replace(/&apos;/g, \"'\")\n              .replace(/&amp;/g, '&')\n              .replace(/&lt;/g, '<')\n              .replace(/&gt;/g, '>');\n}\nlet unescapedHtml = htmlUnescape(escapedJson);\n\n// Unescape backslashes, e.g., \\\\\" -> \", \\\\ -> \\\nlet unescapedBackslashes = unescapedHtml.replace(/\\\\\\\\/g, '\\\\').replace(/\\\\\"/g, '\"');\n\ntry {\n    let profile = JSON.parse(unescapedBackslashes);\n    msg.payload = profile;\n    return msg;\n} catch(err) {\n    node.error(\"JSON parsing failed: \" + err.message);\n    return null;\n}\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":120,"wires":[["cf842fa238a8255b"]]},{"id":"cf842fa238a8255b","type":"mqtt out","z":"984c3ccbfbe6728b","name":"","topic":"HK700/main","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"b825456db90257d5","x":1150,"y":120,"wires":[]},{"id":"6507d70170be1967","type":"comment","z":"984c3ccbfbe6728b","name":"HA-MQTT note","info":"Home Assistant integration does not\nwork properly due to dependency issues.\n\nUsing MQTT to integrate instead.\n","x":160,"y":60,"wires":[]},{"id":"b2b1ca08f4e0a649","type":"mqtt in","z":"984c3ccbfbe6728b","name":"","topic":"HK700/start","qos":"2","datatype":"auto-detect","broker":"b825456db90257d5","nl":false,"rap":true,"rh":0,"inputs":0,"x":150,"y":120,"wires":[["217d4adf253aafd4"]]},{"id":"b825456db90257d5","type":"mqtt-broker","name":"Mosquitto broker in Home Assistant","broker":"localhost","port":1883,"clientid":"","autoConnect":true,"usetls":false,"protocolVersion":4,"keepalive":60,"cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

And setting up the following Automation in Home Assistant to pull it every 120 seconds:

alias: Pull HK700 main data through Node-Red
description: ""
triggers:
  - trigger: time_pattern
    minutes: /2
conditions: []
actions:
  - action: mqtt.publish
    metadata: {}
    data:
      evaluate_payload: false
      qos: "2"
      retain: false
      topic: HK700/start
mode: single

And the following MQTT sensors in HA configuration.yaml to store them into sensors.

mqtt:
  sensor:
    - name: "HK700 WiFi SSID"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.ssid }}"

    - name: "HK700 WiFi Signal Level"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.signalLevel }}"
      unit_of_measurement: "dBm"

    - name: "HK700 WiFi Frequency"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.frequency }}"
      unit_of_measurement: "MHz"

    - name: "HK700 WiFi Channel"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.channel }}"

    - name: "HK700 WiFi BSSID"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.bssid }}"

    - name: "HK700 WiFi MAC"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.mac }}"

    - name: "HK700 WiFi State"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.state }}"

    - name: "HK700 WiFi Connecting Status"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.connectingStatus }}"

    - name: "HK700 WiFi Encryption"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.encryption }}"

    - name: "HK700 WiFi Credentials Suspect"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.credentialsSuspect }}"

    - name: "HK700 WiFi IP"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.addresses[0].ip }}"

    - name: "HK700 WiFi DHCP"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wireless.addresses[0].dhcp }}"

    - name: "HK700 Gateway IP"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.gateways[0].ip }}"

    - name: "HK700 DNS IP"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.dns[0].ip }}"

    - name: "HK700 SoftAP State"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.softAp.state }}"

    - name: "HK700 Wired Cable Connected"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wired.cableConnected }}"

    - name: "HK700 Wired State"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wired.state }}"

    - name: "HK700 Wired Connecting Status"
      state_topic: "HK700/main"
      value_template: "{{ value_json.networkInfo.wired.connectingStatus }}"

I expect this to work for other HK Citation MultiBeam models too, but obviously I didn’t test that.

1 Like

This is awesome! Thank you for sharing.
Have you found any endpoints that provide information related to current state of the Soundbar. Like if it is in AUX / Bluetooth / ARC / Spotify Casting mode?

1 Like

I didn’t for now. But additionally on the HK700 on page http://192.168.4.210/settings.fcgi you can enable Simple Device Discovery Protocol (SDDP) which should allow you to discover some things from this HA page: Settings > System > Network > SSDP Browser. Link to SSDP Browser – My Home Assistant. As described here: Simple Service Discovery Protocol (SSDP) - Home Assistant. If someone ever writes an integration for this, know it’s available for ‘auto discovery’ once enabled.

But since I’m using VLANs I did not get to test this yet. And I am not sure what information is in there. If you try it, please share the contents of it for future reference.

Good to see more people are looking into this.

I have also reverse engineered the API a bit.
Currently I can fire some set commands via the API’s setData endpoint.

secrets.yaml:

# Multibeam 700
multibeam_host: 192.x.y.z
multibeam_setdata: http://192.x.y.z/api/setData
multibeam_getdata: http://192.x.y.z/api/getData

rest_commands (via configuration.yaml → rest_command: !include_dir_merge_named entities/rest_command):

multibeam_hdmi.yaml:

multibeam_hdmi:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "citation:streamAudioSource",
  "roles": "activate",
  "value": {
    "source":"hdmiARC"
  }
}'

multibeam_reboot.yaml:

multibeam_reboot:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "powermanager:goReboot",
  "roles": "activate",
  "value": {}
}'

The rest of my setData commands:

multibeam_pause:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "player:player/control",
  "roles": "activate",
  "value": {"control": "pause"}
}'
multibeam_standby:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "powermanager:goNetworkStandby",
  "roles": "activate",
  "value": {}
}'
multibeam_stop:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "player:player/control",
  "roles": "activate",
  "value": {"control": "stop"}
}'
multibeam_volume_leftrear:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "settings:/sound/surround/leftRear",
  "role": "value",
  "value": {
      "type": "surroundSpeaker",
      "surroundSpeaker": {
          "speakerDistance": 0,
          "speakerTrimLevel": {{ states.input_select.soundbar_rear_volume.state }}
      }
  }
}'
multibeam_volume_rightrear:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "settings:/sound/surround/rightRear",
  "role": "value",
  "value": {
      "type": "surroundSpeaker",
      "surroundSpeaker": {
          "speakerDistance": 0,
          "speakerTrimLevel": {{ states.input_select.soundbar_rear_volume.state }}
      }
  }
}'
multibeam_volume_sub:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "settings:/sound/surround/bassTrimLevel",
  "roles": "value",
  "value": {
    "type":"i32_",
    "i32_": {{ states.input_select.soundbar_basslevel.state }}
  }
}'
multibeam_volume_treble:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "settings:/sound/surround/trebleTrimLevel",
  "roles": "value",
  "value": {
    "type":"i32_",
    "i32_": {{ states.input_select.soundbar_trebletrimlevel.state }}
  }
}'
multibeam_volume:
  url: !secret multibeam_setdata
  method: post
  headers:
    Content-Type: application/json
  payload: '{
  "path": "player:volume",
  "roles": "value",
  "value": {
    "type":"i32_",
    "i32_": {{ states.input_select.soundbar_volume.state }}
  }
}'

In Home Assistant, I have added some helpers, to select the values and pass them to the rest_comands above.

input_select.soundbar to select the various options, i.e. HDMI, Reboot, Pause, _Idle etc.
These can then be used from the Automation, maybe it can be done better, but this is working for me (as long as the Multibeam is on the WiFi, as it sometimes randomly disconnects).

alias: soundbar
description: ""
triggers:
  - entity_id:
      - input_select.soundbar
    to: HDMI
    id: set_HDMI
    trigger: state
  - entity_id:
      - input_select.soundbar
    to: Reboot
    id: do_Reboot
    trigger: state
  - entity_id:
      - input_select.soundbar
    to: Sleep
    id: do_Sleep
    trigger: state
  - entity_id:
      - input_select.soundbar
    to: Stop
    id: do_Stop
    trigger: state
  - entity_id:
      - input_select.soundbar
    to: Pause
    id: do_Pause
    trigger: state
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - set_HDMI
        sequence:
          - parallel:
              - action: rest_command.multibeam_hdmi
                data: {}
              - sequence:
                  - delay:
                      hours: 0
                      minutes: 0
                      seconds: 1
                      milliseconds: 0
                  - action: input_select.select_option
                    data:
                      option: _Idle
                    target:
                      entity_id: input_select.soundbar
      - conditions:
          - condition: trigger
            id:
              - do_Reboot
        sequence:
          - action: rest_command.multibeam_reboot
            data: {}
          - delay:
              hours: 0
              minutes: 0
              seconds: 1
              milliseconds: 0
          - action: input_select.select_option
            data:
              option: _Idle
            target:
              entity_id: input_select.soundbar
      - conditions:
          - condition: trigger
            id:
              - do_Sleep
        sequence:
          - action: rest_command.multibeam_standby
            data: {}
          - delay:
              hours: 0
              minutes: 0
              seconds: 1
              milliseconds: 0
          - action: input_select.select_option
            data:
              option: _Idle
            target:
              entity_id: input_select.soundbar
      - conditions:
          - condition: trigger
            id:
              - do_Stop
        sequence:
          - action: rest_command.multibeam_standby
            data: {}
          - delay:
              hours: 0
              minutes: 0
              seconds: 1
              milliseconds: 0
          - action: input_select.select_option
            data:
              option: _Idle
            target:
              entity_id: input_select.soundbar
      - conditions:
          - condition: trigger
            id:
              - do_Pause
        sequence:
          - action: rest_command.multibeam_pause
            data: {}
          - delay:
              hours: 0
              minutes: 0
              seconds: 1
              milliseconds: 0
          - action: input_select.select_option
            data:
              option: _Idle
            target:
              entity_id: input_select.soundbar
mode: single

I am not sure if I had discovered the current active source, will look it up later - as a bit of the discovery and stuff is on another laptop.

Feel free to comment, if stuff can be simplified :slight_smile:

2 Likes

You could also do an API call to fetch the network info, rather than parsing it from the main.fcgi page. it is the exact same content as:
http://192.x.y.z/api/getData?path=network:info&roles=value

For getting the source, I think you can - to some extend, use the following API endpoint:

http://192.x.y.z//api/getData?path=player:player/data&roles=value

That spits out some information about the active source, i.e. the following 3 snippets from different sources:

        "mediaRoles": {
            "mediaData": {
                "metaData": {
                    "playLogicPath": "googlecast:playlogic",
                    "live": true,
                    "serviceID": "googlecast"

        "mediaRoles": {
            "mediaData": {
                "metaData": {
                    "playLogicPath": "citation:LocalSourcePlayLogic",
                    "serviceID": "hdmiARC"

        "mediaRoles": {
            "mediaData": {
                "metaData": {
                    "playLogicPath": "airplay:playlogic",
                    "live": true,
                    "serviceID": "airplay"
2 Likes

Thanks for sharing, that is very helpful :smiley: