Commit b0445e04 authored by 潘栩锋's avatar 潘栩锋 :bicyclist:

1. SetPlan 会有问题,原因 通过tick产生的planid 很多一样。 现在向服务器获取planid

parent b92d8fb2
......@@ -99,19 +99,12 @@ namespace FLY.IBC.Server
//--------------------------------------------------------------------------------
//添加任务
Misc.BindingOperations.SetBinding(PLCos, "IsConnectedWithPLC", () =>
{
if (PLCos.IsConnectedWithPLC)
{
PLCos.SetPlan("Item", new string[] {
PLCos.SetPlan("Item", new string[] {
"FilmWidth","InletAirFreq","OutletAirFreq",
"IsInletAirMotorError","IsOutletAirMotorError",
"IsInletAirCommError","IsOutletAirCommError"
}, 0);
}
});
//--------------------------------------------------------------------------------
//设置修改后通知
......
......@@ -127,14 +127,14 @@ namespace FLY.Modbus
/// 从本地PC 属性获取value 更新到 本地PLC 寄存器,
/// 目的: 当从PLC读取寄存器值时,能比较不同,产生变化事件
/// </summary>
public void UpdatePLCObjFromProperty()
public void SetAllIsPlcValueChanged()
{
foreach (DataToRegs dr in regs)
{
dr.value = Misc.PropertiesManager.GetValue(dr.owner, dr.propertyName);
dr.ToPLCObj();
dr.isPlcValueChanged = true;
}
}
}
/// <summary>
......
......@@ -60,12 +60,12 @@ namespace FLY.Modbus
/// <summary>
/// PLC obj ,bool or UInt16[]
/// </summary>
public object plc_value;
public object plcValue;
/// <summary>
/// PLC obj 寄存器值是否改变
/// </summary>
public bool changed;
public bool isPlcValueChanged;
/// <summary>
/// 需要从PLC读取数据更新
......@@ -93,13 +93,13 @@ namespace FLY.Modbus
if (type == REG_TYPE.BOOL)
{
plc_value = false;
plcValue = false;
endAddr = addr;
}
else
{
plc_value = new UInt16[ModbusMapper.RegSize(type)];
endAddr = addr + ((UInt16[])plc_value).Count() - 1;
plcValue = new UInt16[ModbusMapper.RegSize(type)];
endAddr = addr + ((UInt16[])plcValue).Count() - 1;
}
}
......@@ -124,7 +124,7 @@ namespace FLY.Modbus
/// </summary>
public void ToPropertyObj()
{
value = ToPropertyObj(plc_value);
value = ToPropertyObj(plcValue);
}
/// <summary>
......@@ -150,12 +150,12 @@ namespace FLY.Modbus
switch (dataArea)
{
case PLCAddressArea.Coil:
plc_value = plcobj;
plcValue = plcobj;
break;
case PLCAddressArea.Register:
{
UInt16[] src = plcobj as UInt16[];
UInt16[] dest = plc_value as UInt16[];
UInt16[] dest = plcValue as UInt16[];
Array.Copy(src, dest, dest.Length);
}
break;
......
......@@ -130,6 +130,7 @@ namespace FLY.Modbus
/// <param name="val">数据值,不能为空</param>
/// <returns></returns>
public abstract void SetNameData(DataToRegs dr, object val);
/// <summary>
/// 取命名数据的值
......@@ -169,36 +170,36 @@ namespace FLY.Modbus
for (int i = 0; i < area_regs.regs.Count(); i++)
{
if (endAddr < area_regs.regs[i].addr)
DataToRegs dr = area_regs.regs[i];
if (endAddr < dr.addr)
{
//在前面
break;
}
else if (addr <= area_regs.regs[i].endAddr)//有交集
else if (addr <= dr.endAddr)//有交集
{
//计算交集
int addr_act = Math.Max(addr, area_regs.regs[i].addr);
int endAddr_act = Math.Min(endAddr, area_regs.regs[i].endAddr);
int addr_act = Math.Max(addr, dr.addr);
int endAddr_act = Math.Min(endAddr, dr.endAddr);
int num_act = endAddr_act - addr_act + 1;//不需要检测<=0, 当为0,下面的循环跑不动
for (int j = 0; j < num_act; j++)
{
int idx1 = addr_act - area_regs.regs[i].addr + j;
int idx1 = addr_act - dr.addr + j;
int idx2 = addr_act - addr + j;
UInt16[] plc_value = (UInt16[])area_regs.regs[i].plc_value;
UInt16[] plc_value = (UInt16[])dr.plcValue;
if (plc_value[idx1] != vals.ElementAt(idx2))
{
plc_value[idx1] = vals.ElementAt(idx2);
area_regs.regs[i].changed = true;
area_regs.regs[i].isPlcValueChanged = true;
}
}
if (endAddr_act == area_regs.regs[i].endAddr)
if (endAddr_act == dr.endAddr)
{
if (area_regs.regs[i].changed)
if (dr.isPlcValueChanged)
{
area_regs.regs[i].changed = false;
DataToRegs dr = area_regs.regs[i];
dr.isPlcValueChanged = false;
dr.ToPropertyObj();
//触发事件
NotifyNameDataChanged(dr);
......@@ -221,23 +222,22 @@ namespace FLY.Modbus
for (int i = 0; i < area_coils.regs.Count(); i++)
{
if (endAddr < area_coils.regs[i].addr)
DataToRegs dr = area_coils.regs[i];
if (endAddr < dr.addr)
{
//在前面
break;
}
else if (addr <= area_coils.regs[i].addr)//有交集
else if (addr <= dr.addr)//有交集
{
int addr_act = area_coils.regs[i].addr;
int addr_act = dr.addr;
int idx2 = addr_act - addr;
if ((bool)area_coils.regs[i].plc_value != vals.ElementAt(idx2))
if ((bool)dr.plcValue != vals.ElementAt(idx2))
{
area_coils.regs[i].plc_value = vals.ElementAt(idx2);
DataToRegs dr = area_coils.regs[i];
dr.plcValue = vals.ElementAt(idx2);
dr.ToPropertyObj();
//触发事件
NotifyNameDataChanged(dr);
......@@ -323,7 +323,87 @@ namespace FLY.Modbus
}
#endregion
#region 寄存器读取更新计划
Dictionary<object, List<DataToRegs>> plans = new Dictionary<object, List<DataToRegs>>();
/// <summary>
/// 登记寄存器更新计划
/// </summary>
public void PlanAdd(object key, DataToRegs dr)
{
if (plans.ContainsKey(key))
{
if (!plans[key].Contains(dr))
plans[key].Add(dr);
}
else
{
plans.Add(key, new List<DataToRegs>());
plans[key].Add(dr);
}
}
/// <summary>
/// 删除寄存器更新计划
/// </summary>
/// <param name="key"></param>
public void PlanRemove(object key)
{
plans.Remove(key);
}
/// <summary>
/// 删除全部寄存器更新计划
/// </summary>
public void PlanClear()
{
plans.Clear();
}
/// <summary>
/// 需要被更新的 寄存器数量
/// </summary>
public int DRNeedUpdateCnt { get; private set; }
/// <summary>
/// 总寄存器数量
/// </summary>
public int DRCnt { get; private set; }
/// <summary>
/// DRmap分配到 每个寄存器区
/// </summary>
public void Build()
{
DRCnt = DRmap.Count;
//TODO, 应该提前做!!!!
foreach (var areaManager in mAreaManager)
areaManager.BuildArray(DRmap);
}
/// <summary>
/// 创建寄存器更新计划
/// </summary>
public void PlanMake()
{
foreach (DataToRegs dr in DRmap)
{
dr.isNeedUpdate = false;
}
foreach (KeyValuePair<object, List<DataToRegs>> kv in plans)
{
foreach (DataToRegs dr in kv.Value)
{
dr.isNeedUpdate = true;
}
}
//foreach (DataToRegs dr in DRmap)
//{
// dr.isNeedUpdate = true;
//}
DRNeedUpdateCnt = DRmap.Count((dr) => dr.isNeedUpdate);
foreach (var areaManager in mAreaManager)
areaManager.MakePlan();
}
#endregion
}
......
......@@ -109,7 +109,7 @@ namespace FLY.Modbus
else
{
foreach (var areaManager in mAreaManager)
areaManager.UpdatePLCObjFromProperty();
areaManager.SetAllIsPlcValueChanged();
rws.Clear();
}
}
......@@ -252,9 +252,9 @@ namespace FLY.Modbus
public override void SetNameData(DataToRegs dr, object val)
{
RegWrite rw;
rw = rws.Find((c) => { return (c.dr == dr); });
if (rw != null)
rws.Remove(rw);
//rw = rws.Find((c) => { return (c.dr == dr); });
//if (rw != null)
// rws.Remove(rw);
rw = new RegWrite(dr, val);
rws.Add(rw);
......@@ -268,17 +268,16 @@ namespace FLY.Modbus
rws.Remove(rw);
//更新 本地的 PLC 数据
rw.dr.value = rw.val;
rw.dr.ToPLCObj();
rw.dr.isPlcValueChanged = true;
switch (rw.dr.dataArea)
{
case PLCAddressArea.Coil:
if (mclient.Do_0F((UInt16)rw.dr.addr, new bool[] { (bool)rw.dr.plc_value }, Do_0F_callback, null) != ModbusClient_Errno.OK)
if (mclient.Do_0F((UInt16)rw.dr.addr, new bool[] { (bool)rw.dr.plcValue }, Do_0F_callback, null) != ModbusClient_Errno.OK)
return;
break;
case PLCAddressArea.Register:
if (mclient.Do_10((UInt16)rw.dr.addr, (UInt16[])rw.dr.plc_value, Do_10_callback, null) != ModbusClient_Errno.OK)
if (mclient.Do_10((UInt16)rw.dr.addr, (UInt16[])rw.dr.plcValue, Do_10_callback, null) != ModbusClient_Errno.OK)
return;
break;
}
......@@ -301,85 +300,6 @@ namespace FLY.Modbus
}
#region 寄存器读取更新计划
Dictionary<object, List<DataToRegs>> plans = new Dictionary<object, List<DataToRegs>>();
/// <summary>
/// 登记寄存器更新计划
/// </summary>
/// <param name="owner"></param>
/// <param name="propertyName"></param>
public void PlanAdd(object key, DataToRegs dr)
{
if (plans.ContainsKey(key))
{
if (!plans[key].Contains(dr))
plans[key].Add(dr);
}
else
{
plans.Add(key, new List<DataToRegs>());
plans[key].Add(dr);
}
}
/// <summary>
/// 删除寄存器更新计划
/// </summary>
/// <param name="key"></param>
public void PlanRemove(object key)
{
plans.Remove(key);
}
/// <summary>
/// 删除全部寄存器更新计划
/// </summary>
public void PlanClear()
{
plans.Clear();
}
/// <summary>
/// 需要被更新的 寄存器数量
/// </summary>
public int DRNeedUpdateCnt { get; private set; }
/// <summary>
/// 总寄存器数量
/// </summary>
public int DRCnt { get; private set; }
/// <summary>
/// DRmap分配到 每个寄存器区
/// </summary>
public void Build()
{
DRCnt = DRmap.Count;
//TODO, 应该提前做!!!!
foreach (var areaManager in mAreaManager)
areaManager.BuildArray(DRmap);
}
/// <summary>
/// 创建寄存器更新计划
/// </summary>
public void PlanMake()
{
foreach (DataToRegs dr in DRmap)
{
dr.isNeedUpdate = false;
}
foreach (KeyValuePair<object, List<DataToRegs>> kv in plans)
{
foreach (DataToRegs dr in kv.Value)
{
dr.isNeedUpdate = true;
}
}
DRNeedUpdateCnt = DRmap.Count((dr) => dr.isNeedUpdate);
foreach (var areaManager in mAreaManager)
areaManager.MakePlan();
}
#endregion
}
}
......@@ -44,7 +44,7 @@ namespace FLY.Modbus
if (addr == -1)
{
addr = regs[i].addr;
UInt16[] plc_value = (UInt16[])regs[i].plc_value;
UInt16[] plc_value = (UInt16[])regs[i].plcValue;
num = plc_value.Count();
if (num > maxOfOneRead)
{
......@@ -62,7 +62,7 @@ namespace FLY.Modbus
}
else
{
UInt16[] plc_value = (UInt16[])regs[i].plc_value;
UInt16[] plc_value = (UInt16[])regs[i].plcValue;
int n = regs[i].addr + plc_value.Count() - 1 - addr + 1;
if (n <= maxOfOneRead)
......
......@@ -19,7 +19,7 @@ namespace FLY.Modbus.WithThread
/// <summary>
/// 通信超时, 默认是 1s
/// </summary>
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(2);
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(6);
/// <summary>
/// socket 错误信息
/// </summary>
......
......@@ -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);
}
}
}
......@@ -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);
}
......@@ -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
}
}
......@@ -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;
}
}
}
......
......@@ -53,12 +53,11 @@ namespace FLY.OBJComponents.Server
}
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)
......@@ -123,27 +122,53 @@ namespace FLY.OBJComponents.Server
{
plan.FeedTime = DateTime.Now;
}
List<DataToRegs> drs = DRMap;
foreach (string propertyname in propertynames)
{
if (!ObjNames.ContainsKey(objname))
continue;
DataToRegs dr = drs.Find((_dr) => { return (_dr.propertyName == propertyname && _dr.owner == ObjNames[objname]); });
if (dr == null)
{
continue;
((Modbus.WithThread.ModbusMapper_Client)dr.mapper).PlanAdd(planID, dr);
//throw new Exception($"PLCProxySystem.SetPlan 不能找到 {objname}.{propertyname}");
}
dr.mapper.PlanAdd(planID, dr);
if (!plan.mappers.Contains(dr.mapper))
plan.mappers.Add(dr.mapper);
}
foreach (var mapper in plan.mappers)
{
((Modbus.WithThread.ModbusMapper_Client)mapper).PlanMake();
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>
......@@ -158,32 +183,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);
......@@ -194,18 +227,27 @@ namespace FLY.OBJComponents.Server
planIDs.Remove(plan);
foreach (var mapper in plan.mappers)
{
((Modbus.WithThread.ModbusMapper_Client)mapper).PlanRemove(plan.ID);
mapper.PlanRemove(plan.ID);
if (!mappers.Contains(mapper))
mappers.Add(mapper);
}
}
foreach (var mapper in mappers)
{
((Modbus.WithThread.ModbusMapper_Client)mapper).PlanMake();
mapper.PlanMake();
}
}
}
}
/// <summary>
/// 1s 一次,看出哪个令牌过期
/// </summary>
void OnPoll_plans()
{
DateTime now = DateTime.Now;
ClearPlan((plan) => (plan.ID != 0) && (now - plan.FeedTime) > TimeSpan.FromMinutes(2));
}
public string[] GetSyncPropNames()
{
......
......@@ -38,84 +38,89 @@ namespace FLY.Weight.UI.Client.UIModule
mWeighterCsService = TDGage.Current.mWeighterCsService;
root_grid.DataContext = mWeighterCsService;
RebuildPlans();
mWeighterCsService.ResetItemsEvent += MWeighterCsService_ResetItemsEvent;
}
private void MWeighterCsService_ResetItemsEvent()
{
RebuildPlans();
}
/// <summary>
/// 由于数量改变,重新构造更新计划
/// </summary>
void RebuildPlans()
{
if (setPlan_accessory != null)
setPlan_accessory.Dispose();
setPlan_accessory = new SetPLCUpdatePlan(
mWeighterCsService.PLCos,
mWeighterCsService.Accessory,
new string[] {
"TotalFlowSetting",
"TotalFlow",
"TotalProduction",
"ALast",
"ACurrent",
"ACurrentLen",
"AClear",
"BLast",
"BCurrent",
"BCurrentLen",
"BClear",
"TotalFilmWidth",
"IsRimNoRecycle",
"RimWidth",
"ActFilmWidth",
"SetThickness",
"TargetVelocity",
"CurrentVelocity"
"TotalFlowSetting",
"TotalFlow",
"TotalProduction",
"ALast",
"ACurrent",
"ACurrentLen",
"AClear",
"BLast",
"BCurrent",
"BCurrentLen",
"BClear",
"TotalFilmWidth",
"IsRimNoRecycle",
"RimWidth",
"ActFilmWidth",
"SetThickness",
"TargetVelocity",
"CurrentVelocity"
});
foreach (SetPLCUpdatePlan plan in setPlan_items)
plan.Dispose();
setPlan_items.Clear();
for (int i = 0; i < mWeighterCsService.Items.Count(); i++)
{
SetPLCUpdatePlan plan = new SetPLCUpdatePlan(
mWeighterCsService.PLCos,
mWeighterCsService.Items[i],
new string[] {
"CurrentFlow",
"CumulativeProduction",
"FlowSetting",
"CurrentFlow",
"ScrewPDisp",
"ScrewPSet",
"ScrewPDisp",
"MixBucketWeight",
"BinWeight",
"MixIsOn",
"BucketValveIsOpen",
"ScrewMotorFreq",
"ScrewMotorIsOn",
"ScrewIsAutoMode",
"ScrewManualFreq"
});
item_update_propertynames);
setPlan_items.Add(plan);
}
mWeighterCsService.ResetItemsEvent += MWeighterCsService_ResetItemsEvent;
}
private void MWeighterCsService_ResetItemsEvent()
{
//把多出来的删除
int remove_cnt = setPlan_items.Count() - mWeighterCsService.Items.Count();
if (remove_cnt > 0)
{
for (int i = 0; i < remove_cnt; i++)
{
SetPLCUpdatePlan plan = setPlan_items[setPlan_items.Count() - 1 - i];
plan.Dispose();
}
setPlan_items.RemoveRange(setPlan_items.Count() - remove_cnt, remove_cnt);
}
else
{
int start_idx = setPlan_items.Count();
int add_cnt = -remove_cnt;
for (int i = 0; i < add_cnt; i++)
{
SetPLCUpdatePlan plan = new SetPLCUpdatePlan(
mWeighterCsService.PLCos,
mWeighterCsService.Items[start_idx+i],
item_update_propertynames);
setPlan_items.Add(plan);
}
}
}
string[] item_update_propertynames = new string[] {
"CurrentFlow",
"CumulativeProduction",
"FlowSetting",
"CurrentFlow",
"ScrewPDisp",
"ScrewPSet",
"ScrewPDisp",
"MixBucketWeight",
"BinWeight",
"MixIsOn",
"BucketValveIsOpen",
"ScrewMotorFreq",
"ScrewMotorIsOn",
"ScrewIsAutoMode",
"ScrewManualFreq"
};
private void button_frequency_Click(object sender, RoutedEventArgs e)
{
......
......@@ -21,7 +21,7 @@
</StackPanel>
<StackPanel Orientation="Vertical" Margin="4" >
<TextBlock Text="PLC连接状态" />
<TextBlock Text="{Binding IsRunning}" FontSize="20"/>
<TextBlock Text="{Binding Client.IsConnected}" FontSize="20"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="4" >
<TextBlock Text="异常次数" />
......
......@@ -107,37 +107,32 @@ namespace FLY.Weight.Server
//--------------------------------------------------------------------------------
//添加任务
Misc.BindingOperations.SetBinding(PLCos, "IsConnectedWithPLC", () =>
for (int i = 0; i < Items.Count(); i++)
{
if (PLCos.IsConnectedWithPLC)
List<string> props = new List<string>
{
for (int i = 0; i < Items.Count(); i++)
{
List<string> props = new List<string>
{
"BucketValveIsOpen",
"MixDisp",
"ClearProduction",
"CumulativeProduction",
"CurrentFlow",
"ScrewPDisp",
"ScrewMotorFreq"
};
for (int j = 0; j < Items[i].BinCnt; j++)
{
int no = j + 1;
props.Add($"MixSet_{no}");
props.Add($"MixPSet_{no}");
props.Add($"MixDisp_{no}");
props.Add($"MixPDisp_{no}");
}
"BucketValveIsOpen",
"MixDisp",
"ClearProduction",
"CumulativeProduction",
"CurrentFlow",
"ScrewPDisp",
"ScrewMotorFreq"
};
PLCos.SetPlan($"Items[{i}]", props, 0);
}
PLCos.SetPlan("Accessory",new string[] { "TotalFlow"}, 0);
for (int j = 0; j < Items[i].BinCnt; j++)
{
int no = j + 1;
props.Add($"MixSet_{no}");
props.Add($"MixPSet_{no}");
props.Add($"MixDisp_{no}");
props.Add($"MixPDisp_{no}");
}
});
PLCos.SetPlan($"Items[{i}]", props, 0);
}
PLCos.SetPlan("Accessory",new string[] { "TotalFlow"}, 0);
//--------------------------------------------------------------------------------
//报警
......@@ -498,17 +493,12 @@ namespace FLY.Weight.Server
//--------------------------------------------------------------------------------
//添加任务
Misc.BindingOperations.SetBinding(PLCos, "IsConnectedWithPLC", () =>
foreach (var kv in obj_error)
{
if (PLCos.IsConnectedWithPLC)
{
foreach (var kv in obj_error)
{
string objname = PLCos.ObjNames.First(_kv => _kv.Value == kv.Key).Key;
PLCos.SetPlan(objname, kv.Value.error_property.Keys.ToArray(), 0);
}
}
});
string objname = PLCos.ObjNames.First(_kv => _kv.Value == kv.Key).Key;
PLCos.SetPlan(objname, kv.Value.error_property.Keys.ToArray(), 0);
}
//--------------------------------------------------------------------------------
//连接断开事件
......@@ -569,12 +559,12 @@ namespace FLY.Weight.Server
}
//测试---
//只加载第1个
{
//var plc = new Modbus.WithThread.ModbusMapper_Client(new Modbus.WithThread.ClientTCP(plcgroup.Devices[1].EP));
//plcos.PLCs.Add(plc);
//plc = new Modbus.WithThread.ModbusMapper_Client(new Modbus.WithThread.ClientTCP(plcgroup.Devices[1].EP));
//plcos.PLCs.Add(plc);
}
//{
// var plc = new Modbus.WithThread.ModbusMapper_Client(plcgroup.Devices[0].EP);
// plcos.PLCs.Add(plc);
// plc = new Modbus.WithThread.ModbusMapper_Client(plcgroup.Devices[1].EP);
// plcos.PLCs.Add(plc);
//}
List<int> bincnts = new List<int>();
Regex r = new Regex(@"Items\[([0-9])\]");
Regex r2 = new Regex("MixPSet_([1-9])");
......
......@@ -140,19 +140,11 @@ namespace FLY.Winder.Server
//--------------------------------------------------------------------------------
//添加任务
Misc.BindingOperations.SetBinding(PLCos, "IsConnectedWithPLC", () =>
foreach (var kv in obj_error)
{
if (PLCos.IsConnectedWithPLC)
{
foreach (var kv in obj_error)
{
string objname = PLCos.ObjNames.First(_kv => _kv.Value == kv.Key).Key;
PLCos.SetPlan(objname, kv.Value.error_property.Keys.ToArray(), 0);
}
//
}
});
string objname = PLCos.ObjNames.First(_kv => _kv.Value == kv.Key).Key;
PLCos.SetPlan(objname, kv.Value.error_property.Keys.ToArray(), 0);
}
//--------------------------------------------------------------------------------
//连接断开事件
......
<?xml version="1.0" encoding="utf-8"?>
<PLCGroup>
<Devices>
<PLCDevice EP="127.0.0.1:502" />
<PLCDevice EP="127.0.0.1:501" />
<PLCDevice EP="127.0.0.1:503" />
<PLCDevice EP="127.0.0.1:504" />
<PLCDevice EP="127.0.0.1:505" />
<PLCDevice EP="127.168.50.2:502" />
<PLCDevice EP="127.168.50.1:502" />
<PLCDevice EP="127.168.50.3:502" />
<PLCDevice EP="127.168.50.4:502" />
<PLCDevice EP="127.168.50.5:502" />
</Devices>
<Variables>
<PLCVariable DeviceIndex="1" Mode="0" Addr="970" Type="bool" Scale="1" OwnerName="Items[0]" PropertyName="AlarmIsOn" />
......
<?xml version="1.0"?>
<SoftwareCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DefaultInstallPath>D:\佛山市枫莱尔自动化技术有限公司\windows</DefaultInstallPath>
<Items>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>测厚仪服务器</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.Thick.Blowing.UI.Fix.Server</Path>
<Exe>FLY.Thick.Blowing.UI.Fix.Server.exe</Exe>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>测厚仪客户端</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.Thick.Blowing.UI.Fix.Client</Path>
<Exe>FLY.Thick.Blowing.UI.Fix.Client.exe</Exe>
<Others>
<string>main_module</string>
<string>music</string>
<string>版本说明.txt</string>
<string>测厚仪说明书.pdf</string>
</Others>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>自动风环</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.FeedbackRenZiJia.UI.Server</Path>
<Exe>FLY.FeedbackRenZiJia.UI.Server.exe</Exe>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>LP2</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\LP2</Path>
<Exe>FLY.LinkProxy.UI.Server.exe</Exe>
</SoftwareItem>
</Items>
</SoftwareCollection>
\ No newline at end of file
<?xml version="1.0"?>
<SoftwareCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DefaultInstallPath>D:\佛山市枫莱尔自动化技术有限公司\windows</DefaultInstallPath>
<Items>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>测厚仪服务器</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.Thick.Blowing.UI.Fix.Server</Path>
<Exe>FLY.Thick.Blowing.UI.Fix.Server.exe</Exe>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>测厚仪客户端</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.Thick.Blowing.UI.Fix.Client</Path>
<Exe>FLY.Thick.Blowing.UI.Fix.Client.exe</Exe>
<Others>
<string>main_module</string>
<string>music</string>
<string>版本说明.txt</string>
<string>测厚仪说明书.pdf</string>
</Others>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>自动风环</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.FeedbackRenZiJia.UI.Server</Path>
<Exe>FLY.FeedbackRenZiJia.UI.Server.exe</Exe>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>自动上料</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\FLY.Weight.UI.Server</Path>
<Exe>FLY.Weight.UI.Server.exe</Exe>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>LP2</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\LP2</Path>
<Exe>FLY.LinkProxy.UI.Server.exe</Exe>
</SoftwareItem>
</Items>
</SoftwareCollection>
\ No newline at end of file
......@@ -50,5 +50,11 @@
<Path>佛山市枫莱尔自动化技术有限公司\windows\LP2</Path>
<Exe>FLY.LinkProxy.UI.Server.exe</Exe>
</SoftwareItem>
<SoftwareItem>
<IsAutoRun>true</IsAutoRun>
<Name>LP3</Name>
<Path>佛山市枫莱尔自动化技术有限公司\windows\LP3</Path>
<Exe>FLY.LinkProxy.UI.exe</Exe>
</SoftwareItem>
</Items>
</SoftwareCollection>
\ No newline at end of file
File added
File added
File deleted
File deleted
File deleted
File deleted
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