Add more sensor prefixes to NUT (outlet groups)

Hello everyone, I’m using the NUT Integration to track some UPS’s in my home, mostly Eaton rack-mount units, that have outlet groups. These outlet groups are presented in NUT as the output below but aren’t picked up by Home Assistant NUT Integration as it seems to only pick up ups , battery , input and output prefixes with the default config.

Specifically, I’m looking to add outlet, outlet1 and outlet2 values so they can be tracked in Home Assistant

My end goal is to be able to track each outlet group’s power in Home Assistant and use the Integration plug-in to convert them to kWh for Energy Dashboard Thanks in advance for any assistance.

Example from my NUT diagnostics form inside Home Assistant showing it sees the extra values form the UPS:

"nut_data": {
      "ups_list": {
        "unraid-ups": "Eaton 5PX UPS on Server Rack in repeater mode"
      },
      "status": {
        "battery.capacity": "12.00",
        "battery.charge": "100",
        "battery.charge.low": "20",
        "battery.charge.restart": "0",
        "battery.charger.status": "resting",
        "battery.energysave": "no",
        "battery.protection": "yes",
        "battery.runtime": "9234",
        "battery.type": "PbAc",
        "device.mfr": "EATON",
        "device.model": "Eaton 5PX 3000",
        "device.serial": "12345ABCDE",
        "device.type": "ups",
        "driver.name": "dummy-ups",
        "driver.parameter.mode": "repeater",
        "driver.parameter.pollinterval": "2",
        "driver.parameter.port": "[email protected]",
        "driver.parameter.synchronous": "no",
        "driver.version": "2.7.4",
        "driver.version.internal": "0.14",
        "input.current": "0.00",
        "input.frequency": "60.0",
        "input.frequency.extended": "no",
        "input.frequency.nominal": "60",
        "input.sensitivity": "normal",
        "input.transfer.boost.low": "102",
        "input.transfer.high": "151",
        "input.transfer.low": "89",
        "input.transfer.trim.high": "132",
        "input.voltage": "120.4",
        "input.voltage.extended": "no",
        "input.voltage.nominal": "120",
        "outlet.1.autoswitch.charge.low": "0",
        "outlet.1.current": "1.10",
        "outlet.1.delay.shutdown": "65535",
        "outlet.1.delay.start": "0",
        "outlet.1.desc": "PowerShare Outlet 1",
        "outlet.1.id": "1",
        "outlet.1.power": "132",
        "outlet.1.powerfactor": "59.00",
        "outlet.1.realpower": "78",
        "outlet.1.status": "on",
        "outlet.1.switchable": "yes",
        "outlet.2.autoswitch.charge.low": "0",
        "outlet.2.current": "2.50",
        "outlet.2.delay.shutdown": "65535",
        "outlet.2.delay.start": "0",
        "outlet.2.desc": "PowerShare Outlet 2",
        "outlet.2.id": "2",
        "outlet.2.power": "301",
        "outlet.2.powerfactor": "87.00",
        "outlet.2.realpower": "262",
        "outlet.2.status": "on",
        "outlet.2.switchable": "yes",
        "outlet.current": "0.50",
        "outlet.desc": "Main Outlet",
        "outlet.id": "0",
        "outlet.power": "94",
        "outlet.powerfactor": "97.00",
        "outlet.realpower": "92",
        "outlet.switchable": "no",
        "output.current": "4.10",
        "output.frequency": "60.0",
        "output.frequency.nominal": "60",
        "output.powerfactor": "0.87",
        "output.voltage": "120.4",
        "output.voltage.nominal": "120",
        "ups.beeper.status": "enabled",
        "ups.delay.shutdown": "20",
        "ups.delay.start": "30",
        "ups.efficiency": "94",
        "ups.firmware": "02",
        "ups.load": "17",
        "ups.load.high": "105",
        "ups.mfr": "EATON",
        "ups.model": "Eaton 5PX 3000",
        "ups.power": "494",
        "ups.power.nominal": "2880",
        "ups.productid": "ffff",
        "ups.realpower": "432",
        "ups.realpower.nominal": "2700",
        "ups.serial": "12345ABCDE",
        "ups.shutdown": "enabled",
        "ups.start.auto": "yes",
        "ups.start.battery": "yes",
        "ups.start.reboot": "yes",
        "ups.status": "OL",
        "ups.test.interval": "604800",
        "ups.test.result": "Done and passed",
        "ups.timer.shutdown": "0",
        "ups.timer.start": "0",
        "ups.type": "offline / line interactive",
        "ups.vendorid": "0463"
      }
    }

I haven’t seen a reply to I went ahead and took a stab at creating the sensor definitions that would need to be added to core/homeassistant/components/nut/const.py. I used existing sensor definitions wherever possible or the next closest definition so hopefully that are correct.

I have no idea if changes are required anywhere else for these new sensor definitions but am willing to help.

The GitHub specifically mentions putting Feature Requests on this forum as opposed to opening an Issue or Pull Request on Github, so I’m just following those instructions.

These changes includes 3 new sections that are common to Eaton UPS’s: outlet, outlet1 and outlet2 and all their values. The example values returned by NUT for these are seen in my first post.

I’ve also added a new entry under the output section for Power Factor as well.

I just used ups.load as a base for the 4 new Power Factor values, but if there is a better definition then using Percentage for Power Factor, I welcome any feedback.

    "outlet.1.autoswitch.charge.low": SensorEntityDescription(
        key="outlet.1.autoswitch.charge.low",
        name="Outlet 1 Autoswitch Charge Low",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.current": SensorEntityDescription(
        key="outlet.1.current",
        name="Outlet 1 Current",
        icon="mdi:flash",
        native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.delay.shutdown": SensorEntityDescription(
        key="outlet.1.delay.shutdown",
        name="Outlet 1 Shutdown Delay",
        native_unit_of_measurement=TIME_SECONDS,
        device_class=SensorDeviceClass.DURATION,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.delay.start": SensorEntityDescription(
        key="outlet.1.delay.start",
        name="Outlet 1 Start Delay",
        native_unit_of_measurement=TIME_SECONDS,
        device_class=SensorDeviceClass.DURATION,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.desc": SensorEntityDescription(
        key="outlet.1.desc",
        name="Outlet 1 Description",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.id": SensorEntityDescription(
        key="outlet.1.id",
        name="Outlet 1 Identifier",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.power": SensorEntityDescription(
        key="outlet.1.power",
        name="Outlet 1 Apparent Power",
        icon="mdi:flash",
        native_unit_of_measurement=POWER_VOLT_AMPERE,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.powerfactor": SensorEntityDescription(
        key="outlet.1.powerfactor",
        name="Outlet 1 Power Factor",
        icon="mdi:gauge",
        native_unit_of_measurement=PERCENTAGE,
        state_class=SensorStateClass.MEASUREMENT,
    ),
    "outlet.1.realpower": SensorEntityDescription(
        key="outlet.1.realpower",
        name="Outlet 1 Real Power",
        native_unit_of_measurement=POWER_WATT,
        device_class=SensorDeviceClass.POWER,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.status": SensorEntityDescription(
        key="outlet.1.status",
        name="Outlet 1 Status",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.1.switchable": SensorEntityDescription(
        key="outlet.1.switchable",
        name="Outlet 1 Switchable",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.autoswitch.charge.low": SensorEntityDescription(
        key="outlet.2.autoswitch.charge.low",
        name="Outlet 1 Autoswitch Charge Low",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.current": SensorEntityDescription(
        key="outlet.2.current",
        name="Outlet 2 Current",
        icon="mdi:flash",
        native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.delay.shutdown": SensorEntityDescription(
        key="outlet.2.delay.shutdown",
        name="Outlet 2 Shutdown Delay",
        native_unit_of_measurement=TIME_SECONDS,
        device_class=SensorDeviceClass.DURATION,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.delay.start": SensorEntityDescription(
        key="outlet.2.delay.start",
        name="Outlet 2 Start Delay",
        native_unit_of_measurement=TIME_SECONDS,
        device_class=SensorDeviceClass.DURATION,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.desc": SensorEntityDescription(
        key="outlet.2.desc",
        name="Outlet 2 Description",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.id": SensorEntityDescription(
        key="outlet.2.id",
        name="Outlet 2 Identifier",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.power": SensorEntityDescription(
        key="outlet.2.power",
        name="Outlet 2 Apparent Power",
        icon="mdi:flash",
        native_unit_of_measurement=POWER_VOLT_AMPERE,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.powerfactor": SensorEntityDescription(
        key="outlet.2.powerfactor",
        name="Outlet 2 Power Factor",
        icon="mdi:gauge",
        native_unit_of_measurement=PERCENTAGE,
        state_class=SensorStateClass.MEASUREMENT,
    ),
    "outlet.2.realpower": SensorEntityDescription(
        key="outlet.2.realpower",
        name="Outlet 2 Real Power",
        native_unit_of_measurement=POWER_WATT,
        device_class=SensorDeviceClass.POWER,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.status": SensorEntityDescription(
        key="outlet.2.status",
        name="Outlet 2 Status",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.2.switchable": SensorEntityDescription(
        key="outlet.2.switchable",
        name="Outlet 2 Switchable",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.current": SensorEntityDescription(
        key="outlet.current",
        name="Outlet Current",
        icon="mdi:flash",
        native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.desc": SensorEntityDescription(
        key="outlet.desc",
        name="Outlet Description",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.id": SensorEntityDescription(
        key="outlet.id",
        name="Outlet Identifier",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.power": SensorEntityDescription(
        key="outlet.power",
        name="Outlet Apparent Power",
        icon="mdi:flash",
        native_unit_of_measurement=POWER_VOLT_AMPERE,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.powerfactor": SensorEntityDescription(
        key="outlet.powerfactor",
        name="Outlet Power Factor",
        icon="mdi:gauge",
        native_unit_of_measurement=PERCENTAGE,
        state_class=SensorStateClass.MEASUREMENT,
    ),
    "outlet.realpower": SensorEntityDescription(
        key="outlet.realpower",
        name="Outlet Real Power",
        native_unit_of_measurement=POWER_WATT,
        device_class=SensorDeviceClass.POWER,
        state_class=SensorStateClass.MEASUREMENT,
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "outlet.switchable": SensorEntityDescription(
        key="outlet.switchable",
        name="Outlet Switchable",
        icon="mdi:information-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        entity_registry_enabled_default=False,
    ),
    "output.powerfactor": SensorEntityDescription(
        key="output.powerfactor",
        name="Power Factor",
        icon="mdi:gauge",
        native_unit_of_measurement=PERCENTAGE,
        state_class=SensorStateClass.MEASUREMENT,
    ),

I’ve updated the list to fix a few that were not set as Diagnostic values and changed the ‘realpower’ values to not be Diagnostic Values and be Enabled by default which is how the current ‘watts’ value was defined.

I have pushed the ‘const.py’ file to my local Home Assistant Docker and recreated a NUT integration to my Eaton UPS and it loaded the new values correctly in my testing, would be nice to have someone else verify it as well though.

More details of the changes in the Pull Request I created on GutHub here: Update const.py to include Outlet Groups on Eaton UPS's by axipher · Pull Request #81367 · home-assistant/core · GitHub

It’s my first time in a long time doing a Pull Request, but it seems like the only way to get this to work.