Example #1
0
        private async Task OnIsDue(ApcupsdSensorConfiguration configuration, CancellationToken cancellationToken)
        {
            if (!configuration.Enable)
            {
                return;
            }

            MeasurementTimingService.ResetDue(configuration);
            var upsBatteryMeasurement = await GetUpsBatteryMeasurement(configuration, cancellationToken);

            await Mediator.Publish(new OutboundMeasurement()
            {
                Name = "ups-battery",
                Item = upsBatteryMeasurement,
            }, cancellationToken);
        }
Example #2
0
        private async Task <UpsBatteryMeasurement> GetUpsBatteryMeasurement(ApcupsdSensorConfiguration configuration, CancellationToken cancellationToken)
        {
            using (var process = Process.Start(new ProcessStartInfo()
            {
                FileName = "apcaccess",
                Arguments = "-u",
                StandardOutputEncoding = Encoding.UTF8,
                RedirectStandardOutput = true,
                UseShellExecute = false,
            }))
            {
                var result = new UpsBatteryMeasurement()
                {
                    Timestamp = DateTime.UtcNow,
                    Alias     = configuration.Alias,
                    Hostname  = System.Net.Dns.GetHostName(),
                };
                while (!process.HasExited)
                {
                    while (!process.StandardOutput.EndOfStream)
                    {
                        var line = await process.StandardOutput.ReadLineAsync();

                        var match = Regex.Match(line, "^(.+): (.+)");
                        if (!match.Success)
                        {
                            // skip
                        }
                        else
                        {
                            var topic = match.Groups[1].Value.Trim();
                            var value = match.Groups[2].Value.Trim();

                            switch (topic)
                            {
                            case "DATE":
                            {
                                try
                                {
                                    if (DateTime.TryParseExact(value.Substring(0, 19), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var timestamp))
                                    {
                                        result.Age = DateTime.Now - timestamp;
                                    }
                                }
                                catch (ArgumentOutOfRangeException)
                                {
                                    // ignore
                                }
                                catch (FormatException)
                                {
                                    // ignore
                                }
                            }
                            break;

                            case "MANDATE":
                            {
                                try
                                {
                                    if (DateTime.TryParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var manufacturingDate))
                                    {
                                        result.ManufacturingDate = manufacturingDate;
                                    }
                                }
                                catch (FormatException)
                                {
                                    // ignore
                                }
                            }
                            break;

                            case "MODEL":
                            {
                                result.Model = value;
                            }
                            break;

                            case "BATTV":
                            {
                                if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.CurrentBatteryVoltage = valueParsed;
                                }
                            }
                            break;

                            case "NOMBATTV":
                            {
                                if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.NominativeBatteryVoltage = valueParsed;
                                }
                            }
                            break;

                            case "BCHARGE":
                            {
                                if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.BatteryCharge = valueParsed;
                                }
                            }
                            break;

                            case "MBATTCHG":
                            {
                                if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.MinBatteryCharge = valueParsed;
                                }
                            }
                            break;

                            case "TIMELEFT":
                            {
                                if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.TimeLeft = TimeSpan.FromMinutes(valueParsed);
                                }
                            }
                            break;

                            case "MINTIMEL":
                            {
                                if (double.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.MinTimeLeft = TimeSpan.FromMinutes(valueParsed);
                                }
                            }
                            break;

                            case "CUMONBATT":
                            {
                                if (double.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var valueParsed))
                                {
                                    result.CumulativeOnBattery = TimeSpan.FromSeconds(valueParsed);
                                }
                            }
                            break;

                            case "STATUS":
                            {
                                /*
                                 * CAL TRIM BOOST ONLINE ONBATT OVERLOAD LOWBATT REPLACEBATT NOBATT SLAVE SLAVEDOWN
                                 * or
                                 * COMMLOST
                                 * or
                                 * SHUTTING DOWN
                                 */
                                result.StatusText = value;
                                if (value.Contains("ONLINE"))
                                {
                                    result.IsOnline = true;
                                }

                                if (value.Contains("ONBATT"))
                                {
                                    result.IsOnBattery = true;
                                }

                                if (value.Contains("OVERLOAD"))
                                {
                                    result.IsOverload = true;
                                }

                                if (value.Contains("LOWBATT"))
                                {
                                    result.IsOnLowBattery = true;
                                }

                                if (value.Contains("REPLACEBATT"))
                                {
                                    result.IsBatteryReplacementRequested = true;
                                }

                                if (value.Contains("NOBATT"))
                                {
                                    result.IsBatteryMissing = true;
                                }

                                if (value.Contains("COMMLOST"))
                                {
                                    result.IsCommunicationLost = true;
                                }

                                if (value.Contains("SHUTTING DOWN"))
                                {
                                    result.IsShuttingDown = true;
                                }
                            }
                            break;
                            }
                        }
                    }
                }

                if (!string.IsNullOrWhiteSpace(result.StatusText))
                {
                    return(result);
                }

                return(null);
            }
        }
Example #3
0
 public ApcupsdSensor(IMediator mediator, ApcupsdSensorConfiguration configuration, IMeasurementTimingService measurementTimingService)
 {
     Mediator                 = mediator ?? throw new ArgumentNullException(nameof(mediator));
     Configuration            = configuration ?? throw new ArgumentNullException(nameof(configuration));
     MeasurementTimingService = measurementTimingService ?? throw new ArgumentNullException(nameof(measurementTimingService));
 }