设备控制(反馈处理)
因为项目的关系,经常需要程序控制各种设备并接收设备消息反馈,这里以中控为例,说下我对消息反馈的做法。
首先需要根据具体的消息反馈建立对应的类,分别为总电源,大屏模式,灯光。
View Code
1 public enum Power { Off, On } 2 3 public class PowerNotify : Notify { 4 public Power Power { get; set; } 5 } 6 7 public class ApolloModeNotify : Notify { 8 public int Mode { get; set; } 9 } 10 11 public class LightNotify : Notify { 12 public int Id { get; set; } 13 public Power Power { get; set; } 14 }
因为通过网络接收到的消息反馈是字符串类型的,所以需要一个用于转换的类,将不同的字符串转换成对应的反馈对象。
View Code
1 public delegate void NotifyEventHandler(Notify notify); 2 3 public class CrestronHandler { 4 public event NotifyEventHandler OnNotifyReceived; 5 6 public CrestronHandler(Client client) { 7 InstallHandler(); 8 9 this.client = client; 10 client.OnDataReceived += new DataReceivedEventHandler(OnDataReceived); 11 } 12 13 private Client client; 14 }
这里的Client是Tcp连接客户端,接收反馈字符串。
InstallHandler用于记录转换关系:
View Code
1 public delegate bool IsMsgFit(string msg); 2 public delegate List<Notify> NotifyGenerateHandler(string msg); 3 4 private void InstallHandler() { 5 condition2Handler.Add(IsPowerMsg, GenPowerNotify); 6 condition2Handler.Add(IsApolloMsg, GenApolloNotify); 7 condition2Handler.Add(IsLightMsg, GenLightNotify); 8 } 9 private Dictionary<IsMsgFit, NotifyGenerateHandler> condition2Handler = new Dictionary<IsMsgFit, NotifyGenerateHandler>();
具体的转换如下:
View Code
1 private bool IsPowerMsg(string msg) { 2 return msg.StartsWith("POWERFB"); 3 } 4 5 private bool IsApolloMsg(string msg) { 6 return msg.StartsWith("APOLLOFB"); 7 } 8 9 private bool IsLightMsg(string msg) { 10 return msg.StartsWith("LIGHT"); 11 } 12 13 private List<Notify> GenPowerNotify(string msg) { 14 Notify notify = null; 15 if (msg.Contains("ALLON")) { 16 notify = new PowerNotify { Power = Power.On }; 17 } else if (msg.Contains("ALLOFF")) { 18 notify = new PowerNotify { Power = Power.Off }; 19 } 20 21 return new List<Notify> { notify }; 22 } 23 24 private List<Notify> GenApolloNotify(string msg) { 25 Notify notify = null; 26 if (msg.Contains("MODE")) { 27 int mode = Convert.ToInt32(msg.Substring(13)); 28 notify = new ApolloModeNotify { Mode = mode }; 29 } 30 31 return new List<Notify> { notify }; 32 } 33 34 private List<Notify> GenLightNotify(string msg) { 35 string[] subMsg = msg.Split(new string[] { "LIGHT", "FB:" }, StringSplitOptions.RemoveEmptyEntries); 36 int id = Convert.ToInt32(subMsg[0]); 37 Power power = (subMsg[1] == "ON") ? Power.On : Power.Off; 38 LightNotify notify = new LightNotify { Id = id, Power = power }; 39 return new List<Notify> { notify }; 40 }
然后就是接收反馈字符串,逐一进行尝试是否符合条件,符合的话就生成对应的反馈对象,
并触发OnNotifyReceived事件,程序中关心反馈的地方只要订阅此事件并做相应的反馈处理即可。
View Code
1 private void OnDataReceived(byte[] data) { 2 string msg = Encoding.ASCII.GetString(data).ToUpper(); 3 4 foreach (var each in condition2Handler) { 5 if (each.Key(msg)) { 6 List<Notify> notifys = null; 7 try { 8 notifys = each.Value(msg); 9 if (notifys == null) { throw new Exception(); } 10 } catch { 11 Logger.Instance.Warn(string.Format("接收到无法解析的命令 => 【{0}】", msg)); 12 return; 13 } 14 15 try { 16 foreach (var notify in notifys) { 17 if (OnNotifyReceived != null) OnNotifyReceived(notify); 18 } 19 } catch (Exception ex) { 20 Logger.Instance.WarnWithException(this, "client_NotifyHandler", "Notify执行失败", ex); 21 } 22 23 break; 24 } 25 } 26 }