SignalK / specification

Signal K is a JSON-based format for storing and sharing marine data from different sources (e.g. nmea 0183, 2000, seatalk, etc)
Other
91 stars 69 forks source link

RFC 0001: A Structure for Specifying Equipment Associations #264

Open timmathews opened 8 years ago

timmathews commented 8 years ago

Version: 2.0

Summary

This RFC proposes a way to define associations between various pieces of equipment on board a boat. It should be flexible enough for non-boat uses as well, when the specification is expanded to those areas. It may also work for charts, routes and waypoints.

Motivation

Many shipboard items are related on one way or another. Engines and alternators are the topic du jour but there are many other relationships, especially in the electrical realm. Associations also exist for hydraulic systems, plumbing, and on some hybrid boats, even between electric and diesel propulsion systems. Signal K, nor – as far as I am aware – any other marine standard provides a way to describe these relationships. While many relationships are one-to-one and are naturally captured in the hierarchy of Signal K, there are others which are cross-functional or many-to-many, and these relationships cannot be captured in the existing schema.

The engine-alternator relationship is an obvious example. A less obvious one is that of a freshwater pump. A pump (or rather an associated pressure sensor) would likely be part of the tanks schema, but it is also an electrical load and should therefore be associated with a circuit so that its current consumption, run state, etc. can be monitored.

Detailed design

All of the relationship information exists as metadata in the Signal K object (_meta) and is also available through a relationships API provided by a Signal K server. Because of the nature of relationships (i.e. they must be created by the end user or an installer), this RFC does not apply to Signal K gateway implementations or simple Signal K sensors.

{
  "propulsion": {
    "engine0": {
      "_meta": {
        "includes": [
          "electrical.dc.sources.alternator0",
          "electrical.dc.sources.alternator1"
        ]
      }
    },
    "engine1": {
      "_meta": {
        "includes": [
          "electrical.dc.sources.alternator2",
          "electrical.dc.sources.alternator3"
        ]
      }
    }
  },
  "electrical": {
    "dc": {
      "sources": {
        "alternator0": {
          "_meta": {
            "requires": [
              "propulsion.engine0",
              "electrical.dc.distribution.mainbus"
            ]
          }
        }
      }
    }
  }
}

This has the added benefit of quickly indicating the direction of the relationship. Alternators require engines and distribution busses; engines and distribution busses include alternators.

Extending this to a relationships REST API, the resulting object might look a little different:

GET /relationships?for=electrical.dc

{
  "alternator0": {
    "requires": [
      "propulsion.engine0",
      "electrical.dc.distribution.mainbus"
    ]
  },
  "battery0": {
    "requires": [
      "electrical.ac.charger0",
      "electrical.dc.distribution.mainbus"
    ]
  },
  "distribution.mainbus": {
    "includes": [
      "electrical.dc.battery0",
      "electrical.dc.alternator0",
      "electrical.dc.loadPanel0"
    ]
  }
}

Drawbacks

While this adds some obvious complexity, perhaps the biggest drawback is that it makes deciding when something should be hierarchical or not a rather complex issue. If this structure had existed before defining the engine object, would transmissions be a subsection of engines or at the same level and and related through this construct? Perhaps it makes sense to limit this to cross-cutting concerns, like linking electrical and propulsion or plumbing and electrical.

Alternatives

Some possible additional keys include relatedTo, equivalentTo, provides and consumes. These could be used for example to indicate that an engine provides horsepower and an alternator consumes horsepower thereby establishing the directionality of the relationship. A battery would both consume and provide electricity.

{
  "_meta": {
    "relatedTo" : ["..alternator2"], 
    "equivalentTo" : [?],
    "provides" : ["electricity", "charging"],
    "consumes" : ["horsepower"]
  }
}

Unresolved questions

  1. Is an array of related objects sufficient or should there be more information?
  2. How can display devices use this information to group gauges?
  3. Can this be extended to charts, routes, buoys, etc?
rob42 commented 8 years ago

Hmm... yes we should have a way to track relationships between objects (keys?). It should be potentially bi-directional, aka the engine has an altermator, the alternator has (depends) on an engine. That would allow some powerful guis, fault tracking, and what-if scenarios, eg the engine is down, so what effect does that have on electrics and the current power consumption...

I dont like the global associations solution, its too divorced from the objects it relates too, and will get out of sync, or need a lot of maintenance. The meta solution has more appeal, but it must also work for objects, not just keys.

This makes me think of graph theory, uml, and osgi bundle stuff :-(

"_meta": {
     "dependsOn" : ["engine..."],
     "dependants" : [ optional, could reverse it via dependsOn, maybe special cases],
     "relatedTo" : ["..alternator2"], 
     "equivalentTo" : [?],
     "provides" : ["electricity", "charging"],
     "consumes" : ["horsepower"]
      ...
}

We dont need to design all that, just the basic structure so we can deal with the alternator issue.

timmathews commented 8 years ago

The meta solution has more appeal, but it must also work for objects, not just keys.

Doesn't it already? I thought _meta could exist at any node of the graph. As a was writing, I realized the _meta solution probably makes more sense, but I had already written the first part.

dependsOn and dependents are enough for now, although provides and consumes are potentially interesting. I also like includes and requires as keywords. An engine includes an alternator, but an alternator requires an engine. Likewise, a bus includes an alternator, a battery, a solar charger, a shore power charger, and a load panel, but doesn't require any of them.

Bot are necessary if we want to document a directional dependency graph.

tkurki commented 8 years ago

You guys are again thinking about a single json doc: why not have both, embedded in the objects and a separate associations list, available under a specific path?

I really think we must move beyond the single in-memory / serialised view of the universe.

timmathews commented 8 years ago

I'm certainly not opposed to it. Would we duplicate the info or provide references? I'm partial to references, but I can see the downsides of having extra indirection.

References would look like this:

{
  // associations object as above, abbreviated
  "relationships": {
    "engine0": [],
    "engine1": [],
    "startbatt0": []
    "andSoOn": []
  },
  "propulsion": {
    "engine0": {
      "_meta": {
        "$relationships": ["engine0"]
      }
    },
  },
  "electrical": {
    "dc": {
      "sources": {
        "alternator0": {
          "_meta": {
            "$relationships": ["engine0", "maindistributionbus"]
          }
        }
      }
    }
  }
}

And duplicating the information would mean having the associations object from above (which I'm kind of liking the name relationships for better) and having @rob42's proposed _meta. If we go this way, the associations/relationships object should be extended to support directionality.

tkurki commented 8 years ago

If you let go of putting everything in a single doc and think of responses to REST GETs .../associations and .../propulsion as generated from a single data model the question about duplication vs reference is not really relevant.

rob42 commented 8 years ago

I find it interesting to think over these things from different perspectives. For instance the signalk hierarchy could be represented by writing a unix files system, with $source as a link. value as a file. This allusion has no concept of depends, etc A UML modelling (ugh) allusion does, but experience shows that its used at the start of a project but rarely maintained, and if it is then its a large external effort. The round-trip uml>code>uml vision is largely dead now. Ive found the http://www.planttext.com/ method very useful, and easy to derive from misc data. Lessons to learn there in terms of easily and automatically deriving value from relationships. A separate relationships API fits nicely into this technique. Easy to add and extend too

Ive had a lot to do with SNMP in the past. Lots of good data, but the same problem as UML, you have to build the diagrams, and separately model the environment at great expense. And then the cool router icon flashes just before the phone rings :-(

The linux package management (apt) is very powerful this way. It provides a full dependencies/provides graph and successfully controls hierarchies of thousands of versions of apps. Lessons there I think.

In the end SNMP, JMX, NMEA and many other management protocols lack support for relationships, and have no way to propagate them. So they leave the problem of deriving and showing them to the user.

I think thats the problem we should solve here.

Provide a way that we can specify global relationships (aka an alternator depends on an engine, an engine depends on fuel, etc), and ways that a device can specify its own depends, provides, etc.

I am starting to think the relationships API is the solution. It should be optional, A server can query a device, and a device can provide its requirements, kind of like apt does. That then allows a future where we can manage complex systems upgrades, and derive dependency graphs for faults, draw pretty diagrams etc

thomasonw commented 8 years ago

OK, basic question here: In the current electrical schema the is an 'assocatedBus' embedded in the dcQuantities and acQuanities. This proves a way to create linkage, at least inside the electrical world. A battery might call out the 'houseBus', while a charger also calling out the 'houseBus' tells the world that both devices are connected. Could this idea be expanded? Example, upon adding alternator to the electrical schema (still tbd), there could be a field for 'assocatedEngine' to include the engine ID?

Is there sufficient standardization in all the schema's to let this work? Would I be able to associate an alternator to a generator in the same way, calling out the generators ID?

rob42 commented 8 years ago

Its possible and would work, but probably get messy when you consider future possibilities for relationships between things. If we can outline a generic way to do it to any item in the schema, then we have some powerful options later. For instance in the case above you can find everything connected to the houseBus, but which of them consumes and which produces power. So ideally we add a consumer key, but then the alternator consumes horsepower from the engine, so another key, etc.

thomasonw commented 8 years ago

That would be nice - and we then remove the embedded linkage now in the electrical schema? Moving to this generic solution.

And I assume data sources which have a level of linkage already built in (e.g., the NEMA2000 battery ID's) could automatically populated the SignalK linkage table as CAN packets arrive. (More work for the provider module it sounds like..)

tkurki commented 8 years ago

connected to the houseBus, but which of them consumes and which produces power. So ideally we add a consumer key, but then the alternator consumes horsepower from the engine, so another key, etc.

A battery may potentially consume or provide power, so there is both static and dynamic nature to the association.

See also http://www.xantrex.com/power-products/inverter-chargers/overview.aspx

pod909 commented 7 years ago

Some thoughts on this...

The fundamental purpose of Signal K is to provide a way to communicate a range of attributes (values and actions) that exist in the physical marine environment.

Within Signal K an attribute is represented as a key/value pair. The key gives meaning to the value or action. The value gives some kind of measure. The measure has a statistical meaning (e.g. the absolute value, a mean, a min, a max) for a time interval. The same time interval may be relevant to more than one attribute.

The value of an attribute has relevance with in a context. In Signal K the context is represented by a set of nested objects.

On the network attributes arise and are consumed by devices. A device is a kind of context. A device provides a bridge between to physical world and the network; capturing values and actions (sensors), showing them (displays) or reacting to them (alarms, switches, actuators, motors etc.).

Attributes may have more than one context. For instance the charge remaining on a starter battery has relevance in terms of the device that measures it, the circuit the battery is on and the batteries physical location.

Due to their nature sensors are normally unaware of the context of the attributes they provide. Network services need to understand how to translate attributes between contexts so that their relevance can be understood and they can be consumed by other devices. Specifically an attribute provided in the context of a sensor needs to be translated so that it can be understood in the context of a vessel.


A key is the description of an attribute. In Signal K the key is represented by a nested set of objects or a string.

A value is the measure of an attribute. It may be the absolute value or a statistical value.

An attribute exists within a context. In Signal K each context is an object whose id is a context name. General context can be defined by the Signal K standard, others only apply locally. Context may be nested inside each other. Context names need to be unique with in their parent context.

When the context is not defined by the Signal K standard a way is needed for a network node to tell consumers about the contexts that it can provide attributes for.

OPTION 1: Where attributes are streamed in a single context the context can be given at the start of the stream. OPTION 2a: A list of contexts available under a context can be listed at the root or before the point that none standard context start to exist in the object tree. OPTION 2b: A list of contexts available from a node can be made available via a separate service. OPTION 2c: Contexts can be discovered by inspecting the object tree.

We also need a way to tell a node how to map between the attributes in different context. This has most relevance when a value or action is provided in a sensor context and we want to update the attribute for one or more other contexts (e.g. the location with-in a vessel) as a result.

OPTION A: In the value object we could add a list of contexts that have an attribute that must be updated when this value is updated and a description of how the update should be made.

Some contexts currently defined by the Signal K standard:

Context: vessels Name: “vessels” Parent: root level container

Context: vessel Name: a uuid for the vessel Parent: vessels

Proposed new contexts:

Context: manifest Name: “manifest” Parent: vessel

Context: device Name: a UUID for the device Parent: manifest

Pulling it together (options 2a and A):

{
  "vessels": {
    "1234": {
       "manifest": {
         "achme-thing-12345": {
           "electrical": {
             "voltage": {
               "value":15,
               "n2k": {
                   "png": "965034985"
                   ...
               },
               "contexts": [
                 "vessels.1234.batteryStore.battery1"
                ]
              }
            }
          }
        },
        "tableOfContexts": [
          "batteryStore.battery1",
          "engineStarterCircuit"
        ],
        "batteryStore": {
          "battery1": {
            "electrical": {
              "voltage": {
                "latest": {
                "min": 12,
                "max": 34,
                "value": 15,
                "contexts": [
                  "vessels.1234.engineStarterCircuit"
                ]
               }
              }
            }
          },
          ...
        },
        "engineStarterCircuit": {
          "electrical": {
            "voltage": {
              "sum": {
                "value":36,
                "values": {
                  "vessels.1234.batteryStore.battery1": { "value": 15 },
                  "vessels.1234.batteryStore.battery2": { "value":  11 }
                }
         }
       }
    }
  }
}
sumps commented 7 years ago

What benefits and new functionality are we hoping this RFC will give us? Is it just to store various schematic diagrams of how equipment is connected together?

I like the idea of a manifest in which we can store all of the equipment and how it physically links together, where it is located and other associations. I do not like the idea of lots of duplication and certainly do not want to see dynamic data like voltages included in the manifest group.

pod909 commented 7 years ago

This structure allows:

Some use case that can be supported by this with out needing to extend the standard:

The manifest is vessel level list of things from which we receive values. So it's a context for a value it's self. The value:15 shown would be the raw value received from that thing. Just added a transport object to show how "source" could be handled in this model.

pod909 commented 7 years ago

With in this model it could be OK for values to exist at the branches and not just the leaves. The manifest would probably be better off outside of the vessels

timmathews commented 7 years ago

So, I think a first attempt at this requires the alternate approach I outlined above (with relationships available in _meta) and also via the relationships API which could provide the same data in a much easier to consume way for auto-configuring instrument panels.

Let's ignore the stuff I said about duplication because @tkurki is correct, whether the relationships exist in _meta, in a new relationships group or via a REST API, internally it's all the same information, there really isn't any duplication at all.

@pod909's hierarchical contexts are interesting, but I think drifting from the core concept of relationships. And I also think that sensors should remain pretty dumb. It's up to the Signal K server to assign meaning to the values received from a sensor.

@sumps, this stuff is all purely optional (as is most of SK) and I agree that it needs to be strictly segregated from values (excepting that it can also appear under _meta).

I'm going to update the RFC based on this and hopefully we can move forward with it. It needs a branch of the spec (and a PR) for the new objects under _meta and probably could benefit from a plugin in the server to provide the relationships API.

jboynes commented 7 years ago

@timmathews I proposed #297 as a way of defining device specific data. Left undefined in there is the mechanism for associating device-specific data values with a vessel-wide model. I think this RFC should be able to address that.

For example, I used an example of an environment sensor publishing data for node /devices/acme-bme280-f1df70/lastReading/temperature which would mapped by an installer to /vessels/2309999/environment/inside/masterCabin/temperature based on knowledge of where she installed the device. This seems like a relationship between those two paths.

pod909 commented 7 years ago

@timmathews the basic concept would be the same with none hierarchical contexts. Agree that the mapping belongs in _meta some how.

timmathews commented 7 years ago

Last night I updated the RFC and in so doing, perhaps I've better digested what @pod909 is getting at. And if I understand it correctly, it could have big implications for the SK schema and greatly simplify things at the same time. It may also address the undefined issue from #297 of associating a device-specific datum with a vessel datum.

I started writing this around midnight, but didn't finish. Hopefully I haven't forgotten anything I epiphany-ed last night.

To wit: all of the discussion about how to organize the electrical schema is moot. We just need the following:

electrical.dc.voltage
electrical.dc.current
electrical.dc.circuitState
electrical.dc.dimmerLevel

That's pretty much it. Maybe some additional stuff around chargers, e.g. chargeState, chargeMode, etc. But the complex hierarchy is completely unnecessary.

Why? Well, because we already have the ability to support multiple instances of a value by way of the values object:

"voltage": {
  "values": {
    "acme-thing-12345": {
      "value": 12.5,
      "timestamp": "2016-11-28T03:55:15Z",
      "context": "voltage"
    },
    "n2k-thing": {
      "value": 13.2,
      "timestamp": "2016-11-28T03:55:05Z",
      "pgn": 127751
    },
    "nmea0813-thing-VV": {
      "value": 12.5,
      "timestamp": "2016-11-28T03:55:15Z",
      "sentence": VVV
    }
  }  
}

Note that there isn't a default value at all in this case. This actually makes the job of a Signal K gateway much simpler, since it doesn't need to know how to get a generic DC voltage from PGN 127751 to the correct place in the SK hierarchy, nor does it need to know which one a user might prefer. It just publishes it to dc.voltage.values.thingThatGeneratedTheValue.

Then in the Signal K server (or just in an individual app, if the installation doesn't have a server), the device manifest is applied (which then generates the meta entries and data for the relationships API). The manifest provides "context" in the human sense for the data by using the Signal K "context" to map this data to specific uses.

Given the three voltage values above, let the manifest below be the equipment inventory and relationship model.

"manifest": {
  "alternator0": {
    // Don't get too hung up on the organization of attributes here (or their names). These are just
    // examples of things that could end up in `meta`
    "displayName": "Alternator #1 (12V, 100A)",
    "nominalVoltage": 12,
    "maximumVoltage": 14.8,
    "mimimumvoctage": 11.5,
    "maximumCurrent": 100,
    "deratingFactor": 0.3,
    "maximumTemperature": 145,
    // This is how the server knows where to get the value to populate the alternator leaves in the tree
    // This can also be used to generate a "$manifest" property in the tree for the object at this path
    "$source": "electrical.dc.voltage.values.acme-thing-12345"
    // These are the important parts for the relationships
    // They can be used to automatically populate values in the Signal K tree such as
    // "propulsion.engine0.alternator0.voltage" and "electrical.dcBus0.alternator0.voltage"
    "belongsTo": [
      "electrical.dc.bus0"
    ],
    "requires": [
      "propulsion.engine0"
    ]
  },
  "bus0": {
    "displayName": "House DC Bus (12V, 100A)",
    "nominalVoltage": 12,
    "$source": "electrical.dc.voltage.values.n2k-thing",
    "requires": [
      "electrical.dc.alternator0",
      "electrical.dc.battery0"
    ],
    "associatedWith": [
      "electrical.dc.batteryCharger0",
      "electrical.dc.solarMPTT0",
      "electrical.dc.loadPanel0",
      "electrical.dc.batteryCharger0",
      "electrical.dc.inverter0",
    ]
  },
  "battery0": {
    "displayName": "House Battery Bank (12V, 600Ah)",
    "nominalVoltage": 12,
    "maximumVoltage": 14.8,
    "minimumVoltage": 10.8,
    "$source": "electrical.dc.voltage.values.nmea0183-thing-VV",
    "capacity": 2160000,
    "belongsTo": [
      "electrical.dc.bus0"
    ]
  }
}

So, from this you can see that we have defined a place for values read from sensors (electrical.dc.voltage) with underlying support for multiple values from different sensors. This exists today (well, at a slightly different location, but we know that electrical needs rework anyhow). We show how useful, vessel specific metadata is added to the system. Ideally, this is configured through a GUI and persisted to disk (consider this an implementation detail). And finally, we show how the Signal K server (or a sufficiently smart client) can use this metadata to correctly associate arbitrary context-free sensor data with the appropriate parts of the vessel's Signal K schema in a generic and vessel-specific way.

No longer do we need to worry about pre-defining all of the possible locations in the schema for battery data, alternator data, solar charger data, some device we haven't thought of data, etc. It all exists in the manifest. And it still works in a configuration-free environment. All of the sensor data can still get to the screen and can still be displayed with the correct units, albeit with a somewhat generic name (which is easily overridden client-side). And the best part about this is that it doesn't require any changes (modulus planned changes to electrical) to already existing Signal K structure. It should work just as well for environment.depth.whatever as it does for electrical.dc.voltage.

@pod909, I hope I've understood correctly your goals with the manifest.

pod909 commented 7 years ago

Values start to propgate out from the manifest but there's no reason to limit mappings to just there.

TKs issue on time base is greatly facilitated by this. The value property becomes one of a number of 'function' values that could exist on the same level as the values.

Instead of just "value" you could have: "latest": the latest value from the values object by timestamp "sum", "mean", "max", "min"...

With suitable relationships in _meta those aggregate values could also be mapped out to other contexts.

I say values propogate and you've suggested multiple instances of a value. That is what they would look like in the tree however it would be pretty easy to normalize this in back end data so that the update of a value is automatically represented where ever the value exists in the SK object.

jboynes commented 7 years ago

@timmathews Thanks for the updates, I have a couple of clarifying questions/thoughts.

How vessel and manifest tie together. Would the manifest be part of the vessel type, appearing in the model at /vessels/{id}/manifest as @pod909 suggested?

How about a devices property at the root of the manifest as the parent for all the SK capable devices on the vessel? That would make it easier for us to add other things to the manifest object, such as a crew list, cargo list, stores etc.

Should we make a distinction between devices and equipment, where the former are related to devices that emit SignalK data? For example, if I have a dumb alternator with a SK-capable voltmeter on its output, the alternator would appear under equipment and the voltmeter under devices. The equipment tree would be a place for static reference information that the owner/installer wanted to add.

Each manifest entry could be described by a JSON schema provided by the manufacturer. This could be sourced from the same place as the metadata I proposed for device-vessel integration. For example, a device in its hello message includes the location of the schema for the manifest, which can be used to pre-populate the entry, including reference information like data types, units, value ranges, description, configurable values, supplemental data (battery capacity, tank capacity). That way the installer does not need to enter it by hand.

I don't see how the voltage tree handles a device that emits multiples of the same quantity e.g. for a multimeter emitting

{"thing":{"v1":12.2, "v2": 11.5, "i1":4.5}}

voltage.values.thing.value won't contain both. Rather than repeat values, we could do

{
  "voltage": {
    "thing": { "v1": 12.2, "v2":11.5}
  },
  "current": {
    "thing": { "i1": 4.5}
  }
}

That feels odd though.

If I follow this train of thought, I end up with a model where any tree structure for data becomes unnecessary and we end up with a map of named values where the names do not matter. The manifest becomes a store for descriptions of the values, with no real structure or commonality. The REST interface then becomes a way of querying for or subscribing to a subset of the values based on semantics rather than naming, and the subset of values is defined by a view in the UI (e.g. a "Anchored" or "Under Way" view that contains values selected by the user although some common default selections may be suggested by the UI application e.g. "Propulsion" or "Navigation").

I need to think on that a bit more.

pod909 commented 7 years ago

I put manifest inside the vessel but really it should be at the top level along side vessels

On 30 November 2016 at 07:37, Jeremy Boynes notifications@github.com wrote:

@timmathews https://github.com/timmathews Thanks for the updates, I have a couple of clarifying questions/thoughts.

How vessel and manifest tie together. Would the manifest be part of the vessel type, appearing in the model at /vessels/{id}/manifest as @pod909 https://github.com/pod909 suggested?

How about a devices property at the root of the manifest as the parent for all the SK capable devices on the vessel? That would make it easier for us to add other things to the manifest object, such as a crew list, cargo list, stores etc.

Should we make a distinction between devices and equipment, where the former are related to devices that emit SignalK data? For example, if I have a dumb alternator with a SK-capable voltmeter on its output, the alternator would appear under equipment and the voltmeter under devices. The equipment tree would be a place for static reference information that the owner/installer wanted to add.

Each manifest entry could be described by a JSON schema provided by the manufacturer. This could be sourced from the same place as the metadata I proposed for device-vessel integration. For example, a device in its hello message includes the location of the schema for the manifest, which can be used to pre-populate the entry, including reference information like data types, units, value ranges, description, configurable values, supplemental data (battery capacity, tank capacity). That way the installer does not need to enter it by hand.

I don't see how the voltage tree handles a device that emits multiples of the same quantity e.g. for a multimeter emitting

{"thing":{"v1":12.2, "v2": 11.5, "i1":4.5}}

voltage.values.thing.value won't contain both. Rather than repeat values, we could do

{ "voltage": { "thing": { "v1": 12.2, "v2":11.5} }, "current": { "thing": { "i1": 4.5} } }

That feels odd though.

If I follow this train of thought, I end up with a model where any tree structure for data becomes unnecessary and we end up with a map of named values where the names do not matter. The manifest becomes a store for descriptions of the values, with no real structure or commonality. The REST interface then becomes a way of querying for or subscribing to a subset of the values based on semantics rather than naming, and the subset of values is defined by a view in the UI (e.g. a "Anchored" or "Under Way" view that contains values selected by the user although some common default selections may be suggested by the UI application e.g. "Propulsion" or "Navigation").

I need to think on that a bit more.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SignalK/specification/issues/264#issuecomment-263803974, or mute the thread https://github.com/notifications/unsubscribe-auth/AF0KF2wOY6E3NqBjXWMqlCqjM1dFcm08ks5rDSeggaJpZM4KKuyR .

pod909 commented 7 years ago

some thought needs to be given to time base to allow for multiple values from the same source. time slicing may be a different thing altogether tho. At the moment the SK model is mostly about the latest value for each thing

On 30 November 2016 at 07:55, Ric Morris pod909@gmail.com wrote:

I put manifest inside the vessel but really it should be at the top level along side vessels

On 30 November 2016 at 07:37, Jeremy Boynes notifications@github.com wrote:

@timmathews https://github.com/timmathews Thanks for the updates, I have a couple of clarifying questions/thoughts.

How vessel and manifest tie together. Would the manifest be part of the vessel type, appearing in the model at /vessels/{id}/manifest as @pod909 https://github.com/pod909 suggested?

How about a devices property at the root of the manifest as the parent for all the SK capable devices on the vessel? That would make it easier for us to add other things to the manifest object, such as a crew list, cargo list, stores etc.

Should we make a distinction between devices and equipment, where the former are related to devices that emit SignalK data? For example, if I have a dumb alternator with a SK-capable voltmeter on its output, the alternator would appear under equipment and the voltmeter under devices. The equipment tree would be a place for static reference information that the owner/installer wanted to add.

Each manifest entry could be described by a JSON schema provided by the manufacturer. This could be sourced from the same place as the metadata I proposed for device-vessel integration. For example, a device in its hello message includes the location of the schema for the manifest, which can be used to pre-populate the entry, including reference information like data types, units, value ranges, description, configurable values, supplemental data (battery capacity, tank capacity). That way the installer does not need to enter it by hand.

I don't see how the voltage tree handles a device that emits multiples of the same quantity e.g. for a multimeter emitting

{"thing":{"v1":12.2, "v2": 11.5, "i1":4.5}}

voltage.values.thing.value won't contain both. Rather than repeat values, we could do

{ "voltage": { "thing": { "v1": 12.2, "v2":11.5} }, "current": { "thing": { "i1": 4.5} } }

That feels odd though.

If I follow this train of thought, I end up with a model where any tree structure for data becomes unnecessary and we end up with a map of named values where the names do not matter. The manifest becomes a store for descriptions of the values, with no real structure or commonality. The REST interface then becomes a way of querying for or subscribing to a subset of the values based on semantics rather than naming, and the subset of values is defined by a view in the UI (e.g. a "Anchored" or "Under Way" view that contains values selected by the user although some common default selections may be suggested by the UI application e.g. "Propulsion" or "Navigation").

I need to think on that a bit more.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SignalK/specification/issues/264#issuecomment-263803974, or mute the thread https://github.com/notifications/unsubscribe-auth/AF0KF2wOY6E3NqBjXWMqlCqjM1dFcm08ks5rDSeggaJpZM4KKuyR .

pod909 commented 7 years ago

Outside of how the data is represented in the REST interface for partial paths the tree structure has been on the way out for a while I think (?) . The reference servers are now key:value based.

On 30 November 2016 at 08:07, Ric Morris pod909@gmail.com wrote:

some thought needs to be given to time base to allow for multiple values from the same source. time slicing may be a different thing altogether tho. At the moment the SK model is mostly about the latest value for each thing

On 30 November 2016 at 07:55, Ric Morris pod909@gmail.com wrote:

I put manifest inside the vessel but really it should be at the top level along side vessels

On 30 November 2016 at 07:37, Jeremy Boynes notifications@github.com wrote:

@timmathews https://github.com/timmathews Thanks for the updates, I have a couple of clarifying questions/thoughts.

How vessel and manifest tie together. Would the manifest be part of the vessel type, appearing in the model at /vessels/{id}/manifest as @pod909 https://github.com/pod909 suggested?

How about a devices property at the root of the manifest as the parent for all the SK capable devices on the vessel? That would make it easier for us to add other things to the manifest object, such as a crew list, cargo list, stores etc.

Should we make a distinction between devices and equipment, where the former are related to devices that emit SignalK data? For example, if I have a dumb alternator with a SK-capable voltmeter on its output, the alternator would appear under equipment and the voltmeter under devices. The equipment tree would be a place for static reference information that the owner/installer wanted to add.

Each manifest entry could be described by a JSON schema provided by the manufacturer. This could be sourced from the same place as the metadata I proposed for device-vessel integration. For example, a device in its hello message includes the location of the schema for the manifest, which can be used to pre-populate the entry, including reference information like data types, units, value ranges, description, configurable values, supplemental data (battery capacity, tank capacity). That way the installer does not need to enter it by hand.

I don't see how the voltage tree handles a device that emits multiples of the same quantity e.g. for a multimeter emitting

{"thing":{"v1":12.2, "v2": 11.5, "i1":4.5}}

voltage.values.thing.value won't contain both. Rather than repeat values, we could do

{ "voltage": { "thing": { "v1": 12.2, "v2":11.5} }, "current": { "thing": { "i1": 4.5} } }

That feels odd though.

If I follow this train of thought, I end up with a model where any tree structure for data becomes unnecessary and we end up with a map of named values where the names do not matter. The manifest becomes a store for descriptions of the values, with no real structure or commonality. The REST interface then becomes a way of querying for or subscribing to a subset of the values based on semantics rather than naming, and the subset of values is defined by a view in the UI (e.g. a "Anchored" or "Under Way" view that contains values selected by the user although some common default selections may be suggested by the UI application e.g. "Propulsion" or "Navigation").

I need to think on that a bit more.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SignalK/specification/issues/264#issuecomment-263803974, or mute the thread https://github.com/notifications/unsubscribe-auth/AF0KF2wOY6E3NqBjXWMqlCqjM1dFcm08ks5rDSeggaJpZM4KKuyR .

pod909 commented 7 years ago

Agree that some more standard context, such as equipment, would be sensible to stop a free for all/server that is confusing to set-up initially/UI that just doesn't know where to look

(I'll stop using email now!)

On 30 November 2016 at 08:09, Ric Morris pod909@gmail.com wrote:

Outside of how the data is represented in the REST interface for partial paths the tree structure has been on the way out for a while I think (?) . The reference servers are now key:value based.

On 30 November 2016 at 08:07, Ric Morris pod909@gmail.com wrote:

some thought needs to be given to time base to allow for multiple values from the same source. time slicing may be a different thing altogether tho. At the moment the SK model is mostly about the latest value for each thing

On 30 November 2016 at 07:55, Ric Morris pod909@gmail.com wrote:

I put manifest inside the vessel but really it should be at the top level along side vessels

On 30 November 2016 at 07:37, Jeremy Boynes notifications@github.com wrote:

@timmathews https://github.com/timmathews Thanks for the updates, I have a couple of clarifying questions/thoughts.

How vessel and manifest tie together. Would the manifest be part of the vessel type, appearing in the model at /vessels/{id}/manifest as @pod909 https://github.com/pod909 suggested?

How about a devices property at the root of the manifest as the parent for all the SK capable devices on the vessel? That would make it easier for us to add other things to the manifest object, such as a crew list, cargo list, stores etc.

Should we make a distinction between devices and equipment, where the former are related to devices that emit SignalK data? For example, if I have a dumb alternator with a SK-capable voltmeter on its output, the alternator would appear under equipment and the voltmeter under devices. The equipment tree would be a place for static reference information that the owner/installer wanted to add.

Each manifest entry could be described by a JSON schema provided by the manufacturer. This could be sourced from the same place as the metadata I proposed for device-vessel integration. For example, a device in its hello message includes the location of the schema for the manifest, which can be used to pre-populate the entry, including reference information like data types, units, value ranges, description, configurable values, supplemental data (battery capacity, tank capacity). That way the installer does not need to enter it by hand.

I don't see how the voltage tree handles a device that emits multiples of the same quantity e.g. for a multimeter emitting

{"thing":{"v1":12.2, "v2": 11.5, "i1":4.5}}

voltage.values.thing.value won't contain both. Rather than repeat values, we could do

{ "voltage": { "thing": { "v1": 12.2, "v2":11.5} }, "current": { "thing": { "i1": 4.5} } }

That feels odd though.

If I follow this train of thought, I end up with a model where any tree structure for data becomes unnecessary and we end up with a map of named values where the names do not matter. The manifest becomes a store for descriptions of the values, with no real structure or commonality. The REST interface then becomes a way of querying for or subscribing to a subset of the values based on semantics rather than naming, and the subset of values is defined by a view in the UI (e.g. a "Anchored" or "Under Way" view that contains values selected by the user although some common default selections may be suggested by the UI application e.g. "Propulsion" or "Navigation").

I need to think on that a bit more.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SignalK/specification/issues/264#issuecomment-263803974, or mute the thread https://github.com/notifications/unsubscribe-auth/AF0KF2wOY6E3NqBjXWMqlCqjM1dFcm08ks5rDSeggaJpZM4KKuyR .