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

Reporting no known location through the Location object (/6) #570

Open
kFYatek opened this issue Oct 10, 2023 · 21 comments
Open

Reporting no known location through the Location object (/6) #570

kFYatek opened this issue Oct 10, 2023 · 21 comments

Comments

@kFYatek
Copy link

kFYatek commented Oct 10, 2023

The Location object (/6) in its current version 1.0, defines the Latitude, Longitude and Timestamp resources as Mandatory; however, the device may often not know its location, for example when it is still waiting for the first GPS fix since reboot.

What is the preferred way of reporting such condition by a LwM2M Client device?

Here are some possible solutions, none of them feeling "right":

  • Report the (0, 0) coordinates. This seems to be the most common approach - however, (0, 0) are perfectly valid coordinates in the Gulf of Guinea, which may be valid for e.g. a boat or an aircraft.
    • That could be paired with the Timestamp value of 0, which would be interpreted as 1970-01-01, which is an obviously improbable value. However, this requires the server to query the Timestamp resource to check the location validity, even if it's only interested in the coordinates. Using 1970-01-01 as an "invalid time" value, while common, doesn't feel particularly elegant, as it is still technically a valid timestamp.
    • Alternatively, the device could report the Radius of more than the circumference of Earth; however, this not only requires the server to query additional resource, but also is infeasible for devices that otherwise don't support the Radius resource - the device would need to set the Radius to some valid value once valid location is available, which may not always be feasible.
  • Report NaN (not-a-number) values. That would be arguably the most elegant solution, but unfortunately not all data types supported by LwM2M have a clear representation of NaN values - JSON explicitly doesn't support those, and for Plain Text it's not defined. This leaves only TLV and CBOR-based formats as feasible for transferring such values, which isn't really acceptable.
  • Make attempts to read the resources result in some CoAP-layer error, e.g. Internal Server Error. That is "clean" in terms of data model consistency, but explicitly expecting error responses complicates server-side logic, in particular when the Observe/Notify mechanism is to be considered - it is impossible to start an observation if the current response is an error, so it would make it impossible for the server to wait for a valid location by means of an Observe request.
  • Disregard the Mandatory status of those resources and don't populate them when valid location is not avaiable. That would obviously violate the object definition; not only that, supporting resources that show up and disappear depending on the client state complicates server-side logic and existing servers are known to not handle this case elegantly (even for properly Optional resources).
  • Don't populate the entire Object Instance of the Location object until a valid location is avaiable; that is also "clean" in terms of consistency, but feels somewhat heavy-handed. It also mandates an Update request once a valid location is available (because the list of object instances has changed). It, however, makes it technically possible to issue an Observe request (the server can observe the entire /6 path).

Here are some possible proposed solutions that would require amending the LwM2M TS and/or the Location object definition:

What do you think about each of those?

@kiemlicz
Copy link

Very nice summary!

(0,0) coordinates are valid coordinates - period.

Make attempts to read the resources result in some CoAP-layer error, e.g. Internal Server Error. That is "clean" in terms of data model consistency, but explicitly expecting error responses complicates server-side logic

Partially agree: 5.03 fits, this should be expected by any server - not only for location object.
If the data cannot be returned currently, then re-try (5.03)

If for any reason: error code is not meant to be used here then Add an additional resource to the Location object that would signify the validity of other resources. sounds 'right'

@sbernard31
Copy link

Just for completeness :

Disregard the Mandatory status of those resources and don't populate them when valid location is not avaiable

I guess that mean client will return NOT_FOUND ? if I guess right then you will face some issue with Observe Request too.

@sbernard31
Copy link

Use NaN values and define a standard representation of those for the remaining data types - for example as the string nan for Plain Text, and as the null value for JSON-based formats.

For pure JSON, the RFC for number says :

      Numeric values that cannot be represented in the grammar
      below (such  as Infinity and NaN) are not permitted.

but eventually you can consider to use null (but this is no more a Number from the RFC point of view)

For SenML, I'm not sure we can do that.
The RFC says that v JSON Type is Number and :

  • I understand that Number means not null (see above ☝️)
  • I see nothing which allow usage of null in this RFC.

Note that it seems also true for SenML-CBOR :

      For JSON Numbers, the CBOR representation can use integers,
      floating-point numbers, or decimal fractions (CBOR Tag 4);
      however, a representation SHOULD be chosen such that when the CBOR
      value is converted to an IEEE double-precision, floating-point
      value, it has exactly the same value as the original JSON Number
      converted to that form.  For the version number, only an unsigned
      integer is allowed.

From SenML point of view, I guess the idea behind this is : "If you have no value just don't add the SenML record" ?

@sbernard31
Copy link

sbernard31 commented Oct 11, 2023

Use NaN values and define a standard representation of those for the remaining data types - for example as the string nan for Plain Text, and as the null value for JSON-based formats.

I understand that this will lead to make all number nullable in all LWM2M Object. I don't know if we want to do that. 🤔

(This remember me this old discussion about mandatory and nullable value at : #77 (comment))

@giuseppe-melis
Copy link

giuseppe-melis commented Oct 11, 2023

I opened the issue #508 3 years ago, but we have never submitted any new object version proposal :-(
We put hold on this proposal because in the meantime we used a different approach: technically the fix is invalid when the timestamp is 0... so the first option of the summary.

Related to the sentence "this requires the server to query the Timestamp resource to check the location validity, even if it's only interested in the coordinates", I don't agree because the lat-long set of info without the timestamp is an incomplete meaning...
I was in position A at timestamp A, I was in position B at timestamp B, etc
so the meaning set of info must be lat-long-time, and for this reason all 3 were defined as mandatory at the beginning

@sbernard31
Copy link

sbernard31 commented Oct 11, 2023

Add an additional resource to the Location object that would signify the validity of other resources. This has been proposed before, see #508, but not put forward since.

So this has same drawback than using timestamp=0 or I missed something ?

@sbernard31
Copy link

I don't agree because the lat-long set of info without the timestamp is an incomplete meaning

This can be generally true, but I can imagine use case where you just want to know "last known position" and so for this usecase it seems to me that timestamp is not really mandatory.

@sbernard31
Copy link

Another option :

Specify in Location Object, a specific value to which is not a valid latitude / longitude which means unknown.
Eg. if a valid value for longitude is between 0.0 and 360.0 , then maybe we define that 512 means unknown.

(I'm not an expert in GPS coordinate, so maybe this is not possible.)

@kFYatek
Copy link
Author

kFYatek commented Oct 11, 2023

Add an additional resource to the Location object that would signify the validity of other resources. This has been proposed before, see #508, but not put forward since.

So this has same drawback than using timestamp=0 or I missed something ?

Mostly. It is arguably more elegant, because we wouldn't need to rely on 1970-01-01 being treated as "invalid time", so this would make it possible to report historical locations from the 1960s and 1970s if desired for any reason ;) Yes, I know it's little more than a weird hypothetical.

Another option :

Specify in Location Object, a specific value to which is not a valid latitude / longitude which means unknown. Eg. if a valid value for longitude is between 0.0 and 360.0 , then maybe we define that 512 means unknown.

(I'm not an expert in GPS coordinate, so maybe this is not possible.)

The latitude is in the range [-90, 90] and the longitude is in the range [-180, 180] (-180 is equivalent to 180 but there doesn't seem to be a clear standard on which to include). Using values clearly outside of those ranges is indeed an interesting idea, if a bit hacky.

@sbernard31
Copy link

Using values clearly outside of those ranges is indeed an interesting idea, if a bit hacky.

Yep, but maybe the solution with less concrete drawback ? and this looks like a bit what is done for Object Link Data type :

     An Object Link referencing no Object Instance will contain 2 MAX-ID values (null link).

@kiemlicz
Copy link

then maybe we define that 512 means unknown. my 2 cents: I feel uneasy about this

  • currently there are no limits/range for lat and lon
  • something similar could be proposed for different date-type resource, e.g. use 40 as a surely invalid day, however there are inventions like lienient calendar. I don't know if something equivalent exists for GPS location data (seems possible to wrap the coordinates)

@sbernard31
Copy link

currently there are no limits/range for lat and lon

I'm not sure 🤔, I understand that a range is defined.

The Location object says :

  • For resource 0 : The decimal notation of latitude, e.g. -43.5723 [World Geodetic System 1984].
  • For resource 1 : The decimal notation of longitude, e.g. 153.21760 [World Geodetic System 1984].

So I hope this refer to a kind of standard. I understand this is probably what is described here : https://en.wikipedia.org/wiki/Decimal_degrees ? (better source to real standard are welcome)

If it's right, it is said :

    As with latitude and longitude, the values are bounded by ±90° and ±180° respectively. 

(which matches #570 (comment))

@sbernard31
Copy link

something similar could be proposed for different date-type resource, e.g. use 40 as a surely invalid day, however there are inventions like lienient calendar. I don't know if something equivalent exists for GPS location data (seems possible to wrap the coordinates)

As long as this is clearly defined in Location object that this kind of lenient notation is not allowed (if it exists), I don't see the issue.

@sbernard31
Copy link

Even if I can agree using a constant is maybe not so elegant, the question is "which is the least bad solution".

With current big picture, IMHO, defining a constant for unknown value solves all issue exposed above at cost of some elegance.
Maybe not so bad trade-off. 🙂

@kFYatek
Copy link
Author

kFYatek commented Oct 11, 2023

Even if I can agree using a constant is maybe not so elegant, the question is "which is the least bad solution".

With current big picture, IMHO, defining a constant for unknown value solves all issue exposed above at cost of some elegance. Maybe not so bad trade-off. 🙂

Personally I'd be more for a "any value outside of the valid range is treated as no valid value" kind of definition, rather than defining a specific constant. Feels less random IMO, and makes the meaning of all possible values clear. If we designate e.g. 512 as a specific "null" constant, then what would 1024 mean?

But the idea of using out-of-range values seems to indeed solve all the issues.

What would be the compatibility implications? Are there any implementations known to use alternate ranges, e.g. [0, 360] instead of [-180, 180], or imperfect wraparounds (e.g. temporarily reporting 180.1 instead of -179.9 when travelling across the 180th meridian), that would be affected by explicitly defining all out-of-range values as "null"?

@sbernard31
Copy link

Personally I'd be more for a "any value outside of the valid range is treated as no valid value" kind of definition, rather than defining a specific constant. Feels less random IMO, and makes the meaning of all possible values clear

I don't know if this is really random but yes this is arbitrary value.

If we designate e.g. 512 as a specific "null" constant, then what would 1024 mean?

  • in range => valid value (expected behavior)
  • 512 (or something else) => unknown value/no value (expected behavior)
  • other values => invalid value (bad device behavior)

What would be the compatibility implications? Are there any implementations known to use alternate ranges, e.g. [0, 360] instead of [-180, 180], or imperfect wraparounds (e.g. temporarily reporting 180.1 instead of -179.9 when travelling across the 180th meridian), that would be affected by explicitly defining all out-of-range values as "null"?

Maybe acceptable with current and previous version of the object, but if implementer switch to last version they should adapt their code. (because range will be clarified)

Maybe Arbitrary value could allow some server implementation to tolerate this kind of bad implementation more easily ?
I mean 512 will always be consider as unknown but if needed some server implementation can be more flexible about valid range. (but doing this will be clearly out of spec)

@sbernard31
Copy link

The advantage to use an arbitrary value vs using all out of range :

  • no ambiguity for implementer, if they want to express "unknown value" they know they must return 512 (else everyone should decide what to use).
  • we can choose a value without floating point conversion issue and which is generally small to encode (e.g. for string representation).
  • we can detect quickly if device respect the new spec for location object (fail fast).
  • (Not so sure but) Could be easier to tolerate out of range device (like described above ☝️).
  • (not likely but) if we need another value later for another meaning, we just reserve one for "unknown meaning".

@kiemlicz
Copy link

I feel that the discussion floated into abuse-the-value direction whereas there are other options.

Particularly: what is so wrong about returning 5.03?

Make attempts to read the resources result in some CoAP-layer error

The GPS fix is yet to be acquired, which means that whoever tries to read it

  • is not making a mistake (non 4.XX code to be returned), and simultaneously
  • the device is unable to fulfill the request (5.XX situation)

@sbernard31
Copy link

sbernard31 commented Oct 17, 2023

what is so wrong about returning 5.03?

This is explained by @kFYatek in the issue description :

Make attempts to read the resources result in some CoAP-layer error, e.g. Internal Server Error. That is "clean" in terms of data model consistency, but explicitly expecting error responses complicates server-side logic, in particular when the Observe/Notify mechanism is to be considered - it is impossible to start an observation if the current response is an error, so it would make it impossible for the server to wait for a valid location by means of an Observe request.

@kiemlicz
Copy link

As already stated that all options are bad, then in my opinion the least broken is:
CoAP-layer error 5.03
Device can't handle the request, device politely tells that to the server

The return of (0,0) or something like (512, 1500100900) I think is depicted here:
image

@sbernard31
Copy link

sbernard31 commented Oct 17, 2023

As already stated that all options are bad, then in my opinion the least broken is CoAP-layer error 5.03

I think we get your opinion and it can make sense.
Personally, I don't think we can compare a kind of "unknown" value meaning with a "bad request" meaning.

All option are bad but some resolve all concrete issues raised by @kFYatek.
Others (like sending an error code) doesn't, so I think :

  • IF we want to support the observe use case THEN "sending error code" is out.
  • IF we don't want to support it THEN sending an error is a possible solution.

About using 5.03, note that this is allowed by LWM2M v1.2.1 but not for LWM2M v1.0.x or v1.1.x.

Just to be clear, I just try to help to find a solution but I'm not affected by this issue.

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

4 participants