Files
BR_YKC/上位机/YKC/PilesDataStore.cs

175 lines
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace YKC
{
public class GunData
{
public List<double> Current { get; set; } = new List<double>();
public List<double> Voltage { get; set; } = new List<double>();
public List<double> Power { get; set; } = new List<double>();
public List<double> Energy { get; set; } = new List<double>();
public List<double> ServiceFee { get; set; } = new List<double>();
public List<double> ElectricityFee { get; set; } = new List<double>();
public List<double> TotalAmount { get; set; } = new List<double>();
public List<int> Status { get; set; } = new List<int>();
public List<DateTime> Timestamps { get; set; } = new List<DateTime>();
public string OrderNo { get; set; } = "";
public double? Soc { get; set; } = null;
public double? CumulativeTime { get; set; } = 0;
public double? RemainingTime { get; set; } = 0;
private const int MaxPoints = 300;
private void AddToList<T>(List<T> list, T value)
{
list.Add(value);
if (list.Count > MaxPoints)
list.RemoveAt(0);
}
public void Append(JObject g)
{
AddToList(Timestamps, DateTime.Now);
AddToList(Current, g.Value<double?>("current") ?? double.NaN);
AddToList(Voltage, g.Value<double?>("voltage") ?? double.NaN);
AddToList(Power, g.Value<double?>("power") ?? double.NaN);
AddToList(Energy, g.Value<double?>("energy") ?? double.NaN);
AddToList(ServiceFee, g.Value<double?>("service_fee") ?? double.NaN);
AddToList(ElectricityFee, g.Value<double?>("electricity_fee") ?? double.NaN);
double? total = g.Value<double?>("total_amount");
if (total == null)
{
double? sf = g.Value<double?>("service_fee");
double? ef = g.Value<double?>("electricity_fee");
if (sf != null && ef != null)
total = sf + ef;
}
AddToList(TotalAmount, total ?? double.NaN);
AddToList(Status, g.Value<int?>("status") ?? 0);
OrderNo = g.Value<string>("order_no") ?? OrderNo;
Soc = g.Value<double?>("soc") ?? Soc;
CumulativeTime = g.Value<double?>("cumulative_time") ?? CumulativeTime;
RemainingTime = g.Value<double?>("remaining_time") ?? RemainingTime;
}
public double? LatestOrNull(List<double> list)
{
for (int i = list.Count - 1; i >= 0; i--)
if (!double.IsNaN(list[i])) return list[i];
return null;
}
public int? LatestStatus()
{
for (int i = Status.Count - 1; i >= 0; i--)
return Status[i];
return null;
}
}
public class PileData
{
public GunData Gun1 { get; set; } = new GunData();
public GunData Gun2 { get; set; } = new GunData();
}
public class PilesDataStore
{
private readonly object _lock = new object();
public Dictionary<int, PileData> Piles { get; } = new Dictionary<int, PileData>();
private const int PileCount = 6;
public PilesDataStore()
{
for (int i = 1; i <= PileCount; i++)
Piles[i] = new PileData();
}
public void HandleReport(JObject msg)
{
var pilesArr = msg["piles"] as JArray ?? msg["data"] as JArray;
if (pilesArr == null) return;
lock (_lock)
{
foreach (var p in pilesArr)
{
int idx = p.Value<int?>("index") ?? p.Value<int?>("pile_index") ?? p.Value<int?>("id") ?? 0;
if (idx < 1 || idx > PileCount) continue;
var gunsArr = p["guns"] as JArray;
if (gunsArr == null)
{
Piles[idx].Gun1.Append((JObject)p);
continue;
}
foreach (var g in gunsArr)
{
int gunNum = g.Value<int?>("gun") ?? g.Value<int?>("gun_no") ?? g.Value<int?>("id") ?? 0;
if (gunNum == 1) Piles[idx].Gun1.Append((JObject)g);
else if (gunNum == 2) Piles[idx].Gun2.Append((JObject)g);
}
}
}
}
public JObject GetLatest(int pileIndex, int gunNum)
{
lock (_lock)
{
if (!Piles.ContainsKey(pileIndex)) return null;
var gun = gunNum == 1 ? Piles[pileIndex].Gun1 : Piles[pileIndex].Gun2;
return new JObject
{
["current"] = gun.LatestOrNull(gun.Current),
["voltage"] = gun.LatestOrNull(gun.Voltage),
["power"] = gun.LatestOrNull(gun.Power),
["energy"] = gun.LatestOrNull(gun.Energy),
["service_fee"] = gun.LatestOrNull(gun.ServiceFee),
["electricity_fee"] = gun.LatestOrNull(gun.ElectricityFee),
["total_amount"] = gun.LatestOrNull(gun.TotalAmount),
["status"] = gun.LatestStatus(),
["order_no"] = gun.OrderNo,
["soc"] = gun.Soc,
["cumulative_time"] = gun.CumulativeTime,
["remaining_time"] = gun.RemainingTime,
};
}
}
public JArray GetChartData(int pileIndex, int gunNum)
{
lock (_lock)
{
if (!Piles.ContainsKey(pileIndex)) return null;
var gun = gunNum == 1 ? Piles[pileIndex].Gun1 : Piles[pileIndex].Gun2;
var arr = new JArray();
for (int i = 0; i < gun.Timestamps.Count; i++)
{
arr.Add(new JObject
{
["t"] = new DateTimeOffset(gun.Timestamps[i]).ToUnixTimeSeconds(),
["current"] = double.IsNaN(gun.Current[i]) ? (JToken)null : gun.Current[i],
["voltage"] = double.IsNaN(gun.Voltage[i]) ? (JToken)null : gun.Voltage[i],
["power"] = double.IsNaN(gun.Power[i]) ? (JToken)null : gun.Power[i],
});
}
return arr;
}
}
}
public static class PilesStoreHolder
{
public static readonly PilesDataStore Instance = new PilesDataStore();
}
}