ワンクリックで
watts-home-auth
Azure AD B2C auth flow for the Watts® Home API (home.watts.com) used by SunStat Connect Plus and Tekmar WiFi thermostats.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Azure AD B2C auth flow for the Watts® Home API (home.watts.com) used by SunStat Connect Plus and Tekmar WiFi thermostats.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Pattern for keeping a rolling temperature-trend sample buffer in Hubitat state, computing slope over a configurable window, and classifying rising/falling/steady/unknown.
Implement Tuya Local v3.3 Groovy drivers on Hubitat using rawSocket, AES-128-ECB, queued retries, and defensive frame parsing.
Use Hubitat async HTTP plus a request queue to authenticate with Cognito, cache tokens in state, refresh proactively, and replay a single 401-failed request.
When two agents produce overlapping skills in one session, consolidate by merging unique content into the highest-confidence existing skill.
Never let cached-state dedup bypass session validity in cloud-backed Hubitat drivers.
Standard guard pattern for async HTTP response callbacks in Hubitat drivers
SOC 職業分類に基づく
| name | watts-home-auth |
| description | Azure AD B2C auth flow for the Watts® Home API (home.watts.com) used by SunStat Connect Plus and Tekmar WiFi thermostats. |
| domain | protocol |
| confidence | high |
| source | reverse-engineered via seanami/homebridge-tekmar-wifi |
The Watts® Home API (https://home.watts.com/api) is the cloud backend for Watts Water Technologies North America products including SunStat Connect Plus and Tekmar WiFi thermostats. Authentication is Azure AD B2C with OAuth 2.0 PKCE — not AWS Cognito, and not the EU Watts Vision API.
LOGIN_BASE = https://login.watts.io
TENANT = wattsb2cap02.onmicrosoft.com
POLICY = B2C_1A_Residential_UnifiedSignUpOrSignIn
CLIENT_ID = c832c38c-ce70-4ebc-83b6-b4548083ac90
REDIRECT_URI= msalc832c38c-ce70-4ebc-83b6-b4548083ac90://auth
SCOPE = https://wattsb2cap02.onmicrosoft.com/wattsapiresi/manage offline_access openid profile
TOKEN_URL = https://login.watts.io/tfp/wattsb2cap02.onmicrosoft.com/B2C_1A_Residential_UnifiedSignUpOrSignIn/oauth2/v2.0/token
POST https://login.watts.io/tfp/wattsb2cap02.onmicrosoft.com/B2C_1A_Residential_UnifiedSignUpOrSignIn/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id=c832c38c-ce70-4ebc-83b6-b4548083ac90
&grant_type=refresh_token
&refresh_token={STORED_REFRESH_TOKEN}
&client_info=1
&scope=https://wattsb2cap02.onmicrosoft.com/wattsapiresi/manage%20offline_access%20openid%20profile
Response:
{
"access_token": "eyJhbGci...",
"refresh_token": "eyJraWQ...",
"expires_in": 900,
"expires_on": 1768718583,
"refresh_token_expires_in": 7776000
}
Initial login requires OAuth2 PKCE with multi-step HTML form scraping (extract CSRF token from HTML → POST credentials → follow redirect → exchange code for tokens). Not feasible in Groovy.
Recommended Hubitat bootstrap approach:
node dist/cli/index.js login from the seanami/homebridge-tekmar-wifi CLIaccess_token, refresh_token, and expires_on (Unix epoch int) from tokens.json into driver preferencesAlternative (unconfirmed): Check if ROPC policy exists:
POST https://login.watts.io/tfp/wattsb2cap02.onmicrosoft.com/B2C_1A_ResourceOwnerPasswordCredentials/oauth2/v2.0/token
grant_type=password&client_id={CLIENT_ID}&scope={SCOPE}&username={email}&password={pw}
If this returns 200 with tokens, initial auth can be done in Hubitat as a simple POST.
// State keys
// state.accessToken (String)
// state.refreshToken (String)
// state.tokenExpiresAt (Long, Unix epoch seconds)
private String getValidToken() {
Long nowSecs = Math.round(now() / 1000.0d) as Long
if (state.tokenExpiresAt && nowSecs > (state.tokenExpiresAt - 300)) {
refreshTokens()
}
return state.accessToken
}
private void refreshTokens() {
def params = [
uri: "https://login.watts.io",
path: "/tfp/wattsb2cap02.onmicrosoft.com/B2C_1A_Residential_UnifiedSignUpOrSignIn/oauth2/v2.0/token",
contentType: "application/json",
requestContentType: "application/x-www-form-urlencoded",
body: "client_id=c832c38c-ce70-4ebc-83b6-b4548083ac90" +
"&grant_type=refresh_token" +
"&refresh_token=${state.refreshToken}" +
"&client_info=1" +
"&scope=https%3A%2F%2Fwattsb2cap02.onmicrosoft.com%2Fwattsapiresi%2Fmanage%20offline_access%20openid%20profile"
]
httpPost(params) { resp ->
if (resp.status == 200) {
state.accessToken = resp.data.access_token
state.refreshToken = resp.data.refresh_token // always update!
state.tokenExpiresAt = resp.data.expires_on as Long
} else {
log.error "Token refresh failed: ${resp.status}"
}
}
}
All calls to https://home.watts.com/api/* require:
Authorization: Bearer {access_token}
Api-Version: 2.0
Content-Type: application/json
refresh_token, the next refresh will fail with 401. Always state.refreshToken = resp.data.refresh_token.smarthome.wattselectronics.com is a European product by Watts Electronics, unrelated to SunStat/Tekmar.getValidToken() guard runs before every HTTP call.seanami/homebridge-tekmar-wifi: https://github.com/seanami/homebridge-tekmar-wifi
— src/lib/api/auth.ts, docs/AUTHENTICATION.md (captured 2026-01-18)