I had a very simple requirement and I wanted to share the solution in case there are others using AdGuard Home on their network.
AdGuard Home has a REST API that works with BASIC AUTH that provides a number of endpoints to gather information and change the settings. So we will be using the HTTP binding.
The REST API docs for the current version of AdGuard Home is located at AdGuardHome/openapi at master · AdguardTeam/AdGuardHome · GitHub. They haven’t deployed the “v1” version of the API yet so you’ll need to look at the openapi docs (the one where the endpoint starts with /control
.
Requirement
Occasionally I or my SO will encounter a link we want to go to that gets blocked by AdGuard. Usually it’s a link in an email or the link that is riddled with trackers but we want to access it anyway.
Note: this is a global enable/disable of all protections. If you have finer need to control (e.g. just enable/disable for one client, just disable parental controls, etc.) the API appears to support that. Look at the docs to see which API endpoints you need to use and the data you need to send.
Prerequisites
- AdGuard Home (tested with v0.107.21 running on FreeBSD opnSense)
- a recent OH (anything in the past few years ought to work, I ran this on OH 4 SNAPSHOT though)
- HTTP binding
- JSONPATH Transformation
- JINJA Transformation
Configuration
The full YAML is below but I’ll also describe the properties set:
Thing
You will need to check “show advanced” to see all of these properties.
Property | Value | Notes |
---|---|---|
Base URL | https://<adguard host or IP>:<adguard port>/control |
|
Username | <adguard admin user> |
|
Password | <adguard admin password> |
|
Authentication Mode | Preemptive Basic Authentication | It does not work with “Basic Authentication” nor “Digest Authentication” |
State Method | GET |
|
Command Method | POST |
You might need to define another Thing if you want to interact with any of the PUT endpoints. |
Content Type | application/json |
|
Ignore SSL Errors | ON | Turn this on if using a self signed certificate |
Protection Channel
Add a Switch Channel to represent and control the global protection status. You will need to check “Show advanced” to see all of these properties.
Property | Value | Notes |
---|---|---|
State Transformation | JSONPATH:$.protection_enabled |
|
Command Transformation | JINJA:{"protection_enabled": {{value}}} |
I could not get this to work using the State Content field so Jinja to the rescue. |
State URL Extension | /status |
|
Command URL Extension | /dns_config |
|
On Value | true |
|
Off Value | false |
|
Read/Write Mode | Read/Write |
Full YAML
UID: http:url:adguard
label: AdGuard
thingTypeUID: http:url
configuration:
ignoreSSLErrors: true
stateMethod: GET
refresh: 30
commandMethod: POST
timeout: 3000
authMode: BASIC_PREEMPTIVE
baseURL: https://adguardHost:8443/control
password: mindYourOwnBusiness
delay: 0
contentType: application/json
username: username
bufferSize: 2048
channels:
- id: protection_status
channelTypeUID: http:switch
label: Protection Status
description: ""
configuration:
onValue: "true"
mode: READWRITE
commandTransformation: 'JINJA:{"protection_enabled": {{value}}}'
stateExtension: /status
offValue: "false"
stateTransformation: JSONPATH:$.protection_enabled
commandExtension: /dns_config
No, that is not my real URL, username, and password.
Item
Link this Channel to a Switch Item. If you want, you can set an expire on the Item to reenable the protection after a suitable amount of time. I use 1 hour. Don’t forget to configure it as a command so that it gets sent on to the server and doesn’t just update the Item’s state.
value: 1h0m0s,command=ON
config: {}
The Item’s state will represent the protection status at the last time it was polled (I use the default every 30 seconds). Sending an ON or OFF command to the Item will enable/disable the protection status.
Of course you can expose this to Google Assistant or Alexa depending on how closely you need to control it.
Conclusion
As usual, the hardest part is getting the authentication right. Once you have that, it’s a simple matter of creating the Channel(s) to interact with the end points. Messing with any of the other API endpoints is an exercise to the student. You should have enough here and in the links to figure it out.