using RobotLib.Communication; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text.Json; namespace RobotLib.Battery { public class DevBattery : DevBase { private float voltage; private int secondsSinceLastResponse = 0; private Stopwatch stopwatchLastResponse = new(); private const string TOPIC_ROBO_REQ_BATTERY = "/both/cmd/battery/get_volt"; private const string TOPIC_ROBO_RESP_BATTERY = "/mobile/state/battery/voltage"; private const string TOPIC_STAT_RESP_BATTERY = "/stationary/state/battery/voltage"; public event EventHandler BatteryChanged; public event EventHandler SecondsSinceLastResponseUpdate; public float Voltage { get { return voltage; } private set { // value changed? if (voltage != value) { // set new voltage and raise event voltage = value; BatteryChanged?.Invoke(this, new BatteryEventArgs(voltage)); } } } public int SecondsSinceLastResponse { get { return secondsSinceLastResponse; } private set { secondsSinceLastResponse = value; SecondsSinceLastResponseUpdate?.Invoke(this, secondsSinceLastResponse); } } public DevBattery(IPublisherSubscriber com, RobotMode mode) : base(com, GenerateListOfRelevantTopics(mode)) { } private static List GenerateListOfRelevantTopics(RobotMode mode) { if (mode == RobotMode.Stationary) { return new List() { TOPIC_STAT_RESP_BATTERY }; } else { return new List() { TOPIC_ROBO_RESP_BATTERY }; } } public void RequestBatteryVoltage() { base.SendMessage(TOPIC_ROBO_REQ_BATTERY, true.ToString()); if (this.stopwatchLastResponse.IsRunning) { SecondsSinceLastResponse = this.stopwatchLastResponse.Elapsed.Seconds; } } protected override void ParseMessage(string fromTopic, string message) { if (fromTopic == TOPIC_ROBO_RESP_BATTERY || fromTopic == TOPIC_STAT_RESP_BATTERY) { this.stopwatchLastResponse.Stop(); this.stopwatchLastResponse.Start(); SecondsSinceLastResponse = 0; var parsedString = GetValueFromMesage("voltage", message); if (parsedString == null) parsedString = "?"; // example message = "Battery: 1.25 V" var valueUnit = parsedString.Trim().Split(' '); string voltage = valueUnit[0].Trim(); float fVoltage = float.NaN; if(float.TryParse(voltage, out fVoltage)) { this.Voltage = fVoltage; } } } private T GetValueFromMesage(string parameter, string message) { var data = JsonSerializer.Deserialize>(message); data.TryGetValue(parameter, out T value); return value; } } }