// 更新点表 - 门 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); // 按需关闭蜂鸣器. }
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)); }
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; }
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; // 设置异常. } }
/// 控制一樘门 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); }
// 关闭警告指示(红灯, 蜂鸣器) 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); } } }
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; }
// 门状态变化回调 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); } } }
public void AddDoor(Door d) { if (_doors == null) { _doors = new List<Door>(); } _doors.Add(d); }
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; }
// 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; }