Yale touchscreen lock device type, and initial dev experience

I started out with work done by @bigpunk6 and @yvesracine (see this thread), and wanted to add the ability to set the lock configuration settings.

Before I explain more, here’s my current working version:

Preferences

I started by trying to use the Device Preferences, since it seemed like the intuitive place to go in the UI. It didn’t work out. There is no way to pre-populate the UI controls with values from the current configuration. Actually, there is no way to pre-populate the controls with values at all. The defaultValue attribute has no effect; no matter the value provided, radio buttons all start unselected and value fields empty.

On top of the defaultValue issue, the settings property map that backs the inputs is not writable from the context of the command or handler methods, so that route was out.

Then there’s the fact that even though the settings map is updated when selections are made in the preferences, no event is generated nor update method called that would allow for those values to be read and sent to the lock as ConfigurationSet commands. I tried the refreshAfterSelection attribute with no success.

None of this is documented. Much printf debugging. No reflection allowed.

Summary

Can’t set settings values from code, UI doesn’t provide the opportunity to do anything with the settings updated through the UI. Not well documented, and can’t cheat by looking at the classes to see what methods and properties they expose.

╯°□°)╯︵-┻━┻


Tiles

I added all of the configuration state changes as commands, a handler to parse ConfigurationReport commands and made tiles to control toggling, cycling through, and setting values.

Sliders

Initially used slider controls. So, yeah, here’s the thing: they have a fixed range of 0-100. That’s still useful if you’re setting a relative value like a dimmer, since you can convert the number to a proportional number in the range you actually use, but when you are trying to set specific numbers…no. I’m sure this will be remedied shortly, as this implementation was only intended as a stopgap measure. A year and a half ago.

Not Sliders

Is there an option to directly enter a value like you can in preferences? I’m guessing not; guessing because the documentation on the different Tile types is incomplete.

So, on to using two arrow (standard) Tiles and a Value Tile to increment/decrement the value displayed by the Value Tile. This works, but is painfully slow since additional change commands are ignored until the current one has been processed. This requires more care with the layout, since you want all three Tiles on the same row. I made a blank tile to help force this, since I couldn’t find any reference to ways of controlling layout other than the ordering of the elements in the list.

For configurations with more than two, non-numeric states, I started with a Tile for each state, but ended up switching to a single Tile that cycles through the states. Purely a matter of taste. Though, it did make layout easier.

General

  • Don’t count on using the simulator to view your labels, outside of perhaps a gross check to see if they exist.
  • If you have enough Tiles that the simulator detail view extends off the bottom of the screen, you can zoom out to fit more in. However, past a certain point, the layout compresses into two columns.
  • The font size makes things more difficult to read and do not improve the aesthetic appeal of my gorgeous UI design. (Android phone)
  • How can I included icons with a url, as is possible for the main icon? I think the answer is that you can do so from the UI on the phone if the icons are set to be replaceable, but you cannot in the metadata.

Summary

╯°□°)╯︵-┻━┻

I’m beginning to think that the UI defined via metadata is a good-enough kludge intended for crude development efforts, and that independent front-ends for the web-service are the direction in which things are being encouraged. Or not discouraged.

I’ve got more thoughts about how things fit together, but I’m out of time…

1 Like

Adding a mention to @Jim, as there are some interesting observations that might be useful in his efforts to clean up the ST dev documentation.

The updated() method gets called after settings are changed. As far as I know this is totally undocumented. I filed a ticket about changes to settings not being persisted, but it’s been more than a year, so at this point the best you can do is save the current state in the state map and compare against that.

Here’s how I do it in the Aeon Siren device type:

def updated() {
	if(!state.sound) state.sound = 1
	if(!state.volume) state.volume = 3

	log.debug "settings: ${settings.inspect()}, state: ${state.inspect()}"

	Short sound = settings.sound?.toShort() ?: 1
	Short volume = settings.volume?.toShort() ?: 3

	if (sound != state.sound || volume != state.volume) {
		state.sound = sound
		state.volume = volume
		return response([
			secure(zwave.configurationV1.configurationSet(parameterNumber: 37, size: 2, configurationValue: [sound, volume])),
			"delay 1000",
			secure(zwave.basicV1.basicSet(value: 0x00)),
		])
	}
}

During bi-weekly Developer Calls, there have been a few discussions that focus on the limitations of the Device Tile user interface controls.

I make two observations:

  1. I, personally, wonder if it is an optimal philosophy that the SmartThings Mobile Apps should be a “portal” to arbitrarily complex interfaces. Sure, it is convenient to have full-feature control of all your Things from one mobile app and it provides a nice level of abstraction to make different vendor’s devices have a common user interface, but is it realistic and optimal? The challenge of a “dashboard” (or “portal”) as a user-experience staple has existed for decades! I remember vendors showing off their “dashboards” that tried to squeeze data from a half-dozen mainframe sources into a Windows 3.0 screen.

    Vendors will always be able to offer customized UI’s that are tailored to their device functionality (e.g., it is hard, illegal, or inefficient for SmartThings to replicate the Sonus App, or even the Philips Hue App).

  2. SmartThings has told us that they are (likely) adding HTML5 functionality to the Mobile Apps, which will certainly improve the ability to code rich UIs. But now I worry that this could defeat the “dashboardness” of the system with very inconsistent look-and-feel from one Thing to another, even if they are both … thermostats, or both locks, etc…

    Ideally, even under HTML5, there needs to be a restricted toolkit of control widgets and enforced design guidelines.

You have a ‘d’ on the end of “update”… ╯°□°)╯︵-┻━┻

I tried this, but was using update(). No wonder it didn’t work.

In the [SmartDevice Type Class Summary][1] under Methods defined by SmartDevice Type Handlers, there’s an entry for:

<command name>() <command name>(<arguments>) Called when the preferences of an installed app are updated. Typically unsubscribes and re-subscribes to events from the configured devices and unschedules/reschedules jobs.
I believe this to be the entry for updated(), without the placeholders filled in. It doesn’t have a ‘d’, either.
[1]: https://graph.api.smartthings.com/ide/doc/deviceType

1 Like

Yah… I bet there was confusion because Class SmartApp has updated() method documentation, but not Class SmartDevice Type.

https://graph.api.smartthings.com/ide/doc/smartApp

Devices don’t have “jobs”, but SmartApps can schedule jobs. In other words, the Class docs are … ???

Part of what drives my suspicion is my recognition that very often my frustrations are those of the developer/enthusiast, and not those of the average user. My urge is to make/extend things, while the average user just wants to set things up and maybe tweak a setting or two in their SmartApps.

2 Likes

My bungled attempt to use updated() was inspired by @Mike_Maxwell’s Device Type for the Aeon Labs Microswitch. I think he had issues of his own with triggering the update, but I think it works as well as it can.

Still the fact that only the UI can change the setting creates the risk of getting out sync, especially for devices that can be configured manually (like this lock, for instance).

@llamas - I saw in another thread your reference to .NET… it seems Visual Studio has spoiled you. :wink: All kidding aside, a solid IDE with intelligent code completion (eg. IntelliSense) can make it much easier to develop - especially in an unfamiliar platform/code base.

┬──┬ ノ(°—°ノ)

2 Likes

documented or not def updated() {} is called within the device class after closing the preference panel, I use it in all my non battery devices to change configuration parmeters.

1 Like

Yah… we really need the Reference Material documentation updated (ummm… no pun intended) :wink:

While the various examples and how-to’s are very useful for new folks, I am personally much more interested in accurate low-level reference documentation. It not only helps in the development process, but also helps in discussions because we can use consistent terminology and reference the exact methods and parameters, and so on.

We know @Jim has a big workload … but hope, perhaps, we can influence his priorities?

Yeah, I went so far as creating mock classes for the command classes and some of the SmartThings classes so that I could get code-completion in IntelliJ IDEA. I gave up on that after figuring out that we couldn’t make classes of our own, and that the undocumented zwave helper class was a wrapper for all the command classes (amongst other things), but with altered casing. I might pick that back up, just as an exercise in transformative scripting,

2 Likes

I’ve been trying to work on a version that uses the settings inputs, experimenting with ways to sync the settings up with current configuration settings on the device. The IDE started choking on me an hour or two ago, probably for whatever reason my devices list returns a server error, so I’ll have to report back after that gets resolved.

The IDE is still not working 100% for me, but I was able to create another device type with the same source (and modified name) which is working most of the time.

I much prefer the preferences layout for setting device configuration values, and it’s where the user would intuitively look. However, the inability to set the preference properties means that there is no way to synchronize the actual settings on the device with the preferences.

I think I’ve had enough fighting with the mystery API for a while.

1 Like