Commit 7ff068c9 authored by 潘栩锋's avatar 潘栩锋 🚴

1. 修改 Project.FLY.OBJComponents

parent 620060c9
......@@ -24,9 +24,10 @@ namespace FLY.OBJComponents.Client
#region property
/// <summary>
/// 最后一行数据的ID
/// 最新数据的ID,就是 Buffer.NewestID,
/// 但不直接使用Buffer.NewestID,因为 Buffer.NewestID可能与接收的数据滞后,或超前
/// </summary>
public int RecordLastID { get; private set; } = 0;
public int RecordLastID { get; private set; } = -1;
/// <summary>
/// 窗口最后一行的目标ID
/// </summary>
......@@ -40,7 +41,7 @@ namespace FLY.OBJComponents.Client
/// </summary>
public int TotalPages { get; private set; }
/// <summary>
/// 当前页码
/// 当前页码, 页码从1-TotalPages
/// </summary>
public int CurrentPage { get; private set; }
......@@ -70,7 +71,7 @@ namespace FLY.OBJComponents.Client
Buffer = buffer;
IsKeepNewest = true;
WindowID = Buffer.NewestID;
WindowID = Buffer.NewestID;//显示最新数据!!!
updatePageInfo();
GetWindow();
......@@ -142,13 +143,13 @@ namespace FLY.OBJComponents.Client
{
case NotifyBufferChangedAction.Add:
{
int newEndingIndex = e.StartingIndex - 1 + 1;
int nFirstID = e.StartingIndex;
int nLastID = newEndingIndex;
int newEndingID = e.EndingID;
int nFirstID = e.EndingID;
int nLastID = newEndingID;
if (IsKeepNewest)//保持数据最新
{
WindowID = newEndingIndex;
WindowID = newEndingID;
}
int wLastID = WindowID;
......@@ -164,27 +165,25 @@ namespace FLY.OBJComponents.Client
}
else
{
push(newEndingIndex, (IList<T>)e.Items);
push(newEndingID, (IList<T>)e.Items);
}
}
break;
case NotifyBufferChangedAction.Replace:
{
int newEndingIndex = e.StartingIndex - 1 + 1;
push(newEndingIndex, (IList<T>)e.Items);
push(e.EndingID, (IList<T>)e.Items);
}
break;
case NotifyBufferChangedAction.Remove:
{
int newEndingIndex = e.StartingIndex - 1 + 1;
remove(newEndingIndex, 1);
remove(e.EndingID, 1);
}
break;
case NotifyBufferChangedAction.Reset:
{
//数据清空
Record.Clear();
RecordLastID = 0;
RecordLastID = -1;
WindowID = Size - 1;
}
break;
......@@ -220,8 +219,8 @@ namespace FLY.OBJComponents.Client
int offset = -rFirstID;
firstID += offset;
lastID += offset;
rLastID += offset;
rFirstID = 0;
rLastID += offset;// = Record.Count()-1
rFirstID = 0;// = 0
if (lastID < -1)//新数据在旧数据前面,不能合并
{
......@@ -288,7 +287,7 @@ namespace FLY.OBJComponents.Client
int offset = -rFirstID;
firstID += offset;
lastID += offset;
rLastID += offset;
rLastID += offset;// = Record.Count() - 1;
rFirstID = 0;
if (lastID <= -1)//被删除数据在当前数据前面,什么都不用做
......@@ -299,11 +298,12 @@ namespace FLY.OBJComponents.Client
{
//重新问buffer获取当前数据块
Record.Clear();
RecordLastID = 0;
RecordLastID = -1;
GetWindow();
}
}
}
/// <summary>
/// 把多出window范围的数据删除
/// </summary>
......@@ -366,19 +366,28 @@ namespace FLY.OBJComponents.Client
void updatePageInfo()
{
int firstID = Buffer.NewestID - Buffer.Count + 1;
int firstID = Buffer.NewestID - (Buffer.Count - 1);
int lastID = Buffer.NewestID;
int wLastID = WindowID;
//修正后,firstID,lastID 就是Buffer 内部数据量的排序,lastID=Count-1
int offset = -firstID;
lastID += offset;
wLastID += offset;
firstID = 0;
int page = (int)(Math.Ceiling(1.0 * wLastID / Size));
TotalPages = page + (int)(Math.Ceiling((1.0 * (lastID - wLastID) / Size)));
int page = wLastID / Size;
int page1st_size = wLastID % Size;
int totalpages = (int)(Math.Ceiling((1.0 * (lastID - page1st_size) / Size)));
if (page1st_size != 0)
{
page++;
totalpages++;
}
CurrentPage = page;
TotalPages = totalpages;
if (CurrentPage <=1)
IsFirstPage = true;
else
......
......@@ -17,7 +17,7 @@ namespace FLY.OBJComponents.Client
public class BufferServiceClient<T> : FObj, IBuffer<T>
{
#region property
public int NewestID { get; private set; } = 0;
public int NewestID { get; private set; } = -1;
public int Count { get; private set; } = 0;
/// <summary>
/// 总容量,当总数量 大于等于 总容量的 100%, 前面的10%数据会被删除
......@@ -45,10 +45,11 @@ namespace FLY.OBJComponents.Client
{
if (isIgnore)
return;
Dictionary<string, object> datas = new Dictionary<string, object>();
datas.Add(e.PropertyName, Misc.PropertiesManager.GetValue(sender, e.PropertyName));
Dictionary<string, object> datas = new Dictionary<string, object>
{
{ e.PropertyName, Misc.PropertiesManager.GetValue(sender, e.PropertyName) }
};
string json = JsonConvert.SerializeObject(datas);
CurrObjSys.SetValueEx(mConn, mServerID, ID, BUFFER_OBJ_INTERFACE.SET_PARAMS,
Misc.Converter.StringToBytes(json));
......@@ -91,7 +92,9 @@ namespace FLY.OBJComponents.Client
string json = Misc.Converter.BytesToString(infodata);
Dictionary<string, object> datas = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
//设置属性
//屏蔽属性改变后,设置到服务器
isIgnore = true;
foreach (KeyValuePair<string, object> kv in datas)
......@@ -129,12 +132,6 @@ namespace FLY.OBJComponents.Client
switch (funcid)
{
case BUFFER_OBJ_INTERFACE.CALL_GETRECORD:
{
string json = Misc.Converter.BytesToString(retdata);
GetRecordReponse<T> p = JsonConvert.DeserializeObject<GetRecordReponse<T>>(json);
((AsyncCBHandler)AsyncDelegate)(AsyncState, p);
}
break;
case BUFFER_OBJ_INTERFACE.CALL_GETRECORD_NEWEST:
{
string json = Misc.Converter.BytesToString(retdata);
......@@ -152,7 +149,12 @@ namespace FLY.OBJComponents.Client
public void GetRecord(int last_id, int count, AsyncCBHandler asyncCB, object asyncContext)
{
BUFFER_OBJ_INTERFACE.Pack_GetRecordRequest request = new BUFFER_OBJ_INTERFACE.Pack_GetRecordRequest() { last_id = last_id, count = count };
BUFFER_OBJ_INTERFACE.Pack_GetRecordRequest request = new BUFFER_OBJ_INTERFACE.Pack_GetRecordRequest()
{
last_id = last_id,
count = count
};
string json = JsonConvert.SerializeObject(request);
CurrObjSys.CallFunctionEx(mConn, mServerID, ID, BUFFER_OBJ_INTERFACE.CALL_GETRECORD,
......@@ -162,7 +164,10 @@ namespace FLY.OBJComponents.Client
}
public void GetRecord(int count, AsyncCBHandler asyncCB, object asyncContext)
{
BUFFER_OBJ_INTERFACE.Pack_GetRecordNewestRequest request = new BUFFER_OBJ_INTERFACE.Pack_GetRecordNewestRequest() { count = count };
BUFFER_OBJ_INTERFACE.Pack_GetRecordNewestRequest request = new BUFFER_OBJ_INTERFACE.Pack_GetRecordNewestRequest()
{
count = count
};
string json = JsonConvert.SerializeObject(request);
CurrObjSys.CallFunctionEx(mConn, mServerID, ID, BUFFER_OBJ_INTERFACE.CALL_GETRECORD_NEWEST,
......
......@@ -53,12 +53,10 @@ namespace FLY.OBJComponents.Client
IsConnected = from.IsConnected;
if (from.IsConnected)
{
CurrObjSys.SenseConfigEx(mConn, mServerID, ID,
0xffffffff, SENSE_CONFIG.ADD);
}
}
#region IPLCProxySystemService
public void FeedPlan(long planID)
......@@ -72,6 +70,17 @@ namespace FLY.OBJComponents.Client
FObjSys.Current.CallFunctionEx(mConn, mServerID, ID,
PLCOS_OBJ_INTERFACE.CALL_FEED_PLAN, Misc.Converter.StringToBytes(json));
}
public void RemovePlan(long planID)
{
PLCOS_OBJ_INTERFACE.Pack_RemovePlanRequest pack = new PLCOS_OBJ_INTERFACE.Pack_RemovePlanRequest()
{
planid = planID
};
string json = JsonConvert.SerializeObject(pack);
FObjSys.Current.CallFunctionEx(mConn, mServerID, ID,
PLCOS_OBJ_INTERFACE.CALL_REMOVE_PLAN, Misc.Converter.StringToBytes(json));
}
public void SetPlan(string objname, IEnumerable<string> propertynames, long planID)
{
......@@ -87,7 +96,25 @@ namespace FLY.OBJComponents.Client
PLCOS_OBJ_INTERFACE.CALL_SET_PLAN, Misc.Converter.StringToBytes(json));
}
/// <summary>
/// 设置更新计划
/// </summary>
/// <param name="objname">对象名</param>
/// <param name="propertynames">属性名</param>
/// <param name="planID">计划的编号,应该全局唯一,建议使用时间ticks</param>
public void SetPlan(string objname, IEnumerable<string> propertynames, SetPlanReponseHandler setPlanReponse, object context)
{
PLCOS_OBJ_INTERFACE.Pack_SetPlan2Request pack = new PLCOS_OBJ_INTERFACE.Pack_SetPlan2Request()
{
objname = objname,
propertyNames = propertynames,
};
string json = JsonConvert.SerializeObject(pack);
FObjSys.Current.CallFunctionEx(mConn, mServerID, ID,
PLCOS_OBJ_INTERFACE.CALL_SET_PLAN2, Misc.Converter.StringToBytes(json), setPlanReponse, context);
}
#endregion
public string[] GetSyncPropNames()
......@@ -102,5 +129,22 @@ namespace FLY.OBJComponents.Client
return null;
}
public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object AsyncDelegate, object AsyncState)
{
switch (funcid)
{
case PLCOS_OBJ_INTERFACE.CALL_SET_PLAN2:
{
string json = Misc.Converter.BytesToString(retdata);
PLCOS_OBJ_INTERFACE.Pack_SetPlan2Reponse reponse = JsonConvert.DeserializeObject<PLCOS_OBJ_INTERFACE.Pack_SetPlan2Reponse>(json);
SetPlanReponseHandler setPlanReponseHandler = (SetPlanReponseHandler)AsyncDelegate;
setPlanReponseHandler(reponse.planid, AsyncState);
}
break;
}
}
}
}
......@@ -11,8 +11,8 @@ namespace FLY.OBJComponents.Client
public class SetPLCUpdatePlan:IDisposable
{
IPLCProxySystemService PLCos;
long planid;
DispatcherTimer timer;
long planid=0;
DispatcherTimer timer;//可能被销毁了
string objname;
IEnumerable<string> propertynames;
......@@ -23,39 +23,56 @@ namespace FLY.OBJComponents.Client
this.propertynames = propertynames;
this.objname = PLCos.ObjNames.First((kv) => kv.Value == obj).Key;
planid = DateTime.Now.Ticks;
timer = new DispatcherTimer()
PLCos.PropertyChanged += PLCos_PropertyChanged;
timer = new DispatcherTimer()//120s 内必须再次注册
{
Interval = TimeSpan.FromSeconds(2)
Interval = TimeSpan.FromSeconds(60)
};
timer.Tick += (s, e) => {
if (PLCos.IsConnectedWithPLC)
timer.Tick += (s, e) =>
{
if (planid != 0)
{
PLCos.FeedPlan(planid);
}
else
{
timer.IsEnabled = false;
}
};
Misc.BindingOperations.SetBinding(PLCos, "IsConnectedWithPLC", () => {
if (PLCos.IsConnectedWithPLC)
if (((PLCProxySystemServiceClient)PLCos).IsConnected)
{
PLCos.SetPlan( this.objname, this.propertynames, (planid, context) =>
{
//重新注册更新计划
PLCos.SetPlan(objname, propertynames, planid);
timer.IsEnabled = true;
this.planid = planid;
timer.Start();
}, null);
}
}
private void PLCos_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsConnected")
{
if (((PLCProxySystemServiceClient)PLCos).IsConnected)
{
PLCos.SetPlan(objname, propertynames, (planid, context) =>
{
this.planid = planid;
timer.Start();
}, null);
}
else
{
timer.IsEnabled = false;
this.planid = 0;
timer.Stop();
}
});
}
}
public void Dispose()
{
timer.Stop();
if(planid!=0)
PLCos.RemovePlan(planid);
}
}
}
......@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace FLY.OBJComponents.Common
{
public class FlyData_WarningHistory : IFlyData
public class FlyData_WarningHistory : IFlyData, IPack2
{
/// <summary>
/// 时间
......@@ -79,6 +79,62 @@ namespace FLY.OBJComponents.Common
str += "," + Description.ToString();
return str;
}
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(BitConverter.GetBytes(Time.Ticks));
buf.Add(ErrCode);
buf.AddRange(BitConverter.GetBytes((int)State));
byte[] bs = Misc.Converter.StringToBytes(Description);
int len;
if (bs == null)
len = 0;
else
len = bs.Length;
buf.AddRange(BitConverter.GetBytes(len));
if (len > 0)
buf.AddRange(bs);
return buf.ToArray();
}
public bool TryParse(byte[] value, int index, out int cnt)// ref int idx)
{
cnt = 8 + 1 + 4 + 4;
if (value.Length - index < cnt)
return false;
int idx = index;
Time = new DateTime(BitConverter.ToInt64(value, idx));
idx += 8;
ErrCode = value[idx];
idx++;
State = (ERR_STATE)BitConverter.ToInt32(value, idx);
idx += 4;
int len = BitConverter.ToInt32(value, idx);
idx += 4;
cnt += len;
if (value.Length - index < cnt)
return false;
if (len == 0)
Description = "";
else
{
Description = Misc.Converter.BytesToString(value, idx, len);
}
idx += len;
return true;
}
public bool TryParse(byte[] value)
{
int cnt;
return TryParse(value, 0, out cnt);
}
}
/// <summary>
......@@ -93,7 +149,11 @@ namespace FLY.OBJComponents.Common
/// <summary>
/// 关闭
/// </summary>
OFF
OFF,
/// <summary>
/// 只发生了一次
/// </summary>
ONCE
}
/// <summary>
......
......@@ -20,7 +20,7 @@ namespace FLY.OBJComponents.Common
{
public NotifyBufferChangedAction Action { get; set; }
public IList<T> Items { get; set; }
public int StartingIndex { get; set; }
public int EndingID { get; set; }
}
public enum NotifyBufferChangedAction
......
......@@ -16,7 +16,15 @@ namespace FLY.OBJComponents.Common
/// <param name="val">属性值</param>
public static void SetValue(object obj, string propertyName, object v)
{
PropertyInfo property = obj.GetType().GetProperties().First(p => { return p.Name == propertyName; });
PropertyInfo property;
try
{
property = obj.GetType().GetProperty(propertyName);
}
catch(Exception e)
{
throw new Exception("PropertiesManager_JSON 类型="+obj.GetType().ToString()+" 不能找到 属性名=" + propertyName, e);
}
if (property != null)
{
if (v.GetType() == property.PropertyType)
......@@ -26,7 +34,8 @@ namespace FLY.OBJComponents.Common
else
{
string json = JsonConvert.SerializeObject(v);
property.SetValue(obj, JsonConvert.DeserializeObject(json, property.PropertyType), null);
v = JsonConvert.DeserializeObject(json, property.PropertyType);
property.SetValue(obj, v, null);
}
}
}
......
......@@ -19,6 +19,7 @@ namespace FLY.OBJComponents.IService
/// 对象名称
/// </summary>
Dictionary<string, INotifyPropertyChanged> ObjNames { get; }
/// <summary>
/// 设置更新计划
/// </summary>
......@@ -26,10 +27,27 @@ namespace FLY.OBJComponents.IService
/// <param name="propertynames">属性名</param>
/// <param name="planID">计划的编号,应该全局唯一,建议使用时间ticks</param>
void SetPlan(string objname, IEnumerable<string> propertynames, long planID);
/// <summary>
/// 更新计划持续,如果不喂狗,20s后停止更新数据
/// 设置更新计划
/// </summary>
/// <param name="objname">对象名</param>
/// <param name="propertynames">属性名</param>
/// <param name="planID">计划的编号,应该全局唯一,建议使用时间ticks</param>
void SetPlan(string objname, IEnumerable<string> propertynames, SetPlanReponseHandler setPlanReponse, object context);
/// <summary>
/// 更新计划持续,如果不喂狗,120s后停止更新数据
/// </summary>
/// <param name="planID">计划的编号</param>
void FeedPlan(long planID);
/// <summary>
/// 主动删除某个计划
/// </summary>
/// <param name="planID"></param>
void RemovePlan(long planID);
}
public delegate void SetPlanReponseHandler(long planid, object context);
}
......@@ -37,7 +37,6 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
......@@ -54,7 +53,6 @@
<Compile Include="Client\SetPLCUpdatePlan.cs" />
<Compile Include="Client\SyncPropServiceClient.cs" />
<Compile Include="Client\WarningServiceClient.cs" />
<Compile Include="Common\HeaderAttribute.cs" />
<Compile Include="Common\NotifyBufferChangedEventArgs.cs" />
<Compile Include="Common\FlyData_WarningHistory.cs" />
<Compile Include="Common\PropertiesManager.cs" />
......@@ -80,6 +78,11 @@
<Compile Include="Server\PLCProxySystem.cs" />
<Compile Include="Server\WarningSystem.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="FodyWeavers.xml">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Project.FLY.FObjSys\FObjSys\FObjBase.csproj">
<Project>{abfe87d4-b692-4ae9-a8c0-1f470b8acbb8}</Project>
......@@ -95,14 +98,6 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fody">
<Version>4.2.1</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.2</Version>
</PackageReference>
......
......@@ -21,6 +21,22 @@ namespace FLY.OBJComponents.OBJ_INTERFACE
{
public long planid;
}
public class Pack_RemovePlanRequest
{
public long planid;
}
public class Pack_SetPlan2Reponse
{
public long planid;
}
public class Pack_SetPlan2Request
{
public string objname;
public IEnumerable<string> propertyNames;
}
#endregion
#region Get
......@@ -28,7 +44,7 @@ namespace FLY.OBJComponents.OBJ_INTERFACE
#endregion
#region Set
#endregion
#region Push
......@@ -45,6 +61,18 @@ namespace FLY.OBJComponents.OBJ_INTERFACE
/// Pack_FeedPlanRequest
/// </summary>
public const UInt16 CALL_FEED_PLAN = 4;
/// <summary>
/// Pack_RemovePlanRequest
/// </summary>
public const UInt16 CALL_REMOVE_PLAN = 5;
/// <summary>
/// requese:Pack_SetPlan2Request
/// reponse:Pack_SetPlan2Reponse
/// </summary>
public const UInt16 CALL_SET_PLAN2 = 6;
#endregion
}
}
......@@ -36,9 +36,11 @@ namespace FLY.OBJComponents.Server.OBJProxy
private void Buffer_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
Dictionary<string, object> p = new Dictionary<string, object>();
p.Add(e.PropertyName, Misc.PropertiesManager.GetValue(buffer, e.PropertyName));
Dictionary<string, object> p = new Dictionary<string, object>
{
{ e.PropertyName, Misc.PropertiesManager.GetValue(sender, e.PropertyName) }
};
string json = JsonConvert.SerializeObject(p);
CurrObjSys.PushObjInfoEx(
this, BUFFER_OBJ_INTERFACE.PUSH_PARAMS,
......@@ -62,9 +64,6 @@ namespace FLY.OBJComponents.Server.OBJProxy
}
}
break;
default:
infodata = null;
break;
}
}
......
......@@ -43,6 +43,20 @@ namespace FLY.OBJComponents.Server.OBJProxy
plcos.SetPlan(pack.objname, pack.propertyNames, pack.planid);
}
break;
case PLCOS_OBJ_INTERFACE.CALL_SET_PLAN2:
{
string json = Misc.Converter.BytesToString(infodata);
PLCOS_OBJ_INTERFACE.Pack_SetPlan2Request pack = JsonConvert.DeserializeObject<PLCOS_OBJ_INTERFACE.Pack_SetPlan2Request>(json);
plcos.SetPlan(pack.objname, pack.propertyNames, (planid, context) =>
{
ConnContext conn = context as ConnContext;
PLCOS_OBJ_INTERFACE.Pack_SetPlan2Reponse p = new PLCOS_OBJ_INTERFACE.Pack_SetPlan2Reponse() { planid = planid };
string s = JsonConvert.SerializeObject(p);
CurrObjSys.PushCallFunctionEx(conn.from, srcid, ID, magic, funcid, Misc.Converter.StringToBytes(s));
}, new ConnContext(from, srcid, magic));
}
break;
case PLCOS_OBJ_INTERFACE.CALL_FEED_PLAN:
{
string json = Misc.Converter.BytesToString(infodata);
......@@ -50,6 +64,13 @@ namespace FLY.OBJComponents.Server.OBJProxy
plcos.FeedPlan(pack.planid);
}
break;
case PLCOS_OBJ_INTERFACE.CALL_REMOVE_PLAN:
{
string json = Misc.Converter.BytesToString(infodata);
PLCOS_OBJ_INTERFACE.Pack_FeedPlanRequest pack = JsonConvert.DeserializeObject<PLCOS_OBJ_INTERFACE.Pack_FeedPlanRequest>(json);
plcos.RemovePlan(pack.planid);
}
break;
}
}
}
......
......@@ -20,7 +20,7 @@ namespace FLY.OBJComponents.Server
public List<T> list = new List<T>();
#region property
public int NewestID { get; set; }
public int NewestID { get; set; } = -1;
public int Count { get; private set; } = 0;
/// <summary>
......@@ -46,11 +46,14 @@ namespace FLY.OBJComponents.Server
public int GetID(int idx)
{
return NewestID - (list.Count() - 1 - idx);
int offset = (NewestID - (list.Count() - 1));
return offset + idx;
}
public int GetIndex(int id)
{
return list.Count() - 1 - (NewestID - id);
int offset = (NewestID - (list.Count() - 1));
return id - offset;
}
public void Add(T t)
{
......@@ -60,9 +63,8 @@ namespace FLY.OBJComponents.Server
{
list.RemoveRange(0, Capacity / 10);
}
if (list.Count() != 1)
NewestID++;
NewestID++;
Count = list.Count();
......@@ -72,7 +74,7 @@ namespace FLY.OBJComponents.Server
{
Action = NotifyBufferChangedAction.Add,
Items = new T[] { t },
StartingIndex = NewestID
EndingID = NewestID
});
}
public void AddRange(IList<T> array)
......@@ -83,9 +85,8 @@ namespace FLY.OBJComponents.Server
{
list.RemoveRange(0, Capacity / 10);
}
if (list.Count() != 1)
NewestID += array.Count();
NewestID += array.Count();
Count = list.Count();
BufferChanged?.Invoke(this,
......@@ -93,7 +94,7 @@ namespace FLY.OBJComponents.Server
{
Action = NotifyBufferChangedAction.Add,
Items = array,
StartingIndex = NewestID
EndingID = NewestID
});
}
public override string ToString()
......@@ -111,7 +112,7 @@ namespace FLY.OBJComponents.Server
{
Action = NotifyBufferChangedAction.Replace,
Items = new T[] { t },
StartingIndex = id
EndingID = id
});
}
public void Remove(int id)
......@@ -127,14 +128,14 @@ namespace FLY.OBJComponents.Server
new NotifyBufferChangedEventArgs<T>()
{
Action = NotifyBufferChangedAction.Remove,
StartingIndex = id,
EndingID = id,
Items = new T[] { t }
});
}
public void Reset()
{
list.Clear();
NewestID = 0;
NewestID = -1;
Count = 0;
BufferChanged?.Invoke(this,
new NotifyBufferChangedEventArgs<T>()
......
......@@ -5,6 +5,7 @@ using System.ComponentModel;
using System.Linq;
using System.Text;
using FLY.Modbus;
using System.Windows.Threading;
namespace FLY.OBJComponents.Server
{
......@@ -29,8 +30,8 @@ namespace FLY.OBJComponents.Server
public List<ModbusMapper> mappers = new List<ModbusMapper>();
}
List<Plan> planIDs = new List<Plan>();
public List<ModbusMapper.DataToRegs> DRMap = new List<ModbusMapper.DataToRegs>();
public List<ModbusMapper_Client> PLCs = new List<ModbusMapper_Client>();
public List<DataToRegs> DRMap = new List<DataToRegs>();
public List<Modbus.WithThread.ModbusMapper_Client> PLCs = new List<Modbus.WithThread.ModbusMapper_Client>();
public Dictionary<string, INotifyPropertyChanged> ObjNames { get; } = new Dictionary<string, INotifyPropertyChanged>();
/// <summary>
......@@ -47,18 +48,17 @@ namespace FLY.OBJComponents.Server
}
public void Init()
{
foreach (ModbusMapper_Client plc in PLCs)
foreach (var plc in PLCs)
{
plc.NameDataChanged += plc_NameDataChanged;
}
Misc.BindingOperations.SetBinding(PLCs[0].mclient, "IsConnected", () =>
Misc.BindingOperations.SetBinding(PLCs[0].Client, "IsConnected", () =>
{
IsConnectedWithPLC = PLCs[0].mclient.IsConnected;
if (!IsConnectedWithPLC)
ClearPlan();
IsConnectedWithPLC = PLCs[0].Client.IsConnected;
//if (!IsConnectedWithPLC)
// ClearPlan();
});
foreach (var obj in ObjNames.Values)
......@@ -69,19 +69,24 @@ namespace FLY.OBJComponents.Server
FObjBase.PollModule.Current.Poll_Config(FObjBase.PollModule.POLL_CONFIG.ADD,
OnPoll_plans, TimeSpan.FromSeconds(1));
//启动!!!!
foreach (var plc in PLCs)
plc.Start();
//PLCs[0].Start();
}
private void Obj_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (isShield)
return;
List<ModbusMapper.DataToRegs> drs = DRMap;
List<DataToRegs> drs = DRMap;
ModbusMapper.DataToRegs dr = drs.Find((_dr) => { return (_dr.propertyName == e.PropertyName) && (_dr.owner == sender); });
DataToRegs dr = drs.Find((_dr) => { return (_dr.propertyName == e.PropertyName) && (_dr.owner == sender); });
if (dr == null)
return;//不会刷新PLC
//向HMI写入数据,mRegs每次只能写入一个,它有列表保存功能。
//向PLC写入数据,mRegs每次只能写入一个,它有列表保存功能。
//SetNameData可以执行很多次,不过它只能一个个发。
dr.mapper.SetNameData(dr, Misc.PropertiesManager.GetValue(sender, e.PropertyName));
}
......@@ -90,16 +95,22 @@ namespace FLY.OBJComponents.Server
void plc_NameDataChanged(object sender, NameDataChangedEventArgs e)
void plc_NameDataChanged(object sender, DataToRegs dr)// NameDataChangedEventArgs e)
{
ModbusMapper_Client plc = sender as ModbusMapper_Client;
//var plc = sender as Modbus.WithThread.ModbusMapper_Client;
//object value = plc.GetNameData(e.Owener, e.PropertyName);
//这是从PLC 更新过来的,不需要向PLC写入
//这是从HMI 更新过来的,不需要向HMI写入
isShield = true;
Misc.PropertiesManager.SetValue(e.Owener, e.PropertyName, plc.GetNameData(e.Owener, e.PropertyName));
isShield = false;
}
FObjBase.PollModule.Current.Dispatcher.Invoke(new SetValueHandler((owner, propertyname, value) =>
{
isShield = true;
Misc.PropertiesManager.SetValue(dr.owner, dr.propertyName, dr.value);
isShield = false;
}), dr.owner, dr.propertyName, dr.value);
}
delegate void SetValueHandler(object owner, string propertyname, object value);
/// <summary>
/// 设置更新计划
/// </summary>
......@@ -118,27 +129,53 @@ namespace FLY.OBJComponents.Server
{
plan.FeedTime = DateTime.Now;
}
List<ModbusMapper.DataToRegs> drs = DRMap;
List<DataToRegs> drs = DRMap;
foreach (string propertyname in propertynames)
{
ModbusMapper.DataToRegs dr = drs.Find((_dr) => { return (_dr.propertyName == propertyname && _dr.owner == ObjNames[objname]); });
if (!ObjNames.ContainsKey(objname))
continue;
DataToRegs dr = drs.Find((_dr) => { return (_dr.propertyName == propertyname && _dr.owner == ObjNames[objname]); });
if (dr == null)
{
continue;
//throw new Exception($"PLCProxySystem.SetPlan 不能找到 {objname}.{propertyname}");
}
dr.mapper.PlanAdd(planID, dr);
if (!plan.mappers.Contains(dr.mapper))
plan.mappers.Add(dr.mapper);
}
foreach (ModbusMapper mapper in plan.mappers)
foreach (var mapper in plan.mappers)
{
mapper.PlanMake();
}
}
long freeplanid = 1;
long GetFreePlanID()
{
long planid = freeplanid;
freeplanid++;
if (freeplanid == 0)
freeplanid = 1;
return planid;
}
/// <summary>
/// 设置更新计划
/// </summary>
/// <param name="objname">对象名称</param>
/// <param name="propertynames"></param>
/// <param name="planID">计划的编号,应该全局唯一,建议使用时间ticks</param>
public void SetPlan(string objname, IEnumerable<string> propertynames, SetPlanReponseHandler reponseHandler, object context)
{
long planID = GetFreePlanID();
SetPlan(objname, propertynames, planID);
reponseHandler(planID, context);
}
/// <summary>
/// 更新计划持续,如果不喂狗,20s后停止更新数据
/// </summary>
......@@ -153,32 +190,40 @@ namespace FLY.OBJComponents.Server
}
/// <summary>
/// 清除全部计划
/// 主动删除某个计划
/// </summary>
void ClearPlan()
/// <param name="planID"></param>
public void RemovePlan(long planID)
{
if (planIDs.Count() > 0)
{
foreach (var plc in PLCs)
{
plc.PlanClear();
plc.PlanMake();
}
planIDs.Clear();
}
ClearPlan((plan) => (plan.ID == planID));
}
/// <summary>
/// 1s 一次,看出哪个令牌过期
/// 清除 非0 全部计划
/// </summary>
void OnPoll_plans()
void ClearPlan()
{
//if (planIDs.Count() > 0)
//{
// foreach (var plc in PLCs)
// {
// plc.PlanClear();
// plc.PlanMake();
// }
// planIDs.Clear();
//}
ClearPlan((plan) => (plan.ID != 0));
}
void ClearPlan(Func<Plan, bool> condition)
{
if (planIDs.Count() > 0)
{
var _remove =
from plan in planIDs
where (plan.ID != 0) && (DateTime.Now - plan.FeedTime) > TimeSpan.FromSeconds(10)
where condition(plan)
select plan;
if (_remove.Count() > 0)
{
List<Plan> remove = new List<Plan>(_remove);
......@@ -201,6 +246,15 @@ namespace FLY.OBJComponents.Server
}
}
}
/// <summary>
/// 1s 一次,看出哪个令牌过期
/// </summary>
void OnPoll_plans()
{
DateTime now = DateTime.Now;
ClearPlan((plan) => (plan.ID != 0) && (now - plan.FeedTime) > TimeSpan.FromMinutes(2));
}
public string[] GetSyncPropNames()
{
......
......@@ -41,31 +41,24 @@ namespace FLY.OBJComponents.Server
ReasonList = new Buffer<FlyData_WarningHistory>();
NewestList = new BufferStorage<FlyData_WarningHistory>("warning_newest.csv");
}
/// <summary>
/// 报警复位!!!!
/// </summary>
public Action ResetEvent;
public void Reset()
{
ReasonList.Reset();
ResetEvent?.Invoke();
}
/// <summary>
/// 正在报警!!!
/// </summary>
public Action RingEvent;
#region IWarningServiceSimple
public void Add(byte errcode, string description, ERR_STATE state)
{
FlyData_WarningHistory reason = new FlyData_WarningHistory();
reason.Time = DateTime.Now;
reason.ErrCode = errcode;
reason.Description = description;
reason.State = state;
FlyData_WarningHistory reason = new FlyData_WarningHistory
{
Time = DateTime.Now,
ErrCode = errcode,
Description = description,
State = state
};
FlyData_WarningHistory error = null;
Buffer<FlyData_WarningHistory> reasonList = ReasonList as Buffer<FlyData_WarningHistory>;
......@@ -85,7 +78,7 @@ namespace FLY.OBJComponents.Server
case ERR_STATE.ON:
if (error == null)
{
((Buffer<FlyData_WarningHistory>)ReasonList).Add(reason.Clone());
reasonList.Add(reason.Clone());
}
else
......@@ -103,20 +96,12 @@ namespace FLY.OBJComponents.Server
else
{
error.State = state;
((Buffer<FlyData_WarningHistory>)ReasonList).Remove(error_id);
reasonList.Remove(error_id);
}
break;
}
((Buffer<FlyData_WarningHistory>)NewestList).Add(reason);
if (reasonList.Count > 0)
{
RingEvent?.Invoke();
}
else
{
Reset();
}
}
#endregion
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment