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 (legacy API) - static zone assignments
    • KumoCloudv3 (new 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:

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
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'/thermostatsupervisor:'tag' thermostatsupervisor.'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', 'kumocloudv3', 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
  • 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", "kumocloudv3", "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]
    • kumocloudv3: [0,1] (dynamically assigned based on 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 infinitity).

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

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 thermostatsupervisor.supervisor_flask_server <runtime parameters>"

emulator.py:

Script will run an emulator with fabribated thermostat meta data.

command line usage: "python -m thermostatsupervisor.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 thermostatsupervisor.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 thermostatsupervisor.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 thermostatsupervisor.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 thermostatsupervisor.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 kumocloud account only.
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 thermostatsupervisor.kumocloud <thermostat type> <zone>"

kumocloudv3.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 thermostatsupervisor.kumocloudv3 <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 thermostatsupervisor.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 thermostatsupervisor.blink <thermostat type> <zone>"

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 thermostatsupervisor.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.13.tar.gz (205.4 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.13-py3-none-any.whl (247.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for thermostatsupervisor-1.0.13.tar.gz
Algorithm Hash digest
SHA256 0b47e1db81acb7400334f920aa422b308b34cab993a3c5146f8f994e8154e991
MD5 2b51a2e25e64241ae212a30e269db83c
BLAKE2b-256 07f6fc56d60288936fd2434751af428abbe0182c86810fd7e5e110fbf4c43415

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for thermostatsupervisor-1.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 730737381fbbccb0d1cf44d594baa7428e3aaac9dd3b00b14ddf584a887cf9f0
MD5 d0c03883783d65b9d6a632489a161491
BLAKE2b-256 74d209ed4decad7527b36e38741dff4394ccaa17a58e37bb5fc7459ff0189056

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