AreaManager.cs 4.54 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FLY.Modbus
{

    /// <summary>
    /// PLC 区管理
    /// </summary>
    public abstract class AreaManager 
    {
        /// <summary>
        /// 现在工作中的读取计划任务
        /// </summary>
        public List<Plan> plan = new List<Plan>();

        /// <summary>
        /// 当true, plan_buffer -> plan
        /// </summary>
        protected bool isPlanChanged = false;

        /// <summary>
        /// 设置读取计划任务时的缓冲,目前线程安全
        /// </summary>
        protected List<Plan> plan_buffer = new List<Plan>();

        /// <summary>
        /// 当前执行的计划任务序号
        /// </summary>
        protected int currIndex = 0;
        /// <summary>
        /// 获取下一个plan,返回下一个plan,若已经到了最后一个,则在开始
        /// 下一个之前,返回一个null
        /// </summary>
        /// <returns></returns>
        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;
        }

        /// <summary>
        /// 清除doing状态
        /// </summary>
        public void ClearPlanState()
        {
            foreach (Plan p in plan)
            {
                p.isDoing = false;
            }
            currIndex = 0;
        }
        /// <summary>
        /// 一个property 对应 N个 PLC寄存器;
        /// 地址必须是从小到大排列,不能有重叠
        /// </summary>
        public List<DataToRegs> regs = new List<DataToRegs>();

        protected PLCAddressArea area;

        protected int maxOfOneRead = 50;
        public AreaManager(PLCAddressArea area, int maxOfOneRead)
        {
            this.area = area;
            this.maxOfOneRead = maxOfOneRead;

        }
        /// <summary>
        /// 根据DataToRegs列表构建数组
        /// </summary>
        public void BuildArray(List<DataToRegs> DRmap)
        {
            List<DataToRegs> 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;
            });
        }
        /// <summary>
        /// 
        /// </summary>
        public void MakePlanReal()
        {
            lock (plan_buffer)
            {
                if (isPlanChanged)
                {
                    isPlanChanged = false;
                    plan.Clear();
                    plan.AddRange(plan_buffer);
                }
            }
        }


        /// <summary>
        /// 根据当前regs的配置指定读寄存器的计划
        /// 只是设置 plan_buffer
        /// </summary>
        public abstract void MakePlan();

        /// <summary>
        /// 从本地PC 属性获取value 更新到 本地PLC 寄存器,
        /// 目的: 当从PLC读取寄存器值时,能比较不同,产生变化事件
        /// </summary>
        public void SetAllIsPlcValueChanged()
        {
            foreach (DataToRegs dr in regs)
            {
                dr.isPlcValueChanged = true;
            }
        }

    }

    /// <summary>
    /// 每次向PLC读取寄存器的任务
    /// </summary>
    public class Plan
    {
        /// <summary>
        /// coil or register
        /// </summary>
        public PLCAddressArea area;

        /// <summary>
        /// 地址
        /// </summary>
        public int addr;

        /// <summary>
        /// 数量
        /// </summary>
        public int num;
        /// <summary>
        /// 是否正在读取
        /// </summary>
        public bool isDoing;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="area"></param>
        /// <param name="addr"></param>
        /// <param name="num"></param>
        public Plan(PLCAddressArea area, int addr, int num)
        {
            this.area = area;
            this.addr = addr;
            this.num = num;
        }
    }


}