Add simulator architecture separation and warning system
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import json
|
||||
import random
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class ESP32Simulator:
|
||||
def __init__(self):
|
||||
self.relays = {
|
||||
"starlink": False,
|
||||
"fridge": True
|
||||
}
|
||||
|
||||
self.wifi_override_until = 0
|
||||
self.ignition_on = True
|
||||
self.soc = 82.0
|
||||
self.last_update = time.time()
|
||||
|
||||
def load_config(self):
|
||||
config_path = Path(__file__).parent / "config.json"
|
||||
with config_path.open() as f:
|
||||
return json.load(f)
|
||||
|
||||
def update_battery(self):
|
||||
now = time.time()
|
||||
elapsed_hours = (now - self.last_update) / 3600
|
||||
self.last_update = now
|
||||
|
||||
load_amps = 6.0
|
||||
if self.relays["starlink"]:
|
||||
load_amps += 4.5
|
||||
if self.relays["fridge"]:
|
||||
load_amps += 2.0
|
||||
|
||||
capacity_ah = 100
|
||||
self.soc -= (load_amps * elapsed_hours / capacity_ah) * 100
|
||||
self.soc = max(self.soc, 0)
|
||||
|
||||
return -load_amps
|
||||
|
||||
def get_status(self):
|
||||
current = self.update_battery()
|
||||
starlink_on = self.relays["starlink"]
|
||||
wifi_override_active = time.time() < self.wifi_override_until
|
||||
|
||||
temps = {
|
||||
"fridge_zone_1": self.sensor(36, 2),
|
||||
"fridge_zone_2": self.sensor(12, 3),
|
||||
"rear_seat": self.sensor(78, 8),
|
||||
"outside": self.sensor(88, 8)
|
||||
}
|
||||
|
||||
sensor_health = {
|
||||
"fridge_zone_1": True,
|
||||
"fridge_zone_2": True,
|
||||
"rear_seat": True,
|
||||
"outside": True
|
||||
}
|
||||
|
||||
remaining_ah = round(self.soc, 1)
|
||||
runtime_hours = round(remaining_ah / abs(current), 1) if current else 0
|
||||
|
||||
return {
|
||||
"timestamp": int(time.time()),
|
||||
|
||||
"vehicle": {
|
||||
"ignition_on": self.ignition_on
|
||||
},
|
||||
|
||||
"battery": {
|
||||
"soc": round(self.soc),
|
||||
"voltage": round(13.0 + (self.soc / 100) * 0.4, 2),
|
||||
"current": round(current, 1),
|
||||
"remaining_ah": remaining_ah,
|
||||
"runtime_hours": runtime_hours,
|
||||
"temperature_f": self.sensor(76, 4)
|
||||
},
|
||||
|
||||
"temps": temps,
|
||||
"sensor_health": sensor_health,
|
||||
|
||||
"relays": self.relays,
|
||||
|
||||
"network": {
|
||||
"wifi_enabled": starlink_on or wifi_override_active,
|
||||
"wifi_override_active": wifi_override_active,
|
||||
"rs485_connected": True,
|
||||
"starlink_enabled": starlink_on
|
||||
},
|
||||
|
||||
"config": self.load_config()
|
||||
}
|
||||
|
||||
def sensor(self, base, spread):
|
||||
return round(random.uniform(base - spread, base + spread), 1)
|
||||
|
||||
def set_relay(self, name, state):
|
||||
if name not in self.relays:
|
||||
return False
|
||||
|
||||
self.relays[name] = bool(state)
|
||||
return True
|
||||
|
||||
def enable_wifi(self, minutes):
|
||||
self.wifi_override_until = time.time() + minutes * 60
|
||||
|
||||
def toggle_ignition(self):
|
||||
self.ignition_on = not self.ignition_on
|
||||
return self.ignition_on
|
||||
|
||||
|
||||
esp32 = ESP32Simulator()
|
||||
Reference in New Issue
Block a user