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) # 30–180 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, }