Describe the device once
A ModDef document is a declarative map of a device's Modbus registers: storage types, byte order, scaling, sentinels, write constraints, and the semantic measurand each point reports. It is the same file whether you read it from Go, TypeScript, Rust, Python, C, or C++.
No hand-written register offsets scattered across firmware. No re-deriving the scale factor in three codebases. The definition is the source of truth; every runtime decodes it identically.
# growatt-sph.moddef.yaml: one definition, every runtime
- point_id: pv1_voltage
storage_type: U16
value_type: { primitive: DECIMAL }
mapping: { space: INPUT_REGISTER, offset: 3 }
transform: { scale: { numerator: 1, denominator: 10 } }
measurand: { base_quantity: voltage }
Use it from your stack
Load the definition, bind a transport, and read a point by name. The runtime applies the offset, scaling, byte order, and sentinels from the document, so you never repeat them in code. The same call returns 230.5 in every language.
Or query by meaning with a measurand (“grid frequency”, “L1-N voltage”) and let the runtime find the point.
- Go
- TypeScript
- Rust
- Python
- C
- C++
doc, _ := moddef.Load("growatt-sph.moddef.yaml")
dev, _ := client.New(doc, "growatt-sph", transport)
v, _ := dev.ReadPoint(ctx, "pv1_voltage")
fmt.Println(v) // 230.5
const doc = await loadDocument("growatt-sph.moddef.yaml");
const dev = Device.create(doc, "growatt-sph", transport);
console.log(await dev.readPoint("pv1_voltage")); // 230.5
let doc = moddef_core::load("growatt-sph.moddef.yaml")?;
let mut dev = Device::new(&doc, Some("growatt-sph"), transport)?;
let v = dev.read_point("pv1_voltage").await?; // 230.5
doc = load("growatt-sph.moddef.yaml")
dev = Device.create(doc, "growatt-sph", transport)
print(await dev.read_point("pv1_voltage")) # 230.5
md_doc_t doc;
md_doc_init(&doc, flash_ptr, flash_len); /* zero-copy view */
md_dev_t dev;
md_dev_init(&dev, &doc, MD_STR("growatt-sph"), &transport);
md_value_t v;
md_dev_read(&dev, MD_STR("pv1_voltage"), &v); /* v.v.f64 == 230.5 */
auto doc = moddef::Document::view(flash_bytes).value();
auto dev = moddef::Device::open(doc, "growatt-sph", transport).value();
if (auto v = dev->read("pv1_voltage"); v && v->as_f64())
printf("%.1f V\n", *v->as_f64()); // 230.5
Idiomatic in every language
One schema, six implementations that share a conformance suite. Pick the SDK your stack already speaks.