Workflow for integrating customized Hub connected device?

Hello ST community,

I am new to the SmartThings development and would appreciate if you can give me some pointers or tutorials on the standard workflow of my project below.

Devices I have:

  • Samsung SmartThings Station
  • ESP8266

Project details:
I want to integrate my customized device, which is ESP8266 and some other sensors, with ST. I would like to use ST app to send some parameters settings through slide bars/text boxes within a customized device profile. The main tutorial I followed is this one: Tutorial | Creating Drivers for LAN Devices with SmartThings Edge. I tried to modify the code, like adding new capabilities in driver/profile/…yml file but I am not sure if that’s how it should be done. The other guide I am reading is this: Device Profiles | SmartThings Developers.
My question is that: to create a customized device profile with my own detailed view, do I have to go through the whole ST workspace device profile creation routine, or I can simply modify the driver code from the ESP8266 tutorial above since I don’t plan to publish the driver/device.

Thank you very much for your help!

1 Like

Welcome to the SmartThings Community, @jackj!

Ok, I see the confusion here. So, first, there are some things you need to consider:

  1. Using the Developer Workspace or not depends on the integration type you’re working with.
  2. Currently, the only device integrations that require the Dev WS are Cloud-to-Cloud (ST Schema) and Direct-Connected.
  3. As you chose to work with Edge drivers, the Dev WS isn’t necessary for your development.
  4. About this: “some parameters settings through slide bars/text boxes”. It would be possible using custom capabilities since they have those different display types. And just as a future reference, that’s something different for the known “settings” menu (AKA preferences in the device profile)

So, you’re right that you can edit the driver from the sample to create your own profile (the one in the YAML file). When you install the device, that file’s configuration is used to create the profile so the device can use it.
If you want to customize the different views (eg. change capabilities’ current range or options allowed), you can use the embedded device configurations.

Hello @nayelyz,

Thank you very much for your answer. I saw your replies in a lot of posts I browsed :smile: and appreciate the help. I think I will go with the edge driver/custom capabilities route in this case.

For my current progress, I followed this guide Edge Drivers - Driver Presentation and Custom Capabilities and was able to create the example customized “fancyswitch” capability. At the same time, I was able to add “notification” capability as well, which I modified for use as a text input for my ESP8266.

My current question is as follows (If I need to start another thread according to the community rule, please let me know since it is getting a bit detailed):
The specific capability I want to create is: 1. using the textbox to enter a string and send it to ESP8266 through HTTP (already done with “notification” capability); 2. storing this string as one of the modes linked to a button on the same SmartThings UI; If I push this button, I can send the same string again. The second part of my capability is very close to the current “colorControl” capability, in which there are 5 “recently used colours” buttons that stored the previous color entered.

I have checked the capability and presentation JSON files for “colorControl”, but it seems like it doesn’t cover the part which implements the way of saving recent color into one button. Can you give a pointer on where I should look into?

Thank you!

There’s no need to create a new post, here is ok.

So, if I understand correctly, you will have several (and dynamic modes), so, you would need a button for each one of them?
It would be tricky because you cannot make capabilities appear dynamically, but, in Edge, there’s an option to change the current profile that is controlling the device, the function is called try_update_metadata. However, it requires the “new” profile is already part of the driver package.

That kind of design is part of the special UI of this capability, several SmartThings (AKA stock) capabilities have a special UI, as mentioned in the other thread, to present charts and other extra controls like in “switch”, so, in this case, there’s no option for you to create a design like colorControl, if your custom capability is too similar, it might be worth to use instead of the custom one.

Note: Custom capabilities are not supported by third-party integrations like Alexa.

Hello,

Thanks for the answer.

So, if I understand correctly, you will have several (and dynamic modes), so, you would need a button for each one of them?

So in this case, I actually don’t need the button to appear dynamically. The 5 buttons can be spawned at the beginning. The only thing I want to do is, after I enter a string in the text box (notification capability in this case), dynamically save and link this string that with one of the 5 buttons, and next time I push this button, it will sent the string I input. It is indeed quite close to the “colorControl” capability. The current “colorControl” has 5 buttons generated at the beginning but no color associated with them until you input hue and saturation in the colormap

Screen Shot 2023-04-19 at 12.33.17 PM

As for creating something like “colorControl”, I did read from other posts that there is another app UI layer that implements it and we don’t have access. I was thinking about just using the “colorControl” capability for UI. The way is: 1. store string that users input in the app; 2. associate the string with one random color that I can input into the “colorControl” capability. The capability will activate one of the 5 buttons that it has that corresponds to the recently used color; 3. Next time when I press that color button, it will send the corresponding string. However, I can’t find a way to save the String that user inputs in the edge driver/SmartThings app.

It would be great if I can have some guidance on how to save user inputs for two ways of implementation above. Thanks again!

ok, in a driver, you can use the persistent store which allows you to save a value and use across the driver by simply calling device:set_field to save and device:get_field to get the variable’s value:
For example:

device:set_field("preset1",value)
device:get_field("preset1")

You would do this when you get the command from “notification” to get the input from the user (argument).

You cannot get an identifier to know which preset was selected by the user, this only sends the command setColor which has the hue and saturation values that correspond to that color.
So, you can use the persistent storage again to define which color was selected for that specific text and then, when you get a setColor command, you can compare what you saved with the color info received.

Please, let me know if you have any questions about this.

Got it thanks. Yesterday I actually found datastore module and that worked on my end. Is that the same as persistent store or should I use persistent store instead?

@jackj,
Checking the documentation, it says that:

So, I asked the team about that and they mentioned the following:

  1. Interacting with driver.datastore directly shouldn’t be necessary. However, if you want to save a “setting”/“property” that you want to use throughout the driver, you can do: driver.datastore["my_key"] = "my_setting". This way it will be saved in the datastore and persist through restarts.
  2. You can either declare their own fields directly on the driver template. We can add keys to the driver object but these aren’t persisted and will be removed if the driver restarts.
  3. Or use set/get_field (preferred) if you need the data to be associated with a specific device
  1. Elements on #2 and #3 are stored in the datastore. The difference is that set_field /get_field, uses the device as part of the lookup key.

Thank you. I get the datastore to work as I needed it now. I have two more questions regarding the customized capability.

  1. Currently, after I create the capability and get it to work on ST UI, the UI shows the capability name directly. Is there a way to change the display name to something else? I tried to navigate through the documentation about the capabilities presentation display, but it isn’t very clear on that. Is “label” the parameter I should change?
  2. Another thing I find is that the capability update doesn’t seem to work for me. I have a customized capability that is very similar to “switchLevel”, which is just a slider with a different range. However, after I created the capability and presentation, I tried to change the range and the name of the setter function and didn’t update. I also tried to repackage the driver and install it, still doesn’t work. Just wondering if there is any pointer on that.

Thanks,

That can be done with translations: Capability Translations | Developer Documentation | SmartThings

First you need to create the translation, then, modify the capability presentation to point to the right path.

Note: When we create a custom capability, the English (en) translation is created automatically, so in that case, you can only update it.

To get the current configuration of a translation using the CLI you can run this command:

smartthings capabilities:translations capabilityID en -j

You can save that config into a file, modify it and then use the command capabilities:translations:update or capabilities:translations:upsert to update it.

Remember to verify the changes were saved properly with the first command.

  1. Ok, in Edge drivers, the configuration from a custom capability isn’t refreshed right after we update the config through the CLI. Last time we got a report about that, the time for them to be refreshed was reduced as follows:

It now takes up to 14 hours, but to force the refresh, it should be possible to wait for two hours after the update and reboot the Hub.

Got it thanks!

For the capability update, it would be great if the update can refresh a bit faster for the development cycle :sweat_smile:. One bit of hacky way I tried is just deleting the current capability and recreating it, but it seems like if I create the capability with the same name, it will still have the old settings and configs from the deleted capability. So I guess in ST system, I didn’t really delete the capability right? Also if I simply just update the capability, do I need to repackage the driver?

Yes, I’ve noticed this as well, as we cannot delete the capability presentation, when we create it again using the same name it is still bounded to the old configuration.

It shouldn’t be necessary to repackage the driver but, as the device profile and the device presentation are created automatically, you need to check if reinstalling the device is actually refreshing the device presentation as well.
You can query the current configuration of the device presentation with the command below:

smartthings presentation presentationId -j

The presentationId (AKA VID) can be found in the device’s details when you list them.

Thank you for the information. I saw presentationID (VID) mentioned a lot in other posts and I am still kind of confused about it. If I understand it correctly, each device will have its device profile. The device profile contains its device ID, device name, capability, VID, and other information. Currently, I just realize that since I am following this tutorial Tutorial | Creating Drivers for LAN Devices with SmartThings Edge, the profile comes within the driver folder in yaml file and that is the file I’ve been edited. When I use CLI command smartthings deviceprofiles [ID], the return shows “no item found”. I do find my device and its corresponding presentation id using smartthings devices and smartthings devices:presentation though. Is it because I never create a device profile using smartthings deviceprofiles:create?

@nayelyz may be better briefed on this this than the end users like myself, but I might be able to point a few things out in the meantime and hopefully not derail the thread too much.

If you use smartthings edge:drivers to view an Edge driver you have created you will see it lists a number of Device Integration Profiles with a UUID and a version number. Those are the ‘profiles’ in your Edge driver package. If they are visible online they are currently well hidden. However they probably don’t really need to be online.

If you look at a device created with your driver using smartthings devices you will see that it has a profile ID that you can view using smartthings deviceprofiles. That device profile will look familiar to you and it also has metadata pointing to your driver (by ID) and a particular profile (by name rather than ID). It is derived from your Edge driver Device Integration Profile.

If you update a profile in your Edge driver and upload the package you will find that the version number of the Device Integration Profile changes. What I hope you will also find, because it is how it seems to work for me, is that any device that was using that profile will show a different device profile ID. It may be a brand new profile, but if you have effectively reverted to a previous version of your Edge driver profile the device profile corresponding with that will be used.

I appreciate that there are too many uses of the word ‘profile’ there.

Thanks @orangebucket. Using smartthings devices and smartthings deviceprofiles, I can locate the device and corresponding device profiles. I also got the device integration profiles through edge driver as well. Just curious, is this UUID used in any cases and can be entered in any CLI command?
I can also use smartthings deviceprofiles to locate the profile now. I used the wrong ID for that yesterday (there are device ID, device profile ID, and presentation ID, and I kinda mixed them up before).
If I understand it correctly, in my case, when I upload the driver package with the profile included, there is automatically a device profile generated. And every time I update it, the “major version” corresponds to that device integration profile will change. In this case, my questions are: 1. will the device profile ID change every time I update the profile yaml file within the driver folder, assuming I don’t change the name of the profile? 2. You mention that

any device that was using that profile will show a different device profile ID

does that mean if a new identical device is connected to the hub and uses the same driver, it will have a different device profile ID? What I thought was that these two devices will have different device IDs but the same device profile ID because they are technically identical and uses the same profile and profile presentation.

My best guess is that every new version of a profile in an Edge driver will result in a new device profile being created when the driver is uploaded, with the exception that if, for example, version 4 is the same as version 2 then the device profile previously created will be reused.

Let’s suppose you have an Edge driver with a profile named ‘twomodes’ and you update that profile and upload the driver. What I was suggesting was that any existing device using the same driver (driverId) and the ‘twomodes’ profile would be updated to use the new device profile within a short time of the upload. The devices would all be using the same device profile ID as each other and they would all update.

The point I was intending to make is that in my testing it didn’t seem to matter which version of the driver the device was using. If it was using the ‘twomodes’ profile it got the latest version independently of the driver code version.

It could be nonsense but it was how it seemed to work to me. I’d be happy to be wrong. My interest is more in how things tie together than developing Edge drivers so I defer to the more active developers.

Sounds good. The information is pretty helpful. thanks!