Device Property Update Form

Hey guys,

I want to update device properties through a text form so I can type the exact values instead of moving a slider.

I use MQTT to communicate with a ESP32. Publishing values to the dashboard is no problem and works fine. The only problem is that I need the ESP zu subscribe to values that I want to type in a form inside the dashboard.

The documentation provides an example using AngularJS to manipulate property values. (DASHBOARDS - Thinger.io Documentation).

However, I don’t understand it. The example speaks of three values in one property - value.a, value.b and value.c.
How can a property have three values? What does this mean when creating the property? Do I have to create a property named value? And what’s the payload then? Usually I use one property per value.

Could you please provide a step-by-step instruction? From creating the property in the products tab in thinger to integrating everything in the dashboard. I understand the idea but I can’t figure out a way to get it to work…

Thanks a lot for your help.
Georg

Hi @GeorgD

To achieve what you want you need to create an API resource in the product:

The request tab would be similar to the following one:

Then, in your device, you will have the new api resource. It’s execution will send the message to the topic from the above image:
device_api

This would be enough to create the form you want, by using device resources instead of device properties, by using simple widgets or a mix between the widget you show and the call device resource:

What if you want persistence of the last value sent? In that case you need properties. The default value of the API resource would become property.<property_name>, instead of the string “hello world”, and the property in the source of the property in the product would need to be the same topic that you are submitting your values.

Regards!

@jaimebs Thanks a lot for your help, I managed to set up the API correctly and it works as needed.

The only thing left is to relocate the input field from the API-Tab to the actual dashboard. I got all my graphs and buttons arranged on my dashboard and would like to add the input field there as well.

Is there a way to do this? With the AngularJS example I can only manipulate device properties, but since I need the API to sync them with the device there needs to be a way to call the API automatically?

Regards
Georg

Hi @GeorgD

You can modify both with HTML widgets. In the AngularJS example, where it is written DeviceProperty write DeviceResource instead, and where is says property write resource. There is also an example regarding device resources linked in my previous reply, which you can use code wise to view the difference between calling a DeviceProperty and a DeviceResource

Regards

Hi @jaimebs

I think i got it. I used the DeviceControlWidget example, which calls an API (e.g. increase).

Unfortunately, there’s no description how to implement an increase function as an API. To increase a value, I firstly need the value before increasing it. I therefor created a property, which pulls the variable from the Device resource. I then tried using it as start value for the payload → {{payload=property.property_name}}. This works fine when using the API manually, but doesn’t do the job when the API is called by the script.

Thanks again for helping me out.

Georg

@jaimebs I tried to figure out a solution for the problem I described in my last posting, regarding the increase function, but I couldn’t come up with a solution. Could you please help me?

Thanks, Georg

Hi,

Increases or decreases are done on the device, the resource is defined to get the received value and add it (positive to increase or negative to decrease).

The resource is defined a kind of:

thing["Resource"] << [](pson &in)
  {
    if (in["increase"].is_empty())
      in["increase"] = temp;
    else
      temp = temp + in["increase"];
};

That resource will show the actual temperature and will increase or decrease it by the received value, note that the widget send the value +1 or -1 automatically when the button is pressed, is not established by the user.

Hope this helps

1 Like

Hi @ega,

thanks for your advice. Unfortunately, your example doesn’t work for me. In the dashboard, I can’t choose a device resource that’s an INPUT but only one that’s an OUTPUT or BOTH. But if I create a resource in my controller code that’s both (as described in the documetation) it won’t work either. The widget doesn’t even display the current value.

This is the coding guide regarding the IN/OUT resources:

Could you help me fix this?

Thanks a lot,
Georg

hi,

I would try something like this, aiming both resources (in and out)to the same variable:

thing["Setup"] = [](pson &in, pson &out)
  {
    if (in["Sampling"].is_empty())
    {
      in["Sampling"] = sampling;
      out["Sampling"] = sampling;
    }
    else
    {
      sampling = in["Sampling"];
      out["Sampling"] = sampling;
    }
};

Let me know how it goes.

hi @ega,

doesn’t work either… The Widget won’t display any value nor react on any input. I changed your code to match the code from the example in the thinger documentation (replaced Sampling with increase).

thing["Test"] = [](pson &TestIn, pson &TestOut)
  {
    if (TestIn["increase"].is_empty())
    {
      TestIn["increase"] = TestVal;
      TestOut["increase"] = TestVal;
    }
    else
    {
      TestVal = TestOut["increase"];
      TestOut["increase"] = TestVal;
    }
  };

I’ve made some screenshots again, maybe I’m still doing something wrong?

Hi @GeorgD

I believe the widget calls for 3 separate resources. With this, you would have as only input resources increase and onoff, as only output resource you would have state.

The increase resource would modify a program variable value based on the integer passed as input. The status resource would output the value of the program variable. It would be something like the following code:

int temperature = 0;

thing["increase"] << [](pson& in) {
    temperature += in["value"];
}

thing["state"] >> [](pson& out) {
    out["temperature"] = temperature;
}

You would still need to implement the onoff resource.

If you check the last line of the HTML file you can see that the value to show in the box is value.temperature. With this in mind, the configuration for the HTML widget would be:

  • Resource: state
  • Fields: temperature

The configuration in the widget would be only to show the output, the rest of the functionality of the widget is handled in the js file and the resources called do not need to match the widget configuration.

I have not been able to test it but this approach should take you a little bit closer to achieving the functionality. Start working on showing the value of the output resource and once you get it go ahead on to the input resources.

Regards