123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- using FreeRedis;
- using Newtonsoft.Json;
- using ServiceCenter.Redis;
- namespace ServiceCenter.Virtual_PLC
- {
- /// <summary>
- /// plc数据
- /// </summary>
- public class PlcData
- {
- private static string RedisKey = "Virtual_PLC";
- private static RedisClient Redis;
- /// <summary>
- /// 数据结构缓存
- /// </summary>
- private static List<PLCData> PLCDatas { get; set; } = new List<PLCData>();
- /// <summary>
- /// redis 链接字符串
- /// </summary>
- /// <param name="redisClient">Redis链接字符串</param>
- public PlcData(string redisClient)
- {
- Redis = RedisHub.CreateContext(redisClient, RedisKey);
- }
- /// <summary>
- /// redis 链接字符串
- /// </summary>
- /// <param name="redisClient"></param>
- /// <returns></returns>
- public static PlcData Init(string redisClient)
- {
- return new PlcData(redisClient);
- }
- /// <summary>
- /// 初始化PLC数据
- /// </summary>
- /// <param name="pLCData">一个PLC</param>
- private void InitPlcData(PLCData pLCData)
- {
- if (!PLCDatas.Contains(pLCData))
- {
- PLCDatas.Add(pLCData);
- }
- //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
- var mun = pLCData.Length / pLCData.DataLength;
- int addstart = 0;
- for (int i = 0; i < mun; i++)
- {
- var key = $"{pLCData.IP}:{pLCData.DB}:{addstart}";
- if (Redis.Exists(key)) continue;
- Redis.Set(key, new byte[pLCData.DataLength]);
- addstart = addstart + pLCData.DataLength;
- }
- }
- /// <summary>
- /// 初始化PLC数据
- /// </summary>
- /// <param name="pLCDatas">多个PLC</param>
- public void InitPlcData(List<PLCData> pLCDatas)
- {
- string key = "PLCDataList";
- if (Redis.Exists(key))
- {
- //判断值是否相等,值相等代表已经有过数据生成了,并且没有任何变化
- var RedisPlcData = Redis.Get(key);
- if (JsonConvert.SerializeObject(pLCDatas) == RedisPlcData)
- {
- PLCDatas = pLCDatas;
- return;
- }
- }
- pLCDatas.ForEach(v =>
- {
- InitPlcData(v);
- });
- Redis.Set(key, JsonConvert.SerializeObject(pLCDatas));
- }
- /// <summary>
- /// 按照DB读取
- /// </summary>
- /// <param name="pLCData"></param>
- /// <returns></returns>
- public static byte[] Read(PLCData pLCData)
- {
- byte[] data = new byte[pLCData.Length];
- //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
- var mun = pLCData.Length / pLCData.DataLength;
- int addstart = 0;
- for (int i = 0; i < mun; i++)
- {
- var a = Redis.Get<byte[]>($"{pLCData.IP}:{pLCData.DB}:{addstart}");
- a.CopyTo(data, addstart);
- addstart = addstart + pLCData.DataLength;
- }
- return data;
- }
- /// <summary>
- /// 按照长度读取
- /// </summary>
- /// <param name="pLCData"></param>
- /// <param name="startLength">起始长度</param>
- /// <returns></returns>
- public static byte[] Read(PLCData pLCData, int startLength)
- {
- return System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{startLength}"));
- }
- /// <summary>
- /// 写入数据
- /// </summary>
- /// <param name="pLCData"></param>
- /// <param name="startLength"></param>
- /// <param name="value"></param>
- public static void Write(PLCData pLCData, int startLength, byte[] value)
- {
- var data = PLCDatas.Find(v => v.IP == pLCData.IP && v.DB == pLCData.DB);
- int start = 0;
- if (data.DataLength == data.Length) //数据长度与总长度相等时计算
- {
- start = startLength < data.DataLength ? 0 : data.DataLength - startLength + startLength;
- }
- else //不等
- {
- int addstart = 0;
- var mun = data.Length / data.DataLength;
- var a = new List<int>();
- for (int i = 0; i < mun; i++)
- {
- a.Add(addstart);
- addstart = addstart + data.DataLength;
- }
- start = a.Where(v => v <= startLength).OrderByDescending(v => v).FirstOrDefault();
- startLength = startLength - start;
- }
- var bytes = System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{start}")); //获取原有数据
- value.CopyTo(bytes, startLength); //将变更的数据,更新到redis字节组中
- Redis.Set($"{pLCData.IP}:{pLCData.DB}:{start}", bytes);
- }
- }
- /// <summary>
- /// PLC数据结构
- /// </summary>
- public class PLCData
- {
- /// <summary>
- /// IP
- /// </summary>
- public string IP { get; set; }
- /// <summary>
- /// DB
- /// </summary>
- public int DB { get; set; }
- /// <summary>
- /// 总长度
- /// </summary>
- public int Length { get; set; }
- /// <summary>
- /// 数据长度
- /// </summary>
- public int DataLength { get; set; }
- }
- }
|