예제 #1
0
파일: CMS.cs 프로젝트: liulee/disneycms
        // 更新点表 - 门
        void UpdateFunctionTableByDoor(Zone _z, Door _d)
        {
            DoorState ds = _d.State;
            // 开门/关门
            _ptable.SetValueAt(_z.Reg.SetDoor, _d.Coil, ds.DoorAction == RelayState.ACTION);
            // 开门到位
            _ptable.SetValueAt(_z.Reg.GetOpenState, _d.Coil, ds.OpenState == OnOff.ON);
            // 关门到位
            _ptable.SetValueAt(_z.Reg.GetCloseState, _d.Coil, ds.CloseState == OnOff.ON);
            // 异常
            _ptable.SetValueAt(_z.Reg.GetErrorState, _d.Coil, ds.Error != DoorError.Success);
            // LCB
            _ptable.SetValueAt(_z.Reg.GetLCB, _d.Coil, ds.LCB == OnOff.ON);
            // 绿灯
            _ptable.SetValueAt(_z.Reg.SetGreen, _d.Coil, ds.GreenLamp == RelayState.ACTION);
            // 红灯
            _ptable.SetValueAt(_z.Reg.SetRed, _d.Coil, ds.RedLamp == RelayState.ACTION);

            // 按需关闭蜂鸣器.
        }
예제 #2
0
파일: CMS.cs 프로젝트: liulee/disneycms
        private void _OnDoorStateChanged(Zone _z, Door _d)
        {
            this.CloseAlarmAsNecessary(_d);

            UpdateFunctionTableByDoor(_z, _d);

            if (this.OnDoorStateChanged != null)
            {
                OnDoorStateChanged.Invoke(_z, _d);
            }
            // log.DebugFormat("Zone: {0}, Door {0} changed: ", _z.Name, ValueHelper.GetIpLastAddr(d.IpAddr));
        }
예제 #3
0
파일: CMS.cs 프로젝트: liulee/disneycms
 bool IsActionRequired(Door d, OnOff newAction)
 {
     if (d.State.OpenState == OnOff.ON && newAction == OnOff.ON)
     {
         return false; //门开着.
     }
     if (d.State.CloseState == OnOff.ON && newAction == OnOff.OFF)
     {
         return false; //门关着, 无需关门.
     }
     return true;
 }
예제 #4
0
파일: CMS.cs 프로젝트: liulee/disneycms
 private byte Request(Door d, JDQRequest req)
 {
     JDQResponse resp = _jdqVisitor.Request(d.IpAddr, req);
     if (resp.IsOK)
     {
         return MBException.MB_SUCCESS;
     }
     else
     {
         return MBException.E0B_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND; // 设置异常.
     }
 }
예제 #5
0
파일: CMS.cs 프로젝트: liulee/disneycms
        /// 控制一樘门
        public byte ControlDoor(Door d, OnOff to)
        {
            if (!IsActionRequired(d, to)) {
                //log.DebugFormat("无需操作: {0}", d);
                //return MBException.MB_SUCCESS;
            }
            JDQRequest req = new JDQRequest(JDQRequest.DEV_ID, JDQRequestType.SetOutput);
            byte[] bits = new byte[] { RELAY_OPEN_LEFT, RELAY_OPEN_RIGHT}; //0-2 (继电器, )
            req.SetOutputs(bits, to == OnOff.ON);
            req.SetOutputs(new byte[]{RELAY_RED, RELAY_BEEP }, true ) ; //红灯, 蜂鸣器

            return Request(d, req);
        }
예제 #6
0
파일: CMS.cs 프로젝트: liulee/disneycms
 // 关闭警告指示(红灯, 蜂鸣器)
 private void CloseAlarmAsNecessary(Door d)
 {
     if (d.State.Beep == RelayState.ACTION)
     {
         // 蜂鸣器闭合.
         if ((d.State.DoorAction == RelayState.ACTION && d.State.OpenState == OnOff.ON) ||
            (d.State.DoorAction == RelayState.RESET && d.State.CloseState == OnOff.OFF))
         {
             log.DebugFormat("门 {0} 动作已到位, 自动关闭: 继电器/红灯.", d);
             // 开门动作, 且已到位. 或 关门动作, 已到位.
             JDQRequest req = new JDQRequest(JDQRequest.DEV_ID, JDQRequestType.SetOutput);
             byte[] bits = new byte[] { RELAY_RED, RELAY_BEEP }; //继电器, 红灯, 蜂鸣器)
             req.SetOutputs(bits, false);
             _jdqVisitor.Request(d.IpAddr, req);
         }
     }
 }
예제 #7
0
        private void UpdateDoorState(Door d, JDQResponse input, JDQResponse output)
        {
            /* in
            1	左扇开门到位信号
            2	左扇关门到位信号
            3	右扇开门到位信号
            4	右扇关门到位信号
            5	LCB状态信号
            OUT:
            1	左扇门开关门信号	继电器吸合:触发开左扇门,反之触发关左扇门
            3	右扇门开关门信号	继电器吸合:触发开右扇门,反之触发关右扇门
            5	绿灯控制信号	继电器吸合:绿灯亮,反之绿灯灭
            6	红灯控制信号	继电器吸合:红灯亮,反之红灯灭
            7	蜂鸣器控制信号	继电器吸合:蜂鸣器开始叫,蜂鸣器停止叫
            */
            DoorState ds;
            if (d.State == null)
                d.State = ds = new DoorState();
            else
                ds = d.State;
            if (!input.IsOK || !output.IsOK)
            {
                ds.Reset();
                ds.Error = DoorError.SocketError;
                ds.ExtError = input.ExtError;
                return;
            }
            /// ==== OUTPUT State (继电器) ============
            ds.LeftAction  = output.GetRelayState(0);
            ds.RightAction = output.GetRelayState(2);
            // Lamp
            ds.GreenLamp = output.GetRelayState(4);
            ds.RedLamp = output.GetRelayState(5);
            // Beep
            ds.Beep = output.GetRelayState(6);
            /// ==== INPUT State (开关量) ============
            ds.LeftOpenState  = input.GetInputState(0);  // 左打开
            ds.LeftCloseState = input.GetInputState(1); // 左关闭
            ds.RightOpenState = input.GetInputState(2);  // 右打开
            ds.RightCloseState = input.GetInputState(3); // 右关闭
            // LCB
            ds.LCB = input.GetInputState(4);

            // 开关
            if (ds.LeftAction == RelayState.ACTION && ds.RightAction == RelayState.ACTION) {
                ds.DoorAction = RelayState.ACTION;
            }else if (ds.LeftAction == RelayState.RESET && ds.RightAction == RelayState.RESET) {
                ds.DoorAction = RelayState.RESET;
            }else {
                ds.DoorAction = RelayState.UNKNOWN; // 不一致.
            }

            // 错误判定.
            DoorError lerror = DoorError.UNKNOWN, rerror = DoorError.UNKNOWN;
            bool lOpenOk = false, lCloseOk = false, rOpenOk = false, rCloseOk = false;
            if (RelayState.ACTION == ds.LeftAction)
            { // 下达了左开门指令
                if (OnOff.ON == ds.LeftOpenState)
                    lOpenOk = true;
                else
                    lerror = DoorError.LeftOpenError; // 开左门未到位错误
            }
            else if (RelayState.RESET == ds.LeftAction)
            { // 下达了左关门指令.
                if (OnOff.ON == ds.LeftCloseState)
                    lCloseOk = true;
                else
                    lerror = DoorError.LeftCloseError; //关左门未到位错误
            }
            if (RelayState.ACTION == ds.RightAction)
            { // 下达了右开门指令
                if (OnOff.ON == ds.RightOpenState)
                    rOpenOk = true;
                else
                    rerror = DoorError.RightOpenError; // 右左门未到位错误
            }
            else if (RelayState.RESET == ds.RightAction)
            { // 下达了右关门指令.
                if (OnOff.ON == ds.RightCloseState)
                    rCloseOk = true;
                else
                    rerror = DoorError.RightCloseError; //关右门未到位错误
            }

            // 状态
            ds.Error = DoorError.Success;
            if (lOpenOk && rOpenOk)
            {
                ds.OpenState = OnOff.ON;
            }
            else if (lCloseOk && rCloseOk)
            {
                ds.CloseState = OnOff.ON;
            }

            // 错误
            if (lerror != DoorError.UNKNOWN || rerror != DoorError.UNKNOWN)
            {
                if (rerror == DoorError.UNKNOWN)
                { // 仅左门
                    ds.Error = lerror;
                }
                else if (lerror == DoorError.UNKNOWN)
                {
                    ds.Error = rerror;
                }
                else
                {
                    // 双门错误
                    if (DoorError.LeftOpenError == lerror)
                        ds.Error = DoorError.OpenError;
                    else
                        ds.Error = DoorError.CloseError;
                }
            }
            else
            {
                // none error?
                ds.Error = DoorError.Success;
            }
            return;
        }
예제 #8
0
파일: Main.cs 프로젝트: liulee/disneycms
        // 门状态变化回调
        private void OnDoorStateChanged(Zone z, Door d)
        {
            DataGridViewRow di = _doorRows[d.IpAddr];
            if (di != null)
            {
                UpdateRowText(di, ViewColumns.ACTION, EnumHelper.ToString(d.State.DoorAction));
                UpdateRowText(di, ViewColumns.OPEN_STATE, EnumHelper.ToString(d.State.OpenState));
                UpdateRowText(di, ViewColumns.CLOSE_STATE, EnumHelper.ToString(d.State.CloseState));
                UpdateRowText(di, ViewColumns.GREEN_LAMP, EnumHelper.ToString(d.State.GreenLamp));
                UpdateRowText(di, ViewColumns.RED_LAMP, EnumHelper.ToString(d.State.RedLamp));
                UpdateRowText(di, ViewColumns.LCB, EnumHelper.ToString(d.State.LCB));
                UpdateRowText(di, ViewColumns.BEEP, EnumHelper.ToString(d.State.Beep));
                UpdateRowText(di, ViewColumns.ERROR, EnumHelper.ToString(d.State.Error, d.State.ExtError));

                if (DoorError.Success != d.State.Error)
                {
                    UpdateRowImg(di, Properties.Resources.yellow_24);
                }
                else
                {
                    UpdateRowImg(di, Properties.Resources.green_24);
                }
            }
        }
예제 #9
0
파일: Zone.cs 프로젝트: liulee/disneycms
 public void AddDoor(Door d)
 {
     if (_doors == null)
     {
         _doors = new List<Door>();
     }
     _doors.Add(d);
 }
예제 #10
0
        public IList<Zone> LoadConfig()
        {
            IList<Zone> _zones = new List<Zone>();
            log.InfoFormat("解析文件: '{0}' ...", CFG_FILE);
            var doorCount = 0;
            try
            {
                XDocument doc = XDocument.Load(CFG_FILE);
                var root = doc.Root;

                var ccse = root.Element("ccs");
                _ccsip = GetValue(ccse, "ip", "192.168.31.254");

                string ipPrefix = GetValue(root, "ipp", "192.168.31");
                byte zcnt = Convert.ToByte(GetValue(root, "zones"));
                _regMin = REG_START;
                _regMax = (byte)(REG_START + zcnt * REG_CMD_CNT); //共 7 组命令.

                byte _funcOffset = 0;
                foreach (var ze in root.Elements("zone"))
                {
                    byte zoneCoil = Convert.ToByte(GetValue(ze, "zreg")); //1~6
                    byte regStart = (byte)(_funcOffset + REG_START);
                    _funcOffset++;

                    Zone z = new Zone()
                    {
                        Name = GetValue(ze, "name"),
                        Reg = new RegInfo()
                        {
                            ZoneCoil = zoneCoil,
                            SetDoor = regStart,
                            GetOpenState = (byte)(regStart + zcnt * REG_GET_DOOR_OPEN),
                            GetCloseState = (byte)(regStart + zcnt * REG_GET_DOOR_CLOSE),
                            GetErrorState = (byte)(regStart + zcnt * REG_GET_DOOR_ERROR),
                            GetLCB = (byte)(regStart + zcnt * REG_GET_LCB),
                            SetGreen = (byte)(regStart + zcnt * REG_SET_GREEN), //5=开绿灯
                            SetRed = (byte)(regStart + zcnt * REG_SET_RED),   // 6=开红灯
                        },
                    };
                    _zones.Add(z);
                    // 该区域的门配置.
                    foreach (var de in ze.Elements("d"))
                    {
                        Door d = new Door();
                        string ip = GetValue(de, "ip", "");
                        if (ip.Length <= 3)
                        {
                            ip = ipPrefix + "." + ip;
                        }
                        d.DevId = Convert.ToByte(GetValue(de, "id", "1"));
                        d.Coil = Convert.ToByte(GetValue(de, "c")); //Coil/Bit
                        d.IpAddr = ip;
                        d.Enabled = GetValue(de, "enable", "1") == "1";
                        z.AddDoor(d);
                        UpdateDoorMap(z, d);
                    }
                    doorCount += z.TotalCnt;
                    log.DebugFormat("区域: {0}, doors={1}", z.Name, z.TotalCnt);
                }
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("读取配置文件 {0} 异常:{1}", CFG_FILE, e.Message));
            }
            _zoneCnt = _zones.Count;
            log.InfoFormat("配置已读取, 共 {0} 个区域, {1} 樘门.", _zoneCnt, doorCount);
            return _zones;
        }
예제 #11
0
 // Reg.Bit => Door
 void UpdateDoorMap(Zone z, Door d)
 {
     _doorMap[string.Format("{0}.{1}", z.Reg.SetDoor, d.Coil)] = d;
     _doorMap[string.Format("{0}.{1}", z.Reg.SetGreen, d.Coil)] = d;
     _doorMap[string.Format("{0}.{1}", z.Reg.SetRed, d.Coil)] = d;
     _doorMap[string.Format("{0}.{1}", z.Reg.GetCloseState, d.Coil)] = d;
     _doorMap[string.Format("{0}.{1}", z.Reg.GetOpenState, d.Coil)] = d;
     _doorMap[string.Format("{0}.{1}", z.Reg.GetErrorState, d.Coil)] = d;
     _doorMap[string.Format("{0}.{1}", z.Reg.GetLCB, d.Coil)] = d;
 }