Skip to main content

Monitor remote thermostats and correct deviations from schedule.

Project description

Codacy Security Scan CodeQL Build Status Docker Image CI OSSAR Pylint Code style: black Quality Gate Status

ThermostatSupervisor:

supervisor to detect and correct thermostat deviations

Thermostat & Temperature Monitor Support:

  1. Honeywell thermostat through TCC web site (user must configure TCC web site credentials as environment variables).
  2. 3M50 thermostat on local net (user must provide local IP address of each 3m50 thermostat zone).
  3. SHT31 temperature sensor either locally or remote (user must provide local/remote IP address in environment variables and setup firewall port routing if remote).
  4. Mitsubishi ductless thermostat through KumoCloud on remote network (monitoring) or local network (monitoring and control).
    • KumoCloud (v3 API) - dynamic zone assignments with improved functionality
  5. Blink camera temperature sensors.
  6. Nest thermostats.

errata:

  1. Honeywell thermostat support through TCC web site requires 3 minute poll time (or longer). Default for this thermostat is set to 10 minutes.
  2. a few other low frequency intermittent issues exist, refer to issues in github repo for details.
  3. KumoCloud remote connection currently only supports monitoring, cannot set or revert settings.
  4. supervisor_flask_server not currently working on Linux server.

Build Information:

See Build and Release Process for detailed release instructions.

dependencies:

pyhtcc for Honeywell thermostats (pip3 install pyhtcc)
radiotherm for 3m50 thermostats (mhrivnak/radiotherm or pip3 install radiotherm)
flask, flask-resful, and fask-wtf for sht31 flask server
flask and flask-wtf for supervisor flask server
pykumo for kumocloud (KumoCloud v3 API) and kumolocal
blinkpy for blink camera temp sensor support
python-google-nest for nest temp sensor support
coverage for code coverage analysis
psutil for all thermostat types
refer to requirements.txt for full list of package dependencies.

Run the Docker Image:

docker run --rm -it --privileged --env-file 'envfile' 'username'/src:'tag' src.'module' 'runtime parameters'

  • '--rm' removes the docker container when done
  • '-it' runs in interactive mode so that output is displayed in the console
  • '--env-file' specifies your env variables from file 'envfile', see below for required env variables
  • '--privileged' runs in privileged mode, this may be required to avoid PermissionErrors with device objects
  • 'username' is your DockerHub username
  • 'tag' is the Docker image tag (e.g. 'develop', 'main', etc.)
  • 'module' is the module to run, (e.g. 'supervise', 'honeywell', 'kumocloud', etc.).
  • 'runtime parameters' are supervise runtime parameters as specified below.

Note: The Docker container is configured to use the timezone specified in the timezone file (currently America/Chicago). This ensures that time-based functions display the correct local time instead of UTC.

GitHub repository environment variables required for docker image build (settings / secrets):

  • 'DOCKER_USERNAME' is your DockerHub username
  • 'DOCKER_PASSWORD' is your DockerHub password

Execution Information:

debug / diagnostics:

  1. ./data/ folder contains supervisor logs, including integrated pyhtcc logs
  2. Honeywell pyhtcc logs are integrated into supervisor logging (./data/honeywell_log.txt)

required environment variables:

Environment variables required depend on the thermostat being used.

  • All configurations require the GMAIL env vars:
    • 'GMAIL_USERNAME': email account to send notifications from (source) and to (destination)
    • 'GMAIL_PASSWORD': password for GMAIL_USERNAME
  • Honeywell thermostat requires the 'TCC' env vars:
    • 'TCC_USERNAME': username to Honeywell TCC website
    • 'TCC_PASSWORD': password for TCC_USERNAME
  • SHT31 temp sensor requires the 'SHT31' env vars:
    • 'SHT31_REMOTE_IP_ADDRESS_'zone'': remote IP address / URL for SHT31 thermal sensor, 'zone' is the zone number.
  • Mitsubishi ductless requires the 'KUMOCLOUD' env vars:
    • 'KUMO_USERNAME': username for Kumocloud account
    • 'KUMO_PASSWORD': password for Kumocloud account
  • Blink camera temp sensor requires the 'BLINK' env vars:
    • 'BLINK_USERNAME': username for Blink account
    • 'BLINK_PASSWORD': password for Blink account
    • 'BLINK_2FA': 2 factor auth string for Blink account
    • Setup details for credentials, 2FA, zone mapping, and precedence: Blink User Setup
  • Nest thermostat requires the 'NEST' env vars or env vars supplied via a json file:
    • 'GCLOUD_CLIENT_ID': client ID from Google Clout OAuth credentials
    • 'GCLOUD_CLIENT_SECRET': client secret from Google Clout OAuth credentials
    • 'DAC_PROJECT_ID': project ID from the Nest Device access console
    • Optional env vars to automate initial authorization (eliminates manual URL prompt):
      • 'NEST_ACCESS_TOKEN': OAuth access token from previous authorization
      • 'NEST_REFRESH_TOKEN': OAuth refresh token from previous authorization
      • 'NEST_TOKEN_EXPIRES_IN': token expiration time in seconds (optional, defaults to 3600)
  • Flask applications support optional security and functionality env vars:
    • 'SECRET_KEY': secret key for Flask CSRF protection (optional - auto-generated if not provided)
    • 'WEATHER_API_KEY': OpenWeatherMap API key for outdoor weather data (optional - mock data used if not provided)

updating environment variables:

  • Linux: update file ~/.profile and then "source ~/.profile" to load the file
  • Windows: define env variables in control panel and then re-start IDE
  • docker image: export the env files to a text file and specify during the docker run command
  • Local development: Create a supervisor-env.txt file in the project root directory with KEY=VALUE pairs (one per line). This file will take precedence over system environment variables and is useful for testing and debugging. The file is automatically ignored by git. See supervisor-env.txt.example for a template.

Source Code Information:

supervise.py:

This is the main entry point script.
runtime parameters can be specified to override defaults either via single dash named parameters or values in order:

  • '-h'= help screen
  • argv[1] or '-t'= Thermostat type, currently support "honeywell", "mmm50", "sht31", "kumocloud", "kumolocal" and "blink". Default is "honeywell".
  • argv[2] or '-z'= zone, currently support:
    • honeywell = zone 0 only
    • 3m50 = zones [0,1] on local net
    • sht31: 0 = local net, 1 = remote URL
  • kumocloud, kumolocal: [0,1,2]
    • kumocloud: [0,1,2] (dynamically assigned based on the v3 API response)
    • blink = [0,1,2,3,4,5,6,7,8]
    • emulator = zone 0 only
  • argv[3] or '-p'= poll time in seconds (default is thermostat-specific)
  • argv[4] or '-c'= re-connect time in seconds (default is thermostat-specific)
  • argv[5] or '-d'= tolerance from setpoint allowed in °F (default is 2°F)
  • argv[6] or '-m'= target thermostat mode (e.g. OFF_MODE, COOL_MODE, HEAT_MODE, DRY_MODE, etc.), not yet fully functional.
  • argv[7] or '-n'= number of measurements (default is infinity).

    command line usage (unnamed): "python -m src.supervise <thermostat type> <zone> <poll time> <connection time> <tolerance> <target mode> <measurements>".
    command line usage (named): "python -m src.supervise -t <thermostat type> -z <zone> -p <poll time> -c <connection time> -d <tolerance> -m <target mode> -n <measurements>"

site_supervise.py:

This module provides site-level orchestration for monitoring multiple thermostats simultaneously.
Supports concurrent supervision with multi-threading, per-thermostat configuration, and selective thermostat inclusion/exclusion.
See Site Supervise Documentation for detailed configuration and usage information.
Command-line options:

  • '-h' or '--help': Display help screen with all options
  • '-c' or '--config': Path to site configuration JSON file (default: uses built-in config)
  • '-n' or '--measurements': Number of measurements per thermostat (overrides config)
  • '--threading': Enable multi-threading for parallel supervision (default)
  • '--no-threading': Disable multi-threading (run sequentially for debugging)
  • '-v' or '--verbose': Enable verbose logging (default)
  • '-q' or '--quiet': Disable verbose logging
  • '--display-zones': Display all zones and exit (no supervision)
  • '--display-temps': Display current temperatures and exit (no supervision)

    command line usage: "python -m src.site_supervise [options]"
    Examples:
  • Use default configuration: "python -m src.site_supervise"
  • Use custom config file: "python -m src.site_supervise -c mysite.json"
  • Override measurement count: "python -m src.site_supervise -n 10"
  • Display zones only: "python -m src.site_supervise --display-zones"
  • Disable threading: "python -m src.site_supervise --no-threading"

supervisor_flask_server.py:

This module will render supervise.py output on an HTML page using Flask.
Same runtime parameters as supervise.py can be specified to override defaults:
Port is currently hard-coded to 5001, access at server's local IP address

command line usage: "python -m src.supervisor_flask_server <runtime parameters>"

emulator.py:

Script will run an emulator with fabribated thermostat meta data.

command line usage: "python -m src.emulator <thermostat type> <zone>"

honeywell.py:

Script will logon to TCC web site and query thermostat meta data.
Default poll time is currently set to 3 minutes, longer poll times experience connection errors, shorter poll times are impractical based on emperical data.

command line usage: "python -m src.honeywell <thermostat type> <zone>"

mmm50.py:

Script will connect to 3m50 thermostat on local network, IP address stored in mmm_config.mmm_metadata.
Default poll time is currently set to 10 minutes.

command line usage: "python -m src.mmm <thermostat type> <zone>"

sht31.py:

Script will connect to sht31 thermometer at URL specified (can be local IP or remote URL).
Default poll time is currently set to 1 minute.

command line usage: "python -m src.sht31 <thermostat type> <zone>"

sht31_flask_server.py:

This module will render sht31 sensor output on an HTML page using Flask.
Port is currently hard-coded to 5000.
Production data is at /data, subfolders provide additional commands:

  • /data: production data
  • /unit: unit test (fabricated) data
  • /diag: fault register data
  • /clear_diag: clear the fault register
  • /enable_heater: enable the internal heater
  • /disable_heater: disable the internal heater
  • /soft_reset: perform soft reset
  • /reset: perform hard reset
  • /i2c_recovery: perform clock reset to unlock a stuck i2c bus
  • /i2c_detect: detect i2c device on either bus
  • /i2c_detect_0: detect i2c device on bus 0
  • /i2c_detect_1: detect i2c device on bus 1
  • /i2c_logic_levels: read current logic levels of i2c SDA and SCL pins
  • /i2c_bus_health: comprehensive i2c bus health check with diagnostics
  • /print_block_list: print out the ip ban block list
  • /clear_block_list: clear the ip ban block list

server command line usage:

"python -m src.sht31_flask_server <debug>"
argv[1] = debug (bool): True to enable Flask debug mode, False is default.

client URL usage:

production: "<ip>:<port>/data?measurements=<measurements>"
unit test: "<ip>:<port>/unit?measurements=<measurements>&seed=<seed>"
diag: "<ip>:<port>/diag"
measurements=number of measurements to average (default=10)
seed=seed value for fabricated data in unit test mode (default=0x7F)

kumocloud.py:

Script will connect to Mitsubishi ductless thermostat through the new KumoCloud v3 API.
Default poll time is currently set to 18 seconds.
Zone assignments are dynamically discovered from the v3 API and can vary between installations.
Uses the same login credentials as legacy kumocloud but provides improved functionality and dynamic zone management.

command line usage: "python -m src.kumocloud <thermostat type> <zone>"

kumolocal.py:

Script will connect to Mitsubishi ductless thermostat through kumocloud account and local network.
Default poll time is currently set to 10 minutes.
Zone number refers to the thermostat order in kumocloud, 0=first thermostat data returned, 1=second thermostat, etc.

command line usage: "python -m src.kumolocal <thermostat type> <zone>"

blink.py:

Script will connect to Blink camera through Blink account.
Default poll time is currently set to 10 minutes.
Zone number refers to the thermostat order in Blink server, 0=first thermostat data returned, 1=second thermostat, etc.

command line usage: "python -m src.blink <thermostat type> <zone>" Blink setup reference: docs/blink-user.md

nest.py:

Script will connect to nest thermostats through Google Device Access console account.
Follow instructions in this repo to setup Google Device Access registration and Google Cloud OAuth account: https://github.com/axlan/python-nest/.
Default poll time is currently set to 10 minutes.
Zone number refers to the thermostat order in nest server, 0=first thermostat data returned, 1=second thermostat, etc.

command line usage: "python -m src.nest <thermostat type> <zone>"

Supervisor API required methods:

For complete API documentation, see: Thermostat Classes API and Zone Classes API

Thermostat class:

  • print_all_thermostat_metadata(): Print all thermostat meta data.
  • get_target_zone_id(): Return the target zone ID.

Zone class:

  • get_current_mode(): Determine whether thermostat is following schedule or if it has been deviated from schedule.
  • report_heating_parameters(): Display critical thermostat settings and reading to the screen.
  • get_schedule_heat_sp(): Retrieve the scheduled heat setpoint.
  • set_heat_setpoint(): Sets a new heat setpoint.
  • get_schedule_cool_sp(): Retrieve the scheduled cool setpoint.
  • set_cool_setpoint(): Set a new cool setpoint.
  • refresh_zone_info(): Refresh the zone_info attribute.

API Documentation

Comprehensive API documentation is automatically generated and available through GitHub Pages:

Main Documentation: ThermostatSupervisor API Documentation

Specific API References:

The documentation includes:

  • Complete API reference for all modules
  • Required and optional method specifications
  • Examples and usage patterns
  • Supported thermostat types and configurations
  • Environment variable requirements

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thermostatsupervisor-1.0.16.tar.gz (272.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

thermostatsupervisor-1.0.16-py3-none-any.whl (314.1 kB view details)

Uploaded Python 3

File details

Details for the file thermostatsupervisor-1.0.16.tar.gz.

File metadata

  • Download URL: thermostatsupervisor-1.0.16.tar.gz
  • Upload date:
  • Size: 272.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for thermostatsupervisor-1.0.16.tar.gz
Algorithm Hash digest
SHA256 2060a3f1d90d56685b4075012a7ac74f1644da2314c9649da2ecc74a56041448
MD5 6a89edf05d962d56f65f2e5f8d252538
BLAKE2b-256 bd684ef0ae2fac836547f609b096944934b4380a8212aadabae42bfc1d1cc3df

See more details on using hashes here.

File details

Details for the file thermostatsupervisor-1.0.16-py3-none-any.whl.

File metadata

File hashes

Hashes for thermostatsupervisor-1.0.16-py3-none-any.whl
Algorithm Hash digest
SHA256 d457320d74323ed517d740bc2f1b86d296cd6edcb5df41cfdf2134321194e4ee
MD5 35be5701fd7c490069e605afbb662c70
BLAKE2b-256 1e38b250ba179087a3ace2c7d7480e13fb19528a6cd6b30f7b375fcec4dbc585

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page