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

Is handling of NaN values in scope of spec/library? #74

Open
andig opened this issue Jun 28, 2019 · 5 comments
Open

Is handling of NaN values in scope of spec/library? #74

andig opened this issue Jun 28, 2019 · 5 comments

Comments

@andig
Copy link

andig commented Jun 28, 2019

I‘ve noticed that SMA inverters use maximum unsigned values or minimum signed values in the respective data type number to indicate a NaN value. For example, model 101 single phase inverters will do so for phases B and C. This behaviour is documented by SMA.

Is this behaviour covered by the sunspec standard and this library? Couldn‘t find it in either code or specs I‘ve looked at?

@altendky
Copy link
Contributor

On page 19 of the SunSpec information models document it covers unimplemented registers. On read the SunSpec specified unimplemented value should be returned. On write the value is thrown out and there is no exception. Each data type defines its unimplemented value. For example, not implemented for a uint16 is 0xFFFF (65,535) while for int16 it is 0x8000 (-32768).

@andig
Copy link
Author

andig commented Jun 28, 2019

Thank you for confirming- this is in line with what the SMA inverters apparently are doing. Is this covered by pysunspec?

@altendky
Copy link
Contributor

The values are defined here:

SUNS_UNIMPL_INT16 = -32768
SUNS_UNIMPL_UINT16 = 0xffff
SUNS_UNIMPL_ACC16 = 0
SUNS_UNIMPL_ENUM16 = 0xffff
SUNS_UNIMPL_BITFIELD16 = 0xffff
SUNS_UNIMPL_INT32 = -2147483648
SUNS_UNIMPL_UINT32 = 0xffffffff
SUNS_UNIMPL_ACC32 = 0
SUNS_UNIMPL_ENUM32 = 0xffffffff
SUNS_UNIMPL_BITFIELD32 = 0xffffffff
SUNS_UNIMPL_IPADDR = 0
SUNS_UNIMPL_INT64 = -9223372036854775808
SUNS_UNIMPL_UINT64 = 0xffffffffffffffff
SUNS_UNIMPL_ACC64 = 0
SUNS_UNIMPL_IPV6ADDR = 0
SUNS_UNIMPL_FLOAT32 = 0x7fc00000
SUNS_UNIMPL_STRING = 0
SUNS_UNIMPL_SUNSSF = -32768
SUNS_UNIMPL_EUI48 = 'FF:FF:FF:FF:FF:FF'

and there are a few layers but those end up being used in two places (close to each other) via the .is_impl() calls:

if not point.point_type.is_impl(point.value_base):
point.value_base = None

if point.point_type.is_impl(point.value_base):
if point.sf_point is not None:
point.value_sf = point.sf_point.value_base

@andig
Copy link
Author

andig commented Jun 28, 2019

Great, thank you! I had done a quick check for NaN and didn't notice. I'll try to cover the same in gosuncpec.

@altendky
Copy link
Contributor

Hmm, I haven't dug into the extra layers but 0x7fc00000 is an interesting way to type NaN for the float case. I guess I would float('nan') for py2/3 compatibility and then if the integer is really needed, which seems a bit off, then encode with the struct module and... decode again to get the integer. Anyways, that's probably not a high priority to refactor. :]

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