Skip to content

Latest commit

 

History

History
709 lines (551 loc) · 19.4 KB

CONFIGURATION.md

File metadata and controls

709 lines (551 loc) · 19.4 KB

Configuration

General

All configuration is written in yaml. It can be loaded either from a local file or Amazon S3 bucket.

When run, parsers will search for configuration in order, once found it will load this configuration. Search order is:

  • Local file, when a file name is given via commandline or code
  • S3 file, when S3 bucket and key information are given via code
  • Local file, when PYDOMOTIC_CONFIG_FILE is set
  • S3 file, when PYDOMOTIC_CONFIG_S3 is set
  • Local file pydomotic.yml

When run via the commandline, the configuration file can be specified as an argument or via environment variable.

$ python -m pydomotic -c /path/to/pydomotic.yml
$ PYDOMOTIC_CONFIG_FILE=/path/to/pydomotic.yml python -m pydomotic

When defined in code, S3 configuration is given as a tuple or string in the form bucket/key.

handler = LambdaHandler(s3=('my-bucket', 'my-key'))
# or
handler = LambdaHandler(s3='my-bucket/my-key')

Otherwise, it must be given as a string in the form bucket/key.

$ PYDOMOTIC_CONFIG_S3=my-bucket/my-key python -m pydomotic

Configuration is grouped into four headings: providers, triggers, devices, and automations.

Reading values from environment variables is available in the form of ${env:MY_ENV_VAR}.

For a complete example configuration file, see tests/testdata/full.yml.

Providers

Currently, four providers are provided out of the box.

  • Tuya: Any device that is supported by the Tuya platform. Many IoT manufacturers rely on Tuya for their device APIs. Supported by the gosundpy Python package.
  • Airthings: Any of the Airthings View devices.
  • Ecobee: Any Ecobee smart thermostat and sensors.
  • Moen: The Flo by Moen smart water shutoff valve.
  • Fujitsu: Any Fujitsu WiFi enabled home heat pump system, supported by the pyfujitseu Python package.
  • Noop: A generic provider which can be assigned to any device, useful for testing.

Contributions and requests for further support are welcome.

Each provider relies on its own dependencies which are not installed by default. This means that for each provider you wish to use (aside from the Noop provider), you must specifically install its dependencies. These are installed as pip extras:

$ pip install pydomotic[tuya]
$ pip install pydomotic[airthings]
$ pip install pydomotic[moen]
$ pip install pydomotic[fujitsu]

Tuya

providers:
  tuya:
    username: ${env:TUYA_USERNAME}
    password: ${env:TUYA_PASSWORD}
    access_id: ${env:TUYA_ACCESS_ID}
    access_key: ${env:TUYA_ACCESS_KEY}
    device_status_cache_seconds: 20
    timeout_seconds: 5

devices:
  my-device:
    description: my cool device
    provider: tuya
    id: '1234567890'

username: (required) Your Tuya username.

password: (required) Your Tuya password.

access_id: (required) Your Tuya access id.

access_key: (required) Your Tuya access key.

device_status_cache_seconds: (optional) Time in seconds for caching any device statuses. Useful to reduce the number of API calls being made when referencing the same device from multiple components.

timeout_seconds: (optional) Timeout in seconds for all calls to the Tuya API. Defaults to no timeout.

Airthings

providers:
  airthings:
    client_id: ${env:AIRTHINGS_CLIENT_ID}
    client_secret: ${env:AIRTHINGS_CLIENT_SECRET}
    data_cache_seconds: 20
    timeout_seconds: 5

devices:
  my-device:
    description: my cool device
    provider: airthings
    id: '1234567890'

client_id: (required) Your Airthings client id.

client_secret: (required) Your Airthings client secret.

data_cache_seconds: (optional) Time in seconds for caching any device statuses. Useful to reduce the number of API calls being made when referencing the same device from multiple components.

timeout_seconds: (optional) Timeout in seconds for all calls to the Airthings API. Defaults to no timeout.

Ecobee

providers:
  ecobee:
    app_key: ${env:ECOBEE_APP_KEY}
    refresh_token: ${env:ECOBEE_REFRESH_TOKEN}

devices:
  my-device:
    description: my cool device
    provider: ecobee
    id: '1234567890'

app_key: (required) Your Ecobee app key.

refresh_token: (required) Your Ecobee refresh token.

Moen

providers:
  moen:
    username: ${env:MOEN_USERNAME}
    password: ${env:MOEN_PASSWORD}

devices:
  my-device:
    description: my cool device
    provider: moen
    id: '1234567890'

username: (required) Your Moen username.

password: (required) Your Moen password.

Fujitsu

providers:
  fujitsu:
    username: ${env:FUJITSU_USERNAME}
    password: ${env:FUJITSU_PASSWORD}

devices:
  my-device:
    description: my cool device
    provider: fujitsu
    id: '1234567890'

username: (required) Your Fujitsu username.

password: (required) Your Fujitsu password.

Noop

devices:
  my-device:
    description: my cool device
    provider: noop
    id: '1234567890'

Unlike other providers, the noop provider does not need to be declared in the providers block.

Devices

devices:
  my-socket:
    description: bedroom window fans
    provider: tuya
    id: '123'
  my-bulb:
    description: living room lamp
    provider: tuya
    id: '456'
  my-sensor:
    description: basement radon detector
    provider: airthings
    id: '789'

<name>: (required) Any string value, in the example above my-socket, my-bulb, and my-sensor are all device names.

description: (optional) Any value, used to help identify a device and give it more context.

provider: (required) One of the currently supported providers.

id: (required) The identifier for the device as given by its 3rd party API.

If provided, any further options are ignored.

Automations

Automations represent logical groupings of triggers and actions.

automations:
  summer:
    enabled: true
    components:
      - if:
          temp: '>78'
        then:
          turn-on: socket-A
        else:
          turn-off: socket-A
      - if:
          weekday: saturday,sunday
          sunset: -60
        then:
          turn-on: socket-B

<name>: (required) Any string value, in the example above summer is the automation name.

<name>.enabled: (optional) When true, the components in this automation will be run, otherwise they will be ignored.

<name>.components: (optional) A list, each item can optionally include if, then, and else keys. The if is an object containing the triggers to run. When all triggers evaluate to true, the actions contained in the then object are run. If any of the triggers evaluate to false, the actions contained in the else object are run.

Triggers

The top level triggers block contains configuration required for 3rd party APIs.

triggers:
  location:
    latitude: 40.689
    longitude: -74.044
  timezone: 'America/New_York'
  aqi:
    api_key: ${env:AQI_API_KEY}
  weather:
    api_key: ${env:OPEN_WEATHER_API_KEY}
    data_cache_seconds: 20

location.latitude and location.longitude: (optional) The physical location of your home. Required for determining weather, sunrise/sunset times, air quality, and timezone. Either location or timezone are required.

timezone: (optional) The timezone of the physical location of your home using the timezone identifier from the IANA database. When not set, location.longitude and location.latitude values can be used to determine timezone. However doing so requires installing separate dependencies by running pip install pydomotic[tz]. These dependencies are not installed by default because they take up significant disk space. Either location or timezone are required.

aqi.api_key: (optional) Your API key used to access https://docs.airnowapi.org. Required when using AQI triggers.

weather.api_key: (optional) Your API key used to access https://openweathermap.org. Required when using temperature triggers.

AQI Trigger

Fires when the outdoor air quality index matches a given value or range of values.

automations:
  air-purifier:
    enabled: true
    components:
      - if:
          aqi: '>100'
        then:
          turn-on: switch-A

aqi: (optional) Air quality index to match. Can be single value (ex: 100), a relative value (ex: >=50), or a range of values (ex: 50-100). Multiple values can be given separated by a comma (ex: <50,100-150).

Time Trigger

Fires when the time matches the given value or range of values.

automations:
  night-light:
    enabled: true
    components:
      - if:
          time: 6:00pm
        then:
          turn-on: switch-A

time: (optional) Time value to match, in the form of HH:MMpm. Can be a single value (ex: 5:00am) or a range of values (ex: 9:00pm-11:00pm). Multiple values can be given separated by a comma (ex: 4:00am,5:00am,6:30pm).

Weekday Trigger

Fires when the day of the week matches the given value or range of values.

automations:
  party-time:
    enabled: true
    components:
      - if:
          weekday: Friday
          time: 6:00pm
        then:
          turn-on: stereo

weekday: (optional) The day of the week value to match. Case insensitive and abreviations supported. Can be a single value (ex: Monday) or a range of values (ex: mon-fri). Multiple values can be given separated by a comma (ex: mon,wed,fri).

Date Trigger

Fires when the current date (year, month, day) matches the given value.

automations:
  vacation:
    enabled: true
    components:
      - if:
          date: 2020-03-20
          time: 12:00pm
        then:
          switch: lightbulb-B

date: (optional) The date value to match, in the form of YYYY-MM-DD. Multiple values can be given separated by a comma (ex: 2022-01-15,2022-02-15).

Cron Trigger

Fires when the given cron expression matches the current date/time.

automations:
  fans:
    enabled: true
    components:
      - if:
          cron: '*/15 * * * *'
        then:
          turn-on: socket-A

cron: (optional) Cron expression to match the current date/time. Several predefined shortcuts are supported like @hourly, @daily, @weekly, and @monthly.

Random Trigger

Fires randomly under the given probability.

automations:
  vacation:
    enabled: true
    components:
      - if:
          random: 0.25
        then:
          turn-on: socket-A
        else:
          turn-off: socket-A

random: (optional) The probability between 0 and 1 under which the trigger should fire. The greater the value, the greater the chance the trigger will fire. When 0 the trigger will never fire, when 1 the trigger will always fire, and when 0.5 the trigger will fire one half of the time.

Sunrise/Sunset Trigger

Fires relative to sunrise/sunset time at the current location.

automations:
  wake-up:
    enabled: true
    components:
      - if:
          weekday: mon-fri
          sunrise: 60
        then:
          turn-on: radio

sunrise or sunset: (optional) Time relative to sunrise/sunset to match. When a positive integer (ex: 90) will fire that many minutes after sunrise/sunset. When a negative integer (ex: -120) will fire that many minutes before sunrise/sunset. Can be a single value or a range of values (ex: 45-90). Multiple values can be given separated by a comma (ex: -15,80).

Temperature Trigger

Fires when the outdoor temperature matches the given value or range of values.

automations:
  air-conditioner:
    enabled: true
    components:
      - if:
          temp: '>75'
        then:
          turn-on: switch-A

temp: (optional) Outdoor temperature value to match. Can be single value (ex: 100), a relative value (ex: >=50), or a range of values (ex: 50-100). Multiple values can be given separated by a comma (ex: <50,90-105).

Radon Trigger

Fires when the radon detection level matches the given value or range of values. Only supported as part of a device trigger.

devices:
  radon-sensor:
    description: radon sensor crawlspace
    provider: airthings
    id: '1234567890'

automations:
  air-purifier:
    enabled: true
    components:
      - if:
          radon-sensor:
            radon: '>4'
        then:
          turn-on: switch-A

<name>.radon: (required) Radon level to match in pCi/L. Can be single value (ex: 100), a relative value (ex: >=50), or a range of values (ex: 50-100). Multiple values can be given separated by a comma (ex: <50,100-150).

Webhook Trigger

Fires when the request path matches the given value. Currently only supported in LambdaHandlers. Used to remotely trigger an action based on an external event.

automations:
  releases:
    enabled: true
    components:
      - if:
          webhook: /new-release
        then:
          turn-on: party-lights

webhook: (optional) Request path to match. Path must match exactly and the request must be a POST in order to fire.

Device (Sensor) Trigger

Fires when the result returned by a sensor matches the given value.

devices:
  thermometer:
    description: temperature sensor bedroom
    provider: tuya
    id: '1234567890'

automations:
  heatlamp:
    enabled: true
    components:
      - if:
          thermometer:
            temp: '<60'
        then:
          turn-on: 'socket-A'

<name>: (optional) The name of the device from which to take the reading.

<name>.<value>: (required) Any of the available triggers as defined above, most commonly temp and radon.

Actions

Depending on the device and its provider, the following actions are available.

Turn On/Off Action

Turns on/off the given device.

automations:
  bedroom:
    enabled: true
    components:
      - if:
          time: 10:00am-12:00pm
        then:
          turn-on: 'socket-A'
        else:
          turn-off: 'socket-A'

turn-on and turn-off: (optional) Matches device name as defined in the devices section.

Switch Action

Switches the state of the given device.

automations:
  vacation:
    enabled: true
    components:
      - if:
          random: 0.10
        then:
          switch: 'socket-A'

switch: (optional) Matches device name as defined in the devices section.

Set Mode Action

Sets the current mode for a Flo by Moen device.

devices:
  flo:
    description: Flo by Moen
    provider: moen
    id: '1234567890'

automations:
  vacation:
    enabled: true
    components:
      - if:
          date: 2020-03-20
          time: 7:00am
        then:
          set-mode:
            device: flo
            mode: sleep
            revert-min: 60
            revert-mode: away

set-mode.device: (required) Name of the device whose mode to change.

set-mode.mode: (required) The mode to change to, one of home, away, or sleep.

set-mode.revert-min: (optional) When changing to sleep mode, minutes to wait before automatically reverting mode. Defaults to 480 minutes (8 hours).

set-mode.revert-mode: (optional) When changing to sleep mode, mode to revert to after completion of the sleep, one of home or away. Defaults to home.

Execute Code Action

Lazy loads and executes the given Python method.

devices:
  radon-sensor:
    description: basement radon
    provider: airthings
    id: '1234567890'

automations:
  radon-alert:
    enabled: true
    components:
      - if:
          radon-sensor:
            radon: '>4'
        then:
          exec: custom_actions.send_email

exec: (optional) The module and method name to execute in the form of module.method. Multiple values can be given separated by a comma (ex: custom_actions.turn_on,custom_actions.send_email). Method must accept just one argument, the context object which holds references to all configured sensors and devices. For example:

# custom_actions.py

import boto3
client = boto3.client('ses')

def send_email(context):
    radon = context.devices['radon-sensor'].current_radon()
    client.send_email(
        Source='[email protected]',
        Destination={
            'ToAddresses': ['[email protected]'],
        },
        Message={
            'Subject': {'Data': 'Radon levels too high!'},
            'Body': {
                'Text': {'Data': f'The current radon level is {radon}.'},
            },
        },
    )

Aliases

Aliases are a way to group sections of your configuration file under a single name to be referenced later.

Device Aliases

Device aliases allow you to use a custom name to represent a group of devices. This is useful if you wish to group devices together and reference them by a single name.

For example, consider the following configuration:

automations:
  lighting:
    enabled: true
    components:
      - if:
          sunset: -60
        then:
          turn-on: light-A, light-B, light-C
      - if:
          time: 11:00pm
        then:
          turn-off: light-A, light-B, light-C

  fan:
    enabled: true
    components:
      - if:
          temp: '>78'
        then:
          turn-on: fan-A, fan-B, fan-C
      - if:
          time: 11:00pm
        then:
          turn-off: fan-A, fan-B, fan-C

But now, if you ever wish to add another light to the group, you would need to update all the automations that reference the group. Instead, you can use an alias and only define the group of devices once:

aliases:
  devices:
    lights:
      - light-A
      - light-B
      - light-C
    fans:
      - fan-A
      - fan-B
      - fan-C

automations:
  lighting:
    enabled: true
    components:
      - if:
          sunset: -60
        then:
          turn-on: lights
      - if:
          time: 11:00pm
        then:
          turn-off: lights

  fan:
    enabled: true
    components:
      - if:
          temp: '>78'
        then:
          turn-on: fans
      - if:
          time: 11:00pm
        then:
          turn-off: fans