private Task Handle(UpsBatteryMeasurement measurement, CancellationToken cancellationToken) { if (!HistorianConfiguration.Npgsql.UpsBattery.Enable) { return(Task.CompletedTask); } return(Insert(command => { command .WithCommandText(HistorianConfiguration.Npgsql.UpsBattery.InsertQuery) .AddParameter(nameof(measurement.Timestamp), measurement.Timestamp.ToUniversalTime()) .AddParameter(nameof(measurement.Age), measurement.Age) .AddParameter(nameof(measurement.Hostname), measurement.Hostname) .AddParameter(nameof(measurement.Model), measurement.Model) .AddParameter(nameof(measurement.Alias), measurement.Alias) .AddParameter(nameof(measurement.StatusText), measurement.StatusText) .AddParameter(nameof(measurement.IsOnline), measurement.IsOnline) .AddParameter(nameof(measurement.IsOnBattery), measurement.IsOnBattery) .AddParameter(nameof(measurement.IsOnLowBattery), measurement.IsOnLowBattery) .AddParameter(nameof(measurement.IsCommunicationLost), measurement.IsCommunicationLost) .AddParameter(nameof(measurement.IsShuttingDown), measurement.IsShuttingDown) .AddParameter(nameof(measurement.IsOverload), measurement.IsOverload) .AddParameter(nameof(measurement.IsBatteryReplacementRequested), measurement.IsBatteryReplacementRequested) .AddParameter(nameof(measurement.IsBatteryMissing), measurement.IsBatteryMissing) .AddParameter(nameof(measurement.BatteryCharge), measurement.BatteryCharge) .AddParameter(nameof(measurement.TimeLeft), measurement.TimeLeft) .AddParameter(nameof(measurement.MinBatteryCharge), measurement.MinBatteryCharge) .AddParameter(nameof(measurement.MinTimeLeft), measurement.MinTimeLeft) .AddParameter(nameof(measurement.CumulativeOnBattery), measurement.CumulativeOnBattery) .AddParameter(nameof(measurement.CurrentBatteryVoltage), measurement.CurrentBatteryVoltage) .AddParameter(nameof(measurement.NominativeBatteryVoltage), measurement.NominativeBatteryVoltage) .AddParameter(nameof(measurement.ManufacturingDate), measurement.ManufacturingDate); }, cancellationToken)); }
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); } }