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;
}
}
}