public PellaBridgeClient() { tcpClient = new PellaBridgeTCPClient(); bridgeInfo = new BridgeInfo(); hubIP = IPAddress.Parse(Environment.GetEnvironmentVariable("HUB_IP_ADDRESS")); System.Threading.Thread listenerThread = new System.Threading.Thread(Listener); listenerThread.Start(); tcpClient.Init(); tcpClient.Connect(); GetBridgeInfo(); EnumerateDevices(); }
public BridgeInfo GetBridgeInfo() { lastCommand = "BRIDGEINFO"; tcpClient.SendCommand("?BRIDGEINFO"); if (evtBridgeStatus.WaitOne(timeout)) { bridgeInfo = lastBridgeInfo; return(bridgeInfo); } else { throw new TimeoutException("Request timed out"); } }
private void Listener() { Regex BridgeInfoRegex = new Regex(@"Version: (\w*), MAC: ([\w:]*)"); Regex HelloRegex = new Regex(@"Insynctive Telnet Server"); Regex StatusChangeRegex = new Regex(@"POINTSTATUS-([0-9]{3}),\$([0-9A-F][0-9A-F])"); Regex BatteryChangeRegex = new Regex(@"POINTBATTERYGET-([0-9]{3}),\$([0-9A-F][0-9A-F])"); Regex PointCountRegex = new Regex(@"[0-9]{3}"); Regex NumericRegex = new Regex(@"\$([0-9A-F][0-9A-F])"); do { // Don't wait forever, in case the TCPClient has thrown a socket error elsewhere and been replaced with a // new connection. tcpClient.messageReceived.WaitOne(timeout / 2); // While unlikely, it's possible multiple messages could be waiting after a single event, so loop until all are processed. // Note that a storm of messages is likely to cause issues, as we only track the last command received // So responses may end up getting matching with the wrong request. But that it unavoidable and // will likely never happen in reality. Instead what is more likely is the device pushes an update // while we are sending a command or refresh, and that should work fine. while (tcpClient.messageQueue.TryDequeue(out string message)) { Match m; int deviceID; int newDeviceStatusCode; int newBatteryStatus; PellaBridgeDevice device; switch (message) { case string msg when HelloRegex.IsMatch(msg): lastHello = DateTime.Now; break; case string msg when BridgeInfoRegex.IsMatch(msg): m = BridgeInfoRegex.Match(msg); BridgeInfo bi = new BridgeInfo { Version = m.Groups[1].Value, MAC = m.Groups[2].Value, connectTime = lastHello, IP = tcpClient.BridgeIPAddress.ToString() }; lastBridgeInfo = bi; evtBridgeStatus.Set(); break; case string msg when StatusChangeRegex.IsMatch(msg): m = StatusChangeRegex.Match(msg); deviceID = Int32.Parse(m.Groups[1].Value); newDeviceStatusCode = Convert.ToInt32(m.Groups[2].Value, 16); device = devices.Find(x => x.Id == deviceID); if (device is null) { break; } UpdateDeviceStatus(device, newDeviceStatusCode); break; case string msg when BatteryChangeRegex.IsMatch(msg): m = StatusChangeRegex.Match(msg); deviceID = Int32.Parse(m.Groups[1].Value); newBatteryStatus = Convert.ToInt32(m.Groups[2].Value, 16); device = devices.Find(x => x.Id == deviceID); if (device is null) { break; } UpdateBattery(device, newBatteryStatus); break; case string msg when PointCountRegex.IsMatch(msg): m = PointCountRegex.Match(msg); lastPointCount = Int32.Parse(m.Groups[0].Value); evtPointCount.Set(); break; case string msg when NumericRegex.IsMatch(msg) && lastCommand == "POINTDEVICE": m = NumericRegex.Match(msg); lastDevice = new PellaBridgeDevice(lastID, Convert.ToInt32(m.Groups[1].Value, 16)); evtPointDevice.Set(); break; case string msg when NumericRegex.IsMatch(msg) && lastCommand == "POINTBATTERYGET": m = NumericRegex.Match(msg); lastBatteryStatus = Convert.ToInt32(m.Groups[1].Value, 16); evtBatteryStatus.Set(); break; case string msg when NumericRegex.IsMatch(msg) && lastCommand == "POINTSTATUS": m = NumericRegex.Match(msg); lastDeviceStatus = Convert.ToInt32(m.Groups[1].Value, 16); evtDeviceStatus.Set(); break; } } } while (true); }