/// <summary> /// Listen for data coming from the TPI /// </summary> private void PollTpi() { // Start the first poll 10 seconds after start up Thread.Sleep(10 * 1000); //PollInterval while (true) { EnsureConnection(); try { TpiCommand req = new TpiCommand(RequestCommand.Poll); ExecuteCommand(req); req = new TpiCommand(RequestCommand.KeepAlive, "1"); ExecuteCommand(req); // Dump the Zone Timers during the poll just to keep them relatively fresh! //req = new TpiCommand(RequestCommand.DumpZoneTimers); //ExecuteCommand(req); } catch (Exception ex) { MyLogger.LogError($"Could not execute polling command {MyLogger.ExMsg(ex)}"); } Thread.Sleep(PollInterval * 1000); } }
private void EnsureConnection() { do { lock (thisLock) { try { // Make sure we have not already connnected on another thread if (_client != null && _client.Connected) { return; } // Clean up anything that is outstanding if (_client != null) { //_client.Client.Shutdown(SocketShutdown.Both); _client.Dispose(); } MyLogger.LogInfo("Reconnecting the socket"); _client = new TcpClient(); Task ca = _client.ConnectAsync(Host, Port); if (ca.Wait(15000) == false) { MyLogger.LogError($"ERROR: Could not connect within 15 seconds to {Host} on Port {Port}"); } // Return if we connected properly if (_client.Connected) { return; } _client.Dispose(); _client = null; MyLogger.LogError($"ERROR: Could not connect to {Host} on Port {Port}"); } catch (Exception ex) { MyLogger.LogError($"ERROR: trying to connect {Host} on Port {Port} - {MyLogger.ExMsg(ex)}"); _client = null; } // Wait 5 seconds before trying to re-connect MyLogger.LogInfo("Waiting 5 seconds before trying to re-connect"); Thread.Sleep(5000); } } while (_client == null); }
public void DisArmSystem(int partitionId) { if (String.IsNullOrEmpty(ArmingCode)) { MyLogger.LogError("You must specify an arming code in the configuration"); throw new Exception("You must specify an arming code in the configuration"); } // Send the appropriate command sequence string cmd = String.Format("{0}{1}", partitionId, ArmingCode); TpiCommand tpiCmd = new TpiCommand(RequestCommand.PartitionDisarmControl, cmd); _tpiSocket.ExecuteCommand(tpiCmd); }
/// <summary> /// Send a command to the TPI. This method will issue a lock to prevent multiple threads /// from sending a command at the same time. /// </summary> /// <param name="tpiRequest"></param> public void ExecuteCommand(TpiCommand tpiRequest) { // Take a lock so only one request can be sent at a time lock (thisLock) { if (_client == null || _client.Connected == false) { MyLogger.LogError($"Socket is not connected. Cannot send command => {((int)tpiRequest.Command):D3}:{tpiRequest.Command.ToString().PadRight(20)} - {tpiRequest.CommandData}"); return; } MyLogger.LogInfo($"> {((int)tpiRequest.Command):D3}:{tpiRequest.Command.ToString().PadRight(20)} - {tpiRequest.CommandData}"); // Send the request var data = Encoding.ASCII.GetBytes(tpiRequest.TPIData); var serverStream = _client.GetStream(); serverStream.Write(data, 0, data.Length); serverStream.Flush(); } }
private void ParsePayload() { // First, handle all of the events related to the alarm system switch (Command) { case ResponseCommand.TimeDateBroadcast: DateBroadcast = DateTime.ParseExact(Data.Substring(0, 10), "hhmmMMDDYY", System.Globalization.CultureInfo.InvariantCulture); break; case ResponseCommand.IndoorTemperatureBroadcast: case ResponseCommand.OutdoorTemperatureBroadcast: ThermostatId = Convert.ToInt32(Data.Substring(0, 1)); Temperature = Convert.ToInt32(Data.Substring(1, 3)); break; case ResponseCommand.EnvisalinkZoneTimerDump: SecondsSinceOpened = new Int32[64]; for (int i = 0; i < 64; i++) { string swappedBytes = Data.Substring((i * 4) + 2, 2) + Data.Substring(i * 4, 2); int val = Convert.ToInt32(swappedBytes, 16); if (val > 0) { SecondsSinceOpened[i] = (65535 - val) * 5; } } break; case ResponseCommand.RingDetected: case ResponseCommand.DuressAlarm: case ResponseCommand.FKeyAlarm: case ResponseCommand.FKeyRestore: case ResponseCommand.AKeyAlarm: case ResponseCommand.AKeyRestoral: case ResponseCommand.PKeyAlarm: case ResponseCommand.PKeyRestore: case ResponseCommand.TwoWireSmokeAuxAlarm: case ResponseCommand.TwoWireSmokeAuxRestore: case ResponseCommand.PanelBatteryTrouble: case ResponseCommand.PanelBatteryTroubleRestore: case ResponseCommand.PanelACTrouble: case ResponseCommand.PanelACRestore: case ResponseCommand.SystemBellTrouble: case ResponseCommand.SystemBellTroubleRestoral: case ResponseCommand.FtcTrouble: case ResponseCommand.BufferNearFull: case ResponseCommand.GeneralSystemTamper: case ResponseCommand.GeneralSystemTamperRestore: case ResponseCommand.FireTroubleAlarm: case ResponseCommand.FireTroubleAlarmRestore: case ResponseCommand.VerboseTroubleStatus: case ResponseCommand.CodeRequired: case ResponseCommand.CommandOutputPressed: case ResponseCommand.MasterCodeRequired: case ResponseCommand.InstallersCodeRequired: break; case ResponseCommand.KeypadLedStatePartition1Only: case ResponseCommand.KeypadLedflashStatePartition1Only: PartitionId = 1; break; case ResponseCommand.PartitionReady: case ResponseCommand.PartitionNotReady: case ResponseCommand.PartitionReadyForceArmingEnabled: case ResponseCommand.PartitionInAlarm: case ResponseCommand.PartitionDisarmed: case ResponseCommand.ExitDelayinProgress: case ResponseCommand.EntryDelayinProgress: case ResponseCommand.KeypadLockout: case ResponseCommand.PartitionFailedtoArm: case ResponseCommand.PgmOutputisinProgress: case ResponseCommand.ChimeEnabled: case ResponseCommand.ChimeDisabled: case ResponseCommand.InvalidAccessCode: case ResponseCommand.FunctionNotAvailable: case ResponseCommand.FailuretoArm: case ResponseCommand.PartitionisBusy: case ResponseCommand.SystemArminginProgress: case ResponseCommand.SpecialClosing: case ResponseCommand.PartialClosing: case ResponseCommand.SpecialOpening: case ResponseCommand.TroubleLedon: case ResponseCommand.TroubleLedoff: PartitionId = Convert.ToInt32(Data.Substring(0, 1)); break; case ResponseCommand.PartitionArmed: PartitionId = Convert.ToInt32(Data.Substring(0, 1)); ArmingMode = (TpiArmedMode)Convert.ToInt32(Data.Substring(1, 1)); break; case ResponseCommand.UserClosing: case ResponseCommand.UserOpening: PartitionId = Convert.ToInt32(Data.Substring(0, 1)); UserId = Convert.ToInt32(Data.Substring(1, 4)); break; case ResponseCommand.ZoneAlarm: case ResponseCommand.ZoneAlarmRestore: case ResponseCommand.ZoneTamper: case ResponseCommand.ZoneTamperRestore: PartitionId = Convert.ToInt32(Data.Substring(0, 1)); ZoneId = Convert.ToInt32(Data.Substring(1)); break; case ResponseCommand.ZoneFault: case ResponseCommand.ZoneFaultRestore: case ResponseCommand.ZoneOpen: case ResponseCommand.ZoneRestored: ZoneId = Convert.ToInt32(Data); break; case ResponseCommand.LoginInteraction: case ResponseCommand.CommandAcknowledge: break; default: MyLogger.LogError($"Invalid data returned [{Data}]"); break; } }
/// <summary> /// Listen for data coming from the TPI /// </summary> private void ListenForData() { // Listen forever while (true) { EnsureConnection(); string[] lines; NetworkStream clientStream = null; try { clientStream = _client.GetStream(); var message = new byte[4096]; while (!_shutdown) { var bytesRead = 0; try { //blocks until a client sends a message bytesRead = clientStream.Read(message, 0, 4096); } catch (Exception ex) { //a socket error has occured MyLogger.LogError($"ListenData Exception: {MyLogger.ExMsg(ex)}"); // Wait 5 seconds before trying to re-connect MyLogger.LogInfo("Waiting 5 seconds before trying to re-connect"); Thread.Sleep(5000); break; } if (bytesRead == 0) { //the client has disconnected from the server break; } //message has successfully been received var encoder = new ASCIIEncoding(); var value = encoder.GetString(message, 0, bytesRead); lines = Regex.Split(value, "\r\n"); foreach (string line in lines) { if (!String.IsNullOrEmpty(line)) { var r = new TpiResponse(line); MyLogger.LogInfo($"< {((int)r.Command):D3}:{r.Command.ToString().PadRight(20)} - {r.Data}"); if (ResponseReceived != null) { ResponseReceived(this, r); } } } } } catch (Exception ex) { MyLogger.LogError(MyLogger.ExMsg(ex)); } } }