using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FLY.Modbus { /// /// PLC 区管理 /// public abstract class AreaManager { /// /// 现在工作中的读取计划任务 /// public List plan = new List(); /// /// 当true, plan_buffer -> plan /// protected bool isPlanChanged = false; /// /// 设置读取计划任务时的缓冲,目前线程安全 /// protected List plan_buffer = new List(); /// /// 当前执行的计划任务序号 /// protected int currIndex = 0; /// /// 获取下一个plan,返回下一个plan,若已经到了最后一个,则在开始 /// 下一个之前,返回一个null /// /// public Plan GetNextPlan() { int cnt = plan.Count(); if (cnt <= 0) return null; if (currIndex >= cnt) { currIndex = 0; return null; } Plan p = plan.ElementAt(currIndex); currIndex += 1; return p; } /// /// 清除doing状态 /// public void ClearPlanState() { foreach (Plan p in plan) { p.isDoing = false; } currIndex = 0; } /// /// 一个property 对应 N个 PLC寄存器; /// 地址必须是从小到大排列,不能有重叠 /// public List regs = new List(); protected PLCAddressArea area; protected int maxOfOneRead = 50; public AreaManager(PLCAddressArea area, int maxOfOneRead) { this.area = area; this.maxOfOneRead = maxOfOneRead; } /// /// 根据DataToRegs列表构建数组 /// public void BuildArray(List DRmap) { List drs = DRmap.FindAll((c) => { return c.dataArea == area; }); // 分配寄存器存储空间 regs.Clear(); foreach (DataToRegs dr in drs) { regs.Add(dr); } regs.Sort((r1, r2) => { if (r1.addr < r2.addr) return -1; else if (r1.addr > r2.addr) return 1; else return 0; }); } /// /// /// public void MakePlanReal() { lock (plan_buffer) { if (isPlanChanged) { isPlanChanged = false; plan.Clear(); plan.AddRange(plan_buffer); } } } /// /// 根据当前regs的配置指定读寄存器的计划 /// 只是设置 plan_buffer /// public abstract void MakePlan(); /// /// 从本地PC 属性获取value 更新到 本地PLC 寄存器, /// 目的: 当从PLC读取寄存器值时,能比较不同,产生变化事件 /// public void SetAllIsPlcValueChanged() { foreach (DataToRegs dr in regs) { dr.isPlcValueChanged = true; } } } /// /// 每次向PLC读取寄存器的任务 /// public class Plan { /// /// coil or register /// public PLCAddressArea area; /// /// 地址 /// public int addr; /// /// 数量 /// public int num; /// /// 是否正在读取 /// public bool isDoing; /// /// /// /// /// /// public Plan(PLCAddressArea area, int addr, int num) { this.area = area; this.addr = addr; this.num = num; } } }