ArthurMitchell42 / nutcase

A NUT and APCd UPS data conversion bridge and graphic UI to link to both Prometheus metrics and JSON format for HomePage/Uptime Kuma etc.
https://arthurmitchell42.github.io/nutcase/
GNU General Public License v3.0
26 stars 3 forks source link

Add examples for APC UPS #16

Closed Druidblack closed 9 months ago

Druidblack commented 10 months ago

For APC UPS, unlike NAT, the request parameters differ. To make it easier to configure the parameters request for homepage, I suggest adding a template for APC. P.S. On all my UPS that I have (powercom, ippon and apc), the operating time was not displayed correctly anywhere, so you can suggest requesting battery power in the sample template.

   - APC Back-UPS ES 700G (Irina PC):
        href: http://192.168.1.161:9995/log?lines=40
        description: APC Back-UPS ES 700G
        icon: ups.png
        widget:
            type: customapi
            url: http://192.168.1.161:9995/json?mode=apc&target=192.168.1.94:3551
            refreshInterval: 60000 # In milliseconds, set to ~60s
            method: GET
            mappings:
                - field: 
                    APC Back-UPS ES 700:
                      LINEV
                  label: Input
                  format: text
                - field: 
                    APC Back-UPS ES 700: BCHARGE
                  label: Battery charge
                  format: text
                - field: 
                    APC Back-UPS ES 700:
                      LOADPCT
                  label: Power
                  format: text
                - field: 
                    APC Back-UPS ES 700:
                      UPSMODE
                  label: Status
                  format: text
                  remap:
                    - value: "OL"
                      to: On-Line
                    - value: "OB"
                      to: Discharge
   - PowerCom RPT-2000AP:
        href: http://192.168.1.161:9995/log?lines=40
        description: PowerCom RPT-2000AP
        icon: ups.png
        widget:
            type: customapi
            url: http://192.168.1.161:9995/json?target=192.168.1.195:3493
            refreshInterval: 60000 # In milliseconds, set to ~60s
            method: GET
            mappings:
                - field: 
                    powercom_raptor_2000_ap:
                      input.voltage
                  label: Input
                  format: text
                  suffix: V
                - field: 
                    powercom_raptor_2000_ap: battery.charge
                  label: Battery charge
                  format: text
                  suffix: "%"
                - field: 
                    powercom_raptor_2000_ap:
                      ups.load
                  label: Power
                  format: text
                  suffix: "%"
                - field: 
                    powercom_raptor_2000_ap:
                      ups.status
                  label: Status
                  format: text
                  remap:
                    - value: "OL"
                      to: On-Line
                    - value: "OL TRIM"
                      to: On-Line Trim
                    - value: "OB"
                      to: Discharge
ArthurMitchell42 commented 10 months ago

Thank you for this feedback. As I only have access to a simulator for the apcupsd it would be enormously helpful if you could open the JSON for your ES700 in a browser with:

http://192.168.1.161:9995/json?mode=apc&target=192.168.1.94:3551

and save the JSON you get as a file and attach it here please. This would really help my test benching. :)

I'm not sure why the runtime isn't working for your PowerCom device. Since it's a NUT server I would expect it to send the battery.runtime parameter by default. Could I ask for a JSON dump for it please and I'll comb through it to see if there is something I can do from my side?

Thanks in advance. A

Druidblack commented 10 months ago
{
  "server_version": "3.14.14 (31 May 2016) mingw",
  "server_address": "192.168.1.94",
  "server_port": 3551,
  "APC Back-UPS ES 700": {
    "description": "Back-UPS ES 700G @ DESKTOP-UREEQQ0",
    "APC": "001,034,0853",
    "DATE": "2024-01-02 22:02:53 +0300",
    "HOSTNAME": "DESKTOP-UREEQQ0",
    "VERSION": "3.14.14 (31 May 2016) mingw",
    "UPSNAME": "APC Back-UPS ES 700",
    "CABLE": "USB Cable",
    "DRIVER": "USB UPS Driver",
    "UPSMODE": "Stand Alone",
    "STARTTIME": "2024-01-01 15:27:43 +0300",
    "MODEL": "Back-UPS ES 700G",
    "STATUS": "ONLINE",
    "LINEV": "232.0 Volts",
    "LOADPCT": "6.0 Percent",
    "BCHARGE": "100.0 Percent",
    "TIMELEFT": "32.9 Minutes",
    "MBATTCHG": "5 Percent",
    "MINTIMEL": "3 Minutes",
    "MAXTIME": "0 Seconds",
    "SENSE": "Medium",
    "LOTRANS": "190.0 Volts",
    "HITRANS": "256.0 Volts",
    "ALARMDEL": "No alarm",
    "BATTV": "13.7 Volts",
    "LASTXFER": "Automatic or explicit self test",
    "NUMXFERS": "0",
    "TONBATT": "0 Seconds",
    "CUMONBATT": "0 Seconds",
    "XOFFBATT": "N/A",
    "STATFLAG": "0x05000008",
    "SERIALNO": "5B1637T49067",
    "BATTDATE": "2016-09-18",
    "NOMINV": "230 Volts",
    "NOMBATTV": "12.0 Volts",
    "FIRMWARE": "871.O4 .I USB FW:O4",
    "END APC": "2024-01-02 22:03:28 +0300"
  }
}

{
  "server_version": "2.8.0",
  "server_address": "192.168.1.1",
  "server_port": 3493,
  "IPPON_Back_Basic_650S_Euro": {
    "description": "Description unavailable",
    "battery.charge": "100",
    "battery.voltage": "13.60",
    "battery.voltage.high": "13.00",
    "battery.voltage.low": "10.40",
    "battery.voltage.nominal": "12.0",
    "device.type": "ups",
    "driver.name": "blazer_usb",
    "driver.parameter.pollinterval": "15",
    "driver.parameter.port": "auto",
    "driver.parameter.synchronous": "auto",
    "driver.version": "2.8.0",
    "driver.version.internal": "0.14",
    "driver.version.usb": "libusb-1.0.0 (API: 0x1000102)",
    "input.current.nominal": "2.0",
    "input.frequency": "50.3",
    "input.frequency.nominal": "50",
    "input.voltage": "231.4",
    "input.voltage.fault": "232.0",
    "input.voltage.nominal": "220",
    "output.voltage": "231.4",
    "ups.beeper.status": "enabled",
    "ups.delay.shutdown": "30",
    "ups.delay.start": "180",
    "ups.load": "19",
    "ups.productid": "5161",
    "ups.status": "OL",
    "ups.temperature": "25.0",
    "ups.type": "offline / line interactive",
    "ups.vendorid": "0665",
    "clients": {
      "count": 1,
      "list": [
        "::1"
      ]
    }
  }
}

{
  "server_version": "2.7.4",
  "server_address": "192.168.1.183",
  "server_port": 3493,
  "ippon_back_comfo_800": {
    "description": "Description unavailable",
    "battery.charge": "100",
    "battery.voltage": "13.60",
    "battery.voltage.high": "13.00",
    "battery.voltage.low": "10.40",
    "battery.voltage.nominal": "12.0",
    "device.type": "ups",
    "driver.name": "blazer_usb",
    "driver.parameter.pollinterval": "2",
    "driver.parameter.port": "auto",
    "driver.parameter.synchronous": "no",
    "driver.version": "2.7.4",
    "driver.version.internal": "0.12",
    "input.current.nominal": "3.0",
    "input.frequency": "50.0",
    "input.frequency.nominal": "50",
    "input.voltage": "234.3",
    "input.voltage.fault": "234.3",
    "input.voltage.nominal": "220",
    "output.voltage": "234.3",
    "ups.beeper.status": "enabled",
    "ups.delay.shutdown": "30",
    "ups.delay.start": "180",
    "ups.load": "16",
    "ups.productid": "5161",
    "ups.status": "OL",
    "ups.temperature": "25.0",
    "ups.type": "offline / line interactive",
    "ups.vendorid": "0665",
    "clients": {
      "count": 1,
      "list": [
        "::1"
      ]
    }
  }
}

{
  "server_version": "2.7.4",
  "server_address": "192.168.1.195",
  "server_port": 3493,
  "powercom_raptor_2000_ap": {
    "description": "Description unavailable",
    "battery.charge": "100",
    "battery.charge.low": "10",
    "battery.charge.warning": "30",
    "battery.date": "2014/01/15",
    "battery.runtime": "800",
    "battery.type": "PbAc",
    "device.mfr": "POWERCOM Co.,LTD",
    "device.model": "HID UPS Battery",
    "device.serial": "G008E39401",
    "device.type": "ups",
    "driver.name": "usbhid-ups",
    "driver.parameter.pollfreq": "30",
    "driver.parameter.pollinterval": "2",
    "driver.parameter.port": "auto",
    "driver.parameter.serial": "G008E39401",
    "driver.parameter.synchronous": "no",
    "driver.version": "2.7.4",
    "driver.version.data": "PowerCOM HID 0.5",
    "driver.version.internal": "0.41",
    "input.frequency": "50.0",
    "input.voltage": "236.0",
    "input.voltage.nominal": "220",
    "output.frequency": "50.0",
    "output.voltage": "236.0",
    "output.voltage.nominal": "220",
    "ups.beeper.status": "disabled",
    "ups.date": "2014/01/15",
    "ups.delay.shutdown": "20",
    "ups.delay.start": "60",
    "ups.load": "15",
    "ups.mfr": "POWERCOM Co.,LTD",
    "ups.model": "HID UPS Battery",
    "ups.productid": "0004",
    "ups.serial": "G008E39401",
    "ups.status": "OL",
    "ups.test.result": "Done and passed",
    "ups.timer.shutdown": "0",
    "ups.timer.start": "740640",
    "ups.vendorid": "0d9f",
    "clients": {
      "count": 1,
      "list": [
        "::1"
      ]
    }
  }
}

{
  "server_version": "2.7.4",
  "server_address": "192.168.1.161",
  "server_port": 3493,
  "ups": {
    "description": "Description unavailable",
    "battery.charge": "100",
    "battery.charge.low": "10",
    "battery.charge.warning": "30",
    "battery.date": "2014/01/15",
    "battery.runtime": "480",
    "battery.type": "PbAc",
    "device.mfr": "POWERCOM Co.,LTD",
    "device.model": "HID UPS Battery",
    "device.serial": "G008E39402",
    "device.type": "ups",
    "driver.name": "usbhid-ups",
    "driver.parameter.pollfreq": "30",
    "driver.parameter.pollinterval": "2",
    "driver.parameter.port": "auto",
    "driver.parameter.serial": "G008E39402",
    "driver.parameter.synchronous": "no",
    "driver.version": "2.7.4",
    "driver.version.data": "PowerCOM HID 0.5",
    "driver.version.internal": "0.41",
    "input.frequency": "50.0",
    "input.voltage": "240.0",
    "input.voltage.nominal": "220",
    "output.frequency": "50.0",
    "output.voltage": "208.0",
    "output.voltage.nominal": "220",
    "ups.beeper.status": "disabled",
    "ups.date": "2014/01/15",
    "ups.delay.shutdown": "20",
    "ups.delay.start": "60",
    "ups.load": "34",
    "ups.mfr": "POWERCOM Co.,LTD",
    "ups.model": "HID UPS Battery",
    "ups.productid": "0004",
    "ups.serial": "G008E39402",
    "ups.status": "OL TRIM",
    "ups.test.result": "Done and passed",
    "ups.timer.shutdown": "0",
    "ups.timer.start": "848340",
    "ups.vendorid": "0d9f",
    "clients": {
      "count": 1,
      "list": [
        "::1"
      ]
    }
  }
}

{
  "server_version": "3.14.14 (31 May 2016) mingw",
  "server_address": "192.168.1.2",
  "server_port": 3551,
  "HOME-PC": {
    "description": "Back-UPS BF500 @ HOME-PC",
    "APC": "001,045,1036",
    "DATE": "2024-01-02 22:35:57 +0300",
    "HOSTNAME": "HOME-PC",
    "VERSION": "3.14.14 (31 May 2016) mingw",
    "UPSNAME": "HOME-PC",
    "CABLE": "USB Cable",
    "DRIVER": "USB UPS Driver",
    "UPSMODE": "Stand Alone",
    "STARTTIME": "2024-01-02 22:35:31 +0300",
    "MODEL": "Back-UPS BF500",
    "STATUS": "ONLINE",
    "LINEV": "232.0 Volts",
    "LOADPCT": "19.0 Percent",
    "BCHARGE": "100.0 Percent",
    "TIMELEFT": "23.1 Minutes",
    "MBATTCHG": "5 Percent",
    "MINTIMEL": "3 Minutes",
    "MAXTIME": "0 Seconds",
    "OUTPUTV": "230.0 Volts",
    "SENSE": "Medium",
    "DWAKE": "0 Seconds",
    "DSHUTD": "0 Seconds",
    "LOTRANS": "180.0 Volts",
    "HITRANS": "266.0 Volts",
    "RETPCT": "0.0 Percent",
    "ITEMP": "29.2 C",
    "ALARMDEL": "No alarm",
    "BATTV": "13.6 Volts",
    "LINEFREQ": "50.0 Hz",
    "LASTXFER": "Low line voltage",
    "NUMXFERS": "0",
    "TONBATT": "0 Seconds",
    "CUMONBATT": "0 Seconds",
    "XOFFBATT": "N/A",
    "SELFTEST": "NO",
    "STESTI": "None",
    "STATFLAG": "0x05000008",
    "MANDATE": "2006-01-19",
    "SERIALNO": "AB0604341606",
    "BATTDATE": "2006-07-27",
    "NOMOUTV": "230 Volts",
    "NOMINV": "230 Volts",
    "NOMBATTV": "12.0 Volts",
    "NOMPOWER": "325 Watts",
    "FIRMWARE": "814.s3.I  USB FW:s3",
    "END APC": "2024-01-02 22:36:08 +0300"
  }
}

Ippon does not have the battery.runtime parameter, and in PowerCom, the battery.runtime parameter is always the same and does not change.

Druidblack commented 10 months ago

6666

p.s

If by analogy with https://github.com/Brandawg93/PeaNUT If you make a graphical interface and collect statistics for each UPS, then it will be very cool. Since your program can collect statistics from both NUT and APC.

Druidblack commented 10 months ago

By the way, you may want to add getting information from the app as well. UPSMONPro https://www.upspowercom.com/PRO-Windows.jsp it does not have an explicit web interface, but when the program is running under windows, it gives a text file with the ups parameters.

In the home assistant, I took these readings for myself in this way.

236
236
17
50
40
100
1
1
1
2

In the home assistant, I took these readings for myself in this way.


  - platform: rest
    resource: http://192.168.1.95:8000/ups.txt
    name: ts

  - platform: template
    sensors:
      ups_input_voltage:
        friendly_name: "UPS Powercom Raptor RPT-2000AP Input-Voltage"
        value_template: "{{ states('sensor.ts')[:3] }}"
        unit_of_measurement: 'V'

  - platform: template
    sensors:
      ups_output_voltage:
        friendly_name: "UPS Powercom Raptor RPT-2000AP Output-Voltage"
        value_template: "{{ states('sensor.ts')[3:8] }}"
        unit_of_measurement: 'V'

  - platform: template
    sensors:
      ups_load_level:
        friendly_name: "UPS Powercom Raptor RPT-2000AP Load Level"
        value_template: "{{ states('sensor.ts')[8:13] }}"
        unit_of_measurement: '%'

  - platform: template
    sensors:
      ups_frequency:
        friendly_name: "UPS Powercom Raptor RPT-2000AP Frequency"
        value_template: "{{ states('sensor.ts')[13:17] }}"
        unit_of_measurement: 'Hz'

  - platform: template
    sensors:
      ups_temperature:
        friendly_name: "UPS Powercom Raptor RPT-2000AP Temperature"
        value_template: "{{ states('sensor.ts')[17:21] }}"
        unit_of_measurement: '°C'

  - platform: template
    sensors:
      ups_battery_level:
        friendly_name: "UPS Powercom Raptor RPT-2000AP Battery Level"
        value_template: "{{ states('sensor.ts')[21:26] }}"
        unit_of_measurement: '%'
ArthurMitchell42 commented 10 months ago

Wow, that's really impressive, 6 UPS's on one display. Thank you very much for the captured data. I see there are a few issues that I could improve on:

  1. Most of your devices don't have the ups.realpower.nominal and so they only give a % output power value. If I change the rework style ratio to optionally support an integer for the control value as well as a variable name then NUTCase will still be able to calulate the real output power. The user can then manually set the device power as part of the set up process.
  2. APC likes to put units on values which looks untidy in HomePage and is redundant as each mapping field already has a label. I think I'll add some kind of option to trim that text part of the value field. Let me think on how best to do that.
  3. For the devices that don't supply accurate (or any) battery.runtime value, can I assume that the only useful information during an outage is the battery.charge figure? If so I may be able to extrapolate some useful information from that.

Right now I'm adding a GUI which will display data in real time along with some diagnostics. Adding a database behind that to store data is in my mind but as that's a big additional chunk of work then I'll take that in stages and look to do that later in the year after the GUI is stable and mature.

ArthurMitchell42 commented 10 months ago

Can I also check: does the APC variable "TIMELEFT": "32.9 Minutes" give you the same information as the NUT variable battery.runtime please? If so I can add a new rework method to allow re-formatting of that value to something user defined.

Druidblack commented 10 months ago

The TIMELEFT variable returns the same time from the moment the UPS is turned on. It turns out that on all systems and on all UPS there are some problems with calculating the operating time. It seems to me easier to deduce this time from the moment the ipb appeared on the network. 4444

ArthurMitchell42 commented 10 months ago

Version V0.3.0 Beta 1 is now available with extra features for APC and NUT devices. Both types of device can now be scraped by Prometheus for metrics so that one Grafana dashboard can display the status of all UPS's.

Druidblack commented 10 months ago

Good job. If you can make an example with a configuration file, it would be great. I looked at the description of the configuration file and realized that I didn't understand anything. English is not a native language, and there is a lot of new information in the description.

ArthurMitchell42 commented 10 months ago

The configuration file is documented with examples on the Wiki. This should get you going along with the other Wiki notes on using the GUI.

ArthurMitchell42 commented 10 months ago

So for example the full file I'm testing with at the moment looks like this:

rework:
  - from: battery.runtime
    to: nutcase.battery.runtime
    style: time
    control: "%Mm %Ss"
# Other examples are: "%H:%M:%S" or "%-M:%S"
  - from: ups.status
    to: nutcase.ups.status
    style: simple-enum
    control: 
      from: [ "OL", "OB", "LB", "CHRG", "RB", "FSD", "BYPASS", "SD", "CP", "BOOST", "OFF" ]
      to: [ "On-Line", "On-Bat", "Low-Bat", "Charging", "Replace-Bat", "Force-Shutdown", "Bypass", "Shutdown", "On-Line", "Boost", "Off" ]
      default: "Other"
  - from: ups.status
    to: nutcase.ups.status.composite
    style: comp-enum
    control: 
      from: [ "OL", "OB", "LB", "CHRG", "RB", "FSD", "BYPASS", "SD", "CP", "BOOST", "OFF" ]
      to: [ "On-Line", "On-Bat", "Low-Bat", "Charging", "Replace-Bat", "Force-Shutdown", "Bypass", "Shutdown", "On-Line", "Boost", "Off" ]
      default: "Other"
      # join: "-"
  - from: ups.load
    to: nutcase.ups.load.watts
    style: ratio
    control: ups.realpower.nominal
  - from: ups
    to: nutcase.ups.client-count
    style: cl-count
    control: [ "4", 'Missing {d} of {c}', 'Clients OK ({c})', '{d} Extra']
  - from: ups
    to: nutcase.ups.client-check
    style: cl-check
    control: [ '10.0.10.10', '10.0.10.178', '10.0.10.11', '10.0.10.9', '10.0.10.183', '127.0.0.1' ]
webhooks:
  # default: 
  #   - http://10.0.10.180:3001/api/push/fFWFJscQXd?status=up&msg=OK&ping= 
  #   - http://10.0.10.9:3001/api/push/d3bzhCuNm6?status=up&msg=OK&ping=
  ok:
    - http://10.0.10.180:3001/api/push/fFWFJscQXd?status=up&msg=OK&ping= 
    - http://10.0.10.9:3001/api/push/d3bzhCuNm6?status=up&msg=OK&ping=
  fail: 
    - http://10.0.10.180:3001/api/push/fFWFJscQXd?status=down&msg=OK&ping=
    - http://10.0.10.9:3001/api/push/d3bzhCuNm6?status=up&msg=OK&ping=
# Boolean values: True = True, On and Yes    False = False, Off and No
settings:
  log_level: debug
  order_metrics: True
  coloured_log: True
  default_log_lines: 30
  cache_period: 30
  apc_strip_units: true
  ui_format_runtime: "%-Hh %-Mm %Ss"
servers:
  - server: "10.0.10.9"
    port: 3493
    device: 'ups'
    default: true
    power: 550
    # username: monuser
    # password: secret
  - server: "10.0.10.180"
    port: 3493
    device: 'eaton3s'
    power: 850
    # username: monuser
    # password: secret
  - server: "10.0.10.184"
    port: 3493
    device: 'alpha'
    power: 2000