ASCU_ALL/DataClients/STPClient.cs
2021-05-25 17:00:45 +05:00

460 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace DataClients
{
public class STPClient
{
private NetClient netClient;
private FileClient fileClient;
public STPClient()
{
netClient = new NetClient();
fileClient = new FileClient();
}
public STPClient(NetClient nc, FileClient fc)
{
netClient = nc;
fileClient = fc;
}
public bool CheckConnection()
{
var byteStr = netClient.SocketWork(NetClient.Cmd.version);
if (byteStr.Length < 1) return false;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding(866);
var version = enc.GetString(byteStr[0]);
if (version.Contains("STP TCP Server"))
return true;
return false;
}
public Pasport GetPasport(string link)
{
var result = new Pasport();
var arr = new List<byte>();
var count_error = 0;
var flag_err = false;
do
{
flag_err = false;
result = new Pasport();
arr = new List<byte>();
try
{
{
var tmp = netClient.SocketWork(NetClient.Cmd.pasp_download, link);
foreach (var e in tmp) arr.AddRange(e);
}
result.byteArr = arr.ToArray();
}
catch
{
flag_err = true;
count_error++;
Thread.Sleep(3000);
}
} while (flag_err && count_error < 3);
return result;
}
public (string name, string dir)[] GetListPasport(DateTime date)
{
var result = new List<(string name, string dir)>();
var str = date.ToString(@"yyyy\/MM\/dd");
var e = netClient.SocketWork(NetClient.Cmd.dir_browse, str);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding(866);
foreach(var t in e)
{
var subres = "";
var r1 = enc.GetString(t);
var r2 = r1.Split('-');
if (r2.Length > 1)
for (var i = 1; i < r2.Length; i++) {
if (subres.Length > 0) subres = subres + "-";
subres = subres + r2[i].Split('.')[0];
}
if (!String.IsNullOrEmpty(subres))
result.Add((subres, str + '/' + r1));
}
return result.ToArray();
}
public ADresult GetAnalogDiscret(DateTime start, DateTime end, ushort vdp)
{
var cursor = start;
byte[] subRes = new byte[0];
var resByteMatrix = new List<ByteMatrix>();
while (cursor.AddDays(-1) <= end)
{
subRes = GetFile(cursor, vdp, 1);
var arr = STPConverter.GetADByteMatrix(cursor, subRes);
resByteMatrix.AddRange(arr);
cursor = cursor.AddDays(1);
}
return STPConverter.AnalogDiscret(resByteMatrix,vdp);
}
public List<IshData> GetIshData(DateTime start, DateTime end, ushort vdp)
{
var result = new List<IshData>();
var cursor = start.AddDays(-1);
byte[] subRes = new byte[0];
do
{
cursor = cursor.AddDays(1);
subRes = GetFile(cursor, vdp, 0);
var arr = STPConverter.IshData(subRes);
foreach (var e in arr)
if (start <= e.time && e.time <= end)
result.Add(e);
} while (cursor <= end);
return result;
}
public List<TechCycle> GetTechCycle(DateTime start, DateTime end, ushort vdp)
{
var result = new List<TechCycle>();
var cursor = start;
byte[] subRes = new byte[0];
TechCycle currTechCycle = new TechCycle()
{
start = start,
index = TechCycle.Operation.unloading_loading
};
do
{
cursor = cursor.AddDays(-1);
subRes = GetFile(cursor, vdp, 3);
} while (subRes.Length == 0 && cursor > start.AddDays(-10));
{
if (subRes.Length > 0)
{
var b = STPConverter.TechCycle(subRes);
if (b.Length > 0) currTechCycle = b.Last();
}
}
do
{
cursor = cursor.AddDays(1);
subRes = GetFile(cursor, vdp, 3);
var arr = STPConverter.TechCycle(subRes);
foreach(var e in arr)
{
if (e.start <= start)
{
currTechCycle = e;
continue;
}
if (e.start >= end)
{
currTechCycle.end = e.start;
result.Add(currTechCycle);
currTechCycle = e;
break;
}
if (e.start > start && e.start < end)
{
currTechCycle.end = e.start;
if (result.Count > 0 && result[result.Count - 1].index == currTechCycle.index)
result[result.Count - 1].end = currTechCycle.end;
else
result.Add(currTechCycle);
currTechCycle = e;
}
}
} while (cursor <= end);
{
if (result.Count == 0)
{
currTechCycle.start = start;
currTechCycle.end = end;
result.Add(currTechCycle);
}
else if (result[result.Count - 1].end < end)
{
currTechCycle.end = end;
result.Add(currTechCycle);
}
}
return result;
}
public List<Protect> GetProtectData(DateTime start, DateTime end, ushort vdp)
{
var result = new List<Protect>();
var cursor = start.AddDays(-1);
byte[] subRes = new byte[0];
do
{
cursor = cursor.AddDays(1);
subRes = GetFile(cursor, vdp, 4);
var arr = STPConverter.ProtectData(subRes);
foreach (var e in arr)
if (start <= e.time && e.time <= end)
result.Add(e);
} while (cursor <= end);
return result;
}
private byte[] GetFile(DateTime time, ushort vdp, ushort index)
{
var result = new List<byte>();
var name = time.ToString("yyyyMMdd") + "." + vdp.ToString("D2") + index.ToString("D1");
var temp = new List<byte>();
temp.AddRange(fileClient.GetFile(time, vdp, index));
if (temp.Count == 0)
{
var subTemp = netClient.SocketWork(NetClient.Cmd.download_nh, name);
foreach (var e in subTemp)
temp.AddRange(e);
}
return temp.ToArray();
}
}
public static class STPConverter
{
public static IshData[] IshData(byte[] arr)
{
var result = new List<IshData>();
try
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding(866);
var strs = enc.GetString(arr).Split('\n');
foreach (var e in strs)
{
var substr = e.Split('\t');
if (substr.Length < 3) continue;
var time = Converter.ConvertUnixTimeToDateTime(Int32.Parse(substr[1]));
for(var i = 2; i < substr.Length; i++)
{
if (String.IsNullOrEmpty(substr[i])) continue;
var tmp = substr[i].Split(' ');
var c = new IshData() { time = time, id = Convert.ToUInt16(tmp[0]) };
var val = "";
for (var j = 1; j < tmp.Length; j++)
val = j < (tmp.Length - 1) ? val + tmp[j] + ' ' : val + tmp[j];
c.value = val;
result.Add(c);
}
}
return result.ToArray();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return result.ToArray();
}
}
public static TechCycle[] TechCycle(byte[] arr)
{
var result = new List<TechCycle>();
try
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding(866);
var strs = enc.GetString(arr).Split('\n');
foreach(var e in strs)
{
var substr = e.Split('\t');
if (substr.Length != 3) continue;
var cycle = new TechCycle();
cycle.index = (DataClients.TechCycle.Operation)UInt32.Parse(substr[0]);
cycle.start = Converter.ConvertUnixTimeToDateTime(Int32.Parse(substr[2]));
if (result.Count > 0) result[result.Count - 1].end = cycle.start;
result.Add(cycle);
}
return result.ToArray();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return result.ToArray();
}
}
public static Protect[] ProtectData(byte[] arr)
{
var result = new List<Protect>();
try
{
var cursor = 0;
var time = new DateTime();
while (cursor < arr.Length)
{
if (cursor + 4 >= arr.Length) break;
time = Converter.ConvertUnixTimeToDateTime(BitConverter.ToInt32(arr, cursor));
cursor += 4;
if (cursor + 4 >= arr.Length) break;
time = time.AddMilliseconds((double)BitConverter.ToInt32(arr, cursor) / 1000000);
cursor += 4;
while (true)
{
if (cursor >= arr.Length) break;
if (arr[cursor] == 0xff)
{
cursor++;
break;
}
var id = (int)arr[cursor];
cursor++;
if (cursor >= arr.Length) break;
var value = (int)arr[cursor];
cursor++;
result.Add(new Protect()
{
time = time,
id = id,
value = value
});
}
}
return result.ToArray();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return result.ToArray();
}
}
public static ADresult AnalogDiscret(List<ByteMatrix> adBytes, int vdp)
{
var result = new ADresult();
try
{
var aMatrix = new AnalogsMatrix(vdp);
foreach(var an in aMatrix.matrix)
{
var subRes = new List<Tuple<DateTime, double?>>();
foreach(var b in adBytes)
{
var c = new byte?[2];
for(var i = 0; i < 2; i++)
c[i] = b.matrix.Length > an.Value.byteId[i] ?
b.matrix[an.Value.byteId[i]] : null;
double? d = c[0].HasValue && c[1].HasValue ?
(double?)BitConverter.ToInt16(new byte[] { c[0].Value, c[1].Value }, 0) * an.Value.mul : null;
d = !d.HasValue ? null : d.Value < an.Value.min ? an.Value.min : d.Value > an.Value.max ? an.Value.max : d;
var e = new Tuple<DateTime, double?>(b.time, d);
if (subRes.Count > 1 && subRes[subRes.Count - 1].Item2 == e.Item2 && subRes[subRes.Count - 2].Item2 == e.Item2)
subRes.RemoveAt(subRes.Count - 1);
subRes.Add(e);
}
result.an.Add(an.Key, subRes.ToArray());
}
var dMatrix = new DiscretsMatrix(vdp);
foreach (var di in dMatrix.matrix)
{
var subRes = new List<Tuple<DateTime, bool?>>();
foreach (var b in adBytes)
{
bool? c = b.matrix.Length <= di.Value.byteId ? null :
!b.matrix[di.Value.byteId].HasValue ? null :
(bool?)((b.matrix[di.Value.byteId] & (1 << di.Value.bitId)) != 0);
c = !c.HasValue ? null : di.Value.invert ? !c : c;
var e = new Tuple<DateTime, bool?>(b.time, c);
if ((subRes.Count == 0) || (subRes.Count > 0 && subRes[subRes.Count - 1].Item2 != e.Item2))
subRes.Add(e);
}
result.di.Add(di.Key, subRes.ToArray());
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return result;
}
return result;
}
public static List<ByteMatrix> GetADByteMatrix(DateTime time, byte[] arr)
{
var result = new List<ByteMatrix>();
var byteArr = new List<byte?>();
var currTime = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0);
var halfsec = 0;
var cursor = 0;
try
{
while (cursor < arr.Length)
{
var id = arr[cursor];
cursor++;
switch (id)
{
case 0xfb:
halfsec = BitConverter.ToInt32(arr, cursor);
cursor = cursor + 4;
break;
case 0xfc:
byteArr = new List<byte?>();
result.Add(
new ByteMatrix()
{
time = currTime.AddSeconds((double)(halfsec + 1) / 2),
matrix = byteArr.ToArray()
}
);
halfsec = BitConverter.ToInt32(arr, cursor);
cursor = cursor + 4;
break;
case 0xfe:
halfsec = halfsec + BitConverter.ToInt16(arr, cursor);
break;
case 0xff:
result.Add(
new ByteMatrix()
{
time = currTime.AddSeconds((double)halfsec / 2),
matrix = byteArr.ToArray()
}
);
halfsec++;
break;
default:
var a = Convert.ToInt32(id);
while (byteArr.Count <= a) byteArr.Add(null);
byteArr[a] = arr[cursor];
cursor++;
break;
}
}
return result;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return result;
}
}
}
}