BMS/simulators/bots/ats.py
2026-03-19 11:32:17 +00:00

52 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
from datetime import datetime, timezone, timedelta
from bots.base import BaseBot
class AtsBot(BaseBot):
"""Automatic Transfer Switch — monitors which utility feed is active and logs transfers."""
interval = 30
def __init__(self, site_id: str, ats_id: str) -> None:
super().__init__()
self.site_id = site_id
self.ats_id = ats_id
self._active_feed = "utility-a"
self._transfer_count = 0
self._last_transfer = None # ISO string or None
self._transfer_ms = None # last transfer time in ms
self._transferring = False
def get_topic(self) -> str:
return f"bms/{self.site_id}/power/ats/{self.ats_id}"
def set_scenario(self, name: str | None) -> None:
super().set_scenario(name)
if name == "ATS_TRANSFER":
# Simulate a transfer to generator / utility-b
self._active_feed = "generator"
self._transfer_count += 1
self._transfer_ms = round(random.uniform(80, 200)) # typical ATS 80200 ms
self._last_transfer = datetime.now(timezone.utc).isoformat()
self._transferring = True
elif name in (None, "RESET"):
self._active_feed = "utility-a"
self._transferring = False
def get_payload(self) -> dict:
# Utility voltage sensing (slight variation on active feed)
ua_v = 415.0 + random.gauss(0, 1.0) if self._active_feed == "utility-a" else 0.0
ub_v = 415.0 + random.gauss(0, 1.0) if self._active_feed == "utility-b" else 415.0 + random.gauss(0, 0.5)
gen_v = 415.0 + random.gauss(0, 1.5) if self._active_feed == "generator" else 0.0
return {
"state": "transferring" if self._transferring else "stable",
"active_feed": self._active_feed,
"transfer_count": self._transfer_count,
"last_transfer_at": self._last_transfer,
"last_transfer_ms": self._transfer_ms,
"utility_a_v": round(ua_v, 1),
"utility_b_v": round(ub_v, 1),
"generator_v": round(gen_v, 1),
}