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

75 lines
2.8 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 bots.base import BaseBot
class NetworkBot(BaseBot):
"""Network switch — publishes live port/bandwidth/CPU/health data."""
interval = 60
def __init__(self, site_id: str, switch_id: str, port_count: int = 48) -> None:
super().__init__()
self.site_id = site_id
self.switch_id = switch_id
self.port_count = port_count
self._uptime_s = random.randint(30 * 86400, 180 * 86400) # 30180 day uptime
self._active_ports = int(port_count * random.uniform(0.65, 0.85))
self._down = False
self._degraded = False
def get_topic(self) -> str:
return f"bms/{self.site_id}/network/{self.switch_id}"
def set_scenario(self, name: str | None) -> None:
super().set_scenario(name)
self._down = (name == "SWITCH_DOWN")
self._degraded = (name == "LINK_FAULT")
if name is None:
self._down = False
self._degraded = False
def get_payload(self) -> dict:
self._uptime_s += self.interval
if self._down:
return {
"state": "down",
"uptime_s": 0,
"port_count": self.port_count,
"active_ports": 0,
"bandwidth_in_mbps": 0.0,
"bandwidth_out_mbps": 0.0,
"cpu_pct": 0.0,
"mem_pct": 0.0,
"temperature_c": 0.0,
"packet_loss_pct": 100.0,
}
if self._degraded:
active = max(1, int(self._active_ports * 0.5))
pkt_loss = round(random.uniform(5.0, 25.0), 2)
else:
active = self._active_ports + random.randint(-1, 1)
active = max(1, min(self.port_count, active))
self._active_ports = active
pkt_loss = round(random.uniform(0.0, 0.05), 3)
util = active / self.port_count
bw_in = round(util * random.uniform(200, 800) + random.gauss(0, 10), 1)
bw_out = round(util * random.uniform(150, 600) + random.gauss(0, 8), 1)
cpu = round(max(1.0, min(95.0, util * 40 + random.gauss(0, 3))), 1)
mem = round(max(10.0, min(90.0, 30 + util * 20 + random.gauss(0, 2))), 1)
temp = round(35.0 + util * 20 + random.gauss(0, 1.5), 1)
return {
"state": "degraded" if self._degraded else "up",
"uptime_s": self._uptime_s,
"port_count": self.port_count,
"active_ports": active,
"bandwidth_in_mbps": max(0.0, bw_in),
"bandwidth_out_mbps": max(0.0, bw_out),
"cpu_pct": cpu,
"mem_pct": mem,
"temperature_c": temp,
"packet_loss_pct": pkt_loss,
}