Skip to main content

Ecosystem-agnostic smart home lighting & AC automation using Matter protocol

Project description

Home Lighting Programmer

Ecosystem-agnostic smart home automation using the Matter protocol. Replaces physical switches with sensor-driven control of lights (circadian-aware brightness + color temperature schedules) and air conditioners (temperature-driven hysteresis with occupancy gating).

Note: For domestic use only. Not hardened for production/commercial deployment.

How It Works

The system runs a 1Hz loop that:

  1. Reads real-time sensor data (motion/presence) via Server-Sent Events
  2. Interpolates the configured schedule to determine target brightness and color temperature
  3. Sends commands only when the target state changes

Three lighting modes are supported:

  • Decoration - Static color and intensity
  • Utility - Sensor-triggered, low-latency response
  • Ambient - Time-based color temperature and brightness that follows natural daylight

Requirements

Installation

pip install light-programmer

Quick Start

# Step 1: Auto-generate config from your hardware
light-genconfig --ip 192.168.1.220 --port 8080 --out config.json

# Step 2: Edit config.json to customize schedules and sensor logic

# Step 3: Run
light-programmer --server 192.168.1.220:8080 --config config.json

Configuration

Each device entry in the config JSON has:

{
    "id": "dev_kitchen_sink",       // Matter node ID
    "note": "Sink area light",      // Human-readable description
    "schedule": [                   // Time-based control points
        { "time": "06:30", "level": 50,  "kelvin": 4000 },
        { "time": "12:00", "level": 100, "kelvin": 4000 },
        { "time": "21:30", "level": 100, "kelvin": 2700 }
    ],
    "sensor": [                     // Simple sensor trigger
        { "id": "kitchen_motion", "timeout": 5 }
    ]
}
  • level: Brightness 0-100%
  • kelvin: Color temperature 2700-6500K (omit for non-color lights)
  • timeout: Seconds to keep light on after sensor clears
  • Values between schedule points are linearly interpolated

See sample.json for a full working example.

Advanced Sensor Logic

For complex scenarios, use sensor_condition instead of sensor. It supports a tree of boolean operators:

Node Type Description
sensor true if occupied or within timeout
time_window true if current time is between start and end (cross-midnight supported)
AND All operands must be true
OR At least one operand must be true
NOT Inverts its operand

Example: Light on only when at desk AND not in bed

{
    "sensor_condition": {
        "operator": "AND",
        "operands": [
            { "type": "sensor", "id": "desk_presence", "timeout": 15 },
            {
                "operator": "NOT",
                "operands": [
                    { "type": "sensor", "id": "bed_presence", "timeout": 5 }
                ]
            }
        ]
    }
}

Example: Follow schedule during day, sensor-only at night

{
    "sensor_condition": {
        "operator": "OR",
        "operands": [
            { "type": "time_window", "start": "06:00", "end": "22:00" },
            { "type": "sensor", "id": "room_motion", "timeout": 5 }
        ]
    }
}

During 06:00-22:00 the light follows its schedule regardless of sensors. Outside that window, it only turns on when the sensor detects motion.

Air Conditioner Control

AC entries are temperature-driven (no time schedule). They use a Matter thermostat (/api/ac) plus a separate climate sensor (/api/climate) for the ambient reading.

{
    "id": "dev_ac_livingroom",
    "type": "ac",                          // marks this entry as an AC
    "climate_sensor": "dev_temp_livingroom",
    "mode": "cool",                        // cool / heat / dry / fan / auto
    "setpoint": 26.0,                      // °C sent to the thermostat
    "on_above": 29.0,                      // turn on when ambient ≥ 29 °C
    "off_below": 26.5,                     // turn off when ambient ≤ 26.5 °C
    "on_delay_minutes": 5,                 // require continuous occupancy ≥ 5 min before turning on
    "active_window": {"start": "10:00", "end": "23:30"},
    "sensor": [
        {"id": "dev_occ_livingroom", "timeout": 15}
    ]
}

Bring-up rule (off → on): ambient ≥ on_above AND occupancy continuously satisfied for on_delay_minutes AND time within active_window.

Bring-down rule (on → off): ambient ≤ off_below, OR occupancy fails (after each sensor's timeout hold), OR outside active_window.

In the dead band between off_below and on_above the AC holds its previous state — this is the hysteresis. For mode: "heat", swap to on_below / off_above (turn on when cold enough, off when warm enough).

The same sensor / sensor_condition AST used by lights applies — combine multiple occupancy sensors with AND/OR/NOT as needed. If the climate sensor is unreachable, the AC holds its last decision rather than flapping.

MCP Server (AI Agent Configuration)

An MCP server is bundled so AI agents (Claude Desktop, Claude Code, etc.) can discover devices and edit the config for you.

pip install light-programmer[mcp]
light-programmer-mcp                  # stdio transport

Example Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "light-programmer": {
      "command": "light-programmer-mcp",
      "env": { "MATTER_SRV_KEY": "your-api-key" }
    }
  }
}

Tools exposed:

Tool Purpose
list_devices Discover lights / sensors / climate / AC from /api/metadata
read_climate, read_ac_state, read_status Live readings
read_config, write_config, validate_config Whole-file CRUD with schema validation
upsert_entry, remove_entry Per-entry edits keyed by device id
set_light, set_ac Direct device control for quick tests
config_schema (prompt) Schema reference an agent can pull when authoring entries

Validation rejects writes with bad time formats, out-of-range levels/Kelvin, missing thresholds, or hysteresis bands where off_below ≥ on_above (cool) / off_above ≤ on_below (heat).

Project Structure

File Purpose
light_programmer/programmer.py Main automation controller — runs the 1Hz loop for lights and ACs
light_programmer/matter_lib.py Device abstractions: LightDevice, SensorDevice, ClimateSensorDevice, ACDevice
light_programmer/genconfig.py Generates config JSON from hardware discovery
light_programmer/mcp_server.py MCP server exposing discovery + config CRUD tools to AI agents
sample.json Example configuration with 11 devices
pyproject.toml Package configuration and CLI entry points

License

MIT

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

light_programmer-0.2.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

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

light_programmer-0.2.0-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file light_programmer-0.2.0.tar.gz.

File metadata

  • Download URL: light_programmer-0.2.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for light_programmer-0.2.0.tar.gz
Algorithm Hash digest
SHA256 dbc53d9ded7746d0747df8d5f4ef198faee80a13c1bea012a3f08db69c427712
MD5 513763791c22afe6032dc54cd1bddbfa
BLAKE2b-256 e45afde68f829736f262a13815dfa3409bff4a8b3156f3b8117cf521d1bdd118

See more details on using hashes here.

Provenance

The following attestation bundles were made for light_programmer-0.2.0.tar.gz:

Publisher: python-publish.yml on dongnh/light_programmer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file light_programmer-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for light_programmer-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 187a8446c0e0af3371d666bdaade6d2db7e174056a979e81b0efdaf170c5551d
MD5 f3e51b08332cb81db3b4bd635375ef4c
BLAKE2b-256 fd35fe1ccee92c0d93daf02f19c7fee0cff7f25720ee2cc321c477b43d41fad7

See more details on using hashes here.

Provenance

The following attestation bundles were made for light_programmer-0.2.0-py3-none-any.whl:

Publisher: python-publish.yml on dongnh/light_programmer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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