175 lines
6.6 KiB
C#
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();
|
|
}
|
|
}
|