Monitor CyberPower UPS plugged into Windows Machine via USB

I also found the reported load use to be way off. Currently using an old rpi running NUT until this is resolved.

Hi all.

I just bought a Cyberpower VP700ELCD which is conected via USB to a Windows 10 pc with the PowerPanel app installed.

Can someone explain the step by step guide to getting this integrated to HA? I’m running Hassio on a NAS.
Thanks in advance

Here is my configuration.yaml for a cyberpower and the entities card setup.

First you need to download and install the latest CyberPower Panel Business V4 at PowerPanel® Business 4 | CyberPower Systems

I installed this on my Windows 10 computer (IP 192.168.1.7). I disabled Personal Edition of CyberPower in my startup services and installed Version 4 of the Business edition that I downloaded from the link above (ppb440-setup.exe).

You launch CyberPower Business (username : admin , password: admin) and it should automatically find your UPS via the USB port connection.

I went to settings, enabled SNMP v1, and created the public and private groups and linked to 0.0.0.0 which means any computer on my network can query the snmp service. I set these to read/write

Secondly you need to download the latest MIB file from CyberPower at MIB Files | CyberPower Systems

Note where this is saved, mine was of course in the Windows Downloads folder. Unzip the file, mine was called MIB002-0001-10.mib and I stored it in a folder called “MIB” off the Downloads folder.

Use an MIB browser, I used iReasoning MIB Browser (Free MIB Browser / MIB Browser / SNMP Browser.)

Install and start the iReasoning Browser. Choose “File…Open…” and go to the folder where you stored the CyberPower MIB file and select it. Start by selecting your ip address or localhost as the address in the top right box. In my image below you will see it is connected to ‘localhost’ since I am running the iReasoning Browser on the same computer the UPS is plugged into. If you are running this on another computer you would have to put in the IP address of the computer attached to the UPS (192.168.1.7 in my case). Easier to just run on the same Windows 10 machine. Note that my HA is running in Docker on a Ubuntu machine elsewhere on my network at 192.168.1.38 but I never need to enter this anywhere to get everything to work.

It’s not super intuitive but start after loading the MIB go down the tree with ‘private…enterprises…cps…products…ups’ and work your way down the folder tree in the MIB file and you will see lots of OIDs you can use. Double click a ‘leaf’ on the tree and it will query the OID and return a value. The OID is listed at the bottom left and the values when you double click are shown on the right hand panel.

You can try any of the OIDs to see which work on your UPS, most were OK on my Value II 1600E but if the OID is not supported it will just tell you that.

Note two things.
First the OIDs from CyberPower need the “.0” at the end, you cannot use just the OID you see in a viewer.
Second, look at the response data, it might be an integer; ticks (e.g. time remaining in my example below); or a series of strings, for example the “Status”, which you can then use to develop the value_template in configuration.yaml. I have many examples below.

Then its time to edit the ‘sensor’ section of your configuration.yaml file.

###############################
#                             #
#            UPS              #
#                             #
###############################
- platform: snmp
  host: 192.168.1.7
  baseoid: .1.3.6.1.4.1.3808.1.1.1.4.2.1.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Output Voltage
  value_template: '{{ (value | int / 10 ) }}'
  unit_of_measurement: "V"
- platform: snmp
  host: 192.168.1.7
  baseoid: .1.3.6.1.4.1.3808.1.1.1.1.1.1.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Model
- platform: snmp
  host: 192.168.1.7
  baseoid: .1.3.6.1.4.1.3808.1.1.1.4.1.1.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Status
  value_template: >
    {% set vals = {'1': 'unknown', '2':'onLine', '3':'onBattery', '4':'onBoost', '5':'sleep', '6':'off', '7':'rebooting'} %}
    {{vals[value]}}
- platform: snmp
  host: 192.168.1.7
  baseoid:  .1.3.6.1.4.1.3808.1.1.1.3.2.6.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Advanced Status
  value_template: >
    {% set vals = {'1': 'normal', '2':'Over Voltage', '3':'Under Voltage', '4':'Frequency failure', '5':'Blackout'} %}
    {{vals[value]}}
- platform: snmp
  host: 192.168.1.7
  baseoid: .1.3.6.1.4.1.3808.1.1.1.4.1.1.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Battery Status
  value_template: >
    {% set vals = {'1': 'unknown', '2':'Normal', '3':'Battery Low'} %}
    {{vals[value]}}
- platform: snmp
  host: 192.168.1.7
  baseoid: .1.3.6.1.4.1.3808.1.1.1.2.2.1.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Battery Capacity
  value_template: '{{ (value | float) }}'
  unit_of_measurement: "%"
- platform: snmp
  host: 192.168.1.7
  baseoid:  .1.3.6.1.4.1.3808.1.1.1.4.2.3.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Load
  value_template: '{{ (value | float) }}'
  unit_of_measurement: "%"
- platform: snmp
  host: 192.168.1.7
  baseoid:  .1.3.6.1.4.1.3808.1.1.1.2.2.2.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Battery Voltage
  value_template: '{{ (value | int / 10 ) }}'
  unit_of_measurement: "V"
- platform: snmp
  host: 192.168.1.7
  baseoid: .1.3.6.1.4.1.3808.1.1.1.2.2.4.0
  accept_errors: 'true'
  community: public
  port: 161
  name: UPS Run Time Remaining
  value_template: >-
    {% set time = (value | int) | int %}
    {% set minutes = ((time % 360000) / 6000) | int%}
    {% set hours = ((time % 8640000) / 360000) | int %}
    {% set days = (time / 8640000) | int %}
    {%- if time < 60 -%}
      Less then 1 min
      {%- else -%}
      {%- if days > 0 -%}
        {{ days }}d
      {%- endif -%}
      {%- if hours > 0 -%}
        {%- if days > 0 -%}
          {{ ' ' }}
        {%- endif -%}
        {{ hours }}hr
      {%- endif -%}
      {%- if minutes > 0 -%}
        {%- if days > 0 or hours > 0 -%}
          {{ ' ' }}
        {%- endif -%}
        {{ minutes }}min
      {%- endif -%}
    {%- endif -%}
- platform: template
  sensors:
    ups_battery_capacity:
      unit_of_measurement: "%"
      value_template: "{{ states('sensor.ups_battery_capacity_2') }}"
      friendly_name: "Battery Capacity"
      icon_template: >
        {% set level = states('sensor.ups_battery_capacity_2') | float | multiply(0.1) | round(0,"floor") | multiply(10)| round(0) %}
        {% if is_state('sensor.ups_status', 'onLine') and is_state('sensor.ups_battery_capacity_2' , '100.0' ) %}
          mdi:battery
        {% elif is_state('sensor.ups_status', 'onLine')  %}
          mdi:battery-charging-{{level}}
        {% else %}
          mdi:battery-{{level}}
        {% endif %}

Note that the template at the bottom creates a smart icon. It shows the level of the battery and the icon has the ‘flash’ symbol on the right if it is charging and does not have the flash if at 100% or running on batteries and discharging. (Thanks to RobC and AndyVR on Discord for this icon code)

the entities card setup

type: entities
entities:
  - entity: sensor.ups_model
    name: Model
    icon: mdi:power-plug
  - entity: sensor.ups_status
    name: Status
    icon: mdi:power
  - entity: sensor.ups_battery_capacity
    name: Battery Capacity
  - entity: sensor.ups_run_time_remaining
    name: Run time remaining
    icon: mdi:av-timer
  - entity: sensor.ups_battery_status
    name: Battery Status
    icon: mdi:car-battery
  - entity: sensor.ups_battery_voltage
    name: Battery Voltage
    icon: mdi:car-battery
  - entity: sensor.ups_output_voltage
    name: Output Volts
    icon: mdi:power-socket-au
  - entity: sensor.ups_advanced_status
    name: Advanced status
  - entity: sensor.ups_load
    icon: mdi:signal-cellular-3
header:
  type: picture
  image: local/ups5.jpg
  tap_action:
    action: none
  hold_action:
    action: none

and the card itself

Note in the image above the battery is at 94% and charging (the flash icon to the right of the battery). This is using the icon created in the ‘sensors’ template

13 Likes

Works like a charm. Literally copy-paste-joy. Thanks!

Is it possible to get the output load or output power values through SNMP? I tried using the MIB Browser, and for some reason the upAdvancedOutputLoad value is locked at 14 and the upsAdvanceOutputPower value returns an error.

If it’s possible I never found it – as you did, the expected field just has a fixed value. If you stumble across an OID, please share. I just report battery %, Battery time and status, and the time gives me an indication of load - not a good one, but at least rough idea.

I never found it either. Strange as it reports this in the web portal so we all know it is there somewhere

To be fair, it’s a consumer UPS (business ones tend to have network cards) and you could probably count on two hands if not one all the consumers who want SNMP monitoring. Or know what SNMP is. Heck, even Windows doesn’t put any real effort in SNMP. I monitor thousands of devices and dozens of vendors for clients, and it seems like every implementation I am finding workaround and mistakes. The typical vendor response is “We make a great monitoring product, use ours”.

The standard is: Standards are dead. :frowning:

Not sure this is going to be an option for everyone, but I ended up passing the USB port through to my Home Assistant VM. I was then able to setup NUT and get the power utilization that way. This is for the Costco sold CyberPower LE850G.

1 Like

Yeah, I use NUT on another UPS on linux, works fine, but I want this UPS to actually shut down my windows PC, so that’s not really a possibility. Though… having said that… never looked into the new windows linux subsystem, I wonder if I can run NUT there.

I just finished getting my WinPC+CP1500pfclcd (blueiris server), my NAS, and my HA pi to safely shut down after a power outage, and so far it’s working. Here’s an overview of what I did…

I installed powerpanel business 4 (local) on the winpc, plugged the USB in, and setup SNMP v1 in powerpanel using the “public community” only (read only, as the NAS really only needs power out traps). Since the software is local, it handles shutting down the winpc. V3 I am I guess too dumb to get working in this case… and everything on my LAN is isolated behind a router, and I don’t let anyone I don’t fully trust on my LAN subnet ever anyways (all openVPN from outside).

On my Synology nas, I just configured DSM for an SNMP UPS, SNMP v1, using the public community, added the IP of the pc running ppb4local, and the NAS immediately showed approval (make/model/states showed up from ppb4, no problemo). So now the NAS will know when the UPS is having issues, and can shutdown as needed. If the nas was another windows pc, I’d just use ppb4 remote on it instead… but thank goodness the NAS knows what to do sans SNMP NMS! (…DSM’s built in “SNMP server” was disabled)

For my pi… I already had a hardware solution for this, lol… an arduino nano with the pi USB supply going to a digitalread, and sending states to HA using the serial sensor. This method is powerful, since you get a bunch of useful io from the nano, and a lot of preprocessing can be handled by the 32u (can program it to suit a TON of different applications). For example I am using a second pin to read my 12VAC doorbell signal, and a third to get my smoke alarm signal wire into HA. You can get into maker land with these things… but I bet half of the HA users are already there.

On a side note, I did try a roundabout way using a docker image of ppb4 local… the idea was to have the USB attached to the NAS, Synology handle shutdown from USB, and the ppb4 local instance would then inform a ppb4 remote instance (installed on the winpc) to shutdown in time. Unfortunately I’m too much a newb, and could not get the container to talk succesfully with USB after trying for hours. So I gave up and experimented with SNMP until I came up with something that worked.

I was updating a lot of things and installed 4.8 of Cyberpower, and I think they have fixed at least some of this.

At .1.3.6.1.4.1.3808.1.1.1.2.2.2.0 I now get battery voltage, and at 1.3.6.1.4.1.3808.1.1.1.4.2.3.0 I get load percentage. I could not get load amps to work.

Battery voltage is weird, I thought these all had 12v batteries (1 or 2), and my CP1500PFCLCDa shows 27.5v (consistent with two 12v’s at about 13.8v). However the CP1000AVRLCD shows 20.1v. It tests good (from powerpanel) and shows 100% charged, but it’s a weird battery voltage for SLA batteries. I searched the Cyberpower site for replacement batteries and it calls out a 12V/9Ah battery, so not sure where this 20.1 is coming from, it looks incorrect. It does match what the Powerpanel says, though, so the problem is in its data acquisition not the SNMP hook.

Anyway, I did not explore all the MIB values, but anyone who had issues before may want to try the new version. Take care to get the local+management (larger) download kit, the management only won’t work.

Just a bit of advice - if like me you’ve had the issue that when you reboot Home Assitant and the PC isn’t currently swtiched on, which marks all of these sensors and Unavaiable and they then don’t come back when you power on your PC, then add
accept_errors: true
to each of your sensors config.

Have updated all of my code above to include the UPS load percentage OID and added

accept_errors: 'true'

to all sensors. This stops them from showing an error if not available when the PC is off as HA starts

I have made a few additions to also include a rough estimate of the output watts calculated by the load and max rated capacity, and thought I’d share it if someone else is interested:

  - platform: snmp
    host: 192.168.1.7
    baseoid: .1.3.6.1.4.1.3808.1.1.1.1.2.7.0
    accept_errors: "true"
    community: public
    port: 161
    name: UPS Rated Capacity
    unit_of_measurement: "W"
  - platform: template
    sensors:
      ups_used_watts:
        unit_of_measurement: "W"
        value_template: "{{ (states('sensor.ups_rated_capacity') | float * (states('sensor.ups_load') | float / 100)) | round(2) }}"
        friendly_name: "UPS Used Watts"
1 Like

DO I need to enable something in the Business Local Power Panel? I am getting 401 - not authorized error for the rest api