intel / iotivity-node

Node.js bindings for IoTivity
https://www.iotivity.org/
42 stars 44 forks source link

Why is device.types hardcoded to [] ? #128

Closed hansmbakker closed 7 years ago

hansmbakker commented 7 years ago

In Device.js at line 95, the device.types property is hardcoded to an empty array.

Why is this so? If I would want to e.g. implement a higher-level device from https://openconnectivity.org/specs/OIC_SmartHome_Device_Specification_v1.1.0.pdf, wouldn't I need to set this device.types property?

gabrielschulhof commented 7 years ago

That's just the initial value. You can set it to an array containing zero or more non-empty strings.

On Wed, Mar 1, 2017 at 12:04 AM, wind-rider notifications@github.com wrote:

In Device.js at line 95 https://github.com/otcshare/iotivity-node/blob/master/lib/Device.js#L95, the device.types property is hardcoded to an empty array.

Why is this so? If I would want to e.g. implement a higher-level device from https://openconnectivity.org/specs/OIC_SmartHome_Device_ Specification_v1.1.0.pdf, wouldn't I need to set this device.types property?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/otcshare/iotivity-node/issues/128, or mute the thread https://github.com/notifications/unsubscribe-auth/AA7k0YohJ9wRV1Dup4KlF0ignEL9iQ6bks5rhJoFgaJpZM4MO8e5 .

hansmbakker commented 7 years ago

Ok, but how can you then extend that list? Access to the property seems hidden outside the library, so if I would want to set it from my own program, how can I do that?

gabrielschulhof commented 7 years ago

Wait a minute, you're right! It can't be set by applications. It's because the spec never says anything about types. https://github.com/01org/iot-js-api/blob/master/api/ocf/README.md#the-ocfdevice-object defines the OcfDevice object, which is exposed as require( "iotivity-node" ).device, but the types property is not covered by the spec, so it's not exposed.

As a temporary workaround, you can bypass the high-level API and call OCSetDeviceInfo directly:

var ocf = require( "iotivity-node" );
var csdk = require( "iotivity-node/lib/csdk" );
var desiredTypes = [ "core.light", "core.fan" ];

// Copy all the fields from the high-level device info, and add the types.
var result = csdk.OCSetDeviceInfo( {
  specVersion: ocf.device.coreSpecVersion,
  deviceName: ocf.device.name,
  dataModelVersions: ocf.device.dataModels,
  types: desiredTypes
} );
if (result != csdk.OCStackResult.OC_STACK_OK) {
  throw new Error( "Failed to set device information!" );
}

This will work, however, any subsequent write access to ocf.device will overwrite the types array with an empty array. So, after you've done the above, don't do any of these:

ocf.device = { name: "blah", coreSpecVersion: "1.1.0", ... };
ocf.device.name = "renamed-device";
ocf.device.coreSpecVersion = "2.0.0";

etc. There's generally no reason to set any ocf.device properties nor ocf.device itself, except at the beginning of your program anyway, so this shouldn't be a problem.

@zolkis it looks like we need to add this types array to the definition of OcfDevice at the above link. @wind-rider provides a use case above.

zolkis commented 7 years ago

Created https://github.com/01org/iot-js-api/issues/35.

hansmbakker commented 7 years ago

@gabrielschulhof and @zolkis thank you for your hints and quick response!

Two more questions:

gabrielschulhof commented 7 years ago

@wind-rider I'm planning on moving to OCSetPropertyValue when I move past 1.2.0.

The intention is for an application developer to not have to worry about how the values they set for the device and platform metadata are propagated through the stack but to receive reliable service by simply setting values on ocf.device and/or ocf.platform.

Unfortunately, we missed ocf.device.types in our spec, so that's the only reason you need to do OCSetDeviceInfo() as a workaround. I recommended OCSetDeviceInfo() and not OCSetPropertyValue() because I haven't yet created a binding for OCSetPropertyValue() in the released version of iotivity-node. I'll add the binding in the next release, and I'll stop using OCSetDeviceInfo() and OCSetPlatformInfo() in the high-level bindings at the same time.

gabrielschulhof commented 7 years ago

We could definitely use more (and more realistic) examples.

zolkis commented 7 years ago

I have added device types support. According to the OCF 1.1. specs, discovery can use an array of device types and resource types, so I needed to break the ABI for resource discovery and API for device discovery. Please check, the commit can be found from the issue.