Hey guys, Ive just got a plugwise Adam HA and an Emma pro. I noticed there is no geofencing or presence detection, so i wanted to get that. This means i had a need for pausing of the weekly schedule. Could not find a driver so I was fiddling with Comet and ChatGPT. (since i am not a programmer). I got it to work and want to share it with the community.
This is a small custom Hubitat driver I built for controlling the weekly heating schedule on a Plugwise Adam / Smile OT gateway.
It lets you pause or resume Adam’s internal weekly rule (the same one you toggle from the Plugwise web UI).
Useful if you want to disable heating automatically when nobody is home, or resume it when presence or motion is detected.
Plugwise Adam – Weekly Schedule Toggle Driver (Hubitat)
Hey everyone ![]()
This is a small custom Hubitat driver I built for controlling the weekly heating schedule on a Plugwise Adam / Smile OT gateway.
It lets you pause or resume Adam’s internal weekly rule (the same one you toggle from the Plugwise web UI).
Useful if you want to disable heating automatically when nobody is home, or resume it when presence or motion is detected.
Background
Some older Adam / Smile OT firmwares still expose their REST API at
http://<adam-ip>/core/rules;id=<rule-id>
Toggling a weekly schedule in the Plugwise UI sends a PUT request with XML like this:
<rules>
<rule id="...">
<active>true</active>
</rule>
</rules>
This driver reproduces that call from Hubitat, so you can integrate it with HSM, Rule Machine, or motion automations.
Known behaviour
- Certain Adam firmwares return HTTP 500 for these
PUTrequests (internal Lua Zigbee handler crash).
Despite the 500, the rule does get updated correctly.
The driver logs that as a warning but continues. - The
<template .../>element must not be included in the XML; otherwise you’ll get a “XML validation failed” error. - The XML must be sent in one line, or Adam will sometimes reject it.
Typical use cases
- Pause weekly heating schedule when HSM is Armed Away
- Resume when HSM is Disarmed
- Pause after X minutes of no motion (using a virtual presence switch)
Driver code
/**
* Plugwise Adam - Weekly Rule Toggle
*
* Purpose
* -------
* Lets Hubitat control the Plugwise Adam's internal "weekly rule" via its REST API.
* It can pause or resume the rule (same effect as toggling the schedule in the UI).
*
* Notes
* -----
* - Some Adam firmwares return HTTP 500 even when the update succeeds.
* - Do not include <template .../> in the XML body.
* - Keep XML on one line.
*
* Author: anonymous / community
* Version: 2025-10-31
*/
metadata {
definition(name: "Plugwise Adam - Weekly Toggle", namespace: "community", author: "anonymous") {
capability "Actuator"
capability "Initialize"
command "pauseWeekly", [[name:"Pause weekly schedule"]]
command "resumeWeekly", [[name:"Resume weekly schedule"]]
}
}
preferences {
input name: "adamIp", type: "text", title: "Plugwise Adam IP / hostname", required: true
input name: "adamUser", type: "text", title: "Username", required: true, defaultValue: "smile"
input name: "adamPass", type: "password", title: "Password", required: true
input name: "ruleId", type: "text", title: "Rule ID (weekly)", required: true
input name: "zoneId", type: "text", title: "Zone/Location ID", required: true
input name: "logEnable",type: "bool", title: "Enable debug logging?", defaultValue: true
}
def installed() { initialize() }
def updated() { initialize() }
def initialize() {
if (logEnable) log.info "Plugwise Adam - Weekly Toggle initialised"
}
/**
* Pause = deactivate weekly schedule
*/
def pauseWeekly() {
setWeeklyActive(false)
}
/**
* Resume = activate weekly schedule
*/
def resumeWeekly() {
setWeeklyActive(true)
}
/**
* Builds the XML payload and sends the PUT to Adam.
*/
private setWeeklyActive(Boolean activeFlag) {
if (!adamIp || !adamUser || !adamPass || !ruleId || !zoneId) {
log.warn "Missing required preferences (IP, user, pass, ruleId, zoneId)"
return
}
def url = "http://${adamIp}/core/rules;id=${ruleId}"
// One-line XML, no <template> element allowed
String xml = """<rules><rule id="${ruleId}"><name>weekly</name><description/><active>${activeFlag}</active><directives><when time="[mo 18:00,mo 23:00)"><then preset="home"/></when><when time="[mo 23:00,tu 18:00)"><then preset="asleep"/></when><when time="[tu 18:00,tu 23:00)"><then preset="home"/></when><when time="[tu 23:00,we 18:00)"><then preset="asleep"/></when><when time="[we 18:00,we 23:00)"><then preset="home"/></when><when time="[we 23:00,th 18:00)"><then preset="asleep"/></when><when time="[th 18:00,th 23:00)"><then preset="home"/></when><when time="[th 23:00,fr 18:00)"><then preset="asleep"/></when><when time="[fr 18:00,fr 23:00)"><then preset="home"/></when><when time="[fr 23:00,sa 09:00)"><then preset="asleep"/></when><when time="[sa 09:00,sa 23:45)"><then preset="home"/></when><when time="[sa 23:45,su 09:00)"><then preset="asleep"/></when><when time="[su 09:00,su 23:45)"><then preset="home"/></when><when time="[su 23:45,mo 18:00)"><then preset="asleep"/></when></directives><contexts><context><zone><location id="${zoneId}"/></zone></context></contexts></rule></rules>"""
if (logEnable) log.info "Sending Adam weekly -> ${activeFlag ? 'ON' : 'OFF'} to ${url}"
Map headers = [
"Content-Type": "application/xml",
"Accept" : "*/*",
]
String basic = "${adamUser}:${adamPass}".bytes.encodeBase64().toString()
headers["Authorization"] = "Basic ${basic}"
def params = [
uri: url,
headers: headers,
body: xml,
contentType: "application/xml",
requestContentType: "application/xml"
]
try {
httpPut(params) { resp ->
if (logEnable) {
log.info "Adam response status: ${resp.status}"
try {
log.debug "Adam response body: ${resp.data}"
} catch (ignored) { }
}
}
} catch (e) {
// Known issue: Adam may throw HTTP 500 but still apply the change
log.warn "Adam returned error (likely still applied): ${e.message}"
}
}
Example usage in Rule Machine
Trigger: HSM status changes
Actions:
IF (HSM status = Armed Away) THEN
Plugwise Adam - Weekly Toggle → pauseWeekly()
ELSE
Plugwise Adam - Weekly Toggle → resumeWeekly()
END-IF
Or use a virtual presence / motion-based automation to save gas by pausing the schedule when nobody’s home.
Tested on
- Plugwise Adam / Smile OT (firmware 3.9.x)
- Hubitat C-7
- Works even when Adam returns HTTP 500; rule updates successfully.
That’s it!
If anyone else still runs an Adam locally and wants to integrate it with Hubitat or Node-RED, this should save you some trial-and-error.
Feedback or improvements are welcome ![]()