Skip to main content

OpenEMS Backend InfluxDB Data Model and Edge-ID Collision

How[!warning] Verification status
The storage-key collision vulnerability is confirmed in source code, and the OpenEMSrepository Backendcontains storesa time-seriesreal configured collision. However, the vulnerability alone does not prove that Hillary data contaminated the current Sezibwa Pi2 history. Historical causation must be established from multipleproduction EdgeInfluxDB gatewaysdata, inconnection InfluxDB,periods, and agateway naminglogs gotchabefore thatany canrecords silentlyare mergerewritten twoor edges' data.deleted.

AllExecutive edges write to one shared measurementconclusion

  • The backend'sconfigured backend Timedata.InfluxDB writercomponent putswrites every edge'sedge data into a singleshared InfluxDB measurement,measurement, whosecurrently defaultdata.
  • name
  • It does not use the complete edge ID as the storage discriminator. It parses the trailing number and stores that number in the OEM edge tag, normally edge=<number>.
  • Two edge IDs with the same parsed number are indistinguishable to this timedata store and its history queries.
  • The repository contains hillary-test-pi-1 and aaron-pi-1; both map to edge=1. This is data.a Theregenuine collision risk.
  • The current Sezibwa Pi2 edge definition is nosezibwa-rentals-gw-pi2, measurementwhich (table)maps perto edge=2 and does not collide with Hillary.
  • nfetestpi1 is a hostname/deployment user in this repository, not the backend edge orID, perand site.should Eachnot be used as evidence of an edge-tag collision.

Confirmed backend data pointmodel

is

The separatedrelevant onlyimplementation by a tag.is:

Source: io.openems.backend.timedata.influx/src/io/openems/backend/timedata/influx/TimedataInfluxDb.java

For every accepted data timestamp, the backend constructs an InfluxDB point using:

.Point.measurement(this.config.measurement())
    // default "data" (Config.java)
.addTag("edge"this.oem.getInfluxdbTag(), String.valueOf(influxEdgeId))
    //.time(timestamp, tag name "edge" (OpenemsBackendOem.getInfluxdbTag())
WritePrecision.MS);

The tagdeployment valueconfiguration sets influxEdgeIdmeasurement="data". “Measurement” is the correct InfluxDB term; it is analogous to, but not identical with, a numberrelational parseddatabase fromtable. All edges handled by this configured timedata provider share that measurement unless another Timedata.InfluxDB instance or measurement is configured.

Channel addresses such as meter0/ActivePower and _sum/EssSoc are written as fields. History queries parse the edge'srequested nameedge byID through the same numeric function and filter using the resulting numeric tag.

Confirmed edge-ID parser behavior

InfluxConnector.parseNumberFromName(edgeId). uses:

The flow on the backend

  1. Each Edge/gateway connects to the Backend over a websocket and pushes TimestampedDataNotifications (channel values plus timestamps).
  2. TimedataInfluxDb.write(edgeId, ...) converts the edge name to an integer, then writes points into the one data measurement, each tagged edge=<number>, with fields = channel addresses (for example _sum/EssSoc, meter0/ActivePower).
  3. A history query filters by edge=<number> to pull back a single edge's data.

So all sites, gateways and meters live co-mingled in one measurement, distinguished purely by that numeric edge tag.

The gotcha: edges collide on their trailing number

The edge-name to number regex is

\D++(\d++)$,
which

This capturesextracts the trailing digitsnumeric ofrun rather than preserving the name:full edge ID:

Configured valueEdgeRole namein this repositoryParsed edgeInflux tag valueFinding
edge00
nfetestpi11
gw-aaron-pi-33
hillary-test-pi-1Hillary test edge ID1Collides with aaron-pi-1
aaron-pi-1Aaron edge ID1Collides with hillary-test-pi-1
sezibwa-rentals-gw-pi2Current Sezibwa Pi2 edge definition2No suffix collision with Hillary
nfetestpi1Hostname/deployment userNot applicable as currently configuredNot the backend edge ID

If an edge ID contains no parseable trailing number, the timedata write is not stored. This is Twonot edgescompletely whosesilent: namesTimedataInfluxDb.writeData() endlogs ina warning stating that it could not parse the numeric Influx Edge-ID, then returns without writing the notification.

What a collision does

InfluxDB identifies a point by measurement, tag set, and timestamp. Once two gateways share the same digitnumeric mapedge totag:

  • History queries cannot distinguish which gateway supplied a value.
  • Different channel fields can appear together under the same edge tag,series.
  • If both gateways write the same field at the same timestamp, later writes can replace or combine with the existing point according to InfluxDB point-update behavior.
  • Backend caches keyed by the parsed integer, such as timestamped-channel tracking, can also conflate the two edges.

The resulting history may therefore be mixed, overwritten, or both; “merge” should not be interpreted as guaranteed preservation of every value from both sources.

What is and theiris datanot mergesproven inabout the sharedincident

measurement.

Proven: Thethe backendimplementation cannotis tellcollision-prone, themand apart.two Thisrepository edge configurations currently resolve to edge=1.

Not yet proven: that this caused the reported Hillary-to-Sezibwa contamination. If the affected Sezibwa history was requested under aaron-pi-1, the collision is a verystrong plausiblecausal rootcandidate. causeIf ofit was requested under sezibwa-rentals-gw-pi2, the "Hillary Test" meter appearing inside the Sezibwa microgrid: if the test gateway's name ends in 1-versus-2 mapping means this specific mechanism does not explain it.

Confirm the affected edge ID and theexamine Sezibwa gateway nfetestpi1 also ends in 1, their channels land underproduction edge=1 together.

There is a second failure mode: an edge name with no trailing number throws inside parseNumberFromName, so its data isbefore silentlyfinalizing droppedthe (aroot-cause warning is logged, nothing is written).statement.

RecommendationImmediate containment

    1. EnsureInventory every edge nameregistered endswith inor connecting to the production backend.
    2. Compute the parsed numeric ID for each and identify duplicates before making changes.
    3. Disconnect colliding test rigs from production or assign a globally unique numbertemporary (uniquenumeric acrosssuffix.
    4. Back up InfluxDB and the wholebackend/metadata backend,configuration before renaming an edge.
    5. Update all coupled references together: metadata, API keys, gateway configuration, monitoring, dashboards, automation, and operational documentation.
    6. After each change, verify websocket connectivity, live channels, new timedata writes, history queries, and monitoring alerts.

    [!note] Unique numeric suffixes are containment, not justthe withinpermanent adesign
    A site),naming becauseconvention reduces immediate risk but remains brittle and easy to violate as the fleet grows.

    Permanent backend correction

    1. Use the complete immutable edge ID as the InfluxDB discriminator, or resolve the edge to another stable, globally unique identifier maintained by backend metadata.
    2. Validate uniqueness at edge registration and backend startup. Reject duplicate storage identifiers instead of accepting ambiguous writes.
    3. Fail visibly for invalid identifiers, with actionable logs and operational alerts.
    4. Add automated tests covering identical suffixes, multi-digit suffixes, IDs without numbers, reconnects, resends, and history-query isolation.
    5. Review other structures keyed by the parsed integer, including timestamped-channel tracking and aggregated timedata, so the fix covers more than the point tag.

    Migration requirements

    Changing the tag key or value can make existing history unreachable to current queries. The implementation therefore needs an explicit migration plan, such as:

    • dual-write the legacy numeric tag and the new full-ID tag for a controlled period;
    • support query fallback across both schemas during migration;
    • backfill only records that can be attributed confidently;
    • retain an immutable backup and a tested rollback path; and
    • define a cutover date after which the legacy numeric identity is onlyno thatlonger trailingaccepted.
    • digit.
    nfetestpi1,

    Historical-data nfetestpi3,audit pi2before arecleanup

    safe
      (1,
    1. Identify 3,exactly 2);which alogical Sezibwa edge displayed Hillary channels.
    2. Determine when hillary-test-pi-1 is not, because it collides withand nfetestpi1aaron-pi-1.
    3. Givewere anysimultaneously testconnected rig a non-colliding edge ID (for example a high number like ...-99) or keep it offto the same production backend entirely.and bucket.
    4. WhenInspect auditing per-site data, remember that filtering isedge=1 by thetime numericrange, edgeunique tag,channel inventory, device serial numbers, meter topology, and gateway connection logs.
    5. Classify records as confidently Hillary, confidently Aaron/Sezibwa, or ambiguous.
    6. Quarantine ambiguous records. Do not bydelete siteor name,rewrite sothem merely from channel-name assumptions.
    7. Document any irrecoverable overlap where the same field and timestamp may have been overwritten.

    Approval boundary

    Approved direction: immediate containment, a reviewable backend fix, collision istests, invisibleand unlessa youdocumented checkmigration design.

    Requires separate approval: irreversible deletion, reassignment, or rewriting of production historical data. That work must follow the rawbackup edgeand tags.attribution

audit above.