Set value of a device (tskname) via HTTP request – How?

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Set value of a device (tskname) via HTTP request – How?

#1 Post by Wookbert » 31 Jul 2021, 00:09

We’d like to switch a relay on an ESPEasy via HTTP, but not using the usual method knowing and providing the GPIO pin http://<ip.address>/control?cmd=GPIO,5,1, but instead using just
  • IP/hostname
  • Taskname (= Device)
  • Value Name
  • Value.
So switching from e.g. a server without the server knowing the GPIO pin.

Is that possible? We've read the manual sections on Generic HTTP Advanced, TaskRun, TaskValueSet, ... but we are still not sure if and how this can be done.

Alternatively: Is it possible to add a placeholder string to the Controller Publish query, which publishes the selected GPIO pin of a device (as set in ESPEasy’s Device > Task Settings > GPIO)?

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#2 Post by TD-er » 31 Jul 2021, 01:20

Most plugins do have commands specific for that plugin.
Those plugin specific commands can be prefixed using the task name.
See: https://espeasy.readthedocs.io/en/lates ... f-a-plugin
However I'm not sure if the "gpio" command is still part of the plugin, since the GPIO commands are now part of the core.

Another option is to create your own event and act on it in the rules.
Then you can name it however you like (e.g. turnOnWater) instead of trying to formulate the action(s) you need to take.
Using an event is also more flexible since it also allows to process a sequence of commands via a single call.

Just give a command like this:

Code: Select all

event,myEventName
and then in the rules act on it.

Code: Select all

on myEventName do
  gpio,1,0 // Switch GPIO 1 to '0'
endon

Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Re: Set value of a device (tskname) via HTTP request – How?

#3 Post by Wookbert » 31 Jul 2021, 01:37

Thanks for the swift reply. Got to discuss it here internally.

What about this one?
Wookbert wrote: 31 Jul 2021, 00:09 Alternatively: Is it possible to add a placeholder string to the (Generic HTTP) Controller Publish query, which publishes the selected GPIO pin of a device (as set in ESPEasy’s Device > Task Settings > GPIO)?
That way we <strike>could request</strike> would get the GPIO pin from the ESPEasy and store that info for each device on our server.
Last edited by Wookbert on 31 Jul 2021, 09:21, edited 1 time in total.

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#4 Post by TD-er » 31 Jul 2021, 02:02

Right now we don't have something like this.
But I guess it would make sense to have an entry/filter on the JSON url to show everything that's also shown on the pinstates page.
There all "monitored" pins are shown.

Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Re: Set value of a device (tskname) via HTTP request – How?

#5 Post by Wookbert » 31 Jul 2021, 09:57

Also just tried http://<ip.address>/control?cmd=TaskValueSet,1,1,1 and http://<ip.address>/control?cmd=TaskValueSetAndRun,1,1,1 and while both URLs visibly change the value of task #1, value #1 to "1", the relais doesn't follow and turn on. Hu? What’s the point of setting the Task Value then!?

Bildschirmfoto 2021-07-31 um 09.56.15.png
Bildschirmfoto 2021-07-31 um 09.56.15.png (92.58 KiB) Viewed 1549 times

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#6 Post by Ath » 31 Jul 2021, 10:06

The TaskValueSet command is supposed to only update the values of a Dummy device, a Switch task reads the GPIO pin and shows it's state, not the other way around...
/Ton

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#7 Post by Ath » 31 Jul 2021, 10:43

For my Sonoff S20 switches, I use these events in the rules:

Code: Select all

on switchOn do
  gpio,12,1
  pulse,13,0,100 // Flash the green led 2x (second pulse is (ab)used as delay between flashes)
  pulse,13,1,100
  pulse,13,0,100
endon

on switchOff do
  gpio,12,0
  pulse,13,0,100 // Flash the green led once
endon

on switchToggle do
  if [Relay#State]=1
    asyncevent,switchOff
  else
    asyncevent,switchOn
  endif
endon
And I can use them like this:

Code: Select all

http://<ip.address>/control?cmd=event,switchOn
// or switchOff or switchToggle
No need to know the GPIO's ot Tasks of a device
/Ton

Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Re: Set value of a device (tskname) via HTTP request – How?

#8 Post by Wookbert » 31 Jul 2021, 13:43

TD-er wrote: 31 Jul 2021, 02:02 Right now we don't have something like this.
But I guess it would make sense to have an entry/filter on the JSON url to show everything that's also shown on the pinstates page.
There all "monitored" pins are shown.
The JSON Output shows the GPIO states, but unfortunately not the number of the selected pin.
Ath wrote: 31 Jul 2021, 10:06 The TaskValueSet command is supposed to only update the values of a Dummy device...
So why does TaskValueSet then allows one to change values of Non-DummyDevices at all? What's the point if a switching device doesn't react to it? What’s the point if one can for instance overwrite the Generic - System Info > uptime value through TaskValueSet (yes, this really works)? I don't see how TaskValueSet makes any sense to be allowed on Non-DummyDevice, if the changed value has no effect.

It's a pitty that one can't switch/control a device via HTTP request using just the hostname, device name, value name and value. I mean ESPEasy has all the info required, yet one has to create additional vehicles through rules etc.


Our next idea for a work-around to communicate the GPIO pin selection to our backend server:
  • a) use the (in our case: unused) IDX field – OR –
  • b) append the GPIO pin number to the devices value name, so relay_5 instead of just relay

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#9 Post by Ath » 31 Jul 2021, 14:19

Wookbert wrote: 31 Jul 2021, 13:43 So why does TaskValueSet then allows one to change values of Non-DummyDevices at all?
I think that check went MIA (missing in action) during some (probably major) update during the last couple of months (or year), but maybe TD-er removed it on purpose, (IDK).
Wookbert wrote: 31 Jul 2021, 13:43 What's the point if a switching device doesn't react to it?
If the allowing TaskValueSet command to change a non-Dummy device value is a bug, then this shouldn't matter anymore.
Wookbert wrote: 31 Jul 2021, 13:43 It's a pitty that one can't switch/control a device via HTTP request using just the hostname, device name, value name and value. I mean ESPEasy has all the info required, yet one has to create additional vehicles through rules etc.
That would be a feature request, IMHO.
Wookbert wrote: 31 Jul 2021, 13:43 Our next idea for a work-around to communicate the GPIO pin selection to our backend server:
  • a) use the (in our case: unused) IDX field – OR –
  • b) append the GPIO pin number to the devices value name, so relay_5 instead of just relay
a) IDX is used for sending to the Domoticz controllers, so not available for other purposes.
b) Device value names are user-defined (and usually get a default name), so shouldn't be messed with by ESPEasy. If you want it to be relay_5, you can ;)
/Ton

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#10 Post by Ath » 31 Jul 2021, 14:52

To provide a solution for sending a value to a Dummy device by name, the TaskValueSet (and similar) commands have already been enhanced to support addressing them in that way, see PR #3098.

I've created this small rule to allow setting it from an external source, and have a little control over the values. (TaskValueSet can also be sent as an external command, but doesn't allow any further control)

Code: Select all

on TaskValue do
  logentry,"1: %eventvalue1%, 2: %eventvalue2%, 3: %eventvalue3%"
  TaskValueSet,%eventvalue2%,%eventvalue3%,%eventvalue1%
endon
(the logentry command is for debugging purposes, and can be commented out or deleted)

This rule can be addressed like this: (from the Tools page or externally)

Code: Select all

event,TaskValue=10,Variables,One // requires an enabled Dummy device named Variables, with a value named One, (not case-sensitive)
The EVENT command requires the first argument to be numeric (non-numerics will be parsed as if they are a Rules#Timer=All,... event), that's why I used the first eventvalue as the value to set, because that is (also) required to be numeric (any calculations should be processed at the source system)
/Ton

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#11 Post by TD-er » 31 Jul 2021, 14:59

There are other controllers too that use the IDX field, but it was mainly intended for Domoticz as that one really needs the IDX to distinguish the origin of a value.

I'm a bit surprised to see taskvalueset does apparently do something on other plugins too?
It is intended to work only on Dummy tasks. (n.b. there is also taskvaluesetandrun to immediately send the values to a connected controller)
I don't know what will happen if taskvalueset is executed on other plugins, since some plugins also update the values in the UserVar struct (where taskvalues are kept) in stages and reschedule themselves to flush the values to a controller when all values are collected.
So there may be a good chance you will run into "undefined behavior" as it is never intended to be used on plugins other than the dummy plugin.

So if it really allows to set values of other tasks too, then it for sure is a bug.


Sending commands through events is way more flexible as you can also include event values (upto 4) and perform a lot more complex actions.
If we need to add it to every plugin to decode specific command flags, the code becomes way more complex and it also adds a lot of complexity to secure it.
Right now commands from "external sources" are limited as in you cannot execute every command from remote (e.g. reset to factory default is one that should not be accepted from everywhere)
If you execute commands via events, you as a user can decide what has to be done as you put it in the rules.
So it can only execute those commands you put into the rules.

It may look like it is a work-around, but actually it isn't. It is a very powerful tool to handle events you can define for your use case.
Having yet another way of formatting commands via a HTTP call is actually the work-around kind of handling which makes things a lot more complex to maintain as it is another code path that must be maintained, tested, etc. And it will probably need some extensions later on to add new thought of features which also makes things complex as you don't want to break existing functionality.

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#12 Post by Ath » 31 Jul 2021, 15:05

TD-er wrote: 31 Jul 2021, 14:59 if it really allows to set values of other tasks too, then it for sure is a bug.
I'll have a look if I removed that check by accident when implementing the named arguments there 8-)
/Ton

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#13 Post by TD-er » 31 Jul 2021, 15:17

Ath wrote: 31 Jul 2021, 15:05
TD-er wrote: 31 Jul 2021, 14:59 if it really allows to set values of other tasks too, then it for sure is a bug.
I'll have a look if I removed that check by accident when implementing the named arguments there 8-)
Would be a nice one to fix, as I intended to make a new build this evening. (so we at least have one build in this month... way too long between builds)

Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Re: Set value of a device (tskname) via HTTP request – How?

#14 Post by Wookbert » 31 Jul 2021, 15:22

TD-er wrote: 31 Jul 2021, 15:17 so we at least have one build in this month... way too long between builds
Better properly and flawless, than frequently, often and buggy.
Ath wrote: 31 Jul 2021, 14:19 a) IDX is used for sending to the Domoticz controllers, so not available for other purposes.
That is if one is using Domoticz. If not, it can be diverted from its intended use. A device’s IDX value is part of the JSON output and can also be published by adding %id% to the Generic HTTP Controller Publish query (I've just tested it).

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#15 Post by TD-er » 31 Jul 2021, 15:30

The IDX value for a task is only presented when a controller is linked to the task which is able to use the IDX field.
There are not many of those controllers.
And since it is a field per controller, you may have upto 3 IDX values for a task.

Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Re: Set value of a device (tskname) via HTTP request – How?

#16 Post by Wookbert » 01 Aug 2021, 22:25

I might overlook something here, but according to what we (me and my partner in crime here in Germany) know at this point, we need to GPIO info only for devices we want to control/switch.
TD-er wrote: 31 Jul 2021, 15:30 There are not many of those controllers.
Well, I went randomly through the device pull-down menu, and found that most devices have an IDX field, which we could „kidnap“ if needed. (I'll open a feature request on Github for a „high-level“ TaskSet/switching command however).
TD-er wrote: 31 Jul 2021, 15:30 And since it is a field per controller, you may have upto 3 IDX values for a task.
Can't follow you on that one. Currently we hav a single Generic HTTP Controller with the following Controller Publish query:

Code: Select all

esp-easy?hostname=%sysname%&device=%tskname%&parameter=%valname%&gpio-idx=%id%&value=%value%
It provides us the info as in the query, whether there is one device or eight devices in the unit.

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#17 Post by TD-er » 01 Aug 2021, 23:43

Wookbert wrote: 01 Aug 2021, 22:25 I might overlook something here, but according to what we (me and my partner in crime here in Germany) know at this point, we need to GPIO info only for devices we want to control/switch.
TD-er wrote: 31 Jul 2021, 15:30 There are not many of those controllers.
Well, I went randomly through the device pull-down menu, and found that most devices have an IDX field, which we could „kidnap“ if needed. (I'll open a feature request on Github for a „high-level“ TaskSet/switching command however).
I meant the controller, not the plugin/task.
As soon as you have a controller configured and enabled which does need/support IDX, then all tasks will show the IDX field next to that controller.

Wookbert
Normal user
Posts: 65
Joined: 06 Nov 2020, 03:17

Re: Set value of a device (tskname) via HTTP request – How?

#18 Post by Wookbert » 02 Aug 2021, 13:48

Gotcha. We are using the Generic HTTP Controller alone, so we don't see any problems here.

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#19 Post by Ath » 02 Aug 2021, 14:07

Well, the issue is that these settings are already reserved for use, so can't be given another purpose. And not all plugins have adhered to the standards properly, by using the CONFIG_PIN1/2/3 configuration options available, so there is no generic way of retrieving any GPIO setting from a plugin. That would require an extra function option (PLUGIN_GET_GPIOS_USED?), to retrieve that info from a plugin. And then to decide how to format it... (plain string?, JSON grouped?, include name and/or other info?, and then some more possibilities).

A similar 'issue' exists in the area of the I2C scanner: Currently that's a fixed list of options (taking quite some .bin space, so these names are excluded on some builds), that have to be manually maintained, but if we could query each plugin what I2C addresses it supports (PLUGIN_GET_I2C_ADDRESSES), we could then show the full plugin name. But it would not show a name if the plugin isn't included in the build (but that's similar if the list is excluded), so, another chicken/egg problem :roll:
/Ton

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#20 Post by TD-er » 02 Aug 2021, 14:47

Not sure if that's what he's asking.
He wants to effectively switch a relay in a generic way without the need to know the exact configuration of that node.

So I think it is still the best way to implement an event block in the rules and call the event command with that event name.
Then everything that needs to be done can be local on that node in the rules file.

Trying to find new ways to be able to do this is going to be extremely complex (at least to maintain).
So please let's first make clear what cannot be done using the event call.

User avatar
Ath
Normal user
Posts: 1090
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Set value of a device (tskname) via HTTP request – How?

#21 Post by Ath » 02 Aug 2021, 14:57

Think it also involves reporting back to the external system what GPIO is involved, and it seems he's looking for a more generic way to get that info from the plugin, without putting specifics in the rules code.
But putting that in the rules wouldn't be that bad, I'd think, one could even use [var#x] variables for that, where x is the Task number, and the values could be initialized in the 'on System#Boot do' event.
/Ton

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#22 Post by TD-er » 02 Aug 2021, 15:04

Getting specific info from a plugin/task does probably require quite a lot of new commands -> nightmare to maintain, hit on resources + very limited use case.

However I do see that we don't really have "get" commands which do return a value.
Not sure though how that should be implemented in a generic way.
Therefore I need to know the use case.

If this can be handled via some kind of REST like interface with GET and POST of JSON data, then that's something we will be moving to with the new web UI.
So it is good to have an idea of other use cases that can benefit from it, but that also needs a good idea of a use case ;)

Dexamenos
Normal user
Posts: 6
Joined: 19 Jul 2021, 13:51

Re: Set value of a device (tskname) via HTTP request – How?

#23 Post by Dexamenos » 02 Aug 2021, 16:18

Hi there, I turn out to be the aforementioned partner in crime :-)

Use case: our idea would be a kind of semi-self-configuring system.

Think of: each ESP Easy unit will be pre-configured:
- hardware with one or more relais shield
- software with:
- one controller (Generic HTTP), for all esp units set to the same end point of our server
- one device/task per relais (Switch input - Switch), send info on boot activated
- our server then learns, which ESP devices are present in the network (this might change over time)
- feedback of the relais state works flawlessly with the "Switch input - Switch"

What is missing would be the other way around; automatically get the info to actually change the relais (we are currently doing this per http-request to control?cmd=GPIO....).

My thoughts (please turn me to the right direction, if I'm mistaken here):
- GPIO communication, I consider this "low-level", so more direct interaction with the hardware
- the tasks/devices, I consider them somewhat more "abstract" representations of the hardware
- like I can receive the current "state" of a device via the Controller publishing system (note: this controllers do not publish the low level GPIO state, they directly publish the "value" state), I would luckily also "stear"/control not only on the low-level, but on the more abstract level

Think of:
- device/task => garden_light; type is switch input; valuename => relais; value => 0 / 1; with relais attached to GPIO No 5
- I will receive controller publications with "garden_light / relais / 1"
- However: I can only change with "control?cmd=GPIO,5,1"
- I would be glad to be able to change the relais with something like "control?cmd=taks&name=garden_light&valname=relais&val=1" <- must not be that exact syntax
- My understanding would be, to use the high level "device", which by itself encapsulates the "hardware" info, like GPIO assignment

Many words, I hope we are not bothering you too much.

What do you think? Am I mistaken in the concept of ESP Easy system here?

TD-er
Core team member
Posts: 5373
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Set value of a device (tskname) via HTTP request – How?

#24 Post by TD-er » 02 Aug 2021, 21:05

Automatic update of state change of a GPIO pin is already possible, but it is via the rules.

The rules really are quite powerful, so please have a look at them: https://espeasy.readthedocs.io/en/lates ... Rules.html

You simply enable monitoring a pin using the monitor command: (from the same rules link)

Code: Select all

on System#Boot do
 Monitor GPIO,15
endon

 on GPIO#15=0 do
  if [Plugin#GPIO#Pinstate#13]=0
   // do something
  endif
 endon

 on GPIO#15=1 do
  if [Plugin#GPIO#Pinstate#13]=1
   // do something
  endif
 endon
 
This example acts on the state change of GPIO 15 and does check GPIO 13 to do something.

You can also periodically let the rules check some values. This can be based on a timed interval, but also if a sensor has successfully read a new value and is sent to a controller.
Along with sending it to a controller, it also sends an event, on which you can act in the rules.

For example a task named "bme" with task values T, H and P will either generate 3 events:

Code: Select all

bme#T=23.45
bme#H=67.8
bme#P=1002.34
Or a single event (you can check the checkbox for this on every task, when the rules are enabled)

Code: Select all

bme#All=23.45,67.8,1002.34
So in the rules you can create a block like this:

Code: Select all

on bme#All do
  // all eventvalues are present via %eventvalue1% , %eventvalue2% , %eventvalue3% , %eventvalue4%

endon

So if you want to perform some abstract call, like "lightsOnWhenDark", you can consider that the name of an event and call it using

Code: Select all

event,lightsOnWhenDark
In the rules you can make a block like this:

Code: Select all

on lightsOnWhenDark do
  // compare time against sunrise/sunset
  // then turn light on
  // etc

endon
This way you don't need to know whether a GPIO pin must be inverted, which pin to use, etc.
You can define your own abstract labels.


So please have a look at the rules, because more than what you're now thinking of is already possible and most of the items are almost verbatim used as an example in the rules docs.

And if you need a lot of communication between one or more nodes, please consider using MQTT and use the OpenHAB MQTT controller as it also allows you to send commands to a topic.

Post Reply

Who is online

Users browsing this forum: No registered users and 14 guests