Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add means for Sensors to indicate invalid or unavailable value #356

Closed
BjarneBitscrambler opened this issue Jan 6, 2021 · 2 comments
Closed

Comments

@BjarneBitscrambler
Copy link
Contributor

Issue

Occasions arise when some sensors are unable to provide data, for example a depth sounder without a bottom fix, or a GPS sensor when satellite coverage is lost. There is also the rarer case when sensor hardware fails.

Solutions

In situations when data are unavailable, the Signal K spec (https://signalk.org/specification/1.5.0/doc/data_model.html) says:

Missing or Invalid Data

A sensor or gateway/server may want to send a message indicating known invalid data or the fact that the
sensor is functioning but can not provide data, for example when a depth sensor has no bottom fix. In this
case the value must be JSON null in the delta message and the server must return the value as a 
JSON null in the REST API.

The word may is used, indicating that this approach is not mandatory. The advantage of doing so is that compliant instruments will alert the user to the missing data. For example, the Signal K Instrument Panel (v 0.16.1) shows dashes in place of missing numeric values. Alternatives to providing a JSON null for invalid values are:

  • provide no value update at all during an outage. This will result in the Signal K display "freezing" at the last-known value. Depending on whether the instrument has a timeout set for stale data, and how long it lasts, the user may not notice the problem for quite a while.
  • continuing to send the last-know value. This is misleading to the user.
  • sending a nonsense value - one that normally would not occur. An example is a temperature of 0 K, or a heading of -99 radians. One difficulty with this approach is deciding on a nonsense value that works for all types of parameters. Another problem is that the different Signal K instruments may interpret the nonsense value in various ways - for instance showing a heading modulo(2*Pi), or not physically showing a negative sign because the display for tank capacity doesn't have one.

What Works on Multi-value Producers

I'm trying the JSON null approach (#349) for the Attitude parameter and it works well: the Signal K Instrument Panel displays -.---- for yaw, pitch, and roll during an interruption in orientation sensor operation (simulated by pulling the I2C SDA line off), and reverts to proper values when comms are restored. Implementing this for a multi-value parameter like attitude was easier than it will be for a single-value parameter like temperature. Yaw, pitch, and roll are passed to the SKOutput consumer in a struct; I merely had to add a struct member is_data_valid and in the as_signalk() method output a null instead of numeric value when appropriate.

Is Different for Single-value Producers...

For single-value parameters that are passed using NumericProducer (i.e. ints, floats, booleans) I'm unsure how best to proceed. Some out-of-band signalling method of indicating data validity while keeping output as a single variable is one thought. Another would be to switch to always use output as a struct, and to permanently have one struct member be is_data_valid, and have a second member contain the single-value output. Suggestions?

@mairas
Copy link
Collaborator

mairas commented Jan 7, 2021

To indicate data validity, you can just set the timeout parameter in the metadata. When new deltas have not arrived in timeout seconds, compliant Signal K delta consumers will regard the last value outdated.

Adding metadata in the SensESP internal pipeline would require a major overhaul of the ValueProducer and ValueConsumer classes and the propagated data types. The benefit would be questionable because, as said above, you can simply indicate invalid or missing data by not sending anything.

I don't think this change is aligned with the goals of this project. I'll close this issue.

@mairas mairas closed this as completed Jan 7, 2021
@BjarneBitscrambler
Copy link
Contributor Author

@mairas - I tried the approach you suggest of using the timeout parameter, and it does not work with the example Signal K Instrument Panel consumers (v0.17.1).

Using either the navigation.compassHeading path for which there exists a specific instrument, or the environment.indoor.illuminance path (from the SensESP Analog example) which uses a generic Signal K Instrument, neither one provided any indication that the data was outdated. The test consisted of setting a timeout of several seconds using the metadata in the sensor constructor, verifying that deltas were being sent and the instrument was updating, and then interrupting the data source so the deltas ceased. The standard SensESP datasources (freemem, uptime, etc) were still running, and their instruments were updating, but the compass and analog output instruments just froze their values for the duration of the outage.

So, it appears this is a situation where the intent of the Signal K spec is not being followed by both the instruments and SensESP, leading to a pitfall where a user can be looking at stale/invalid data without knowing about it. It can be fixed from either end, by either sending a null in place of invalid data, or by ensuring the instruments respect the timeout value. It probably should be fixed from both ends, to reduce future chances of matching up a producer and consumer with the same deficiencies and masking a problem.

I'm not going to wade into an argument whether this aligns with the goals of your project, but I do want to document this issue so others won't run across it unawares.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants