LUCAS.DEV
Blog post hero image

Controlling my Denon AVC-X3800H with Siri Shortcuts

Introduction

Ever since I upgraded my sound system back in 2022, I was never really impressed with the remote control options of the Denon AVC-X3800H. The included remote control works as expected, but it’s big and ugly, so I don’t want it laying around. Ideally, I would control everything from my Apple TV remote. However, this only works when watching TV. I can’t turn on the receiver without also turning on my TV, which makes it not an option for music listening.

There’s the Denon AVR Remote phone app, but it’s slow and inconvenient. I can trigger music playback via Spotify Connect/AirPlay, but they both start playing songs before the receiver has fully booted up, resulting in music only being audible a good 10-seconds into the song. Both options work, but neither are preferable.

Web control

One day, I was reading the owner’s manual and discovered a section called Web control function. As it turns out, the Denon receiver hosts a local web server that offers a control panel for the entire unit. This panel supports on/off control for each zone, a setup menu where most settings are configurable, and MAIN ZONE input source select. All of this, straight from my web browser!

Side note: I’m pretty sure the Denon AVR Remote phone app is just displaying this web page 😅

A screenshot of Denon's web control panel

This got me thinking, Siri Shortcuts supports sending HTTP requests. That means it’s possible to control my Denon receiver with Siri voice commands. This would allow me to quickly turn on my receiver, and let it boot up before I start playing music.

Finding the IP address

To get the Denon’s IP address, turn it on and go to the setup menu. From there, go to Network > Information > IP address. Copy the IP address and enter it into your web browser. It should default to port 10443 and load the web control panel.

Configuring the web control

The first step is to make sure the network control setting is set to Always On, so the Denon receiver listens for network commands, even when it’s in standby mode. This is necessary to power on the unit when it’s turned off (standby).

A screenshot of the Network Control settings on Denon's web control panel

Reverse engineering the API

Next step is figuring out which requests are being sent when powering on/off the receiver from the web control panel. After listening to network activity in my browser’s dev tools, I found these are the scripts to call:

Power on

https://{IP}:{PORT}/ajax/globals/set_config?type=4&data=<MainZone><Power>1</Power></MainZone>&_={UNIX_TIMESTAMP}

Power off

https://{IP}:{PORT}/ajax/globals/set_config?type=4&data=<MainZone><Power>3</Power></MainZone>&_={UNIX_TIMESTAMP}

The only difference between the two requests are the power IDs that are provided. 1 is for ON, and 3 is of OFF (standby). The Unix timestamp isn’t required to make a successful request, but I suspect it’s used to manage delayed requests, and ignore them if never requests have been made earlier. Better to leave it in there, just in case.

Since I plan on making a Siri shortcut that toggles the on/off state, I need a way to determine the current state of the receiver to know which request to make. Luckily, there’s an endpoint for that, too!

Get current power state

https://{IP}:{PORT}/ajax/globals/get_config?type=4&_={UNIX_TIMESTAMP}

Calling this will return some XML that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<listGlobals><MainZone><Power>1</Power></MainZone><Zone2><Power>3</Power></Zone2></listGlobals>

This contains all the information we need to determine the power state of MAIN ZONE, which is the zone I wish to control.

Tricking Shortcuts to call Denon’s untrusted server

Great! Only thing missing now is a Siri shortcut that calls these URLs… right? Sadly, no, it’s not that simple. Apple requires a trusted certificate be installed on the server to send HTTP requests securely. The self-signed certificate issued on the receiver’s server is not trusted, so there’s no way to directly call the receiver from Siri shortcuts. I tried all sorts of methods to send these HTTP requests from Siri Shortcuts, but nothing worked. And since I don’t have access to the Denon’s internal server, I had to find another solution.

That’s when it occurred to me that I have web server running on my Synology NAS, which I could use to proxy my requests. The Synology server doesn’t care if I make insecure requests, so as long as the connection between Siri and my Synology server is secure, everything should work. Since I already have a domain name pointing to my Synology server with a trusted certificate installed, all that was left was to write the script that forwards the requests.

Writing the script

I wrote this in PHP, but you can write in whatever language that works for you. It looks like this:

<?php
// This script toggles the power of the Denon AVC-X3800H
//

// Function to call a given URL, ignoring potential SSL insecurities
function getUrl($url) {
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

// Define the URLs
define('URL', '192.168.1.124:10443');
$onURL = "https://" . URL . "/ajax/globals/set_config?type=4&data=<MainZone><Power>1</Power></MainZone>&_=" . time();
$offURL = "https://" . URL . "/ajax/globals/set_config?type=4&data=<MainZone><Power>3</Power></MainZone>&_=" . time();
$statusURL = "https://" . URL . "/ajax/globals/get_config?type=4&_=" . time();

// Get the current power state of the Denon receiver
$xmlData = getUrl($statusURL);
$xml = new SimpleXMLElement($xmlData);
$powerStatus = (int) $xml->MainZone->Power; // 1:on, 3:off

// Turn on or off the Denon receiver, depending on its current power state
if ($powerStatus === 1) {
  echo 'Turning off <i>Denon AVC-X3800H</i>';
  getUrl($offURL); // Send request to Denon receiver
} else if ($powerStatus === 3) {
  echo 'Turning on <i>Denon AVC-X3800H</i>';
  getUrl($onURL); // Send request to Denon receiver
}

exit();

This script will read the current power state of the receiver, and then signal it to turn on or off depending on the initial state. During the HTTP request, I tell it to ignore potential SSL problems, as we already know Denon’s server is untrusted. Since this is happening on the local network, it’s not really cause for concern.

If you’re publicizing a script like this and making it accessible from the web, please make sure to add some authentication, so random people and bots can’t access it.

Creating the Siri shortcut

Once this script is accessible from the web, and you have confirmed that it works, adding the Siri shortcut is trivial.

Three iOS screenshots showing the step-by-step guide on adding a shortcut

Simply follow these steps:

  1. Go to the Shortcuts app and create a new shortcut. The only action needed is the “Get contents of” action, and set it’s value to the URL of the script you have created.

  2. Click the little icon at the bottom, go to Privacy, and make sure Allow Running When Locked is enabled. This will allow you to run the shortcut, even when your phone is locked.

  3. Optionally, you can create additional shortcuts and use them as aliases that run the shortcut you created in step 1. This is nice if you want Siri to recognize multiple phrases that all trigger the main shortcut. For example, I have configured “Turn on receiver,” “Start receiver,” and “Turn off receiver” to run the shortcut from step 1.

Siri will now listen for the names of these shortcuts and call the script, which turns the receiver on or off. I can simply say “Siri, turn on receiver,” and it will be done 🫰.

If you have a Mac, these shortcuts will even work there as well, as shortcuts are synced between your Apple devices. This means you can control your receiver directly from Spotlight – very convenient!

A screenshot showing the Siri shortcut from Spotlight on macOS

Controlling inputs

One last thing that’s missing is the ability to switch input source on the receiver. I want to be able to tell Siri to change the input from HEOS to my iPod on AUX2 or my turntable on Phono.

Thankfully, there’s in an endpoint for exactly that. I won’t show code for this, as it’s essentially just a repeat of the code I showed in the previous step, but with a different endpoint. I will leave you with the URL and a list of input source IDs and what they represent.

Change input source

https://{IP}:{PORT}/ajax/globals/setconfig?type=7&data=%3CSource%20zone%3D%221%22%20index%3D%22{INPUT_SRC_ID}%22%3E%3C%2FSource%3E&={UNIX_TIMESTAMP}

Input Source IDs

Input Source IDChannel
1CBL/SAT
2-
3Blu-ray
4Game
5Media Player
6TV Audio
7AUX1
8AUX2
9CD
10Phono
11Tuner
12-
13HEOS Music

Once you’ve set up the script to change the input source, you can repeat the same steps as before to create Siri shortcuts, along with aliases, to allow Siri to change the input to whatever you desire. As far as I can tell, Shortcuts doesn’t support arguments, so you will need to create a new shortcut for each input source you wish to be able to change with Siri.

Final thoughts

So, that’s my solution to an admittedly very first-world problem. I created this solution 6 months ago as of writing this, and it’s been working flawlessly ever since.

The Shortcuts app could really do with better alias support and listening for arguments. My Shortcuts app is cluttered with aliases for toggling the power and changing input source… it’s not elegant, but it is what it is.

I realize my solution of proxying requests isn’t ideal, as the majority of people likely don’t have a web server at home. Unfortunately, I don’t see a way around it if you want it to play nice with Siri shortcuts. I’m sure there are easier solutions out there for other Shortcuts-esque ecosystems.

Anyway, I hope this has been helpful in some way!

PublishedAuthorHits
October 24, 2024Lucas Taylor28