Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 32 additions & 15 deletions docs/source/Rules/Rules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1977,9 +1977,9 @@ Added: 2023/10/26
1. Get the value of a single field:

- Example command:
``SendToHTTP,api.thingspeak.com,80,/channels/1637928/fields/5/last.csv``
``SendToHTTP,api.thingspeak.com,80,/channels/143789/fields/5/last.csv``
- Example of the resulting event:
``"EVENT: ThingspeakReply=1637928,5,24.2"``
``"EVENT: ThingspeakReply=143789,5,9.65"``

| channel number = ``%eventvalue1%``
| field number = ``%eventvalue2%``
Expand All @@ -1988,29 +1988,46 @@ Added: 2023/10/26
2. Get the values of all fields:

- Example command:
``SendToHTTP,api.thingspeak.com,80,/channels/1637928/feeds/last.csv``
``SendToHTTP,api.thingspeak.com,80,/channels/143789/feeds/last.csv``
- Example of the resulting event:
``"EVENT:ThingspeakReply=1637928,5929,353,42.0,177,19.1,995.6,,"``
``"EVENT: ThingspeakReply=143789,11.12,9.46,9.55,16.32,9.65,8.81,-1.23,14.76"``

| channel number = ``%eventvalue1%``
| values = ``%eventvalue2%`` to ``%eventvalue9%``

.. note::
``last.csv`` is mandatory!

.. warning:: When using the command for all fields, the reply can become extremely big and can lead to memory issues which results in instabilities of your device (especially when all eight fields are filled with very big numbers)
.. warning:: When using the command for all fields, the reply can become extremely big and can lead to memory issues which results in instabilities of your device (especially when all eight fields are filled with very big numbers)

* Example for two single field events in rules:
* Rules example:

.. code:: none
.. code:: none

on ThinkspeakReply do
LogEntry,'The channel number is: %eventvalue1%'
if %eventvalue2% = 5 //when the field number is 5
LogEntry,'%eventvalue3%°C in Berlin'
elseif %eventvalue2% = 6 //when the field number is 6
LogEntry,'%eventvalue3%°C in Paris'
endif
endon
On System#Boot Do
SendToHTTP,api.thingspeak.com,80,/channels/143789/feeds/last.csv
Endon

On ThinkspeakReply Do
LogEntry,'The channel number is: %eventvalue1%'
LogEntry,'%eventvalue6%°C in Berlin'
LogEntry,'%eventvalue7%°C in Paris'
Endon

Added 2024/02/05

* Added the option to get a single value of a field or all values of a channel at a certain time (not only the last entry)

* Examples:

Single channel: ``"sendtohttp,api.thingspeak.com,80,channels/1637928/fields/1.csv?end=2024-01-01%2023:59:00&results=1``
=> gets the value of field 1 at (or the last entry before) 23:59:00 of the channel 1637928

All channels: ``"sendtohttp,api.thingspeak.com,80,channels/1637928/feeds.csv?end=2024-01-01%2023:59:00&results=1``
=> gets the value of each field of the channel 1637928 at (or the last entry before) 23:59:00

.. note::
``csv`` and ``result=1`` are mandatory!

Convert curl POST command to PostToHTTP
---------------------------------------
Expand Down
35 changes: 22 additions & 13 deletions src/src/Helpers/Networking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,24 +1575,33 @@ int http_authenticate(const String& logIdentifier,
// channel number ┘ | └ received values
// field number (only available for a "single-value-event")
// In rules you can grep the reply by "On ThingspeakReply Do ..."

if (httpCode == 200 && equals(host, F("api.thingspeak.com")) && uri.endsWith(F("/last.csv"))) {
String result = http.getString();
const int posTimestamp = result.lastIndexOf(':');
if (posTimestamp >= 0) {
result = parseStringToEndKeepCase(result.substring(posTimestamp), 3);
if (uri.indexOf(F("fields")) >= 0) { //when there is a single field call add the field number before the value
result = parseStringKeepCase(uri, 4, '/') + "," + result;
}
eventQueue.addMove(strformat(
F("ThingspeakReply=%s,%s"),
//-----------------------------------------------------------------------------------------------------------------------------
// 2024-02-05 - Added the option to get a single value of a field or all values of a channel at a certain time (not only the last entry)
// Examples:
// Single channel: "sendtohttp,api.thingspeak.com,80,channels/1637928/fields/1.csv?end=2024-01-01%2023:59:00&results=1"
// => gets the value of field 1 at (or the last entry before) 23:59:00 of the channel 1637928
// All channels: "sendtohttp,api.thingspeak.com,80,channels/1637928/feeds.csv?end=2024-01-01%2023:59:00&results=1"
// => gets the value of each field of the channel 1637928 at (or the last entry before) 23:59:00
//-----------------------------------------------------------------------------------------------------------------------------

if (httpCode == 200 && equals(host, F("api.thingspeak.com")) && (uri.endsWith(F("/last.csv")) || (uri.indexOf(F("results=1")) >= 0 && uri.indexOf(F(".csv")) >= 0))){
String result = http.getString();
result.replace(' ', '_'); // if using a single field with a certain time, the result contains a space and would break the code
const int posTimestamp = result.lastIndexOf(':');
if (posTimestamp >= 0){
result = parseStringToEndKeepCase(result.substring(posTimestamp), 3);
if (uri.indexOf(F("fields")) >= 0){ // when there is a single field call add the field number before the value
result = parseStringKeepCase(uri, 4, '/').substring(0, 1) + "," + result; // since the field number is always the fourth part of the url and is always a single digit, we can use this to extact the fieldnumber
}
eventQueue.addMove(strformat(
F("ThingspeakReply=%s,%s"),
parseStringKeepCase(uri, 2, '/').c_str(),
result.c_str()));
}
}
}
#endif
}

#ifndef BUILD_NO_DEBUG
log_http_result(http, logIdentifier, host + ':' + port, HttpMethod, httpCode, EMPTY_STRING);
#endif
Expand Down