You have three sites and three different OEM feeds. Huawei CSV from Site A. Enphase JSON from Site B. Solarman exports from Site C. You already know the pain: incompatible timestamps, inconsistent error codes, and no single query path across the fleet.
This guide is not a concept piece. It is a seven-day implementation sprint. At the end of the week, you should have one normalized output contract, one validation path, and one baseline fault view across all sites.
Day 1: Define the Ingestion Contract
Start by inventorying every data source you actually ingest, not what the vendor documentation claims is available. Document transport type, interval, timezone behavior, and known missing fields.
- List each OEM source and file/API shape.
- Record interval and timestamp conventions.
- Capture current failure modes (missing records, malformed timestamps, null energy fields).
Your output for Day 1 is a simple source manifest that future transforms can reference.
Day 2: Transform One OEM End-to-End
Pick the noisiest or most business-critical feed first. Build the ODSE transform for that single source and keep scope strict: timestamp normalization, energy field mapping, and error classification.
from odse import transform
rows = transform("huawei_export.csv", source="huawei")
print(rows[0])
Do not optimize yet. The objective is one stable transform path from raw payload to ODSE-compliant records.
Day 3: Add Validation as a Gate, Not a Report
Validation should block bad data before it reaches analytics. If validation runs only as a weekly QA report, you will still make decisions on corrupted inputs.
from odse import validate
result = validate("site_a_odse.json")
print(result.is_valid)
print(result.errors)
Track validation failure classes by frequency. This becomes your remediation backlog.
Day 4: Normalize Two Additional OEMs
Now bring in the other two OEM feeds using the same contract. Avoid custom per-site outputs. The purpose of ODSE is one schema, not three tidy silos.
- Map equivalent energy semantics to the same ODSE fields.
- Map OEM-native errors to shared `error_type` values.
- Preserve raw OEM code as optional diagnostic context.
By end of day, you should be able to concatenate all three outputs without schema exceptions.
Day 5: Build the Portfolio-Level Views
Create two baseline outputs that stakeholders can trust immediately:
- Portfolio fault rollup by `error_type`
- Completeness report by site and day
This is where interoperability moves from engineering task to operating capability.
Day 6: Harden for Real Operations
Add retry handling, idempotent replay behavior, and explicit timezone guards. Most integration failures happen in operations, not during happy-path development.
- Implement replay-safe ingestion.
- Add alerting for transform/validation failure spikes.
- Document fallback behavior for delayed source data.
Day 7: Freeze the Contract and Publish Internal Runbook
Finalize your ODSE contract and document ownership boundaries: who updates transforms, who handles validation failures, and who approves schema-version updates.
Your week-one success criteria:
- Three OEM sources normalized to one ODSE schema.
- Validation running as a required gate.
- Portfolio fault and completeness views available to operations.
Common Mistakes to Avoid
1) Treating ODSE as an analytics layer
ODSE is a data interchange layer. Keep forecasting and anomaly models downstream.
2) Deferring error taxonomy mapping
If this is postponed, you preserve fragmentation under a new file format.
3) Skipping validation in production pipelines
Unvalidated records create silent failures that surface as bad decisions later.
What “Done” Looks Like
At the end of this sprint, you have not solved every analytics problem. You have done something more fundamental: you have created one trustworthy data contract across a fragmented OEM estate.
That becomes the foundation for everything else, from anomaly detection to utility reporting to compliance workflows.
Install `odse`, run your first transform, validate one week of historical data, and open an issue for any unsupported OEM mappings.