Onkyo Receiver Service Monitoring and remediation with Python/Grafana/InfluxDB and Vera

Background

If you have an Onkyo receiver, you probably notice odd issues with the network stack at times, causing various services (Spotify, DLNA, Etc) to stop responding to requests. The only resolution for fixing this state on the receiver is a physical power cycle (A soft reboot will not work). This is a well documented issue. It’s been blamed on faulty hardware, but it’s really a bug in the network stack somewhere causing this state.

Due to this issue, I decided to use Python to automate monitoring my receiver service status, log the results, and talk to my home automation platform to power cycle the plug it’s using for AC power if the service no longer responds. Let’s break down my script – (If you’d like to skip ahead, just grab the python script from below, install the required Onkyo-EISCP library and modify the variables to suit your environment, and run on a schedule with cron)

Functions accomplished by the final script –

Uses the Onkyo-EISCP python library to try to send a EISCP command to the receiver.

  • This is the only reliable way to determine if the various media services on the receiver are in a working state. When the receiver is in this state, the web server will still respond, and it will function normally otherwise, so EISCP commands must be sent to see if a response will be generated. This is the basis of the “health check”.

Sends a measurement to InfluxDB in the form of a integer that will be “0” for failed connectivity, and will be the reverse for a successful connection

  • This measurement is charted with Grafana, and a health check is built around it that will send a slack notification on any failure

Creates a small function to talk to my Vera Lite zwave automation controller.

  • This controller has a smart power switch associated with it that the receiver uses for power.

Script Breakdown

To begin, we define the variables needed to talk to the following –

  • InfluxDB
  • Vera Lite HTTP API
  • Onkyo Reciever
#Define Vera URL
url = 'http://vera.local:49451/data_request?'

#Define receiver IP
receiver = eiscp.eISCP('192.168.99.134')

#Define vera request params
vera_switch_on = {
    'id': 'action',
    'DeviceNum': '77',
    'serviceId': 'urn:upnp-org:serviceId:SwitchPower1',
    'action': 'SetTarget',
    'newTargetValue': '1',
  }

vera_switch_off = {
    'id': 'action',
    'DeviceNum': '77',
    'serviceId': 'urn:upnp-org:serviceId:SwitchPower1',
    'action': 'SetTarget',
    'newTargetValue': '0',
  }

The Vera API talks in JSON format, So we define a multi-line dict that contains the information needed to control our power switch (Id, Device Number, Service ID, action, and target value). We also define a EISCP library object with the IP of our receiver for later use.

Next, we create a simple function that will send a http GET request with our previously defined JSON dict objects depending on the condition we encounter.

def vera_request(qry):
    s = requests.Session()
    req = requests.Request(method='GET', url=url)
    prep = req.prepare()
    prep.url = url + qry
    r = s.send(prep)

The main part of the script is a try/except/else flow.

First, we try to send a EISCP command (dimmer-level-bright) to the receiver using the EISCP library

try:
    #Try to send a command to the reciever
    receiver_status = receiver.command('dimmer-level=bright')

If we encounter any exception, we run some logic to write a measurement to InfluxDB, then power cycle the receiver, using our previously created function (vera_request) and dict objects (vera_switch_on/off)

except:
    print("Cant connect to onkyo")
    receiver_reachable = 0
    json_body = [
    {
        "tags": {
            "host": "onkyo",
        },
        "measurement": "reachable",
        "fields": {
            "int_value": receiver_reachable
        }
    }
]
    client.write_points(json_body)
    print("Turning Receiver off")
    vera_request(vera_switch_off_qry)
    #Sleep 5
    time.sleep(5)
    print("Turning Receiver on")
    vera_request(vera_switch_on_qry)

If we don’t encounter any exception, we jump down to the else and simply print a message to the console, and log the result to InfluxDB

lse:
    print('Success - Receiver Conencted!')
    receiver_reachable = 1
    json_body = [
    {
        "tags": {
            "host": "onkyo",
        },
        "measurement": "reachable",
        "fields": {
            "int_value": receiver_reachable
        }
    }
]
    client.write_points(json_body)

Here’s the script in total –

Here’s a sample grafana dashboard that will graph this data. You can download the dashboard layout here.

The CLI output from the script looks like this –

Sample slack notification

Share this content:

2 thoughts on “Onkyo Receiver Service Monitoring and remediation with Python/Grafana/InfluxDB and Vera”

  1. Onkyo’s are not good network devices. They constantly spew all sorts of crap, and there’s no ability to turn it off via configuration. And the crap they spew is pretty worthless – e.g. even their basic SSDP stuff doesn’t follow the recommendations.

    Just do a pcap (Wireshark, or whatever) to see. Then compare with other manufacturer’s. I got rid of my Onkyo for a Denon, which is much more network friendly.

    1. Yeah, I did some traffic analysis with Wireshark while troubleshooting this issue and noticed that exact thing. After multiple days of traffic capturing, I wasn’t able to determine the exact traffic or protocol that causes the receiver EISCP services to crash unfortunately.

Leave a Comment

Your email address will not be published. Required fields are marked *