public List <Ups> GetUpsFromServer(Server server, string password, string upsName)
        {
            // Update the password on the server object since it can't be passed as a SecureString
            // over the WCF channel
            server.Password = SecureStringExtensions.FromString(password);
            ServerConfiguration serverConfiguration = ServerConfiguration.CreateFromServer(server);

            serverConfiguration.ValidateProperties();

            // Recreate the server object to ensure that it matches what would be created when it
            // is read from configuration at startup.
            server = Server.CreateFromConfiguration(serverConfiguration);

            ServerConnection serverConnection = new ServerConnection(server);

            serverConnection.ConnectAsync(CancellationToken.None).Wait();

            try
            {
                Dictionary <string, string> listResponse =
                    serverConnection
                    .ListUpsAsync(CancellationToken.None).Result;

                List <Ups> upsList = new List <Ups>();

                foreach (string thisUpsName in listResponse.Keys)
                {
                    if (!string.IsNullOrWhiteSpace(upsName) && !string.Equals(thisUpsName, upsName))
                    {
                        continue;
                    }

                    Dictionary <string, string> upsVars =
                        serverConnection
                        .ListVarsAsync(thisUpsName, CancellationToken.None).Result;

                    var ups = Ups.Create(thisUpsName, server, upsVars);

                    var upsContext =
                        ServiceRuntime.Instance.UpsContexts.FirstOrDefault(
                            ctx => ctx.Name == thisUpsName && ctx.ServerState.Name == server.Name);

                    ups.IsManaged = upsContext != null;

                    upsList.Add(ups);
                }

                return(upsList);
            }
            finally
            {
                serverConnection.Disconnect();
            }
        }
        private static Ups GetOrCreateState(UpsContext ctx)
        {
            if (ctx.State != null)
            {
                return(ctx.State);
            }

            return(Ups.Create(
                       ctx.Name,
                       ctx.ServerState,
                       new Dictionary <string, string>()));
        }
示例#3
0
        /// <summary>
        /// Update...
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <remarks>
        /// Note: The caller must hold a reader lock from UpsMonitor prior to calling
        /// this method
        /// </remarks>
        private async Task UpdateStatusAsync(CancellationToken cancellationToken)
        {
            try
            {
                // Get the current status of the device from the server
                Dictionary <string, string> deviceVars =
                    await this.Connection
                    .ListVarsAsync(this.Name, cancellationToken)
                    .ConfigureAwait(false);

                //Dictionary<string, string> deviceRw =
                //    await this.Connection
                //        .ListRwAsync(this.Name, cancellationToken)
                //        .ConfigureAwait(false);

                //List<string> deviceCmd =
                //    await this.Connection
                //        .ListCmdAsync(this.Name, cancellationToken)
                //        .ConfigureAwait(false);

                //Dictionary<string, string> deviceEnum =
                //    await this.Connection
                //        .ListEnumAsync(this.Name + " input.transfer.low", cancellationToken)
                //        .ConfigureAwait(false);

                //Dictionary<string, string> deviceRange =
                //    await this.Connection
                //        .ListRangeAsync(this.Name + " input.transfer.low", cancellationToken)
                //        .ConfigureAwait(false);

                Logger.Debug(
                    "UpdateStatusAsync[Ups={0}]: Successfully queried server",
                    this.QualifiedName);

                var metricMeasurements = this.MetricDatabase.UpdateMetrics(deviceVars);

                if (this.State == null)
                {
                    // We haven't yet pulled the device information from the server yet, so
                    // do that now. Since this will be the first time pulling device state
                    // from the server, we won't have any previous state to compare it to,
                    // so don't bother comparing state.
                    this.State = Ups.Create(this.Name, this.ServerState, deviceVars);

                    // ReSharper disable once MethodSupportsCancellation
                    this.upsMonitor.Changes.Add(
                        new UpsStatusChangeData
                    {
                        // Pass null as the previous state to indicate that this is the first time
                        // receiving state information for this device
                        PreviousState = null,
                        UpsContext    = this
                    });
                }
                else
                {
                    // Create a copy of the current state in case we need it below
                    var previousState = this.State.Clone();

                    // Update the state object is with the new variables from the server
                    this.State.Update(deviceVars);

                    // The status has changed, so queue a status change notification
                    if (previousState.Status != this.State.Status)
                    {
                        // ReSharper disable once MethodSupportsCancellation
                        this.upsMonitor.Changes.Add(
                            new UpsStatusChangeData
                        {
                            // Create a copy of the device state to pass to UpsMonitor
                            PreviousState = previousState,
                            UpsContext    = this
                        });
                    }

#pragma warning disable 4014
                    Task.Run(() =>
                    {
                        foreach (IManagementCallback callbackChannel in
                                 ServiceRuntime.Instance.ClientCallbackChannels)
                        {
                            try
                            {
                                callbackChannel.UpsDeviceChanged(this.State, metricMeasurements.ToArray());
                            }
                            catch (Exception e)
                            {
                                Logger.Error("Caught exception while updating device. " + e.Message);
                                ServiceRuntime.Instance.ClientCallbackChannels.Remove(callbackChannel);
                                break;
                            }
                        }
                    }, cancellationToken);
#pragma warning restore 4014
                }

                // We successfully queried the server, so update the property for this
                this.State.LastPollTime = DateTime.Now;
            }
            catch (NutCommunicationException commEx)
            {
                Logger.Debug(
                    "UpdateStatusAsync[Ups={0}]: Caught exception querying server. {1}",
                    this.QualifiedName,
                    commEx);

                this.Disconnect(true, true);

                // We failed to communicate with the server, so raise a change notification
                // ReSharper disable once MethodSupportsCancellation
                this.upsMonitor.Changes.Add(
                    new UpsStatusChangeData
                {
                    // Create a copy of the device state to pass to UpsMonitor
                    PreviousState = this.State.Clone(),
                    UpsContext    = this,
                    Exception     = commEx
                });
            }

            Logger.Debug(
                "UpdateStatusAsync[Ups={0}]: Finished UpdateStatusAsync()",
                this.QualifiedName);
        }
        public Ups AddUps(
            Server server,
            string password,
            string upsName,
            int numPowerSupplies,
            bool monitorOnly,
            bool force)
        {
            // Update the password on the server object since it can't be passed as a SecureString
            // over the WCF channel
            server.Password = SecureStringExtensions.FromString(password);
            ServerConfiguration serverConfiguration = ServerConfiguration.CreateFromServer(server);

            serverConfiguration.ValidateProperties();

            // Recreate the server object to ensure that it matches what would be created when it
            // is read from configuration at startup.
            server = Server.CreateFromConfiguration(serverConfiguration);

            UpsConfiguration upsConfiguration = new UpsConfiguration()
            {
                DeviceName          = upsName,
                MonitorOnly         = monitorOnly,
                NumPowerSupplies    = numPowerSupplies,
                ServerConfiguration = serverConfiguration
            };

            try
            {
                ServerConnection serverConnection = new ServerConnection(server);

                serverConnection.ConnectAsync(CancellationToken.None).Wait();

                Dictionary <string, string> upsVars =
                    serverConnection
                    .ListVarsAsync(upsName, CancellationToken.None).Result;

                Ups ups = Ups.Create(upsName, server, upsVars);

                // Success. Add the configuration and save
                ServiceRuntime.Instance.Configuration.UpsConfigurations.Add(
                    upsConfiguration);

                ServiceRuntime.Instance.SaveConfiguration();

                // Add to the running instances
                UpsContext upsContext = new UpsContext(upsConfiguration, server)
                {
                    State = ups
                };

                ServiceRuntime.Instance.UpsContexts.Add(upsContext);

#pragma warning disable 4014
                Task.Run(() =>
                {
                    foreach (IManagementCallback callbackChannel in
                             ServiceRuntime.Instance.ClientCallbackChannels)
                    {
                        try
                        {
                            callbackChannel.UpsDeviceAdded(ups);
                        }
                        catch (Exception e)
                        {
                            Logger.Error("Caught exception while updating device. " + e.Message);
                            ServiceRuntime.Instance.ClientCallbackChannels.Remove(callbackChannel);
                            break;
                        }
                    }
                });
#pragma warning restore 4014

                return(ups);
            }
            catch (Exception exception)
            {
                Logger.Error("Exception while adding UPS device. {0}", exception.Message);

                if (force)
                {
                    // Add the configuration and save
                    ServiceRuntime.Instance.Configuration.UpsConfigurations.Add(
                        upsConfiguration);

                    ServiceRuntime.Instance.SaveConfiguration();

                    return(null);
                }

                throw;
            }
        }