/// <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'");
     }
 }
Exemple #2
0
        /// <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");
        }