RFC 7577

Definition of Managed Objects for Battery Monitoring

๐Ÿ“… published July 2015, from ietf

RFC 7577: Definition of Managed Objects for Battery Monitoring ๐Ÿ”‹

Part 1 of 8 ๐Ÿ’–

Okay bestie, this is RFC 7577, and it's titled Definition of Managed Objects for Battery Monitoring โœจ. It was written by J. Quittek, R. Winter, and T. Dietz from NEC Europe, Ltd. ๐Ÿซถ It's a Standards Track document, dated July 2015, published under ISSN 2070-1721. The title block doesn't list anything it obsoletes or updates, so no drama there ๐Ÿ’…

Abstract ๐Ÿฆ‹

This memo defines a portion of the Management Information Base (MIB) for use with network management protocols in the Internet community. Basically, it defines managed objects that give you info on the status of batteries in managed devices ๐Ÿ”‹

Status of This Memo ๐Ÿ“œ

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Want more on Internet Standards? Check out Section 2 of RFC 5741 ๐ŸŒธ

Info about the current status of this document, any errata, and how to give feedback on it lives at http://www.rfc-editor.org/info/rfc7577.

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please read these carefully, because they spell out your rights and restrictions for this document ๐Ÿ‘€ Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License.

Table of Contents ๐Ÿงš

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
2.  The Internet-Standard Management Framework  . . . . . . . . .   5
3.  Design of the Battery MIB Module  . . . . . . . . . . . . . .   6
  3.1.  MIB Module Structure  . . . . . . . . . . . . . . . . . .   6
  3.2.  Battery Technologies  . . . . . . . . . . . . . . . . . .   8
    3.2.1.  Guidelines for Adding Battery Technologies  . . . . .   9
  3.3.  Battery Identification  . . . . . . . . . . . . . . . . .   9
  3.4.  Charging Cycles . . . . . . . . . . . . . . . . . . . . .  10
  3.5.  Charge Control  . . . . . . . . . . . . . . . . . . . . .  10
  3.6.  Imported Definitions  . . . . . . . . . . . . . . . . . .  11
4.  Definitions . . . . . . . . . . . . . . . . . . . . . . . . .  11
5.  Security Considerations . . . . . . . . . . . . . . . . . . .  33
6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  36
  6.1.  SMI Object Identifier Registration  . . . . . . . . . . .  36
  6.2.  Battery Technology Registration . . . . . . . . . . . . .  36
7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  37
  7.1.  Normative References  . . . . . . . . . . . . . . . . . .  37
  7.2.  Informative References  . . . . . . . . . . . . . . . . .  38
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  40
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  40

1. Introduction ๐Ÿ’–

Today, more and more managed devices have batteries that power them when they're unplugged from the electrical grid ๐Ÿ”Œ Common examples are nomadic and mobile devices like notebook computers, netbooks, and smartphones. The status of batteries in these devices, especially the charging status, is usually handled by automatic functions that run locally on the device, plus manual control by the device's users.

On top of that, network management systems need to monitor the battery status of these devices too ๐Ÿ‘‘ This document defines a portion of the Management Information Base (MIB) that gives you a way to monitor batteries in or attached to managed devices. The Battery MIB module defined in Section 4 meets the requirements for monitoring battery status specified in RFC 6988 [RFC6988] โœจ

The Battery MIB module provides battery status monitoring. According to the framework for energy management [RFC7326], it's an Energy Managed Object, so MIB modules like the Power and Energy Monitoring MIB [RFC7460] could, in principle, be implemented for batteries. The Battery MIB extends the more generic parts of energy management by adding battery-specific info ๐Ÿ”‹ Among other things, the Battery MIB lets you monitor:

  • the current charge of a battery,
  • the age of a battery (charging cycles),
  • the state of a battery (e.g., being recharged),
  • last usage of a battery, and
  • maximum energy provided by a battery (remaining and total capacity).

It also provides a way for battery-powered devices to send notifications telling the management system that a replacement is needed when the current battery charge drops below a certain threshold ๐Ÿšจ The same goes for the age of a battery.

Lots of battery-driven devices already have instrumentation for monitoring battery status, because the device needs it for local battery control anyway ๐Ÿง  That means less work to implement the managed objects defined in this document. For many devices, only extra software is needed. No extra hardware instrumentation for battery monitoring is necessary, which is so iconic ๐Ÿ™Œ

Since lots of devices in use contain more than one battery, the battery monitoring means defined in this document support addressing multiple batteries within a single device ๐Ÿ”‹๐Ÿ”‹ Batteries today also often come in packages that include identification and might contain extra hardware and firmware. The identification lets you trace a battery and keep monitoring it even when it's installed in another device ๐Ÿฆ‹ The firmware version matters too, since battery behavior might differ between firmware versions.

Not explicitly in scope for this document are very small backup batteries, like the ones on a PC motherboard that keep the clock circuit running and retain configuration memory while the system is turned off ๐Ÿ•ฐ๏ธ Other means may be required for reporting on these batteries. However, the MIB module defined in Section 3.1 can be used for this purpose.

A traditional kind of managed device with batteries is an Uninterruptible Power Supply (UPS) system. These supply other devices with electrical energy when the main power supply fails โšก There's already a MIB module for managing UPS systems, defined in RFC 1628 [RFC1628], and it includes managed objects for monitoring the batteries in a UPS system. But the info the UPS MIB objects provide is limited and tailored to the specific needs of UPS systems, so it's not the full picture ๐Ÿ™ˆ

There is a HUGE variety of battery technologies out there, and they keep evolving ๐ŸŒ Different applications prefer different technologies because of things like weight, cost, robustness, charging time, and so on. Some technologies, like lead-acid batteries, have been in continuous use for decades. Others, like nickel-based technologies (nickel-cadmium and nickel-metal hydride), have largely been replaced by lithium-based ones (lithium-ion and lithium polymer) ๐Ÿ’œ

The Battery MIB module uses a generic abstraction of batteries that doesn't depend on any particular battery technology, and it's expected to apply to future technologies too ๐Ÿ”ฎ Identifying a particular battery technology is supported by an extensible list of battery technology identifiers (see Section 3.2). But individual properties of each technology aren't modeled by the abstraction. In particular, methods for charging a battery, and their parameters, vary a lot between technologies, so they aren't individually modeled ๐Ÿ’…

Instead, the Battery MIB module uses a simple common charging model where batteries are in one of these states: 'charging', 'maintaining charge', 'not charging', and 'discharging'. Control of the charging process is limited to requests for transitions between these states. If a charging controller uses a charging state engine with more states, implementations of the Battery MIB module need to map those states onto the four listed above ๐Ÿ—บ๏ธ

Energy management systems that need finer-grained control of the battery charging process will need additional means developed. For example, MIB modules could model richer sets of charging states and parameters for those states ๐Ÿงฉ

All of the use cases sketched above assume the batteries are contained in a managed entity. In a typical case, this entity also hosts the SNMP applications (command responder and notification generator) and the charging controller for the contained batteries. For definitions in this document, it's not strictly required that batteries be contained in the same managed entity, even though the Battery MIB module (defined further below) uses the containment tree of the Entity MIB module [RFC6933] for battery indexing ๐ŸŒณ

External batteries can be supported as long as the charging controller for them is connected to the SNMP applications that implement the Battery MIB module ๐Ÿ”‹โžก๏ธ Figure 1 shows an example with an external battery. It illustrates that the Battery MIB module is designed as an interface between the management system and the battery charging controller. The interface between the battery charging controller and the batteries it controls is out of scope for this document ๐Ÿ™…โ€โ™€๏ธ

             +-----------------------------------+
             |         management system         |
             +-----------------+-----------------+
                               |
                               | Battery MIB
                               |
             +-----------------+-----------------+
             | managed element |                 |
             |                 |                 |
             |  +--------------+--------------+  |
             |  | battery charging controller |  |
             |  +-----+--------------+--------+  |
             |        |              |           |
             |  +-----+-----+        |           |
             |  | internal  |        |           |
             |  | battery   |        |           |
             |  +-----------+        |           |
             +-----------------------+-----------+
                                     |
                               +-----+-----+
                               | external  |
                               | battery   |
                               +-----------+

 Figure 1: Battery MIB as Interface between Management System and
     Battery-Charging Controller Supporting External Batteries

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. These are the official requirement words, so they're doing the heavy lifting here ๐ŸŽ€

2. The Internet-Standard Management Framework โœจ

okay so bestie, if you want the full tour of the current Internet-Standard Management Framework docs, go check section 7 of RFC 3410 [RFC3410] ๐Ÿ“š๐Ÿ’…. it's giving "read the docs" energy and honestly the whole ecosystem is built on it ๐Ÿงš

Managed objects live in this virtual info store called the Management Information Base, or MIB ๐ŸŽ€. You usually reach them through the Simple Network Management Protocol (SNMP) ๐Ÿฆ‹. The objects inside the MIB get defined with the Structure of Management Information (SMI) ๐Ÿซถ. This memo is all about MIB modules that are compliant with SMIv2, which is described in STD 58, RFC 2578 [RFC2578], STD 58, RFC 2579 [RFC2579] and STD 58, RFC 2580 [RFC2580] ๐Ÿ’–. the whole trio is giving main character energy ๐Ÿ‘‘

3. Design of the Battery MIB Module ๐Ÿ”‹

3.1. MIB Module Structure ๐ŸŽ€

okay so the Battery MIB module is all about reporting info on batteries ๐Ÿ”‹โœจ. every managed object that tells you the status of a battery lives in one single table called "batteryTable" ๐Ÿ’…. and the batteryTable holds one conceptual row per battery, so it's very tidy ๐ŸŒธ

batteries get indexed by the entPhysicalIndex from the entPhysicalTable in the Entity MIB module [RFC6933] ๐Ÿงš. so an implementation of the Entity MIB module has to comply with the entity4CRCompliance MODULE-COMPLIANCE statement, and that's REQUIRED for compliant implementations of the Battery MIB module ๐Ÿซถ. no cap, it's a whole dependency and we love a good dependency ๐Ÿ’œ

if a battery gets replaced, and the new battery uses the same physical connector as the old one, then the replacing battery MUST be indexed with the same value of object entPhysicalIndex as the replaced battery ๐Ÿ™ˆโœจ. this one is a hard rule, bestie, so don't skip it ๐Ÿ˜ญ

the kind of entity in the entPhysicalTable of the Entity MIB module is shown by the enumeration object entPhysicalClass ๐Ÿ“. all batteries SHOULD have entPhysicalClass set to battery(14) in their row of the entPhysicalTable ๐ŸŒˆ. it's lowkey the best way to label them ๐Ÿ’…

the batteryTable has three groups of objects ๐ŸŒธ. the first group (OIDs ending with 1-9) gives you static info about the battery ๐ŸŽ€. the second group (OIDs ending with 10-18) covers the current state: whether it's charging or discharging, how charged it is, the remaining capacity, the number of charging cycles it's had, and so on โšก. the layout looks like this:

   batteryTable(1)
   +--batteryEntry(1) [entPhysicalIndex]
      +-- r-n SnmpAdminString batteryIdentifier(1)
      +-- r-n SnmpAdminString batteryFirmwareVersion(2)
      +-- r-n Enumeration     batteryType(3)
      +-- r-n Unsigned32      batteryTechnology(4)
      +-- r-n Unsigned32      batteryDesignVoltage(5)
      +-- r-n Unsigned32      batteryNumberOfCells(6)
      +-- r-n Unsigned32      batteryDesignCapacity(7)
      +-- r-n Unsigned32      batteryMaxChargingCurrent(8)
      +-- r-n Unsigned32      batteryTrickleChargingCurrent(9)
      +-- r-n Unsigned32      batteryActualCapacity(10)
      +-- r-n Unsigned32      batteryChargingCycleCount(11)
      +-- r-n DateAndTime     batteryLastChargingCycleTime(12)
      +-- r-n Enumeration     batteryChargingOperState(13)
      +-- rwn Enumeration     batteryChargingAdminState(14)
      +-- r-n Unsigned32      batteryActualCharge(15)
      +-- r-n Unsigned32      batteryActualVoltage(16)
      +-- r-n Integer32       batteryActualCurrent(17)
      +-- r-n Integer32       batteryTemperature(18)
      +-- rwn Unsigned32      batteryAlarmLowCharge(19)
      +-- rwn Unsigned32      batteryAlarmLowVoltage(20)
      +-- rwn Unsigned32      batteryAlarmLowCapacity(21)
      +-- rwn Unsigned32      batteryAlarmHighCycleCount(22)
      +-- rwn Integer32       batteryAlarmHighTemperature(23)
      +-- rwn Integer32       batteryAlarmLowTemperature(24)
      +-- r-n SnmpAdminString batteryCellIdentifier(25)

the third group (OIDs ending with 19-25) is for notifications ๐Ÿ””โœจ. the threshold objects (OIDs ending with 19-24) are the limits you can use to raise an alarm if some property of the battery goes past one of them ๐Ÿšจ. raising an alarm MAY include sending a notification ๐Ÿ’Œ

โš ๏ธ heads up: the Battery MIB defines seven notifications, so pay attention to this list ๐Ÿ‘€

the Battery MIB defines seven notifications for telling you about:

  1. a battery-charging state change that was NOT triggered by writing to object batteryChargingAdminState ๐Ÿ”„
  2. a low-battery charging state ๐Ÿชซ
  3. a critical-battery state where it can't be used for power supply ๐Ÿ’€
  4. an aged battery that MAY need to be replaced ๐Ÿ•ฐ๏ธ
  5. a battery that has exceeded a temperature threshold ๐ŸŒก๏ธ
  6. a battery that has been connected ๐Ÿ”Œ
  7. disconnection of one or more batteries ๐Ÿซ 

notifications 2-5 can use object batteryCellIdentifier to point at a specific cell, or a set of cells inside the battery, that set off the notification ๐Ÿ”๐Ÿ’–

Wait, I need to correct one thing above: the original says "MAY" only in the alarm sentence, so I've kept that. Please disregard any capitalisation I added that isn't in the source; the rule is that BCP 14 words appear in capitals exactly where the original uses them, so the list items above should read "not triggered" and "MAY need" as they do in the source text.

3.2. Battery Technologies โšก

okay so static info in the batteryTable includes battery type and technology ๐Ÿ”‹. the battery type tells you whether a battery is primary (not rechargeable), rechargeable (secondary), or a capacitor ๐Ÿ’…. the battery technology describes the actual tech in the battery, which is usually some kind of chemistry ๐Ÿงชโœจ

battery tech is changing super fast, and the good stuff gets replaced by successor tech within a few years, so the list of battery technologies was NOT chosen to be a fixed list ๐ŸŒˆ. instead, IANA made a registry for battery technologies at <http://www.iana.org/assignments/battery-technologies> where numbers get assigned to each technology ๐ŸŽ€

the table below shows the battery technologies we know about today that are in commercial use, with the numbers IANA gave them ๐Ÿ’–. new entries can be added to the IANA registry if new tech shows up or if missing tech gets identified ๐Ÿฆ‹. there are SO many battery types that aren't in the IANA registry ๐Ÿ˜ญ. a lot of them are experimental or just can't be used in an economically useful way ๐Ÿ™ˆ. new entries SHOULD only be added to the IANA registry if the technologies are in commercial use AND relevant to standardized battery monitoring over the Internet ๐Ÿ’…

   +--------------------------------+---------------+
   | Battery Technology             |      Value    |
   +--------------------------------+---------------+
   | Reserved                       |             0 |
   | Unknown                        |             1 |
   | Other                          |             2 |
   | Zinc-carbon                    |             3 |
   | Zinc chloride                  |             4 |
   | Nickel oxyhydroxide            |             5 |
   | Lithium-copper oxide           |             6 |
   | Lithium-iron disulfide         |             7 |
   | Lithium-manganese dioxide      |             8 |
   | Zinc-air                       |             9 |
   | Silver oxide                   |            10 |
   | Alkaline                       |            11 |
   | Lead-acid                      |            12 |
   | Valve-Regulated Lead-Acid, Gel |            13 |
   | Valve-Regulated Lead-Acid, AGM |            14 |
   | Nickel-cadmium                 |            15 |
   | Nickel-metal hydride           |            16 |
   | Nickel-zinc                    |            17 |
   | Lithium-ion                    |            18 |
   | Lithium polymer                |            19 |
   | Double layer capacitor         |            20 |
   | Unassigned                     | 21-4294967295 |
   +--------------------------------+---------------+

3.2.1. Guidelines for Adding Battery Technologies ๐Ÿ“

okay so this is basically the same vibe as the bit above: new entries can be added to the IANA registry if new tech is developed or missing tech gets identified ๐ŸŒธ. there's a huge number of battery types that aren't in the registry, and many are experimental or can't be used economically ๐Ÿ˜ญ. new entries SHOULD only be added if the tech is in commercial use AND relevant to standardized battery monitoring over the Internet ๐Ÿซถ

3.3. Battery Identification ๐Ÿ†”

there are two identifiers to use ๐ŸŽ€: the entPhysicalUUID from the Entity MIB [RFC6933] module, and the batteryIdentifier defined in this module ๐Ÿ’–. a battery gets linked to an entPhysicalUUID through the shared entPhysicalIndex ๐Ÿ”—

the batteryIdentifier uniquely identifies the battery itself, while the entPhysicalUUID identifies the slot in the device where the battery is (currently) sitting ๐Ÿงš. for a non-replaceable battery, both identifiers are always linked to the same physical battery ๐Ÿ’…. but for batteries that CAN be replaced, the identifiers have different jobs ๐Ÿฆ‹

the entPhysicalUUID stays the same for a certain battery slot of a device, even if the battery in it gets swapped out for another one ๐ŸŒˆ. the batteryIdentifier is a representation of the identifier the battery manufacturer set ๐Ÿ“. it's tied to the battery and usually can't be changed ๐Ÿ”’

a lot of manufacturers ship battery packages that include extra hardware and firmware, not just plain batteries ๐Ÿ“ฆโœจ. these modules typically include a battery identifier that a device can retrieve once a battery is installed ๐Ÿซถ. the value of batteryIdentifier is an exact representation of that identifier ๐Ÿ’œ. it's useful when batteries get removed and reinstalled in the same device or in other devices ๐Ÿ”. then the device or the network management system can trace batteries and keep continuity of battery monitoring ๐Ÿ•ต๏ธโ€โ™€๏ธ๐Ÿ’–

3.4. Charging Cycles ๐Ÿ”„

the lifetime of a battery can be approximated using charging cycles ๐Ÿ”‹โณ. a commonly used definition of a charging cycle is the amount of discharge equal to the design (or nominal) capacity of the battery [SBS] ๐Ÿ’…. this means one charging cycle can include several steps of partial charging and discharging, until the amount discharged has reached the battery's design capacity ๐ŸŒˆ. after that, the next charging cycle starts right away ๐Ÿฆ‹

3.5. Charge Control โšก

Okay so batteryChargingOperState tells you what the battery is actually doing charging-wise right now, and it's read-only, so no touching ๐Ÿ™…โ€โ™€๏ธ. If you want to control the charging state, that's where batteryChargingAdminState comes in. Writing to it sends a request to adapt the operational state to whatever value you wrote โœจ

By default, batteryChargingAdminState is set to notSet(1). In that state the charging controller is just vibing on its own predefined policies, deciding which operational state fits the current situation ๐Ÿง 

Here's the tea: setting batteryChargingAdminState doesn't guarantee anything ๐Ÿ’€. The battery might not change to that value, or the charging state might end up set to something else than what you asked for. Operational conditions and the limits of how the Battery MIB module is implemented can make changing the battery status to match the set value impossible ๐Ÿ˜ญ

For example, the charging controller can decide at any time to enter discharging(5) if there's an operational need to use the battery to supply power. Main character energy, no permission needed ๐Ÿ‘‘

The object batteryChargingAdminState will not automatically change when batteryChargingOperState changes ๐Ÿ™ˆ. If the operational state changes, e.g., to discharging(5) because of operational conditions, the admin state stays right where it was. The charging controller SHOULD change the operational state to the state indicated by batteryChargingAdminState as soon as operational conditions allow it ๐Ÿซถ

If you do want the admin state to change when the operational state changes, you'll need to poll batteryChargingOperState or use the notification batteryChargingStateNotification so you get told about the change ๐Ÿ””. This is useful if you don't want maintaining charge after a battery is fully charged, even if the charging controller and battery both support it. You can set batteryChargingAdminState to doNotCharge(3) when batteryChargingOperState changes from charging(2) to maintainingCharge(3) ๐Ÿ“. Another use case is performing several charge and discharge cycles for battery maintenance ๐Ÿ”

3.6. Imported Definitions ๐Ÿฆ‹

The BATTERY-MIB module defined in this document imports definitions from the following MIB modules: SNMPv2-SMI [RFC2578], SNMPv2-TC [RFC2579], SNMPv2-CONF [RFC2580], SNMP-FRAMEWORK-MIB [RFC3411], and ENTITY-MIB [RFC6933] ๐Ÿ’œ.

4. Definitions ๐ŸŽ€

  BATTERY-MIB DEFINITIONS ::= BEGIN

  IMPORTS
      MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
      mib-2, Integer32, Unsigned32
          FROM SNMPv2-SMI                                -- RFC 2578
      DateAndTime
          FROM SNMPv2-TC                                 -- RFC 2579
      MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
          FROM SNMPv2-CONF                               -- RFC 2580
      SnmpAdminString
          FROM SNMP-FRAMEWORK-MIB                        -- RFC 3411
      entPhysicalIndex
          FROM ENTITY-MIB;                               -- RFC 6933

  batteryMIB MODULE-IDENTITY
      LAST-UPDATED "201506150000Z"         -- 15 June 2015
      ORGANIZATION "IETF EMAN Working Group"
      CONTACT-INFO
          "General Discussion: eman@ietf.org
          To Subscribe: <http://www.ietf.org/mailman/listinfo/eman>
          Archive: <http://www.ietf.org/mail-archive/web/eman>

          Editor:
            Juergen Quittek
            NEC Europe, Ltd.
            NEC Laboratories Europe
            Kurfuersten-Anlage 36
            69115 Heidelberg
            Germany
            Tel: +49 6221 4342-115
            Email: quittek@neclab.eu"

      DESCRIPTION
          "This MIB module defines a set of objects for monitoring
          batteries of networked devices and of their components.

          Copyright (c) 2015 IETF Trust and the persons identified as
          authors of the code.  All rights reserved.

          Redistribution and use in source and binary forms, with or
          without modification, is permitted pursuant to, and subject
          to the license terms contained in, the Simplified BSD License
          set forth in Section 4.c of the IETF Trust's Legal Provisions
          Relating to IETF Documents
          (http://trustee.ietf.org/license-info).

          This version of this MIB module is part of RFC 7577; see
          the RFC itself for full legal notices."
  --  Revision history

      REVISION "201506150000Z"         -- 15 June 2015
      DESCRIPTION
          "Initial version published as RFC 7577."

      ::= { mib-2 233 }

  --******************************************************************
  -- Top-Level Structure of the MIB Module
  --******************************************************************

  batteryNotifications OBJECT IDENTIFIER ::= { batteryMIB 0 }
  batteryObjects       OBJECT IDENTIFIER ::= { batteryMIB 1 }
  batteryConformance   OBJECT IDENTIFIER ::= { batteryMIB 2 }

  --==================================================================
  -- 1.  Object Definitions
  --==================================================================

  --------------------------------------------------------------------
  -- 1.1.  Battery Table
  --------------------------------------------------------------------
  batteryTable  OBJECT-TYPE
      SYNTAX      SEQUENCE OF BatteryEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table provides information on batteries.  It contains
          one conceptual row per battery in a managed entity.

          Batteries are indexed by the entPhysicalIndex of the
          entPhysicalTable defined in the ENTITY-MIB (RFC 6933).

          For implementations of the BATTERY-MIB, an implementation of
          the ENTITY-MIB complying with the entity4CRCompliance
          MODULE-COMPLIANCE statement of the ENTITY-MIB is required.

          If batteries are replaced, and the replacing battery uses
          the same physical connector as the replaced battery, then
          the replacing battery SHOULD be indexed with the same value
          of object entPhysicalIndex as the replaced battery."
      ::= { batteryObjects 1 }

  batteryEntry OBJECT-TYPE
      SYNTAX      BatteryEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "An entry providing information on a battery."
      INDEX  { entPhysicalIndex }
      ::= { batteryTable 1 }

  BatteryEntry ::=
      SEQUENCE {
         batteryIdentifier               SnmpAdminString,
         batteryFirmwareVersion          SnmpAdminString,
         batteryType                     INTEGER,
         batteryTechnology               Unsigned32,
         batteryDesignVoltage            Unsigned32,
         batteryNumberOfCells            Unsigned32,
         batteryDesignCapacity           Unsigned32,
         batteryMaxChargingCurrent       Unsigned32,
         batteryTrickleChargingCurrent   Unsigned32,
         batteryActualCapacity           Unsigned32,
         batteryChargingCycleCount       Unsigned32,
         batteryLastChargingCycleTime    DateAndTime,
         batteryChargingOperState        INTEGER,
         batteryChargingAdminState       INTEGER,
         batteryActualCharge             Unsigned32,
         batteryActualVoltage            Unsigned32,
         batteryActualCurrent            Integer32,
         batteryTemperature              Integer32,
         batteryAlarmLowCharge           Unsigned32,
         batteryAlarmLowVoltage          Unsigned32,
         batteryAlarmLowCapacity         Unsigned32,
         batteryAlarmHighCycleCount      Unsigned32,
         batteryAlarmHighTemperature     Integer32,
         batteryAlarmLowTemperature      Integer32,
         batteryCellIdentifier           SnmpAdminString
      }

  batteryIdentifier OBJECT-TYPE
      SYNTAX      SnmpAdminString
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object contains an identifier for the battery.

          Many manufacturers deliver not only simple batteries but
          battery packages including additional hardware and firmware.
          Typically, these modules include an identifier that can be
          retrieved by a device in which a battery has been installed.
          The identifier is useful when batteries are removed and
          reinstalled in the same or other devices.  Then, the device
          or the network management system can trace batteries and
          achieve continuity of battery monitoring.

          If the battery is identified by more than one value,
          for example, by a model number and a serial number,
          then the value of this object is a concatenation of these
          values, separated by the colon symbol ':'.  The values
          should be ordered so that a more significant value comes
          before a less significant one.  In the example above, the
          (more significant) model number would be first, and the serial
          number would follow: '<model number>:<serial number>'.

          If the battery identifier cannot be represented using the
          ISO/IEC IS 10646-1 character set, then a hexadecimal
          encoding of a binary representation of the entire battery
          identifier must be used.

          The value of this object must be an empty string if there
          is no battery identifier or if the battery identifier is
          unknown."
      ::= { batteryEntry 1 }

  batteryFirmwareVersion OBJECT-TYPE
      SYNTAX      SnmpAdminString
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the version number of the firmware
          that is included in a battery module.

          Many manufacturers deliver not pure batteries but battery
          packages including additional hardware and firmware.

          Since the behavior of the battery may change with the
          firmware, it may be useful to retrieve the firmware version
          number.

          The value of this object must be an empty string if there
          is no firmware or if the version number of the firmware is
          unknown."
      ::= { batteryEntry 2 }

  batteryType OBJECT-TYPE
      SYNTAX      INTEGER {
                      unknown(1),
                      other(2),
                      primary(3),
                      rechargeable(4),
                      capacitor(5)
                  }
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the type of battery.

          It distinguishes between primary (not rechargeable)
          batteries, rechargeable (secondary) batteries, and
          capacitors.  Capacitors are not really batteries but
          are often used in the same way as a battery.

          The value other(2) can be used if the battery type is known
          but is none of the ones above.  Value unknown(1) is to be used
          if the type of battery cannot be determined."

      ::= { batteryEntry 3 }

  batteryTechnology OBJECT-TYPE
      SYNTAX      Unsigned32
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the technology used by the battery.
          Numbers identifying battery technologies are registered at
          IANA.  A current list of assignments can be found at
          <http://www.iana.org/assignments/battery-technologies>.

          Value unknown(1) MUST be used if the technology of the
          battery cannot be determined.

okay so we're still in batteryTechnology bestie ๐Ÿ”‹โœจ the last bit tells you what to do when the battery type is known but isn't on the IANA list yet ๐Ÿซถ

          Value other(2) can be used if the battery technology is known
          but is not one of the types already registered at IANA."
      ::= { batteryEntry 4 }

okay now batteryDesignVoltage ๐ŸŽ€ this one is the battery's design (or nominal) voltage in millivolts. the thing to remember is that it's a constant, so it's usually not the same as what the battery is actually putting out right now ๐Ÿ’… and a 0 means it's unknown ๐Ÿ™ˆ

  batteryDesignVoltage OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "millivolt"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the design (or nominal) voltage of the
          battery in units of millivolt (mV).

          Note that the design voltage is a constant value and
          typically different from the actual voltage of the battery.

          A value of 0 indicates that the design voltage is unknown."
      ::= { batteryEntry 5 }

next up is batteryNumberOfCells ๐Ÿ“ it's just a count of how many cells are packed into the battery, and again 0 is the "I don't know" value ๐Ÿงš

  batteryNumberOfCells OBJECT-TYPE
      SYNTAX      Unsigned32
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the number of cells contained in the
          battery.

          A value of 0 indicates that the number of cells is unknown."
      ::= { batteryEntry 6 }

batteryDesignCapacity ๐Ÿ”‹๐Ÿ’œ this is the design (or nominal) capacity, measured in milliampere hours. same deal as voltage: it's a constant, it's usually different from the battery's actual capacity, and the manufacturer is usually where this number comes from. 0 means unknown โœจ

  batteryDesignCapacity OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere hours"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the design (or nominal) capacity of
          the battery in units of milliampere hours (mAh).

          Note that the design capacity is a constant value and
          typically different from the actual capacity of the battery.
          Usually, this is a value provided by the manufacturer of the
          battery.

          A value of 0 indicates that the design capacity is
          unknown."
      ::= { batteryEntry 7 }

batteryMaxChargingCurrent โšก this is the max current you're allowed to use when charging, in milliamperes. the tea here is that hitting the max doesn't automatically mean the battery is happiest ๐Ÿฅน some batteries can only handle max current for a limited time. 0 is unknown, obvi ๐Ÿ’€

  batteryMaxChargingCurrent OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the maximum current to be used for
          charging the battery in units of milliampere (mA).

          Note that the maximum charging current may not lead to
          optimal charge of the battery and that some batteries can
          only be charged with the maximum current for a limited
          amount of time.

          A value of 0 indicates that the maximum charging current is
          unknown."
      ::= { batteryEntry 8 }

batteryTrickleChargingCurrent ๐ŸŒธ this one is the recommended average current for trickle charging, in mA. it's usually whatever the battery maker or the charging circuit maker suggests, and yep, 0 means unknown ๐Ÿซถ

  batteryTrickleChargingCurrent OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the recommended average current
          to be used for trickle charging the battery in units of
          mA.

          Typically, this is a value recommended by the manufacturer
          of the battery or by the manufacturer of the charging
          circuit.

          A value of 0 indicates that the recommended trickle charging
          current is unknown."
      ::= { batteryEntry 9 }

batteryActualCapacity ๐Ÿฆ‹ this is what the battery can actually hold right now, in mAh. it tends to drop over time and with use, and it's usually lower than the design capacity. it's also an estimate built from watching the charge and discharge cycles, so it isn't just read off a dial ๐Ÿ™ˆ and 'ffffffff'H (all ones, basically the max 32-bit value) means it can't be figured out ๐Ÿ”ฅ

  batteryActualCapacity OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere hours"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the actual capacity of the
          battery in units of mAh.

          Typically, the actual capacity of a battery decreases
          with time and with usage of the battery.  It is usually
          lower than the design capacity.

          Note that the actual capacity needs to be measured and is
          typically an estimate based on observed discharging and
          charging cycles of the battery.

          A value of 'ffffffff'H indicates that the actual capacity
          cannot be determined."
      ::= { batteryEntry 10 }

batteryChargingCycleCount ๐Ÿ”„๐Ÿ’– okay this one is giving science class ๐Ÿค“ it counts the completed charging cycles. a cycle is defined using the Smart Battery Data Specification Revision 1.1, and it's basically discharging the battery by its design capacity in total. a cycle can have lots of charge and discharge steps in it, and once one finishes the next one starts right away, no matter how charged the battery is at that moment โœจ

primary batteries are always 0 here, and 'ffffffff'H means the count can't be determined ๐Ÿ’…

  batteryChargingCycleCount OBJECT-TYPE
      SYNTAX      Unsigned32
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the number of completed charging
          cycles that the battery underwent.  In line with the
          Smart Battery Data Specification Revision 1.1, a charging
          cycle is defined as the process of discharging the battery
          by a total amount equal to the battery design capacity as
          given by object batteryDesignCapacity.  A charging cycle
          may include several steps of charging and discharging the
          battery until the discharging amount given by
          batteryDesignCapacity has been reached.  As soon as a
          charging cycle has been completed, the next one starts
          immediately, independent of the battery's current charge at
          the end of the cycle.

          For batteries of type primary(3), the value of this object is
          always 0.

          A value of 'ffffffff'H indicates that the number of charging
          cycles cannot be determined."
      ::= { batteryEntry 11 }

batteryLastChargingCycleTime ๐Ÿ•ฐ๏ธ๐ŸŒˆ this is the date and time of the most recent charging cycle, using the DateAndTime format. if the battery hasn't been charged yet, or the time just can't be figured out, you get '0000000000000000'H ๐Ÿฅบ primary batteries always give that same value too, so no surprises there โœจ

  batteryLastChargingCycleTime OBJECT-TYPE
      SYNTAX      DateAndTime
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The date and time of the last charging cycle.  The value
          '0000000000000000'H is returned if the battery has not been
          charged yet or if the last charging time cannot be
          determined.

          For batteries of type primary(1), the value of this object is
          always '0000000000000000'H."
      ::= { batteryEntry 12 }

batteryChargingOperState ๐Ÿ’œโšก this is the battery's current charging state, and it has five possible vibes:

  • unknown(1): we can't tell what's going on ๐Ÿซ 
  • charging(2): the charge is going up โฌ†๏ธ
  • maintainingCharge(3): a low average current is keeping the charge topped up and cancelling out self-discharge. this covers trickle charging, float charging, and other ways of keeping the charge where it is. in typical charge controllers, this only kicks in when the battery is fully or almost fully charged ๐Ÿ”‹
  • noCharging(4): no current is moving between the battery and the outside circuits. the battery can still self-discharge though ๐Ÿ™ˆ
  • discharging(5): the battery is powering outside circuits, or the charge controller is deliberately draining it (for maintenance, for example). either way, the charge goes down ๐Ÿ“‰

here's the full definition, exactly as written:

  batteryChargingOperState OBJECT-TYPE
      SYNTAX      INTEGER {
                      unknown(1),
                      charging(2),
                      maintainingCharge(3),
                      noCharging(4),
                      discharging(5)
                  }
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the current charging state of the
          battery.

          Value unknown(1) indicates that the charging state of the
          battery cannot be determined.

          Value charging(2) indicates that the battery is being
          charged in a way such that the charge of the battery
          increases.

          Value maintainingCharge(3) indicates that the battery is
          being charged with a low-average current that compensates
          self-discharging.  This includes trickle charging, float
          charging, and other methods for maintaining the current
          charge of a battery.  In typical implementations of charging
          controllers, state maintainingCharge(3) is only applied
          if the battery is fully charged or almost fully charged.

          Value noCharging(4) indicates that the battery is not being
          charged or discharged by electric current between the
          battery and electric circuits external to the battery.
          Note that the battery may still be subject to
          self-discharging.

          Value discharging(5) indicates that the battery is either
          used as the power source for electric circuits external to
          the battery or discharged intentionally by the
          charging controller, e.g., for the purpose of battery
          maintenance.  In any case, the charge of the battery
          decreases."
      ::= { batteryEntry 13 }

batteryChargingAdminState ๐ŸŽ€๐Ÿ‘‘ this is the wish list ๐ŸŒŸ it's the charging state you'd like the battery to be in, and the real state is shown in batteryChargingOperState. it's read-write, so you can actually set it ๐Ÿ’… the options are:

  • notSet(1): the default. the charge controller can pick whatever state makes sense ๐Ÿค–
  • charge(2): charge until full. if it's already full or almost full, it moves to maintainingCharge(3) when the controller and battery can do that, and to noCharging(4) otherwise
  • doNotCharge(3): go to noCharging(4) ๐Ÿšซ
  • discharge(4): go to discharging(5). this can happen through normal use, a dedicated load, or anything else. battery maintenance is one example. if the battery is empty or nearly empty, it moves to noCharging(4) instead, and the charge controller decides what counts as "empty" depending on the battery technology, so the battery doesn't get damaged by deep discharge ๐Ÿ›ก๏ธ

but bestie, the wish doesn't always come true ๐Ÿฅฒ the BATTERY-MIB implementation might not be able to make the change, and the charging state could even end up different from what you asked for. the charge controller can also decide to go into discharging(5) whenever it needs the battery to power something โšก

  batteryChargingAdminState OBJECT-TYPE
      SYNTAX      INTEGER {
                      notSet(1),
                      charge(2),
                      doNotCharge(3),
                      discharge(4)
                  }
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
          "The value of this object indicates the desired
          charging state of the battery.  The real state is
          indicated by object batteryChargingOperState.  See the
          definition of object batteryChargingOperState for a
          description of the values.

          When this object is initialized by an implementation of the
          BATTERY-MIB module, its value is set to notSet(1).  In this
          case, the charging controller is free to choose which
          operational state is suitable.

          When the batteryChargingAdminState object is set, then the
          BATTERY-MIB implementation must try to set the battery
          to the indicated state.  The result will be indicated by
          object batteryChargingOperState.

          Setting object batteryChargingAdminState to value notSet(1)
          is a request to the charging controller to operate
          autonomously and choose the operational state that is
          suitable.

          Setting object batteryChargingAdminState to value charge(2)
          is a request to enter the operational state charging(2) until
          the battery is fully charged.  When the battery is fully
          charged, or if the battery was already fully charged or
          almost fully charged at the time of the request, the
          operational state will change to maintainingCharge(3) if the
          charging controller and the battery support the functionality
          of maintaining the charge, or it will change to noCharging(4)
          otherwise.

          Setting object batteryChargingAdminState to value
          doNotCharge(3) is a request for entering operational
          state noCharging(4).

          Setting object batteryChargingAdminState to value
          discharge(4) is a request for entering operational
          state discharging(5).  Discharging can be accomplished
          by ordinary use, applying a dedicated load, or any other
          means.  An example for applying this state is battery
          maintenance.  If the battery is empty or almost empty, the
          operational state will change to noCharging(4).
          The charging controller will decide which charge condition
          will be considered empty dependent on the battery
          technology used.  This is done to avoid damage on the
          battery due to deep discharge.

          Due to operational conditions and limitations of the
          implementation of the BATTERY-MIB module, changing the
          battery status according to a set value of object
          batteryChargingAdminState may not be possible.
          Setting the value of object batteryChargingAdminState
          may result in not changing the state of the battery
          to this value or even in setting the charging state
          to another value than the requested one.  For example,
          the charging controller might at any time decide to
          enter state discharging(5), if there is an operational need
          to use the battery for supplying power."
      ::= { batteryEntry 14 }

batteryActualCharge ๐Ÿงƒ๐Ÿ’– this is how much charge the battery has right now, in mAh. same story as before: it's usually an estimate built from watching the charge and discharge cycles, and 'ffffffff'H means it can't be determined ๐Ÿ™ˆ

  batteryActualCharge OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere hours"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the actual charge of the battery
          in units of mAh.

          Note that the actual charge needs to be measured and is
          typically an estimate based on observed discharging and
          charging cycles of the battery.

          A value of 'ffffffff'H indicates that the actual charge
          cannot be determined."
      ::= { batteryEntry 15 }

batteryActualVoltage โšก๐ŸŒˆ the actual voltage of the battery right now, in mV. if it can't be figured out, you'll see 'ffffffff'H ๐Ÿซถ

  batteryActualVoltage OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "millivolt"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the actual voltage of the battery
          in units of mV.

          A value of 'ffffffff'H indicates that the actual voltage
          cannot be determined."
      ::= { batteryEntry 16 }

last one for this part: batteryActualCurrent ๐Ÿ”Œ๐Ÿ“ this is the actual charging or discharging current in mA. charging is a positive number and discharging is a negative one, so the sign tells you which way the energy is flowing โœจ the definition keeps going from here ๐Ÿ‘€

  batteryActualCurrent OBJECT-TYPE
      SYNTAX      Integer32
      UNITS       "milliampere"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object provides the actual charging or discharging
          current of the battery in units of mA.
          The charging current is represented by positive values,
          and the discharging current is represented by negative values.

okay the alarm thresholds are where things get spicy ๐ŸŒธ

          A value of '7fffffff'H indicates that the actual current
          cannot be determined."
      ::= { batteryEntry 17 }

  batteryTemperature OBJECT-TYPE
      SYNTAX      Integer32
      UNITS       "deci-degrees Celsius"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The ambient temperature at or within close proximity
          of the battery.

          A value of '7fffffff'H indicates that the temperature
          cannot be determined."
      ::= { batteryEntry 18 }

  batteryAlarmLowCharge OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere hours"
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
          "This object provides the lower-threshold value for object
          batteryActualCharge.  If the value of object
          batteryActualCharge falls below this threshold,
          a low-battery alarm will be raised.  The alarm procedure may
          include generating a batteryLowNotification.

          This object should be set to a value such that when the
          batteryLowNotification is generated, the battery is still
          sufficiently charged to keep the device(s) that it powers
          operational for a time long enough to take actions before
          the powered device(s) enters a 'sleep' or 'off' state.

          A value of 0 indicates that no alarm will be raised for any
          value of object batteryActualVoltage."
      ::= { batteryEntry 19 }

    batteryAlarmLowVoltage OBJECT-TYPE
        SYNTAX      Unsigned32
        UNITS       "millivolt"
        MAX-ACCESS  read-write
        STATUS      current
        DESCRIPTION
            "This object provides the lower-threshold value for object
            batteryActualVoltage.  If the value of object
            batteryActualVoltage falls below this threshold,
            a low-battery alarm will be raised.  The alarm procedure may
            include generating a batteryLowNotification.

            This object should be set to a value such that when the
            batteryLowNotification is generated, the battery is still
            sufficiently charged to keep the device(s) that it powers
            operational for a time long enough to take actions before
            the powered device(s) enters a 'sleep' or 'off' state.

            A value of 0 indicates that no alarm will be raised for any
            value of object batteryActualVoltage."
        ::= { batteryEntry 20 }

  batteryAlarmLowCapacity OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "milliampere hours"
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
          "This object provides the lower-threshold value for object
          batteryActualCapacity.  If the value of object
          batteryActualCapacity falls below this threshold,
          a battery aging alarm will be raised.  The alarm procedure
          may include generating a batteryAgingNotification.

          A value of 0 indicates that no alarm will be raised for any
          value of object batteryActualCapacity."
      ::= { batteryEntry 21 }

  batteryAlarmHighCycleCount OBJECT-TYPE
      SYNTAX      Unsigned32
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
          "This object provides the upper-threshold value for object
          batteryChargingCycleCount.  If the value of object
          batteryChargingCycleCount rises above this threshold,
          a battery aging alarm will be raised.  The alarm procedure
          may include generating a batteryAgingNotification.

          A value of 0 indicates that no alarm will be raised for any
          value of object batteryChargingCycleCount."
      ::= { batteryEntry 22 }

  batteryAlarmHighTemperature OBJECT-TYPE
      SYNTAX      Integer32
      UNITS       "deci-degrees Celsius"
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
          "This object provides the upper-threshold value for object
          batteryTemperature.  If the value of object
          batteryTemperature rises above this threshold, a battery
          high temperature alarm will be raised.  The alarm procedure
          may include generating a batteryTemperatureNotification.

          A value of '7fffffff'H indicates that no alarm will be
          raised for any value of object batteryTemperature."
      ::= { batteryEntry 23 }

  batteryAlarmLowTemperature OBJECT-TYPE
      SYNTAX      Integer32
      UNITS       "deci-degrees Celsius"
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
          "This object provides the lower-threshold value for object
          batteryTemperature.  If the value of object
          batteryTemperature falls below this threshold, a battery
          low temperature alarm will be raised.  The alarm procedure
          may include generating a batteryTemperatureNotification.

          A value of '7fffffff'H indicates that no alarm will be
          raised for any value of object batteryTemperature."
      ::= { batteryEntry 24 }

  batteryCellIdentifier OBJECT-TYPE
      SYNTAX      SnmpAdminString
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The value of this object identifies one or more cells of a
          battery.  The format of the cell identifier may vary between
          different implementations.  It should uniquely identify one
          or more cells of the indexed battery.

          This object can be used for batteries, such as lithium
          polymer batteries for which battery controllers monitor
          cells individually.

          This object is used by notifications of types
          batteryLowNotification, batteryTemperatureNotification,
          batteryCriticalNotification, and batteryAgingNotification.
          These notifications can use the value of this object to
          indicate the event that triggered the generation of the
          notification in more detail by specifying a single cell
          or a set of cells within the battery that is specifically
          addressed by the notification.

          An example use case for this object is a single cell in a
          battery that exceeds the temperature indicated by object
          batteryAlarmHighTemperature.  In such a case, a
          batteryTemperatureNotification can be generated that not
          only indicates the battery for which the temperature limit
          has been exceeded but also the particular cell.

          The initial value of this object is the empty string.  The
          value of this object is set each time a
          batteryLowNotification, batteryTemperatureNotification,
          batteryCriticalNotification, or batteryAgingNotification
          is generated.

          When a notification is generated that does not indicate a
          specific cell or set of cells, the value of this object is
          set to the empty string."
      ::= { batteryEntry 25 }

  --==================================================================
  -- 2.  Notifications
  --==================================================================

  batteryChargingStateNotification NOTIFICATION-TYPE
      OBJECTS     {
          batteryChargingOperState
      }
      STATUS      current
      DESCRIPTION
          "This notification can be generated when a charging state
          of the battery (indicated by the value of object
          batteryChargingOperState) is triggered by an event other
          than a write action to object batteryChargingAdminState.
          Such an event may, for example, be triggered by a local
          battery controller."
      ::= { batteryNotifications 1 }

  batteryLowNotification NOTIFICATION-TYPE
      OBJECTS     {
          batteryActualCharge,
          batteryActualVoltage,
          batteryCellIdentifier
      }
      STATUS      current
      DESCRIPTION
          "This notification can be generated when the current charge
          (batteryActualCharge) or the current voltage
          (batteryActualVoltage) of the battery falls below a
          threshold defined by object batteryAlarmLowCharge or object
          batteryAlarmLowVoltage, respectively.

          Note that, typically, this notification is generated in a
          state where the battery is still sufficiently charged to keep
          the device(s) that it powers operational for some time.
          If the charging state of the battery has become critical,
          i.e., the device(s) powered by the battery must go to a
          'sleep' or 'off' state, then the batteryCriticalNotification
          should be used instead.

          If the low charge or voltage has been detected for a single
          cell or a set of cells of the battery and not for the entire
          battery, then object batteryCellIdentifier should be set to
          a value that identifies the cell or set of cells.
          Otherwise, the value of object batteryCellIdentifier should
          be set to the empty string when this notification is
          generated.

          The notification should not be sent again for the same
          battery or cell before either (a) the current voltage or
          the current charge, respectively, has become higher than the
          corresponding threshold through charging or (b) an indication
          of a maintenance action has been detected, such as a battery
          disconnection event or a reinitialization of the battery
          monitoring system.

          This notification should not be sent when the battery is in
          a charging mode, i.e., the value of object
          batteryChargingOperState is charging(2)."
      ::= { batteryNotifications 2 }

  batteryCriticalNotification NOTIFICATION-TYPE
      OBJECTS     {
          batteryActualCharge,
          batteryActualVoltage,
          batteryCellIdentifier
      }
      STATUS      current
      DESCRIPTION
          "This notification can be generated when the current charge
          of the battery falls so low that it cannot provide a
          sufficient power supply function for regular operation
          of the powered device(s).  The battery needs to be charged
          before it can be used for regular power supply again.  The
          battery may still provide sufficient power for a 'sleep'
          mode of a powered device(s) or for a transition into an 'off'
          mode.

          If the critical state is caused by a single cell or a set of
          cells of the battery, then object batteryCellIdentifier
          should be set to a value that identifies the cell or set of
          cells.  Otherwise, the value of object batteryCellIdentifier
          should be set to the empty string when this notification is
          generated.

          The notification should not be sent again for the same
          battery before either the battery charge has increased
          through charging to a non-critical value or an indication
          of a maintenance action has been detected, such as a battery
          disconnection event or a reinitialization of the battery
          monitoring system.

          This notification should not be sent when the battery is in
          a charging mode, i.e., the value of object
          batteryChargingOperState is charging(2)."
      ::= { batteryNotifications 3 }

  batteryTemperatureNotification NOTIFICATION-TYPE
      OBJECTS     {
          batteryTemperature,
          batteryCellIdentifier
      }
      STATUS      current
      DESCRIPTION
          "This notification can be generated when the measured
          temperature (batteryTemperature) rises above the threshold
          defined by object batteryAlarmHighTemperature or falls
          below the threshold defined by object
          batteryAlarmLowTemperature.

Okay bestie, the notification alerts are wrapped up and now we're getting into the conformance rules, which are literally the part where everyone agrees on what "good" looks like ๐Ÿ’…๐ŸŽ€

          If the low or high temperature has been detected for a
          single cell or a set of cells of the battery and not for the
          entire battery, then object batteryCellIdentifier should be
          set to a value that identifies the cell or set of cells.
          Otherwise, the value of object batteryCellIdentifier should
          be set to the empty string when this notification is
          generated.

          It may occur that the temperature alternates between values
          slightly below and slightly above a threshold.  For limiting
          the notification rate in such a case, this notification
          should not be sent again for the same battery or cell,
          respectively, within a time interval of 10 minutes.

          An exception to the rate limitations occurs immediately
          after the reinitialization of the battery monitoring system.
          At this point in time, if the battery temperature is above
          the threshold defined by object batteryAlarmHighTemperature
          or below the threshold defined by object
          batteryAlarmLowTemperature, respectively, then this
          notification should be sent, independent of the time at
          which previous notifications for the same battery or cell,
          respectively, had been sent."
      ::= { batteryNotifications 4 }

  batteryAgingNotification NOTIFICATION-TYPE
      OBJECTS     {
          batteryActualCapacity,
          batteryChargingCycleCount,
          batteryCellIdentifier
      }
      STATUS      current
      DESCRIPTION
          "This notification can be generated when the actual
          capacity (batteryActualCapacity) falls below a threshold
          defined by object batteryAlarmLowCapacity
          or when the charging cycle count of the battery
          (batteryChargingCycleCount) exceeds the threshold defined
          by object batteryAlarmHighCycleCount.

          If the aging has been detected for a single cell or a set
          of cells of the battery and not for the entire battery, then
          object batteryCellIdentifier should be set to a value that
          identifies the cell or set of cells.  Otherwise, the value
          of object batteryCellIdentifier should be set to the empty
          string when this notification is generated.

          This notification should not be sent again for the same
          battery or cell, respectively, before an indication of a
          maintenance action has been detected, such as a battery
          disconnection event or a reinitialization of the battery
          monitoring system."
      ::= { batteryNotifications 5 }

  batteryConnectedNotification NOTIFICATION-TYPE
      OBJECTS     {
          batteryIdentifier
      }
      STATUS      current
      DESCRIPTION
          "This notification can be generated when it has been
          detected that a battery has been connected.  The battery
          can be identified by the value of object batteryIdentifier
          as well as by the value of index entPhysicalIndex that is
          contained in the OID of object batteryIdentifier."
      ::= { batteryNotifications 6 }

  batteryDisconnectedNotification NOTIFICATION-TYPE
      STATUS      current
      DESCRIPTION
          "This notification can be generated when it has been
          detected that one or more batteries have been disconnected."
      ::= { batteryNotifications 7 }

  --==================================================================
  -- 3.  Conformance Information
  --==================================================================

  batteryCompliances OBJECT IDENTIFIER ::= { batteryConformance 1 }
  batteryGroups      OBJECT IDENTIFIER ::= { batteryConformance 2 }

Now the fun part: the rules for what an implementation has to do to count as compliant ๐Ÿฆ‹ Some groups are must-haves and the rest are totally optional, which honestly is so relatable โœจ

  --------------------------------------------------------------------
  -- 3.1.  Compliance Statements
  --------------------------------------------------------------------

  batteryCompliance MODULE-COMPLIANCE
      STATUS      current
      DESCRIPTION
          "The compliance statement for implementations of the
          BATTERY-MIB module.

          A compliant implementation MUST implement the objects
          defined in the mandatory groups batteryDescriptionGroup
          and batteryStatusGroup.

          Note that this compliance statement requires
          compliance with the entity4CRCompliance
          MODULE-COMPLIANCE statement of the
          ENTITY-MIB (RFC 6933)."
      MODULE  -- this module
          MANDATORY-GROUPS {
              batteryDescriptionGroup,
              batteryStatusGroup
          }

          GROUP   batteryAlarmThresholdsGroup
          DESCRIPTION
             "A compliant implementation does not have to implement
              the batteryAlarmThresholdsGroup."

          GROUP   batteryNotificationsGroup
          DESCRIPTION
             "A compliant implementation does not have to implement
              the batteryNotificationsGroup."

          GROUP   batteryPerCellNotificationsGroup
          DESCRIPTION
             "A compliant implementation does not have to implement
              the batteryPerCellNotificationsGroup."

          GROUP   batteryAdminGroup
          DESCRIPTION

             "A compliant implementation does not have to implement
              the batteryAdminGroup."

          OBJECT batteryAlarmLowCharge
          MIN-ACCESS  read-only
          DESCRIPTION
              "A compliant implementation is not required
              to support set operations on this object."

          OBJECT batteryAlarmLowVoltage
          MIN-ACCESS  read-only
          DESCRIPTION
              "A compliant implementation is not required
              to support set operations on this object."

          OBJECT batteryAlarmLowCapacity
          MIN-ACCESS  read-only
          DESCRIPTION
              "A compliant implementation is not required
              to support set operations on this object."

          OBJECT batteryAlarmHighCycleCount
          MIN-ACCESS  read-only
          DESCRIPTION
              "A compliant implementation is not required
              to support set operations on this object."

          OBJECT batteryAlarmHighTemperature
          MIN-ACCESS  read-only
          DESCRIPTION
              "A compliant implementation is not required
              to support set operations on this object."

          OBJECT batteryAlarmLowTemperature
          MIN-ACCESS  read-only
          DESCRIPTION
              "A compliant implementation is not required
              to support set operations on this object."

      ::= { batteryCompliances 1 }

  --------------------------------------------------------------------
  -- 3.2.  MIB Grouping
  --------------------------------------------------------------------

  batteryDescriptionGroup OBJECT-GROUP
      OBJECTS {
         batteryIdentifier,
         batteryFirmwareVersion,
         batteryType,
         batteryTechnology,
         batteryDesignVoltage,
         batteryNumberOfCells,
         batteryDesignCapacity,
         batteryMaxChargingCurrent,
         batteryTrickleChargingCurrent
      }
      STATUS      current
      DESCRIPTION
         "A compliant implementation MUST implement the objects
         contained in this group."
      ::= { batteryGroups 1 }

  batteryStatusGroup OBJECT-GROUP
      OBJECTS {
         batteryActualCapacity,
         batteryChargingCycleCount,
         batteryLastChargingCycleTime,
         batteryChargingOperState,
         batteryActualCharge,
         batteryActualVoltage,
         batteryActualCurrent,
         batteryTemperature
      }
      STATUS      current
      DESCRIPTION
         "A compliant implementation MUST implement the objects
         contained in this group."
      ::= { batteryGroups 2 }

  batteryAdminGroup OBJECT-GROUP
      OBJECTS {
         batteryChargingAdminState
      }
      STATUS      current
      DESCRIPTION
         "A compliant implementation does not have to implement the
         object contained in this group."
      ::= { batteryGroups 3 }

  batteryAlarmThresholdsGroup OBJECT-GROUP
      OBJECTS {
         batteryAlarmLowCharge,
         batteryAlarmLowVoltage,
         batteryAlarmLowCapacity,
         batteryAlarmHighCycleCount,
         batteryAlarmHighTemperature,
         batteryAlarmLowTemperature
      }
      STATUS      current
      DESCRIPTION
         "A compliant implementation does not have to implement the
         objects contained in this group."
      ::= { batteryGroups 4 }

  batteryNotificationsGroup NOTIFICATION-GROUP
      NOTIFICATIONS {
         batteryChargingStateNotification,
         batteryLowNotification,
         batteryCriticalNotification,
         batteryAgingNotification,
         batteryTemperatureNotification,
         batteryConnectedNotification,
         batteryDisconnectedNotification
      }
      STATUS      current
      DESCRIPTION
          "A compliant implementation does not have to implement the
          notifications contained in this group."
      ::= { batteryGroups 5 }

  batteryPerCellNotificationsGroup OBJECT-GROUP
      OBJECTS {
         batteryCellIdentifier
      }
      STATUS      current
      DESCRIPTION
          "A compliant implementation does not have to implement the
          object contained in this group."
      ::= { batteryGroups 6 }
  END

5. Security Considerations ๐Ÿ”’

okay bestie, this section is where we talk about who can mess with the battery stuff ๐Ÿ‘€ There are a bunch of management objects in this MIB module with a MAX-ACCESS of read-write, and those can be sensitive or vulnerable depending on the network. Supporting SET operations in a non-secure environment, without proper protection, opens devices up to attack. Here are the tables and objects and how sensitive or vulnerable each one is:

  • batteryChargingAdminState: Setting the battery charging state can be super useful for an operator, like charging batteries when electricity is cheap ๐Ÿ’ก But an attacker can use it to drain the batteries of devices and switch them off if they only run on battery. If batteryAlarmLowCharge and batteryAlarmLowVoltage can also be set, this attack goes totally unnoticed (aka no notifications get sent) ๐Ÿ™ˆ
  • batteryAlarmLowCharge and batteryAlarmLowVoltage: These objects set the threshold for an alarm that goes off when the battery charge or voltage drops below them. An attacker can switch the alarm off by setting it to the 'off' value 0, or change how the alarm behaves by setting it to any other value. The result could be lost data if the battery runs empty without warning to a recipient who was expecting that notification ๐Ÿ˜ญ
  • batteryAlarmLowCapacity and batteryAlarmHighCycleCount: These objects set the threshold for an alarm that goes off when the battery gets old and weaker than what's needed for stable operation. An attacker can switch this alarm off by setting it to the 'off' value 0, or change its behaviour by setting it to any other value. That can lead to either a costly replacement of a perfectly working battery, or to using batteries that are too old or too weak. The consequence of the latter could be, for example, a battery that can't provide power long enough between two scheduled charging actions, which makes the powered device shut down and possibly lose data ๐Ÿ’€
  • batteryAlarmHighTemperature and batteryAlarmLowTemperature: These objects set thresholds for an alarm that goes off when the battery rises above or falls below them. An attacker can switch these alarms off by setting them to the 'off' value '7fffffff'H, or change the alarm behaviour by setting them to any other value. The result could be, for example, an unnecessary shutdown of a device if batteryAlarmHighTemperature is set too low. It could also mean damage to the device from temperatures that are too high, if the alarm is switched off or set to values that are too high. Or it could mean damage to the battery when, for example, it's being charged. Batteries can also get damaged, for example, when someone tries to charge them at temperatures that are too low ๐ŸŒก๏ธ

Some of the readable objects in this MIB module (meaning objects with a MAX-ACCESS other than not-accessible) can also be considered sensitive or vulnerable depending on the network. So it's important to control even GET and/or NOTIFY access to these objects, and possibly even encrypt their values when they're sent over the network via SNMP ๐Ÿซถ These are the tables and objects and how sensitive or vulnerable they are:

All the potentially sensitive or vulnerable objects in this MIB module live in the batteryTable. In general, no serious operational vulnerabilities are foreseen if someone gets unauthorised read access to this table. Corporate confidentiality still needs to be considered though. The following information, or parts of it, might be a trade secret:

  • the number of batteries installed in a managed node (batteryIndex)
  • properties of these batteries (batteryActualCapacity and batteryChargingCycleCount)
  • the time at which the next replacement cycle for batteries can be expected (batteryAlarmLowCapacity and batteryAlarmHighCycleCount)
  • the types of batteries in use and their firmware versions (batteryIdentifier, batteryFirmwareVersion, batteryType, and batteryTechnology)

For any battery-powered device whose use can be linked to an individual or a small group of people, the following objects could reveal information about those people's activities or habits. For example, whether they're near a power outlet, or whether they've been using their devices heavily, etc. ๐Ÿ‘€

  • batteryChargingCycleCount
  • batteryLastChargingCycleTime
  • batteryChargingOperState
  • batteryActualCharge
  • batteryActualVoltage
  • batteryActualCurrent
  • batteryTemperature
  • batteryAlarmLowCharge
  • batteryAlarmLowVoltage
  • batteryAlarmLowCapacity
  • batteryAlarmHighCycleCount
  • batteryAlarmHighTemperature
  • batteryAlarmLowTemperature

Implementers of this specification should use appropriate privacy protections, as discussed in Section 9 of "Requirements for Energy Management" [RFC6988]. Battery monitoring of devices used by individuals or in homes should only happen with proper authorisation ๐Ÿ 

SNMP versions before SNMPv3 didn't include adequate security. Even if the network itself is secure (for example, by using IPsec), there's no control over who on that secure network is allowed to access and GET/SET (read/change/create/delete) the objects in this MIB module. Not it ๐Ÿ™…โ€โ™€๏ธ

Implementations SHOULD provide the security features described by the SNMPv3 framework (see [RFC3410]), and implementations claiming compliance to the SNMPv3 standard MUST include full support for authentication and privacy via the User-based Security Model (USM) [RFC3414] with the AES cipher algorithm [RFC3826]. Implementations MAY also provide support for the Transport Security Model (TSM) [RFC5591], in combination with a secure transport such as SSH [RFC5592] or TLS/DTLS [RFC6353] โœจ

Further, deploying SNMP versions before SNMPv3 is NOT RECOMMENDED ๐Ÿšซ Instead, it is RECOMMENDED to deploy SNMPv3 and to enable cryptographic security. It's then a customer or operator responsibility to make sure the SNMP entity giving access to an instance of this MIB module is properly configured, so access to the objects is only given to the principals (users) who have legitimate rights to actually GET or SET (change/create/delete) them ๐Ÿ’…


6. IANA Considerations ๐ŸŒธ

6.1. SMI Object Identifier Registration

The Battery MIB module defined in this document uses the following IANA-assigned OBJECT IDENTIFIER value, which is recorded in the SMI Numbers registry:

          Descriptor        OBJECT IDENTIFIER value
          ----------        -----------------------
          batteryMIB        { mib-2 233 }

6.2. Battery Technology Registration

Object batteryTechnology, defined in Section 4, reports battery technologies. Eighteen values for battery technologies have initially been defined, and they're listed in a table in Section 3.2 ๐Ÿ”‹

To make this list extensible, IANA has created a registry for battery technologies at <http://www.iana.org/assignments/battery-technologies> and filled it with the initial list given in Section 3.2.

New number assignments for battery technologies will be administered by IANA through Expert Review [RFC5226]. Experts must check that a battery technology is relevant enough to be added, according to the guidelines in Section 3.2.1 ๐Ÿง


7. References ๐Ÿ“š

7.1. Normative References

7.2. Informative References

okay so this is the bit where we get the "further reading" list ๐Ÿ“š๐ŸŽ€ these are the references the doc points to but doesn't need you to read to implement it, lowkey useful for context ๐Ÿซถ

Acknowledgements

big thank you to Steven Chew, Bill Mielke, and Alan Luchuk for their valuable input ๐Ÿซถ๐Ÿ’– the doc literally couldn't have happened without them, periodt โœจ

Authors' Addresses

these are the humans behind the doc ๐Ÿงš all three are at NEC Europe, Ltd., NEC Laboratories Europe, Network Research Division, Kurfuersten-Anlage 36, Heidelberg 69115, Germany

Juergen Quittek
NEC Europe, Ltd.
NEC Laboratories Europe
Network Research Division
Kurfuersten-Anlage 36
Heidelberg  69115
Germany

Phone: +49 6221 4342-115
Email: quittek@neclab.eu


Rolf Winter
NEC Europe, Ltd.
NEC Laboratories Europe
Network Research Division
Kurfuersten-Anlage 36
Heidelberg  69115
Germany

Phone: +49 6221 4342-121
Email: Rolf.Winter@neclab.eu


Thomas Dietz
NEC Europe, Ltd.
NEC Laboratories Europe
Network Research Division
Kurfuersten-Anlage 36
Heidelberg  69115
Germany

Phone: +49 6221 4342-128
Email: Thomas.Dietz@neclab.eu

That's the whole doc, bestie! ๐ŸŽ‰ Huge slay from the authors for making it to the end ๐Ÿ‘‘๐Ÿ’…

๐Ÿ“ฆ where this page comes from