Skip to content

Clean-up or legalise: revise status_set() values vs. the NUT standard dictionary #2708

Open

Description

@jimklimov

The "Status data" section in docs/new-drivers.txt defines certain keywords that are "Possible values for status_set", stressing that "Anything else will not be recognized by the usual clients. Coordinate with the nut-upsdev list before creating something new, since there will be duplication and ugliness otherwise."

In fact we do have a number of other values in code, currently:

:; git grep -w status_set | sed 's,^.*\(status_set[^;]*\);.*$,\1,' | sort | uniq -c
      1 docs/new-drivers.txt:   status_set(val) -- add a status word (OB, OL, etc)
      1 docs/new-drivers.txt:Possible values for status_set:
      1 drivers/dstate.c:void status_set(const char *buf)
      1 drivers/huawei-ups2000.c: * be set via status_set(), those are listed in "status_name".
      1 drivers/huawei-ups2000.c: * for status_set(), for example, "OL" or "OB", the field
      1 drivers/usbhid-ups.c:/** Helper to both status_set("CAL") and track last_calibration_start timestamp */
      6 status_set( status_buf )
      1 status_set("ACFAIL")
      1 status_set("ALARM")
     32 status_set("BOOST")
      1 status_set("BY")
     21 status_set("BYPASS")
     12 status_set("CAL")
     17 status_set("CHRG")
      2 status_set("COMMFAULT")
      1 status_set("DEPLETED")
     13 status_set("DISCHRG")
      1 status_set("ECO")
      5 status_set("FSD")
      4 status_set("HB")
      1 status_set("HE")
      1 status_set("LB ")
     60 status_set("LB")
     63 status_set("OB")
     31 status_set("OFF")
      1 status_set("OL BYPASS")
     67 status_set("OL")
     31 status_set("OVER")
      2 status_set("OVERHEAT")
     35 status_set("RB")
      1 status_set("SD")
      5 status_set("TEST")
      1 status_set("TIP")
     27 status_set("TRIM")
      1 status_set((u8 & 0x04) > 0 ? "OL" : "OB")
      1 status_set(alarms->status_value)
      1 status_set(const char *buf)
      1 status_set(ctx->arglist[counter])
      1 status_set(current <= 0 ? "OL" : "OB")
      1 status_set(flag[j].status_name)
      1 status_set(gpioupsfdlocal->rules[ruleNo]->stateName)
      1 status_set(info_value)
      1 status_set(is_online ? (is_off ? "OFF " : "OL ") : "OB ")
      1 status_set(online ? "OL" : "OB")
      1 status_set(ups2000_alarm[i].status_name)
      1 status_set(val)
  • some code, notably nutdrv_qx and its subdrivers, deals with temporary values of statuses like "!OL"; those are further digested inside the driver, e.g. in update_status() method to set or clear status bits in an integer mask, and finally produce standard tokens in ups_status_set() and ups_alarm_set() (rediscovered in research for Add nutdrv_qx driver for Gtec ZP120N #2818 PR discussion)
  • Values like ALARM => upsmon: add ALARM support #415 and introduce further handling and notifiers for ALARM status #2658, and ECO => ecomode_addon-2 #2684 are recent additions, not standardized here yet but elaborated a lot in other parts of the code base, including C++ bindings, clients like upsmon and should be CGI...
    • Note that ALARM is set in dstate.c since before 2007, see 5f42691 - recent PRs just added its handling in upsmon and other parts of code
  • Values like ACFAIL, BY, COMMFAULT, DEPLETED, HE, OVERHEAT, SD, TIP, TEST are not defined
    • HE may be renamed to ECO now that it has led in evolution across the code base; should other advanced power management technology (ESS, ABM) activation states also be aliased to ECO? (WDYT - @desertwitch @masterwishx ?)
    • is TEST same as CAL?
    • what about others?
  • Some values are set from variables or arrays, to be revised separately.
  • One case sets a two-token string right away, and some have tokens followed by space, which is pedantically incorrect.
    • Fix by setting a token at a time, and committing, as NUT status API dictates.
    • I suppose a similar situation can happen in numerous SNMP subdrivers with e.g. info_lkp_default(4, "OL BYPASS"), seen in a cpqpower_pwr_info[] array. Somebody gotta use those strings, right?..
    • While the implementation of status_set() does check that its argument is absent in a collected status_buf string (although since after NUT v2.8.2 release), it relies on strstr matching of the whole argument - this is one way how some drivers can end up with duplicate status values like OL OL BYPASS I suppose.
    • UPDATE: with PR Fix handling of spaces in driver status_set() args #2801 merged, status_set() for arguments with multiple tokens separated or surrounded by spaces should now do the right thing: recurse to add (or not) each non-trivial token independently and so at most once. PR Test for and fix status_set("ALARM"); update code and docs on correct Numeric format usage #2812 further addresses some nuances for status vs. alarms.

Gotta decide what to do with the unknown names - can rename some cases, but what about others? Legalize them into the docs chapter (also concerns "ALARM" and "ECO"), and add handling in C++ bindings, augeas, clients, etc.?

Perhaps more importantly: would such legalization of keywords acceptable in ups.status constitute a bump of NUT protocol/API for formal versioning, as in "clients conforming to protocol N are expected to handle at least tokens X,Y,Z with ascribed meanings" (free about considering, logging or ignoring other tokens, as long as the client does not crash on them)?

CC @clepple @aquette - WDYT?


Interim update (April 2025): in PR #2850 the more questionable bits about ECO et al were revised, so we do not release a NUT standard naming in v2.8.3 that would be likely to change in a release or two. So some data points and commands became experimental.* and documented as such, and others appeared serving "opaque string" values related to vendor-defined buzzwords. There was a fair amount of technical change in several PRs leading up to it and linked to this issue.

It may be reasonable to actually keep those instant commands this way internally to benefit from usbhid tables mapping these operations to HID tree nodes and values, just not expose to users after some point, and wrap them in an externally available NUT-standard command with an argument. An unfinished PoC in this direction is parked at https://github.com/jimklimov/nut/tree/issue-2708-instcmd - see more at #2850 (comment)

For now, putting the matter to rest, sort of - the currently merged code seems good enough to go out in NUT v2.8.3, and the rest can be elaborated in later releases.

Activity

  1. added
    refactor/fightwarnPR or issue proposal to improve code maintainability without functional changes, or to fix warnings
    portabilityWe want NUT to build and run everywhere possible
    on Dec 3, 2024
  2. added this to the 2.8.4 milestone on Dec 3, 2024
  3. desertwitch commented on Dec 3, 2024

    @desertwitch
    Contributor

    I will give this some more thought, but condensing HE and ESS into ECO would make sense to me. In general - I think - UPS statuses should foremost denote important conditions of the UPS (that the user should more or less immediately notice), so - I think - it makes sense to tidy this up some. ABM is more related to internal handling of battery management (resulting in respective charging/discharging statuses), so this one I'd say is not worthy a status of its own (and currently isn't one, rather ABM enabled/disabled can be checked via their exposed other variables instead).

  4. gdt commented on Dec 3, 2024

    @gdt
    Contributor

    Assorted thoughts:

    • the protocol spec ought to direct clients to ignore status values they don't understand. If not, we should say that

    • in general, the point is to abstract a UPS into generic behavior/status that can be understood without knowing the details. So I think we need to ask not "what word do we use for proprietary feature foo" but "what does this feature mean in general, and then how do we name that".

    • There are probably lots of oddball things that should be cleaned up, and we should just do that, separately from any hard questions about common/abstractable tags.

    • There are clearly going to be device-specific or manufacturer-specific semantics that are too complicated and not amenabel to a multi-vendor abstraction. Probably those should just not go into status. Maybe, we should have a way to have a device-specific status object carried in nut, which is perhaps json, with no expectation that software can process it, unless it is specifically coded for a private interface. And then try not to use this mechanism.

    • For ECO, I don't think we should have a word that means "it is eco as the vendor names it". I think we should define what it means and then for each vendor map that status to ECO if it meets our definition. I don't even know what it means, and why someone would operate less efficiently. I am guessing that it's a switch between "operate on inverter all the time" and "passthrough, but switch to inverter if input fails or goes out of bounds". Historically that's been a fixed design parameter. So maybe instead we should have something that reports "device is on inverter being operated by input" that turns on and off.

    • This means that ECO will appear on devices that always do standby, and will not appear on devices that are always running the inverter. So ECO is the wrong word; it should be something that indicates "input ok and inverter in use". Or maybe it's just "inverter in use" and that comes on when any device goes on battery. I'm not really sure what the right answer is. My point is don't accept any one vendor's labels, and don't accept content-free marketing labels.

    • It is very important as things get more complicated that simpler clients get the correct understanding. So the basics of is the UPS providing output power, is the input AC ok, is the UPS operating from the battery, need to be reliably indicated by the older statuses even if we add new ones. It's not ok to split a status into two parts and have something expecting the old name to cover it all find the new one instead and ignore it. This is like in openstreetmap where we have amenity=foo and then if that gets complicated we keep that and have foo=bar or foo=baz, so that things that only as "is this a foo" get the right answer relative to their ability to comprehend.

    • I think 99% of the value in clients is grasping

      • is the UPS providing output power normally while in put is ok?
      • Is the UPS providing output power from battery?
      • are there any alarms?
      • what are the input/output V, freq, load VA, battery V, battery runtime?
        and after that it's details that are not such a big deal.
  5. masterwishx commented on Dec 3, 2024

    @masterwishx
    Contributor
    • HE may be renamed to ECO now that it has led in evolution across the code base; should other advanced power management technology (ESS, ABM) activation states also be aliased to ECO?

    Sorry for delay.
    Like you said HE =ECO 100% can be renamed.

    ESS = I think something like advanced ECO = when converter is on (for switch to online in 2ms instead 10ms in ECO) but in bypass like in ECO mode.
    So it's a little different from ECO mode also only two enterprise model in Eaton support it (9390,9395) like I wrote in comments in code.
    So not sure if can be renamed becouse of reasons above.

    ABM ≠ ECO.
    Like @desertwitch said it's Advanced battery monitoring for charger, also we have variables like battery.charger.abm.status to see if enabled and battery.charger.type that show if charger in ABM or Constant charge.

    I hope I understood the question right...

  6. masterwishx commented on Dec 3, 2024

    @masterwishx
    Contributor

    https://eaton-powerware.ru/ess.html
    https://www.a-energy.ru/article/eaton-ess-tech/

    Some info from copilot:

    ESS is an innovative technology designed to significantly enhance the energy efficiency of uninterruptible power supplies (UPSs) without compromising load protection. Here are the key points about ESS:

    What Is ESS?
    Energy Saver System (ESS) is a mode of operation available in certain Eaton UPS models.
    Its primary goal is to maximize efficiency while ensuring reliable power delivery to connected loads.
    How Does ESS Work?
    In normal power conditions (when the mains supply quality is good), the UPS operates in ESS mode.
    During ESS mode, the UPS feeds the loads directly from the mains supply (similar to bypass mode).
    The losses in ESS mode are minimal—typically around 1%—because there are no additional devices in the power path between the mains supply and the loads.
    Seamless Transition:
    If the mains supply fails or its quality deteriorates, the UPS switches to double-conversion mode within milliseconds.
    This rapid transition ensures that connected equipment remains protected even during power disturbances.
    Benefits of ESS:
    Energy Efficiency: ESS allows UPSs to achieve up to 99% efficiency across their entire operating range.
    Reliability: ESS maintains UPS reliability by using existing functional elements without introducing complexity.
    Minimal Wastage: ESS minimizes energy wastage, making it ideal for data centers and critical applications.
    Applications for ESS:
    ESS is suitable for various scenarios, including data centers, industrial facilities, and critical infrastructure.
    Anywhere energy efficiency and reliability are essential, ESS shines.
    Remember, ESS is like the UPS doing a little energy-saving dance—keeping your power efficient while ensuring your devices stay protected! If you have more questions or need further details, feel free to ask! 😊🔌

  7. masterwishx commented on Dec 3, 2024

    @masterwishx
    Contributor

    Oh seems I didn't got the question so right.

    So I think HE should be renamed to ECO status.
    ESS can be ESS status, not much ups have it.

    ABM no need for status as per above comments. :)

  8. jimklimov commented on Dec 3, 2024

    @jimklimov
    MemberAuthor

    It's not ok to split a status into two parts and have something expecting the old name to cover it all find the new one instead and ignore it.

    This point is a bit harder historically. Gotta check what different drivers do, but according to notes in the document, for some time now (since before my time IIRC) the CHRG and DISCHRG tokens in ups.status are being phased away in favor of possibly more detailed battery.charger.status, for example. A client expecting either one of these clues may not see the full picture with each and every driver. (The "gotta check" part is whether all drivers do set the status tokens along with the dstate data point.)

    For ECO, I don't think we should have a word that means "it is eco as the vendor names it". I think we should define what it means and then for each vendor map that status to ECO if it meets our definition. I don't even know what it means, and why someone would operate less efficiently...

    To me, the "ECO" definition is fundamentally vague and "as vendor says", with one common feature being that it is some togglable trade-off between power overheads wasted by the UPS to do its job with different strategies, and reliability. Generally it boils down to either being hardwired for two power circuits with inverter and battery in the middle always active (marketed in the past decades as an "on-line UPS"), or hardwired for the inverter being inactive most of the time - with less waste and maybe less wear (marketed as "line-interactive"), or software-defined to have a run-time choice between whichever options the vendor gives. The "ECO" token in ups.status IMHO should convey "currently running less wasteful than I know I can be" and if there are deeper details (e.g. which of many strategies is now in place) - that can be sought in key-value data points.

    As such, I think the "ECO" ups.status also applies to "ESS mode" being active, as one of such vaguely-similar implementations of minimizing UPS overhead in the power budget.

  9. masterwishx commented on Dec 3, 2024

    @masterwishx
    Contributor

    As such, I think the "ECO" ups.status also applies to "ESS mode" being active, as one of such vaguely-similar implementations of minimizing UPS overhead in the power budget

    Sure you right, also as i wrote befor seems only 2 enterprise models using this mode, but after merging essmode status maybe they users will use NUT :)

  10. masterwishx commented on Dec 3, 2024

    @masterwishx
    Contributor

    To me, the "ECO" definition is fundamentally vague and "as vendor says", with one common feature being that it is some togglable trade-off between power overheads wasted by the UPS to do its job with different strategies, and reliability. Generally it boils down to either being hardwired for two power circuits with inverter and battery in the middle always active (marketed in the past decades as an "on-line UPS"), or hardwired for the inverter being inactive most of the time - with less waste and maybe less wear (marketed as "line-interactive"), or software-defined to have a run-time choice between whichever options the vendor gives

    The only Confusing thing with ECO I found was
    Ellipse ECO ups with ECO control that other technology for outlets to disable.

  11. 155 remaining items

  12. added this to the 2.8.4 milestone on Apr 3, 2025
  13. modified the milestones: 2.8.4, 2.8.5 on Jul 29, 2025
  14. modified the milestones: 2.8.5, 2.8.6 on Mar 21, 2026
  15. added a commit that references this issue on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    NUT protocolsdocumentationportabilityWe want NUT to build and run everywhere possiblerefactor/fightwarnPR or issue proposal to improve code maintainability without functional changes, or to fix warningsupsmon

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions