Asset#

class nominal.Asset#

A physical or logical system under test.

Obtained from a client rather than constructed directly:

a = c.getOrCreateAsset("engine-3");   % by name, creating if absent
a = c.assetByRid(rid);                % by RID

Example:

ds = a.getOrCreateDataset("telemetry", "tlm");
r  = a.run("burn-12");
a.update(Labels=["production" "orbit"]);
Constructor Summary
Property Summary
Rid#

Resource identifier.

Name#

Display name.

Description#

Description, or “” if it has none.

Url#

Web URL in the Nominal app.

Labels#

All labels, as a string array.

Properties#

All properties, as a containers.Map.

Method Summary
property(key)#

Value of one property. Errors if the key is absent.

Returns:

string – The property’s value.

setProperty(key, value)#

Set one property, keeping the rest.

a = a.setProperty("serial", "SN-0042");

Re-reads the asset first, so properties set since this object was fetched are kept.

Returns:

nominal.Asset – The updated asset.

removeProperty(key)#

Remove one property, keeping the rest.

Errors if the asset has no such property.

Returns:

nominal.Asset – The updated asset.

datasources(options)#

Everything attached to this asset, as a table.

s = a.datasources(); % read once, then reused s = a.datasources(Refresh=true); % ask Nominal again tlm = s(s.Type == “dataset”, :); % datasets only s.Tags{1} % one source’s tag filter

The first call asks Nominal and keeps the answer, and later calls on this object reuse it. A dataset attached since, by addDataset or from the web app, is not listed until you pass Refresh=true.

Options:

Refresh – Ask Nominal again. Costs one request.

Returns:

table – Variables RefName, Rid, Type, Tags and Offset, ordered by reference name. Type is “dataset”, “video”, “connection” or “other”, and only a dataset RID can open a stream. Tags holds each source’s tag filter as a containers.Map, empty when it sees the whole source. Offset is a duration.

addDataset(dataset, refName, options)#

Attach a dataset you already have to this asset.

a.addDataset(ds);
a.addDataset(ds, "can");
a.addDataset(ds, Tags=struct(UUT="A"));
a.addDataset(ds, Tags=dictionary("test-stand", "3"));

Write one shared dataset with a tag per unit under test, then give each unit’s asset its own slice:

assetA.addDataset(ds, Tags=struct(UUT="A"));
assetB.addDataset(ds, Tags=struct(UUT="B"));

An asset holds a dataset once per tag filter. Attaching the same dataset again with the same Tags moves it to the new reference name. Attaching it with different Tags adds it alongside, so one dataset can appear twice, split by tag:

a.addDataset(ds, "drone",  Tags=struct(source="drone"));
a.addDataset(ds, "remote", Tags=struct(source="remote"));

This asset object is a snapshot and will not show the new data source. Use a.datasources(Refresh=true) to see it.

Parameters:
  • dataset

    Any dataset object: one fetched by RID, from a search, or from an ingest.

  • refName

    The dataset’s name within this asset, unique among its data sources. Spaces, dots and mixed case are fine. It matters when one asset carries two sources measuring the same thing, say a CAN log and a test rig both reporting “engine temp”. Omit it and one is chosen for you: “default” on an asset with none, otherwise the dataset’s own name, otherwise that with a number.

Options:

Tags – Limit this asset to the dataset’s series carrying every one of these tags. A struct, or a dictionary (R2022b+) for a key that is not a valid field name. Values are strings, and numbers are converted.

removeDataset(refName)#

Detach the data source with this reference name.

a.removeDataset("can");

The dataset itself is untouched, and stays on any other asset holding it. Everything else on this asset keeps its tag filter. Errors if nothing here has that reference name.

renameRefName(oldName, newName)#

Change the reference name a data source is under.

a.renameRefName("default", "flight-telemetry");

Workbooks using this asset are updated to match. The tag filter, if any, is kept. Errors if oldName is not attached or newName already is.

fetch(channel, startTime, endTime, options)#

Read one channel as this asset sees it, as a timetable.

tt = a.fetch("rpm", t0, t1)
tt = a.fetch("rpm", t0, t1, RefName="can", Buckets=2000)

Reads through one of the asset’s data sources, so that source’s tag filter and time offset apply without being passed. Otherwise as nominal.Dataset.fetch.

Parameters:
  • startTime

    Zoned datetime or int64 nanoseconds.

  • endTime

    Zoned datetime or int64 nanoseconds.

Options:
  • RefName – Which data source. Defaults to “default”.

  • Buckets – Have Nominal decimate to roughly this many points.

  • Tags – Narrow further, if the source still holds several tag sets.

Returns:

timetable – One variable, named after the channel.

getAttachedDataset(name)#

A dataset already on this asset, by name.

d = a.getAttachedDataset("telemetry");

Read-only: it never creates or attaches anything.

Errors when no dataset of that name is attached, and when more than one is. a.datasources() lists everything without erroring.

Returns:

nominal.Dataset – The attached dataset.

getOrCreateDataset(name, refName, options)#

Ensure this asset has a dataset of that name.

d = a.getOrCreateDataset("telemetry");
d = a.getOrCreateDataset("telemetry", "tlm");
d = a.getOrCreateDataset("telemetry", AttachExisting=false);

Dataset names are not unique in Nominal, so this resolves in three steps and prints which one it took:

  1. A dataset of that name already attached to this asset is returned as-is.

  2. Otherwise a dataset of that exact name elsewhere in the workspace is attached to this asset and returned.

  3. Otherwise one is created and attached.

Step 2 finds the dataset a colleague already made, but it changes your asset based on a name match.

Errors when several datasets share the name, listing their RIDs so you can pick one with client.datasetByRid.

Parameters:

refName

The dataset’s name within this asset, used only when attaching. Omit it and a free one is chosen, as for addDataset.

Options:

AttachExisting – false skips step 2, going straight from step 1 to step 3. Defaults to true.

Returns:

nominal.Dataset – The dataset, attached to this asset.

run(name, startTime)#

Create a run on this asset.

r = a.run("burn-12");                                 % starts now
r = a.run("burn-12", datetime("now", TimeZone="UTC") - minutes(5));

The run is left open. Close it with r.finish().

Parameters:

startTime

Zoned datetime or int64 nanoseconds since the epoch. Omit it to start the run now. int64(0) is the epoch itself.

Returns:

nominal.Run – The new, open run.

update(options)#

Apply metadata changes, returning the updated asset.

a2 = a.update(Name="x", Description="y", ...
              Properties=struct(phase="burn"), ...
              Labels=["a" "b"]);

Options not passed are left alone. Labels and Properties REPLACE rather than merge: passing Labels discards whatever the asset had, so read a.Labels first and concatenate if you mean to add. setProperty changes one property and keeps the rest.

Options:
  • Name – New display name.

  • Description – New description.

  • Properties – Struct of key-value pairs, replacing all of them. struct() clears them.

  • Labels – String array, replacing all of them. string.empty clears them.

Returns:

nominal.Asset – A new object with the changes applied. The original still shows the pre-update state.