Inheritance (?) & Mutations of Device Types (inspired by "Made a Water Leak Sensor"), More Polymorphism

Continuing the discussion from Made a Water Leak Sensor (see quoted below):

I’m curious to know more about the exact changes you found you needed to make to the stock/standard Device Type to make this new Device Type.

Frankly, I can guess, and I could also do a diff (friendly suggestion: If anyone creates a new Device Type that is highly based on an existing one, and you’re using GitHub; it is tremendously helpful to first commit a copy of the original base Device Type, and then make or paste in the New one … This makes the changes immediately viewable in the commit history diff view, of course!! :wink:).

But I have a more nefarious motivation:
I believe that SmartThings Device Types should support inheritance of some sort. They already implement polymorphism and abstraction, so why not go full object-oriented here. With some concept of inheritance, it would be possible to tweak a Device Type without cloning it; you would just override the affected attributes or methods.

In this case, for example, I believe the main logic you are changing is open/closed to dry/wet; along with cosmetic changes in the tiles{}. This idea of “adapt a device” has come up before; for example, the Virtual Open/Close for garage doors, changes the SmartSense Multi to report certain accelerometer angles as open\close instead of using the state of the magnetic contact.

There are many ways to handle this model; the current way, cloning and modifying the Device Type is not bad, though it requires manually changing the Device Type assignment using the IDE (not consumer friendly).

The simplest solution I can think of, actually, is to take a lesson from the the @media{} structure available in CSS: i.e., one CSS file can accommodate screen sizes, with only the necessary differences put in @media sections. For SmartThings, tag could be “@useType{}”, a preference configuration parameter you set at installation time (e.g., “@useType capability.switch { code for on/off handling here }; @useType capability.waterSensor { code for wet/dry here }”.

[But I’d like to see if we could figure out an even better way to handle interface variances with inheritence…, actually.]

1 Like

Hi @tgauchat,
Thanks for the comments. I just fixed up git to show the delta here:

Sorry for that. I’ve really only been doing this SmartThings for a while and this was I think my very first device type ever. I just started my SmartThings github repository for this so I did it quickly. Haste makes waste! :smile:

Anyway, as you can see, not a ton of changes. I do like your idea of over-riding functions, but how would that work for fingerprinting? Device types today try to auto detect what device you have based on it’s clusters and match that to a custom device type. So how would it know to use the one with or without the over-rides?

See my other posts for a discussion about the finger printing process. I’m still struggling with that while I make my own hardware Zigbee device based on an NXP module.

1 Like

Thanks for the update to your GitHub repository and engaging this new Topic, Justin!

The issue of signatures is how can we implement different interfaces to the different instances of the same type of physical device. The signature is what tells us what type of physical device it is, but does not tell us which of the use cases – or interface variants we are interested in.

The analogy off the top-of-my-head is that of a particular make, model and year of car. A very specific type of real world Thing. I buy two of them – both have the exact same signature. But I want to use one of them as capability.transportation, and the other as capability.bed: i.e., The second use case is a “hack”, but completely valid … a car seat can be used as a place to sleep.

Because they have the same signature, we need to tell SmartThings how it should treat this device. I can suggest two ways:

  1. Ask the user at install time using an installation preference dialog what their intended use of the Device Instance is; or

  2. Let the Device Instance be both (all) of the sub-types concurrently – until the device is first used in a SmartApp as one particular capability (e.g., if the SmartApp is something like “Drive to the Store”, then it will allow selection of the car instance from a list of my vehicles, and now it will be locked into capability.transportation; and the opposite case of the SmartApp is “Take a Nap”, capability.bed).

I can’t resist remarking that Implementation Option #2 is an excellent real-world application of quantum theory: Until the Device Instance is observed (i.e., used in a SmartApp), it’s capability is both transportation and bed – just like an electron exists in a cloud of probabilities, not in any specific orbit of an atom.

I hope this analogy holds up for your Water Leak Sensor and similar Device Types where the capabilities depend on how the device is physically used, even if not hacked.

For example, I attached a Smart Sense Multi to a tilt-based no-kill mouse trap. When the mouse reaches the bait, the trap tips, the door closes, and the angle of the sensor changes.

It’s easy enough to use just handle this angle detection in a SmartApp, but why not apply this device mutation ability? I can now create “capability.rodentTrap”, and with attribute “trapContents - [empty, rodent]”, and this is much more accurate and next this new capability can be implemented in many different physical implementations of mouse traps, all of which are compatible with any trap action related SmartApp.

…CP / Terry.

1 Like

Ok, I get it, thanks for explaining the two options in more detail. I really like the idea! As a developer, I was very happy with my SmartThings purchase to see that I was able to create my own device types, and I like how you’re trying to make that easier for the next person down the line to just choose.

In my example I needed to change hardware, so I don’t know if it’s as good of a fit thought. Giving the buyer of this monoprice door open/close sensor the option to use it as a water detector I think for many people would greatly confuse them. But in your example of the tilt sensor it makes a lot of sense. Tilt angle by itself is a pretty generic term. Does it reflect a trap state, a garage door state, a drawer state, etc. I don’t have any myself yet, so I’m not sure what the typical experience is installing one to the average user. Today does it just say the tilt angle in a standard tile?

The one other comment on the trap example is I could also see it confusing people when they install a tilt sensor and have the choice between a lot of various configurations. Without your photo and explanation, I wouldn’t have known what choosing capability.rodentTrap meant for my tilt sensor. How do I configure it? Which axis of the tilt sensor is it using?

I really like the idea but I think the challenge I mention above is representative of the challenges with Home Automation in general and why it’s not maybe taking off faster. Everyone has a slightly different custom requirement for their own situation. And if they aren’t skilled enough to tweak it themselves, then they are probably scared of even trying to install a system. Then they have to pay some expert to come in ($$) to custom install it for them, and a lot of the devices aren’t cheap already so cost also can be a barrier.

Unfortunately, I could see your solution of ultimate flexibility being in some sense even worse for this situation. Your average user may want less options. They just want to plug it in and have it work. So maybe your solution is better as an “advanced” option for contracted installers etc?

One great example of this that I’ve seen play out in another consumer electronic device was the Logitech Squeezebox. I have been a fan of them ever since they started (Slimp3). Logitech bought them, and started making great hardware. But the installation was non-trivial. Even advanced users like myself had (and have) difficulty from time to time with the server and configurations. It’s open source which was a huge plus for the developer community. But that’s no good for mass market. So it eventually stalled and lost to Sonos which (from what I hear) is totally simple to install. They both do similar stuff, but Sonos won out because of simplicity. Plug it in and it works.

1 Like

Very valid points and concerns…

The secret to successful consumer technology isn’t to reduce complexity, but to hide the complexity as much as possible with excellent interfaces (front and back-end).

Selling Things as single purpose devices definitely makes it easier to install, use, and support.

But I think multi-purpose / mutation / polymorphism can be handled with: (a) magic in the back-end [e.g., automatically detecting the resting tilt angle so that installation errors aren’t possible], (b) super brilliant user interface design, and © excellent documentation in the form of videos and/or pictures for each use case.

SmartThings came with ©, videos, right out of the gate for all their Things, and provides step by step pictures for quite a few of the other supported devices. So it looks like they are equipped with at least a part of the winning formula.

If I could manage to get an actual mouse being trapped on video, then I would definitely publish this Device Type mutation and SmartApp to the Community and/or project blog! Your water sensor hack is inspirational!