Every data poll and every action was calling authenticate() before each request, so the integration logged in to the RainMachine on every fetch (with remember=1, i.e. a long-lived token). With the fast + full coordinators sharing one client, this created a fresh token every few seconds — flooding the device's token store (hundreds of tokens, capped at 500) and its "connected clients" list.
Now the client authenticates once, reuses self._token across all requests and both coordinators, and re-authenticates only when a request returns HTTP 401 (token expired/invalid), retrying that request once. test_connection still authenticates explicitly to validate the password during setup.
Result: one token per session instead of hundreds, far less load on the controller, and a clean session list.