OpenEMS Backend InfluxDB Data Model and Edge-ID Collision
How[!warning] Verification status
The storage-key collision vulnerability is confirmed in source code, and theOpenEMSrepositoryBackendcontainsstoresatime-seriesreal configured collision. However, the vulnerability alone does not prove that Hillary data contaminated the current Sezibwa Pi2 history. Historical causation must be established frommultipleproductionEdgeInfluxDBgatewaysdata,inconnectionInfluxDB,periods, andagatewaynaminglogsgotchabeforethatanycanrecordssilentlyaremergerewrittentwooredges' data.deleted.
AllExecutive edges write to one shared measurementconclusion
- The
backend'sconfigured backend Timedata.InfluxDBwritercomponentputswritesevery edge'sedge data into asingleshared InfluxDBmeasurement,measurement,whosecurrentlydefaultdata. - 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-1andaaron-pi-1; both map toedge=1. This isdata.aTheregenuine collision risk. - The current Sezibwa Pi2 edge definition is
nosezibwa-rentals-gw-pi2,measurementwhich(table)mapspertoedge=2and does not collide with Hillary. nfetestpi1is a hostname/deployment user in this repository, not the backend edgeorID,perandsite.shouldEachnot be used as evidence of an edge-tag collision.
Confirmed backend data pointmodel
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 . “Measurement” is the correct InfluxDB term; it is analogous to, but not identical with, a influxEdgeIdmeasurement="data"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
Each Edge/gateway connects to the Backend over a websocket and pushesTimestampedDataNotifications (channel values plus timestamps).TimedataInfluxDb.write(edgeId, ...)converts the edge name to an integer, then writes points into the onedatameasurement, each taggededge=<number>, with fields = channel addresses (for example_sum/EssSoc,meter0/ActivePower).A history query filters byedge=<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++)$,
This capturesextracts the trailing digitsnumeric ofrun rather than preserving the name:full edge ID:
| Configured value | Finding | ||
|---|---|---|---|
hillary-test-pi-1 | Hillary test edge ID | 1 | Collides with aaron-pi-1 |
aaron-pi-1 | Aaron edge ID | 1 | Collides with hillary-test-pi-1 |
sezibwa-rentals-gw-pi2 | Current Sezibwa Pi2 edge definition | 2 | No suffix collision with Hillary |
nfetestpi1 | Hostname/deployment user | Not applicable as currently configured | Not 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
edgetag,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
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
EnsureInventory every edgenameregisteredendswithinor connecting to the production backend.- Compute the parsed numeric ID for each and identify duplicates before making changes.
- Disconnect colliding test rigs from production or assign a globally unique
numbertemporary(uniquenumericacrosssuffix. - Back up InfluxDB and the
wholebackend/metadatabackend,configuration before renaming an edge. - Update all coupled references together: metadata, API keys, gateway configuration, monitoring, dashboards, automation, and operational documentation.
- After each change, verify websocket connectivity, live channels, new timedata writes, history queries, and monitoring alerts.
- Use the complete immutable edge ID as the InfluxDB discriminator, or resolve the edge to another stable, globally unique identifier maintained by backend metadata.
- Validate uniqueness at edge registration and backend startup. Reject duplicate storage identifiers instead of accepting ambiguous writes.
- Fail visibly for invalid identifiers, with actionable logs and operational alerts.
- Add automated tests covering identical suffixes, multi-digit suffixes, IDs without numbers, reconnects, resends, and history-query isolation.
- Review other structures keyed by the parsed integer, including timestamped-channel tracking and aggregated timedata, so the fix covers more than the point tag.
- 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
onlynothatlongertrailingaccepted. - Identify
3,exactly2);whichalogical Sezibwa edge displayed Hillary channels. - Determine when
hillary-test-pi-1is not, because it collides withandnfetestpi1aaron-pi-1. Givewereanysimultaneouslytestconnectedrig a non-colliding edge ID (for example a high number like...-99) or keep it offto the same production backendentirely.and bucket.WhenInspectauditing per-site data, remember that filtering isedge=1bythetimenumericrange,uniqueedgetag,channel inventory, device serial numbers, meter topology, and gateway connection logs.- Classify records as confidently Hillary, confidently Aaron/Sezibwa, or ambiguous.
- Quarantine ambiguous records. Do not
bydeletesiteorname,rewritesothem merely from channel-name assumptions. - Document any irrecoverable overlap where the same field and timestamp may have been overwritten.
[!note] Unique numeric suffixes are containment, not
justthewithinpermanentadesign
Asite),namingbecauseconvention reduces immediate risk but remains brittle and easy to violate as the fleet grows.
Permanent backend correction
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:
nfetestpi1Historical-data nfetestpi3,audit pi2before arecleanup
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