triggered update for virtual http input

82 views
Skip to first unread message

Hidde Beumer

unread,
Feb 21, 2024, 7:11:42 AM2/21/24
to Loxone English
I do have a challenge and wonder if there's any way to solve this in
Loxone.

I have virtual HTTP input that I need to align the updates for based on
a trigger (E.g. on top of the hour). The problem however is that I can
only set the frequency for updates on the Virtual HTTP input, but I
cannot set when the frequency needs to start, it simply starts based on
the restart time of the miniserver (as far as I can tell).

Is there a way to update a input based on a pulse?

Regards,


Hidde




duncan

unread,
Feb 21, 2024, 7:52:38 AM2/21/24
to Loxone English
can you use a pulse at hour change to update/trigger an analog memory?  - each pulse will then transfer the analog input value to the memory output, assuming the data is numeric

hidde....@gmail.com

unread,
Feb 22, 2024, 7:16:17 AM2/22/24
to Loxone English

While using an analog input will make it easier for me to control what goes into the variable, it still won't allow me to control how often I fetch the data from the external HTTP source.

I did manage to implement a process that fetches the data once from the external HTTP server and stores it on the loxone local flash. The file is in a JSON format and now I use the local loxone HTTP service to get the data into the loxone HTTP virtual inputs, I wonder if there's a way in which I can access the local Loxone flash and parse the JSON file into variables in any other way. That way I don't have to implement a rapid refresh of the virtual inputs and decrease the load on the miniserver.

Op woensdag 21 februari 2024 om 13:52:38 UTC+1 schreef duncan:

Rob_in

unread,
Feb 23, 2024, 3:45:31 AM2/23/24
to Loxone English
On Thursday 22 February 2024 at 13:16:17 UTC+1 hidde....@gmail.com wrote:
While using an analog input will make it easier for me to control what goes into the variable, it still won't allow me to control how often I fetch the data from the external HTTP source.

Well, that's not strictly true - you can control the interval, just not the exact timing.

Duncan's proposal sounds OK, although wasteful on resources: fetch every 30/20/10 mins or whatever and use a memory block with a trigger at your exact timing point to update it's output.

Going back to basics I have to ask: why is it you think you need to update this value exactly on the hour? What end result are you actually trying to achieve?

If it absolutely has to happen on the hour then TBH I'd use an external system (RPi, etc) to do this because hacking stuff like this into Loxone is just too cumbersome. I don't bother with any HTTP fetch/parse in the Miniserver anymore - it's just a million times easier to offload those tasks to an SBC.

Robin

Hidde Beumer

unread,
Feb 23, 2024, 4:59:19 AM2/23/24
to loxone-...@googlegroups.com

Well, it's about spot prices which I get as relative values, with a timestamp in UTC. Do somehow I need to convert UTC to the local time (CE with daylight saving), and then take the corresponding value for the hour we're dealing with. Part of the problem is also that the Loxone documentation for this function block is not the best (understatement).

Looks like it either needs to be provided relative inputs (with the current hour as hour0), and then also needs a trigger every hour or so to update the outputs. Or it runs in absolute mode in which the hours correspond with the local time. Looks like I'm going to build a page in which I need to do a bit more parsing and logic to work it all out. I like to stay away from external scripts as much as possible, even though sometimes it tempting given how hard the parsing logic in loxone sometimes ends up...


Hidde

Tico

unread,
Feb 23, 2024, 7:27:40 AM2/23/24
to Loxone English
Here's the code for a PicoC block (Program Block), that extracts a particular value from a file stored on the Miniserver SD card. This can be triggered to retrieve values at an exact time of your choosing. You will need to adapt the code to recognise the field returned in your json.

1. Trigger a Virtual Output to poll the external resource at the desired time. "Save HTTP Response" to the Miniserver SD card.
2. Use a delayed pulse triggered from the above process to run the Program block to retrieve the desired values.

I don't know how to code, but I've used ChatGPT extensively to modify Program block code - 


ChatGPT doesn't know the limitations of the Loxone Program Block. When is comes up with code that doesn't work in the Program Block (the Program Block has an Error Text output), tell it to program the same thing without using 'XYZ' function. After a few iterations, you'll hopefully get code that suits the limitations of the Miniserver. ie. Tell ChatGPT to modify the code to find 'ABC' field associated with 'XYZ' value. The following code finds and outputs an OAuth token after the field "IdToken":"xyz..........................."

PicoC Code -

// PicoC code developed by @Jan W.
// Link refers -
// https://www.loxforum.com/forum/german/software-konfiguration-programm-und-visualisierung/403543-vti-aus-programm-picoc-beschreiben?p=405574#post405574

FILE *fp1;
char str1[7200];
char *tokenStart;
char *tokenEnd;
char token[4095];
char IdToken[20] = "\"IdToken\":\"";
int len;
int nEvents;

while(TRUE)
{
    nEvents = getinputevent();
    if (nEvents & 0x08) // check for change on analogue input 1 (Bit 4) - this is only used as a trigger to run following code
    {
        fp1 = fopen("/user/common/zodiac_token.json", "r");
// open file with token read
        fgets(str1, 7200 , fp1); // copy content of file to string, max. 4094 bytes plus trailing 0

        tokenStart = strstr(str1,"IdToken");
// search for characters 'IDtoken' in string
        if (tokenStart != NULL) {
            //tokenStart += strlen(IdToken); // if found then add length of token itself
tokenStart = tokenStart + strlen(IdToken) -1; // if found then add length of token itself
            tokenEnd = strstr(tokenStart, "\"");
// search for final quotation symbol
            if (tokenEnd != NULL) {
                len = tokenEnd - tokenStart; // if found then calculate length of token
                strncpy(token, tokenStart, len); // copy n bytes from string to token starting from begin of token
token[len] = 0; // add trailing 0 to token string
                setoutput(0,len); // set analogue output 1 to length of token
                setoutputtext(0,token); // set text output 1 to token
            }
        } else {
            setoutputtext(0,"No text found");
// clear output if no token is found              
            setoutput(0,0);
        }
    }
        fclose(fp1);
    }
    sleep(500); // sleep for half a second  
}
Reply all
Reply to author
Forward
0 new messages