/// <summary> /// Initializes a new instance of the <see cref="ParadoxManager"/> class. /// </summary> /// <param name="moduleInferface">The Paradox module interface.</param> internal ParadoxManager(ParadoxModuleInterface moduleInferface) { if (instance == null) { instance = this; this.Interface = moduleInferface; this.Interface.MessageReceived += OnMessageReceived; this.EventManager = new ParadoxSystemEventManager(this); if (!this.Interface.IsConnected) { this.Interface.Connect(); } } else { throw new InvalidOperationException("ParadoxManager is a singleton object. Use the existing instance from 'ParadoxManager.Instance'"); } }
/// <summary> /// Called when start the package. /// </summary> public override void OnStart() { PackageHost.WriteInfo("Initializing Paradox package"); // The group where send AlarmEvent message is the name of the package's instance this.scopeParadox = MessageScope.Create(MessageScope.ScopeType.Group, PackageHost.PackageInstanceName); // Create the Paradox API manager this.paradox = new ParadoxManager(PackageHost.GetSettingValue("PortCom"), PackageHost.GetSettingValue <int>("PortBaudRate")); // When the PRT3 connection changed bool connectionFail = false; this.paradox.Interface.ConnectionStateChanged += (s, e) => { // Disconnection if (!this.paradox.Interface.IsConnected) { if (connectionFail) // already fail ? { PackageHost.WriteInfo("Error unable to reconnect to the PRT3 Serial interface : shutdown package !"); PackageHost.Shutdown(); } else // first disconnection, try to reconnect if still running { PackageHost.WriteWarn("Serial interface is disconnected" + (PackageHost.IsRunning ? " : trying to reconnect" : ".")); if (PackageHost.IsRunning) { connectionFail = true; this.paradox.Interface.Connect(); } } } // Reconnection else { connectionFail = false; PackageHost.WriteInfo("PRT3 Serial interface is reconnected : RefreshAll"); this.RefreshAll(); } // Raise Constellation event this.scopeParadox.GetProxy().AlarmEvent(new { Type = "ConnectionStateChanged", State = this.paradox.Interface.IsConnected }); }; // Raise initial Constellation event this.scopeParadox.GetProxy().AlarmEvent(new { Type = "ConnectionStateChanged", State = this.paradox.Interface.IsConnected }); // Refresh all when the package is reconnected to Constellation PackageHost.ConnectionStateChanged += (s, e) => { if (PackageHost.IsConnected) { PackageHost.WriteInfo("Package is reconnected : RefreshAll"); this.RefreshAll(); } }; // Interface error this.paradox.Interface.InterfaceError += (s, e) => { // Write error PackageHost.WriteError("PRT3 Serial interface error : {0}", e.Exception.ToString()); // Raise Constellation event this.scopeParadox.GetProxy().AlarmEvent(new { Type = "InterfaceError", Exception = e.Exception.Message }); }; // Message logging try { if (!string.IsNullOrEmpty(PackageHost.GetSettingValue("MessagesLogFilePath")) && !string.IsNullOrEmpty(Path.GetFileName(PackageHost.GetSettingValue("MessagesLogFilePath")))) { BlockingCollection <string> logMessages = new BlockingCollection <string>(); this.paradox.Interface.MessageReceived += (s, e) => logMessages.Add(e.Date.ToString("dd/MM/yyyy HH:mm:ss.fff") + " < " + e.Message); this.paradox.Interface.MessageSent += (s, e) => logMessages.Add(e.Date.ToString("dd/MM/yyyy HH:mm:ss.fff") + " > " + e.Message); Task.Factory.StartNew(() => { while (PackageHost.IsRunning) { foreach (var msg in logMessages.GetConsumingEnumerable()) { try { File.AppendAllText( PackageHost.GetSettingValue("MessagesLogFilePath").Replace(".log", "." + DateTime.Now.ToString("yyyy-MM-dd") + ".log"), msg + Environment.NewLine); } catch { } } } }); } } catch (Exception ex) { PackageHost.WriteError("Error with the Paradox message logging : {0}", ex.Message); } // Label received this.paradox.UserLabelReceived += (s, e) => this.PushItem <UserInfo>(e.UserId, o => o.UpdateName(e.Label)); this.paradox.ZoneLabelReceived += (s, e) => this.PushItem <ZoneInfo>((int)e.Zone, o => o.UpdateName(e.Label)); this.paradox.AreaLabelReceived += (s, e) => this.PushItem <AreaInfo>((int)e.Area, o => o.UpdateName(e.Label)); // Area Status changed this.paradox.AreaStatusChanged += (s, e) => this.PushItem <AreaInfo>((int)e.Area, o => { o.HasTrouble = e.HasTrouble; o.InAlarm = e.InAlarm; o.IsInProgramming = e.IsInProgramming; o.IsFullArmed = (e.Status == AreaStatus.Armed) || (e.Status == AreaStatus.ForceArmed); o.IsReady = e.IsReady; o.IsStayArmed = e.Status == AreaStatus.StayArmed; o.LastActivity = e.MessageDate; o.Strobe = e.Strobe; }); // Zone Status changed this.paradox.ZoneStatusChanged += (s, e) => this.PushItem <ZoneInfo>((int)e.Zone, o => { o.InAlarm = e.InAlarm; o.InFireAlarm = e.InFireAlarm; o.IsOpen = e.Status == ZoneStatus.Open; o.IsTamper = e.Status == ZoneStatus.Tampered; o.LowBattery = e.LowBattery; o.SupervisionLost = e.SupervisionLost; o.LastActivity = e.MessageDate; }); // Zone changed this.paradox.EventManager.ZoneChanged += (s, e) => this.PushItem <ZoneInfo>((int)e.Zone, o => { o.IsOpen = e.EventGroup == EventGroup.ZoneOpen; o.IsTamper = e.EventGroup == EventGroup.ZoneTampered; o.LastActivity = e.MessageDate; }); // Zone in alarm this.paradox.EventManager.ZoneInAlarm += (s, e) => this.PushItem <ZoneInfo>((int)e.Zone, o => { o.InAlarm = true; o.LastActivity = e.MessageDate; }); this.paradox.EventManager.ZoneAlarmRestored += (s, e) => this.PushItem <ZoneInfo>((int)e.Zone, o => { o.InAlarm = false; o.LastActivity = e.MessageDate; }); // Log all Paradox system events to Constellation this.paradox.SystemEventReceived += (s, e) => PackageHost.WriteInfo("SystemEventReceived: {0}", e.ToString()); // User enter code on keypad this.paradox.EventManager.UserCodeEnteredOnKeypad += (s, e) => { string userId = "UserInfo" + e.UserId; if (items.ContainsKey(userId)) { PackageHost.WriteInfo(items[userId].Name + " entered code on keyboard "); } this.PushItem <UserInfo>(e.UserId, o => o.LastActivity = e.MessageDate); }; // Status changed this.paradox.EventManager.Status1Changed += (s, e) => { if (e.StatusType == Status1EventType.Armed || e.StatusType == Status1EventType.ForceArmed || e.StatusType == Status1EventType.InstantArmed || e.StatusType == Status1EventType.StayArmed) { this.scopeParadox.GetProxy().AlarmEvent(new { Type = "Armed", Status = e.StatusType.ToString(), Date = e.MessageDate, Text = e.MessageText }); } else if (e.StatusType == Status1EventType.AudibleAlarm || e.StatusType == Status1EventType.SilentAlarm || e.StatusType == Status1EventType.StrobeAlarm) { this.RefreshArea(e.Area); this.scopeParadox.GetProxy().AlarmEvent(new { Type = "Alarm", Status = e.StatusType.ToString(), Date = e.MessageDate, Text = e.MessageText }); } PackageHost.PushStateObject("Status1", new { Status = e.StatusType.ToString() }); }; this.paradox.EventManager.Status2Changed += (s, e) => PackageHost.PushStateObject("Status2", new { Status = e.StatusType.ToString() }); // Arming & disarming events this.paradox.EventManager.Arming += (s, e) => { this.RefreshArea(e.Area); this.scopeParadox.GetProxy().AlarmEvent(new { Type = "Arming", User = items["UserInfo" + e.UserId], Date = e.MessageDate, Text = e.MessageText }); }; this.paradox.EventManager.Disarming += (s, e) => { this.RefreshArea(e.Area); this.scopeParadox.GetProxy().AlarmEvent(new { Type = "Disarming", User = items["UserInfo" + e.UserId], Date = e.MessageDate, Text = e.MessageText }); }; // Other events this.paradox.EventManager.UserCodeEnteredOnKeypad += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "UserCodeEnteredOnKeypad", User = items["UserInfo" + e.UserId], Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.SpecialArming += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "SpecialArming", ArmingType = e.ArmingType.ToString(), Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.AccessDenied += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "AccessDenied", User = items["UserInfo" + e.UserId], Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.AccessGranted += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "AccessGranted", User = items["UserInfo" + e.UserId], Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.AlarmCancelled += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "AlarmCancelled", User = items["UserInfo" + e.UserId], Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.NonReportableEvent += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "NonReportableEvent", Event = e.Event.ToString(), Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.ZoneInAlarm += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "ZoneInAlarm", Zone = items["ZoneInfo" + (int)e.Zone], Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.ZoneAlarmRestored += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "ZoneAlarmRestored", Zone = items["ZoneInfo" + (int)e.Zone], Date = e.MessageDate, Text = e.MessageText }); this.paradox.EventManager.ZoneChanged += (s, e) => this.scopeParadox.GetProxy().AlarmEvent(new { Type = "ZoneChanged", Zone = items["ZoneInfo" + (int)e.Zone], Date = e.MessageDate, Text = e.MessageText }); // Refresh all this.RefreshAll(); // Initialization OK PackageHost.WriteInfo("Paradox System is loaded"); }