Updating Thing properties on the Gateway UI. i.e. Name, Links

Use case: I am authoring a Ring adapter for the mozilla gateway and I am attempting to set the link property on the Thing to a video/mp4 href of the last motion or ring detected after every motion or ding detection. This means I need to update the links property of the device object after the ring event is detected and reflect the new link on the UI so that the user can click on it from the gateway app.

However, after the thing is constructed/added, it is not possible to update the name or links property, we can only update the UI with when a property in device properties array is changed using this.notifyPropertyChanged(property).

As an example device function setName(name) on the gateway-addon-node changes the actual name of the device but it is never reflected on the UI. Similarly, when I programmatically alter the device links array, the changes are never updated to the UI. Was this intentional?

I have done some investigation and looks like there is no THING_UPDATED defined in constants.js, and there are no methods defined on the addon-manager or device classes that can handle such updates to the device/thing.

I can author the changes but have limited time and would like some of the devs to comment if this will cause any issues.

Thanks!

This is an interesting use case, thanks for bringing it up! Adding an updateThing message to the adapter IPC sounds like a good idea. My main concern would be its interaction with caching of thing descriptions on the UI side but it does seem like a worthwhile target for implementation.

Ok I will go ahead and write something up. Am I right in saying that currently there is no way to update these values back to the UI? I hope I haven’t missed something.

Yes, exactly. The easiest way would be to trigger a page reload but doing it properly and seamlessly will be a bit more difficult.

@damooooooooooh Exciting that you’re implementing a Ring adapter!

What exactly do you mean by “I am attempting to set the link property on the Thing”? Do you mean the links member of the Thing Description? These links are really intended to be static links to other resources about the Thing (its properties, actions, events, WebSocket endpoint and UI), not dynamically changing properties.

I may have misunderstood but it sounds like what you really want is a property of the device which updates with a new URL, and are using the links member as a workaround to make a link clickable?

You can already create string properties of Things, but currently that won’t make hyperlinks clickable. Maybe we need a LinkProperty schema which is rendered as a clickable link?

It would also be great if you could propose a new schema for smart doorbells so we can better represent them in the UI.

ben, I have created the ring adapter and it works fine, however it would be helpful to the user to see the motion from the UI.

The device object has a notifyPropertyChanged event which appears to update the ui with changed property values, however changes to the device such as its name , description or links are not updated back to the UI. ASt least in my testing.

When I capture a motion or ding I’ve been trying to set the link url to the url of the ring video so the user can click it to see the last motion.

I’ve tested with this code below, and I can see the links are update don the object, but it never gets update don the UI. Same of I call device.setName(…)

  console.log('Update links', this.links)
  this.links = [
    {
      rel: 'alternate',
      mediaType: 'text/html',
      href: href,
    },
  ];

I also had a video property setup as part of the thing, but same again once you set the link property to a value at the constructor, setting the video link after never gets updated to the UI.

/* this.properties.set(
‘video’,
new RingProperty(
this,
‘video’,
{
@type’: ‘VideoProperty’,
label: ‘Latest Activity’,
type: ‘null’,
readOnly: true,
links: [
{
rel: ‘alternate’,
href: ‘’,
mediaType: ‘’,
},
],
},
null));
*/

Here is the ring-adapter, work in progress and need to refactor once I resolve this issue

@benfrancis. Sorry I didn’t read your message properly and now see that the links properties were meant to be static? If you look at the weather adapter and few others as an example, you can see that when the device is setup, a link is set on the device that can take to the actual forecast.

On the constructor for the weather device you can see following whereby the weather forecast url is set which allows the user to click through to see the full forecast. See the screenshot. When debugging the weather adapter, any update to the links property after the thing is visible on the UI, is reflected on the gateway object but not on the UI.

this.promise = this.poll().then(() => {
      this.links = [
        {
          rel: 'alternate',
          mediaType: 'text/html',
          href: this.provider.externalUrl(),
        },
      ];
    });

Capture

What I would like to do with the Ring adapter is set the href of this link to the last ring video URL of the last activity so the user can click it. In addition, if I have a video property as per my comment above, I need to adjust the link property and set it to the video href of the last activity so the user can see the last motion directly on the gateway ui.

The issue is that when I update the links property, or even the name and description property of the thing, it never gets updated back to the UI, only objects in the properties map get updated back to the UI using notifyPropertyChanged.

Should I be using the links property at all? I feel there should be someway to reflect changes to the thing on the gateway without having to reinitialize it?

Hi @damooooooooooh,

The intended use case for an alternate link relation in the links member of the Thing Description is to provide a URL for an alternative representation of the Thing using a different content type or protocol. The two examples given in the specification are an HTML user interface for the Thing as a whole and a WebSocket endpoint to monitor and control the Thing over the WebSocket API. The link icon which appears in the UI is intended to link to a custom web UI for a Thing.

These top level links are not intended to be updated frequently like the values of properties are (though they can be changed in a new version of the Thing, so we could possibly do a better job of updating the UI when they do).

You could create a Property with type “string” which can be updated dynamically with the latest video clip URL. Its value will then automatically be updated in the UI when it changes, but the downside is that it won’t currently be rendered as a clickable link. So what we could do is work on a HyperlinkProperty schema which renders a URL as a clickable link, a bit like the top level link icon currently shown on the Thing icon.

I hope this makes sense?

Of course we also have a VideoProperty which could be a good fit for this use case, except that again currently I think the video URL in the Link object inside the Property object is assumed to be static (e.g. the URL of a video stream of a webcam). I’m not sure that if you change it via the adapter whether it will immediately be updated in the UI…

Hi Ben, correct, I encountered the issue when I attempted to update the Video property Link information after each ding or motion event on the ring device. This is a problem, as devices like Ring or Wyze do not publish a stream to which can be permanently subscribed but rather there is a separate resource published for each event that will require the pointer/href to that event to change over time.

I intend to write a Wyze cam adapter also, but currently it seems that only retrieving events from these devices is possible, and maybe in future publishing media might also evolve.

Ah, I see! Yes, so we could try to do a better job of reflecting changes to those URLs in the UI. It’s generally assumed that the metadata in the Thing Description itself is fairly static, whereas the Property resource itself is expected to change.

I’m thinking about how your use case best fits into the Web of Things data model, and while you could model this as a property which holds the latest video clip URL, another way to model it would be as a payload of an event. Each event would contain the URL of a video clip relating to the event. Unfortunately currently the UI for events is fairly basic so this wouldn’t work particularly well on the gateway.

If we create a schema for smart doorbells, we might be able to come up with a better UI for this use case.

Okie dokie, let me look at the schema. Thanks!

@benfrancis developing a schema for this may be difficult if the assumption that links property remains static. As the VideoProperty is dependent on the links object to indicate the video source, then adopting the approach of links providing a reference to a static resource will not work. I see a Ring or Wyze cam being a combination of a Video Camera and motion sensor.

Would it be better to have a media property type?

I’m not sure what a MediaProperty would do that a VideoProperty doesn’t already do? Either a HyperlinkProperty or simply adding the video clip URL in the metadata of an event could be possible approaches?

hi @benfrancis, I guess I’m struggling with this use case because by definition the videoproperty relies on the links object to serve up the content, yet it is not suitable for dynamic applications.

Here could be an example of a VideoProperty with altered schema represents the Ring Doorbell feed:

"Video" : {
"@type": "Property",
"type": "rtsp",
"resource": "rtsp://...........",
"href": "/things/ring-doorbell/properties/video"
 }

I don’t feel like this is a clean solution or in keeping with the current model. I do feel that the current usage of the alternate links objects are the correct way to offer alternative representations of the thing, changes just need to be reflected on the UI for it to be useful in dynamic scenarios where the external resource changes.

This is a tricky use case because the doorbell is really creating a collection of new resources with a particular content type (video clips) on the web rather than a fixed property resource which changes value, which is not something which is necessarily handled well so far.

A recorded video clip is not an alternate representation of a doorbell, it’s a new resource created by the doorbell, so it definitely shouldn’t be an alternate link at the top level of the Thing Description.

There a few ways that you could model this as properties or events within the Web of Things information model.

One approach could be a “latestClip” property of @type VideoProperty which has a permanent link aliased to the latest video clip.

Another approach could be a “videoClips” property of type array which has a list of links to recent video clips.

I think the neatest approach, as I mentioned before, might be to have an event which includes a link to a video clip in its payload.

Unfortunately the last two options will not currently be well represented in the gateway’s UI because we haven’t come across this use case before.

We could potentially improve that by creating a SmartDoorbell capability which has a custom UI for this purpose. Remember that a Thing can have multiple capabilities so it could be annotated with a VideoCamera and MotionSensor capability too.

Alternatively we could look at this more holistically as part of a dedicated home monitoring UI composed of multiple Things co-ordinated by the gateway, which is something that SmartThings has done well in the past. So for example you could have multiple motion sensors and cameras around the home and have all cameras start recording a 1 minute clip if one of the motion sensors is tripped. You might want to store all those videos centrally on the gateway rather than separately for each device.

So lots of options we can explore, but in the short term your best option might just be to create a “latestClip” property of @type VideoProperty which links to the latest recorded video clip, and set up rules to notify the user when motion is detected so they can go in and take a look.

Great discussion thanks will look at options and push out first version of the ring adapter

@damooooooooooh I’d recommend looking at the onvif-adapter. It does video streaming and takes snapshots. Essentially, you’d have a static link to something hosted on the gateway (e.g. an image file), and then you can update that file periodically. Doing so prevents the need for updating the link.