switchbot-actions


Nameswitchbot-actions JSON
Version 1.0.2 PyPI version JSON
download
home_pageNone
SummaryA YAML-based automation engine for SwitchBot BLE devices with a Prometheus exporter.
upload_time2025-07-13 16:10:50
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords switchbot automation prometheus ble home-automation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # SwitchBot Actions: A YAML-based Automation Engine

A powerful, configurable automation engine for SwitchBot BLE devices, with an optional Prometheus exporter.

This application continuously scans for SwitchBot Bluetooth Low Energy (BLE) devices and provides a powerful automation engine that can:

-   **React to Events**: Trigger custom actions (like shell commands or webhooks) the moment a device's state changes.
-   **Monitor Sustained States**: Trigger actions when a device remains in a specific state for a continuous duration.

It also includes an optional **Prometheus Exporter** to expose sensor data (temperature, humidity, etc.) and device state as Prometheus metrics.

Inspired by services like GitHub Actions, all behavior is controlled through a single `config.yaml` file, allowing you to define flexible and powerful automation workflows without any code changes.

## Features

-   **Real-time Monitoring**: Gathers data from all nearby SwitchBot devices.
-   **Prometheus Integration**: Exposes metrics at a configurable `/metrics` endpoint.
-   **Powerful Automation**: Define rules to trigger actions based on state changes (`actions`) or sustained states (`timers`).
-   **Flexible Conditions**: Build rules based on device model, address, sensor values, and even signal strength (`rssi`).
-   **Highly Configurable**: Filter devices, select metrics, and define complex rules from a single configuration file.
-   **Extensible Architecture**: Built on a clean, decoupled architecture, making it easy to extend.

## Getting Started

### Prerequisites

  * Python 3.10+
  * A Linux-based system with a Bluetooth adapter that supports BLE (e.g., Raspberry Pi).

### Installation (Recommended using pipx)

For command-line applications like this, we strongly recommend installing with `pipx` to keep your system clean and avoid dependency conflicts.

1.  **Install pipx:**

    ```bash
    pip install pipx
    pipx ensurepath
    ```

    *(You may need to restart your terminal after this step for the path changes to take effect.)*

2.  **Install the application:**

    ```bash
    pipx install switchbot-actions
    ```

3.  **Create your configuration file:**
    Download the example configuration from the GitHub repository to get started.

    ```bash
    curl -o config.yaml https://raw.githubusercontent.com/hnw/switchbot-actions/main/config.yaml.example
    ```

    Then, edit `config.yaml` to suit your needs.

### Alternative Installation (using pip)

If you prefer to manage your environments manually, you can use `pip`. It is recommended to do this within a virtual environment (`venv`).

```bash
# This command installs the package.
# To avoid polluting your global packages, consider running this in a venv.
pip install switchbot-actions
```

## Usage

We recommend a two-step process to get started smoothly.

### Step 1: Verify Hardware and Device Discovery

First, run the application without any configuration file to confirm that your Bluetooth adapter is working and can discover your SwitchBot devices.

```bash
switchbot-actions --debug
```

The `--debug` flag will show detailed logs. If you see lines containing "Received advertisement from...", your hardware setup is correct.

> [\!IMPORTANT]
> **A Note on Permissions on Linux**
>
> If you encounter errors related to "permission denied," you may need to run the command with `sudo`:
>
> ```bash
> sudo switchbot-actions --debug
> ```

### Step 2: Configure and Run

Once you've confirmed that device discovery is working, create your `config.yaml` file. You can use the example as a starting point:

```bash
curl -o config.yaml https://raw.githubusercontent.com/hnw/switchbot-actions/main/config.yaml.example
```

Edit `config.yaml` to define your automations. Then, run the application normally:

```bash
switchbot-actions -c config.yaml
```

## Configuration

The application is controlled by `config.yaml`. See `config.yaml.example` for a full list of options.

> [!NOTE]
> This section provides a quick overview. For a detailed and complete reference of all configuration options, please see the [**Project Specification**](./docs/specification.md#4-configuration-configyaml).

### Command-Line Options

-   `--config <path>` or `-c <path>`: Specifies the path to the configuration file (default: `config.yaml`).
-   `--debug` or `-d`: Enables `DEBUG` level logging, overriding any setting in the config file. This is useful for temporary troubleshooting.
-   `--scan-cycle <seconds>`: Overrides the scan cycle time.
-   `--scan-duration <seconds>`: Overrides the scan duration time.
-   `--interface <device>`: Overrides the Bluetooth interface (e.g., `hci1`).

### Scanner (`scanner`)

Configure the behavior of the Bluetooth (BLE) scanner.

```yaml
scanner:
  # Time in seconds between the start of each scan cycle.
  cycle: 10
  # Time in seconds the scanner will actively listen for devices.
  # Must be less than or equal to `cycle`.
  duration: 3
  # Bluetooth interface to use.
  interface: "hci0"
```

### Event-Driven Actions (`actions`)

Trigger an action **the moment** a device's state changes to meet the specified conditions (edge-triggered). The action will only fire once and will not fire again until the conditions have first become false and then true again.

In the `state` conditions, you can use the following operators for comparison: `>` (greater than), `<` (less than), `>=` (greater/equal), `<=` (less/equal), `==` (equal), and `!=` (not equal).

```yaml
actions:
  - name: "High Temperature Alert"
    # Cooldown for 10 minutes to prevent repeated alerts
    cooldown: "10m" # Supports formats like "5s", "10m", "1.5h"
    conditions:
      device:
        modelName: "Meter"
      state:
        # Triggers the moment temperature becomes greater than 28.0
        temperature: "> 28.0"
    trigger:
      type: "webhook"
      url: "https://example.com/alert"
      payload:
        message: "High temperature detected: {temperature}°C"
      # Optional: Add custom headers for APIs that require them
      headers:
        Authorization: "Bearer YOUR_API_KEY"
        X-Custom-Header: "Value for {address}"

  - name: "Weak Signal Notification"
    conditions:
      device:
        address: "XX:XX:XX:XX:XX:AA"
      state:
        # Triggers if the signal strength is weaker (more negative) than -80 dBm
        rssi: "< -80"
    trigger:
      type: "shell_command"
      command: "echo 'Device {address} has a weak signal (RSSI: {rssi})'"
```

> [!NOTE]
> You can use placeholders in `command`, `url`, `payload`, and `headers`. Available placeholders include `{address}`, `{modelName}`, `{rssi}`, and any sensor value found in the device's data (e.g., `{temperature}`, `{humidity}`, `{isOn}`).

### Time-Driven Timers (`timers`)

Trigger an action when a device has been in a specific state for a **continuous duration** (one-shot). Once the timer fires, it will not restart until the conditions have first become false and then true again.

```yaml
timers:
  - name: "Turn off Lights if No Motion"
    conditions:
      device:
        modelName: "WoPresence"
      state:
        # The state that must be true for the whole duration
        motion_detected: False
      # The duration the state must be sustained
      duration: "5m"
    trigger:
      type: "shell_command"
      command: "echo 'No motion for 5 minutes, turning off lights.'"

  - name: "Alert if Door is Left Open"
    conditions:
      device:
        modelName: "WoContact"
      state:
        contact_open: True
      duration: "10m"
    trigger:
      type: "webhook"
      url: "https://example.com/alert"
      payload:
        message: "Warning: Door {address} has been open for 10 minutes!"
```

### Prometheus Exporter (`prometheus_exporter`)

This feature exposes all collected SwitchBot device data as Prometheus metrics, allowing for powerful monitoring and visualization. Once enabled, metrics will be available at the `/metrics` endpoint (e.g., `http://localhost:8000/metrics`). You can scrape this endpoint with a Prometheus server and use tools like Grafana to create dashboards for temperature, humidity, battery levels, and more.

```yaml
prometheus_exporter:
  enabled: true
  port: 8000
  target:
    # Optional: Only export metrics for these MAC addresses
    addresses:
      - "XX:XX:XX:XX:XX:AA"
    # Optional: Only export these specific metrics
    metrics:
      - "temperature"
      - "humidity"
      - "battery"
      - "rssi"
```

### Logging (`logging`)

Configure the log output format and verbosity. This allows for fine-grained control over log output for both the application and its underlying libraries.

```yaml
logging:
  # Default log level for the application: DEBUG, INFO, WARNING, ERROR
  level: "INFO"

  # Log format using Python's logging syntax
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

  # Set specific log levels for noisy libraries.
  # This is useful for debugging specific components without enabling global debug.
  loggers:
    bleak: "WARNING" # Can be set to DEBUG for deep BLE troubleshooting
    # aiohttp: "WARNING"
```

#### Debugging Notes

-   **For Application Development (`--debug` flag):**
    When you run the exporter with `--debug` or `-d`, the `logging` section in your `config.yaml` is **ignored**. This flag is a shortcut that:
    1.  Sets the log level for `switchbot-actions` to `DEBUG`.
    2.  Sets the log level for the `bleak` library to `INFO` to keep the output clean.

-   **For Library Troubleshooting (e.g., `bleak`):**
    If you need to see `DEBUG` messages from a specific library like `bleak`, do **not** use the `--debug` flag. Instead, edit `config.yaml` and set the desired level in the `loggers` section:
    ```yaml
    logging:
      level: "INFO" # Keep the main app quiet
      loggers:
        bleak: "DEBUG" # Enable detailed output only for bleak
    ```

-   **Troubleshooting Actions and Timers:**
    By default, the execution of `actions` and `timers` is not logged to `INFO` to avoid excessive noise. If you need to verify that your triggers are running, enable `DEBUG` logging for the triggers module in `config.yaml`:
    ```yaml
    logging:
      level: "INFO"
      loggers:
        switchbot_actions.triggers: "DEBUG"
    ```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "switchbot-actions",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "switchbot, automation, prometheus, ble, home-automation",
    "author": null,
    "author_email": "Yoshio HANAWA <y@hnw.jp>",
    "download_url": "https://files.pythonhosted.org/packages/bb/42/759bf9f55cfce915b3f9eaf8b18775228828f5fa75515e5a2c1b5814e556/switchbot_actions-1.0.2.tar.gz",
    "platform": null,
    "description": "# SwitchBot Actions: A YAML-based Automation Engine\n\nA powerful, configurable automation engine for SwitchBot BLE devices, with an optional Prometheus exporter.\n\nThis application continuously scans for SwitchBot Bluetooth Low Energy (BLE) devices and provides a powerful automation engine that can:\n\n-   **React to Events**: Trigger custom actions (like shell commands or webhooks) the moment a device's state changes.\n-   **Monitor Sustained States**: Trigger actions when a device remains in a specific state for a continuous duration.\n\nIt also includes an optional **Prometheus Exporter** to expose sensor data (temperature, humidity, etc.) and device state as Prometheus metrics.\n\nInspired by services like GitHub Actions, all behavior is controlled through a single `config.yaml` file, allowing you to define flexible and powerful automation workflows without any code changes.\n\n## Features\n\n-   **Real-time Monitoring**: Gathers data from all nearby SwitchBot devices.\n-   **Prometheus Integration**: Exposes metrics at a configurable `/metrics` endpoint.\n-   **Powerful Automation**: Define rules to trigger actions based on state changes (`actions`) or sustained states (`timers`).\n-   **Flexible Conditions**: Build rules based on device model, address, sensor values, and even signal strength (`rssi`).\n-   **Highly Configurable**: Filter devices, select metrics, and define complex rules from a single configuration file.\n-   **Extensible Architecture**: Built on a clean, decoupled architecture, making it easy to extend.\n\n## Getting Started\n\n### Prerequisites\n\n  * Python 3.10+\n  * A Linux-based system with a Bluetooth adapter that supports BLE (e.g., Raspberry Pi).\n\n### Installation (Recommended using pipx)\n\nFor command-line applications like this, we strongly recommend installing with `pipx` to keep your system clean and avoid dependency conflicts.\n\n1.  **Install pipx:**\n\n    ```bash\n    pip install pipx\n    pipx ensurepath\n    ```\n\n    *(You may need to restart your terminal after this step for the path changes to take effect.)*\n\n2.  **Install the application:**\n\n    ```bash\n    pipx install switchbot-actions\n    ```\n\n3.  **Create your configuration file:**\n    Download the example configuration from the GitHub repository to get started.\n\n    ```bash\n    curl -o config.yaml https://raw.githubusercontent.com/hnw/switchbot-actions/main/config.yaml.example\n    ```\n\n    Then, edit `config.yaml` to suit your needs.\n\n### Alternative Installation (using pip)\n\nIf you prefer to manage your environments manually, you can use `pip`. It is recommended to do this within a virtual environment (`venv`).\n\n```bash\n# This command installs the package.\n# To avoid polluting your global packages, consider running this in a venv.\npip install switchbot-actions\n```\n\n## Usage\n\nWe recommend a two-step process to get started smoothly.\n\n### Step 1: Verify Hardware and Device Discovery\n\nFirst, run the application without any configuration file to confirm that your Bluetooth adapter is working and can discover your SwitchBot devices.\n\n```bash\nswitchbot-actions --debug\n```\n\nThe `--debug` flag will show detailed logs. If you see lines containing \"Received advertisement from...\", your hardware setup is correct.\n\n> [\\!IMPORTANT]\n> **A Note on Permissions on Linux**\n>\n> If you encounter errors related to \"permission denied,\" you may need to run the command with `sudo`:\n>\n> ```bash\n> sudo switchbot-actions --debug\n> ```\n\n### Step 2: Configure and Run\n\nOnce you've confirmed that device discovery is working, create your `config.yaml` file. You can use the example as a starting point:\n\n```bash\ncurl -o config.yaml https://raw.githubusercontent.com/hnw/switchbot-actions/main/config.yaml.example\n```\n\nEdit `config.yaml` to define your automations. Then, run the application normally:\n\n```bash\nswitchbot-actions -c config.yaml\n```\n\n## Configuration\n\nThe application is controlled by `config.yaml`. See `config.yaml.example` for a full list of options.\n\n> [!NOTE]\n> This section provides a quick overview. For a detailed and complete reference of all configuration options, please see the [**Project Specification**](./docs/specification.md#4-configuration-configyaml).\n\n### Command-Line Options\n\n-   `--config <path>` or `-c <path>`: Specifies the path to the configuration file (default: `config.yaml`).\n-   `--debug` or `-d`: Enables `DEBUG` level logging, overriding any setting in the config file. This is useful for temporary troubleshooting.\n-   `--scan-cycle <seconds>`: Overrides the scan cycle time.\n-   `--scan-duration <seconds>`: Overrides the scan duration time.\n-   `--interface <device>`: Overrides the Bluetooth interface (e.g., `hci1`).\n\n### Scanner (`scanner`)\n\nConfigure the behavior of the Bluetooth (BLE) scanner.\n\n```yaml\nscanner:\n  # Time in seconds between the start of each scan cycle.\n  cycle: 10\n  # Time in seconds the scanner will actively listen for devices.\n  # Must be less than or equal to `cycle`.\n  duration: 3\n  # Bluetooth interface to use.\n  interface: \"hci0\"\n```\n\n### Event-Driven Actions (`actions`)\n\nTrigger an action **the moment** a device's state changes to meet the specified conditions (edge-triggered). The action will only fire once and will not fire again until the conditions have first become false and then true again.\n\nIn the `state` conditions, you can use the following operators for comparison: `>` (greater than), `<` (less than), `>=` (greater/equal), `<=` (less/equal), `==` (equal), and `!=` (not equal).\n\n```yaml\nactions:\n  - name: \"High Temperature Alert\"\n    # Cooldown for 10 minutes to prevent repeated alerts\n    cooldown: \"10m\" # Supports formats like \"5s\", \"10m\", \"1.5h\"\n    conditions:\n      device:\n        modelName: \"Meter\"\n      state:\n        # Triggers the moment temperature becomes greater than 28.0\n        temperature: \"> 28.0\"\n    trigger:\n      type: \"webhook\"\n      url: \"https://example.com/alert\"\n      payload:\n        message: \"High temperature detected: {temperature}\u00b0C\"\n      # Optional: Add custom headers for APIs that require them\n      headers:\n        Authorization: \"Bearer YOUR_API_KEY\"\n        X-Custom-Header: \"Value for {address}\"\n\n  - name: \"Weak Signal Notification\"\n    conditions:\n      device:\n        address: \"XX:XX:XX:XX:XX:AA\"\n      state:\n        # Triggers if the signal strength is weaker (more negative) than -80 dBm\n        rssi: \"< -80\"\n    trigger:\n      type: \"shell_command\"\n      command: \"echo 'Device {address} has a weak signal (RSSI: {rssi})'\"\n```\n\n> [!NOTE]\n> You can use placeholders in `command`, `url`, `payload`, and `headers`. Available placeholders include `{address}`, `{modelName}`, `{rssi}`, and any sensor value found in the device's data (e.g., `{temperature}`, `{humidity}`, `{isOn}`).\n\n### Time-Driven Timers (`timers`)\n\nTrigger an action when a device has been in a specific state for a **continuous duration** (one-shot). Once the timer fires, it will not restart until the conditions have first become false and then true again.\n\n```yaml\ntimers:\n  - name: \"Turn off Lights if No Motion\"\n    conditions:\n      device:\n        modelName: \"WoPresence\"\n      state:\n        # The state that must be true for the whole duration\n        motion_detected: False\n      # The duration the state must be sustained\n      duration: \"5m\"\n    trigger:\n      type: \"shell_command\"\n      command: \"echo 'No motion for 5 minutes, turning off lights.'\"\n\n  - name: \"Alert if Door is Left Open\"\n    conditions:\n      device:\n        modelName: \"WoContact\"\n      state:\n        contact_open: True\n      duration: \"10m\"\n    trigger:\n      type: \"webhook\"\n      url: \"https://example.com/alert\"\n      payload:\n        message: \"Warning: Door {address} has been open for 10 minutes!\"\n```\n\n### Prometheus Exporter (`prometheus_exporter`)\n\nThis feature exposes all collected SwitchBot device data as Prometheus metrics, allowing for powerful monitoring and visualization. Once enabled, metrics will be available at the `/metrics` endpoint (e.g., `http://localhost:8000/metrics`). You can scrape this endpoint with a Prometheus server and use tools like Grafana to create dashboards for temperature, humidity, battery levels, and more.\n\n```yaml\nprometheus_exporter:\n  enabled: true\n  port: 8000\n  target:\n    # Optional: Only export metrics for these MAC addresses\n    addresses:\n      - \"XX:XX:XX:XX:XX:AA\"\n    # Optional: Only export these specific metrics\n    metrics:\n      - \"temperature\"\n      - \"humidity\"\n      - \"battery\"\n      - \"rssi\"\n```\n\n### Logging (`logging`)\n\nConfigure the log output format and verbosity. This allows for fine-grained control over log output for both the application and its underlying libraries.\n\n```yaml\nlogging:\n  # Default log level for the application: DEBUG, INFO, WARNING, ERROR\n  level: \"INFO\"\n\n  # Log format using Python's logging syntax\n  format: \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n\n  # Set specific log levels for noisy libraries.\n  # This is useful for debugging specific components without enabling global debug.\n  loggers:\n    bleak: \"WARNING\" # Can be set to DEBUG for deep BLE troubleshooting\n    # aiohttp: \"WARNING\"\n```\n\n#### Debugging Notes\n\n-   **For Application Development (`--debug` flag):**\n    When you run the exporter with `--debug` or `-d`, the `logging` section in your `config.yaml` is **ignored**. This flag is a shortcut that:\n    1.  Sets the log level for `switchbot-actions` to `DEBUG`.\n    2.  Sets the log level for the `bleak` library to `INFO` to keep the output clean.\n\n-   **For Library Troubleshooting (e.g., `bleak`):**\n    If you need to see `DEBUG` messages from a specific library like `bleak`, do **not** use the `--debug` flag. Instead, edit `config.yaml` and set the desired level in the `loggers` section:\n    ```yaml\n    logging:\n      level: \"INFO\" # Keep the main app quiet\n      loggers:\n        bleak: \"DEBUG\" # Enable detailed output only for bleak\n    ```\n\n-   **Troubleshooting Actions and Timers:**\n    By default, the execution of `actions` and `timers` is not logged to `INFO` to avoid excessive noise. If you need to verify that your triggers are running, enable `DEBUG` logging for the triggers module in `config.yaml`:\n    ```yaml\n    logging:\n      level: \"INFO\"\n      loggers:\n        switchbot_actions.triggers: \"DEBUG\"\n    ```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A YAML-based automation engine for SwitchBot BLE devices with a Prometheus exporter.",
    "version": "1.0.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/hnw/switchbot-actions/issues",
        "Homepage": "https://github.com/hnw/switchbot-actions",
        "Repository": "https://github.com/hnw/switchbot-actions"
    },
    "split_keywords": [
        "switchbot",
        " automation",
        " prometheus",
        " ble",
        " home-automation"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e86d7c70154ca9ff43ef13691959d4c587c7c1ecbf4ac9ffe3911345922c1f14",
                "md5": "656f3299d7ff5d2f2b7cfe55fc919f60",
                "sha256": "e56be294cb0b25425ff2ff90b77db16a2115b792f334305dc19ca28f9d4a41ae"
            },
            "downloads": -1,
            "filename": "switchbot_actions-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "656f3299d7ff5d2f2b7cfe55fc919f60",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 17983,
            "upload_time": "2025-07-13T16:10:48",
            "upload_time_iso_8601": "2025-07-13T16:10:48.936024Z",
            "url": "https://files.pythonhosted.org/packages/e8/6d/7c70154ca9ff43ef13691959d4c587c7c1ecbf4ac9ffe3911345922c1f14/switchbot_actions-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bb42759bf9f55cfce915b3f9eaf8b18775228828f5fa75515e5a2c1b5814e556",
                "md5": "ceb9b2eeef80033af5b68804ffa8e027",
                "sha256": "e5313ff6df91d1237dc7326b178bf9ff87e1e0ba5e4f9c601ea129a12552dfab"
            },
            "downloads": -1,
            "filename": "switchbot_actions-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "ceb9b2eeef80033af5b68804ffa8e027",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 24950,
            "upload_time": "2025-07-13T16:10:50",
            "upload_time_iso_8601": "2025-07-13T16:10:50.519141Z",
            "url": "https://files.pythonhosted.org/packages/bb/42/759bf9f55cfce915b3f9eaf8b18775228828f5fa75515e5a2c1b5814e556/switchbot_actions-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-13 16:10:50",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "hnw",
    "github_project": "switchbot-actions",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "switchbot-actions"
}
        
Elapsed time: 1.36173s