Metadata-Version: 2.4
Name: easy-aso
Version: 0.1.8
Summary: Automated Supervisory Optimization (ASO) for BACnet building automation systems (BAS) and HVAC supervisory control
Author-email: Ben Bartling <ben.bartling@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/bbartling/easy-aso
Project-URL: Repository, https://github.com/bbartling/easy-aso
Project-URL: Issues, https://github.com/bbartling/easy-aso/issues
Keywords: bacnet,bas,building-automation,bacpypes3,hvac,supervisory-control,energy,asyncio
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Office/Business
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: bacpypes3
Requires-Dist: httpx
Requires-Dist: ifaddr
Requires-Dist: rdflib>=7.0.0
Provides-Extra: platform
Requires-Dist: fastapi; extra == "platform"
Requires-Dist: fastapi-jsonrpc>=3.5.0; extra == "platform"
Requires-Dist: uvicorn[standard]; extra == "platform"
Requires-Dist: asyncio-mqtt; extra == "platform"
Requires-Dist: aiosqlite; extra == "platform"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-asyncio; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: fastapi; extra == "dev"
Requires-Dist: fastapi-jsonrpc>=3.5.0; extra == "dev"
Requires-Dist: uvicorn[standard]; extra == "dev"
Requires-Dist: asyncio-mqtt; extra == "dev"
Requires-Dist: aiosqlite; extra == "dev"
Dynamic: license-file

# Easy ASO

[![Discord](https://img.shields.io/badge/Discord-Join%20Server-5865F2.svg?logo=discord&logoColor=white)](https://discord.gg/Ta48yQF8fC)
[![CI](https://github.com/bbartling/easy-aso/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/bbartling/easy-aso/actions/workflows/ci.yml)
![MIT License](https://img.shields.io/badge/license-MIT-green.svg)
![Development Status](https://img.shields.io/badge/status-Beta-blue.svg)
![Python](https://img.shields.io/badge/Python-3.9+-blue?logo=python&logoColor=white)
[![PyPI](https://img.shields.io/pypi/v/easy-aso?label=PyPI&logo=pypi&logoColor=white&cacheSeconds=600)](https://pypi.org/project/easy-aso/)

Easy-to-follow Automated Supervisory Optimization (ASO) event-driven logic combined with an asyncio-first supervisory layer for BACnet building automation — lightweight BAS orchestration at the IoT edge with one BACnet/IP core, small agents, JSON-RPC, and room to grow without a full platform stack. 


---

## Install from PyPI

```bash
pip install easy-aso
```

---

## Online Documentation

This application is part of a broader ecosystem that together forms the **Open FDD AFDD Stack**, enabling a fully orchestrated, edge-deployable analytics and optimization platform for building automation systems.

* 🔗 **DIY BACnet Server**
  Lightweight BACnet server with JSON-RPC and MQTT support for IoT integrations.
  [Documentation](https://bbartling.github.io/diy-bacnet-server/) · [GitHub](https://github.com/bbartling/diy-bacnet-server)

* 📖 **Open FDD AFDD Stack**
  Full AFDD framework with Docker bootstrap, API services, drivers, and React web UI.
  [Documentation](https://bbartling.github.io/open-fdd-afdd-stack/) · [GitHub](https://github.com/bbartling/open-fdd-afdd-stack)

* 📘 **Open FDD Fault Detection Engine**
  Core rules engine with `RuleRunner`, YAML-based fault logic, and pandas workflows.
  [Documentation](https://bbartling.github.io/open-fdd/) · [GitHub](https://github.com/bbartling/open-fdd) · [PyPI](https://pypi.org/project/open-fdd/)

* ⚙️ **easy-aso Framework**
  Lightweight framework for Automated Supervisory Optimization (ASO) algorithms at the IoT edge.
  [Documentation](https://bbartling.github.io/easy-aso/) · [GitHub](https://github.com/bbartling/easy-aso) · [PyPI](https://pypi.org/project/easy-aso/)


---

## ASO made easy

Subclass **`EasyASO`** and implement **`on_start`**, **`on_step`**, and **`on_stop`** — same pattern for reads, writes, and releasing overrides:

```python
import asyncio

from easy_aso import EasyASO


class CustomHvacAso(EasyASO):
    async def on_start(self):
        print("Custom ASO is deploying! Let's do something!")

    async def on_step(self):
        # BACnet read request
        sensor = await self.bacnet_read("192.168.0.122", "analog-input,1")

        # Custom step logic - BACnet write request
        override_valve = sensor + 5.0
        await self.bacnet_write("192.168.0.122", "analog-output,2", override_valve)

        print("Executing step actions... The system is being optimized!")
        await asyncio.sleep(60)

    async def on_stop(self):
        # Custom stop logic - BACnet release request
        await self.bacnet_write("192.168.0.122", "analog-output,2", "null")
        print("Executing stop actions... The system is released back to normal!")
```

---

## Local security bootstrap

Generate local bearer tokens (diy JSON-RPC + supervisor API):

```bash
./scripts/bootstrap-secrets.sh
set -a && . ./.env.local && set +a
```

```powershell
.\scripts\bootstrap-secrets.ps1
Get-Content .env.local | ForEach-Object { if ($_ -match '^(.*?)=(.*)$') { Set-Item -Path Env:\$($matches[1]) -Value $matches[2] } }
```

Then run your stack with:

- `BACNET_RPC_API_KEY` for outbound calls to diy-bacnet-server JSON-RPC
- `SUPERVISOR_API_KEY` for optional inbound auth on `easy_aso.supervisor.app`

Optional supervisor (Open-FDD-friendly default port):

```bash
pip install "easy-aso[platform]"
easy-aso-supervisor --host 0.0.0.0 --port 18090
```

---

## License

MIT
