Skip to content

Reference Clients

Three small files under /examples/, each dependency-free, that cover the same loop as the agent guide: log in, refresh on a 401, set preferences, register an appliance, push readings and a weather forecast, pull or recompute a schedule, and apply the current 30-minute slot’s command. Copy one as a starting point, or read it alongside the OpenAPI description to see the same calls typed out.

Both hm_client.py and hm-client.mjs implement the same client surface:

  • Sign up or log in (POST /auth/signup, POST /auth/login), handling both of signup’s response shapes — a session, or a pending user when email confirmation is on
  • Refresh once on a 401 (POST /auth/refresh) and keep retrying the original call, not the caller
  • Get and set preferences (GET/PUT /api/v1/preferences)
  • Register an appliance (POST /api/v1/appliances)
  • Push HVAC readings (POST /api/v1/readings), leaving out the optional client block — its kind names Hungry Machines’ own software, not yours
  • Push the home’s hourly weather forecast once a day (POST /api/v1/weather)
  • Pull today’s schedule (GET /api/v1/schedules) or force an immediate replan (POST /api/v1/schedule/recompute)
  • A slot_command / slotCommand helper that reads the current 30-minute slot from a given local time and returns the HVAC target temperature — falling back to the comfort band’s midpoint, (high_temps[slot] + low_temps[slot]) / 2, when setpoint_temps is absent or null — or, for EV chargers, batteries, robots and water heaters, the boolean on/off command from intervals[slot]

simulate_readings.py is a separate testing tool, not part of the client: it imports hm_client.py and pushes a stream of plausible synthetic indoor/outdoor readings to one HVAC appliance, 5 minutes apart, so you can exercise a client or watch an account leave "defaults" without wiring up real hardware. It reads HM_EMAIL, HM_PASSWORD and HM_APPLIANCE_ID from environment variables and never prints them — run it against a test account only.

Check an entry’s source before you hand it to the helper. An appliance with no stored plan yet comes back from GET /api/v1/schedules as "schedule": {} with source: "defaults": it has no setpoints and no band, so the helper has nothing to read and there is no command to send. Skip that entry until source is "optimization". The files also pull the schedule once; a long-running client should poll GET /api/v1/schedules/updated-at and pull again when its value changes.

None of the three files cover non-HVAC readings (POST /api/v1/appliances/{appliance_id}/readings) or constraints (POST /api/v1/appliances/{appliance_id}/constraints) — see Build your own client for the full appliance-type matrix.