Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: making a loop script with a remote URL call faster

by stevieb (Canon)
on Jan 15, 2022 at 17:35 UTC ( [id://11140474]=note: print w/replies, xml ) Need Help??


in reply to making a loop script with a remote URL call faster

I have a microcontroller on my garage wall that displays information about my Tesla car, with a visible charge level and an audible alarm if the charge is below a certain point so I don't forget to plug the car in.

The device turns on only when there is motion in the garage. It reaches back every one second to a computer in my house to fetch updated data about the car. The computer in the house serves that device the data, but it also fetches that data from Tesla's API. While there is motion (ie. the microcontroller is asking for updated data), the computer returns whatever data it has available, while repeatedly fetching data from Tesla in case it changes. The fetching from Tesla happens as fast as when one pull is done, another starts immediately. This data is fetched in a separate process than the process that returns existing data to the microcontroller. When the Tesla data updates, the shared variable is updated, and the next return to the microcontroller has this new data.

There is no lag or delay, thanks to the separate process. It also means that the call from the controller to the server is always extremely consistent with no delay.

Here is an extremely (!) simplified version of that you might be able to use as an example. It uses my IPC::Shareable distribution to create the shared memory backed variable that's used between the two processes, and my Async::Event::Interval for the external async process used to fetch the data from the website.

Feel free to ask any questions. I've put this together rather hastily so I'm sure I may not be explaining things very well

use strict; use warnings; use Async::Event::Interval; use Data::Dumper; use IPC::Shareable; use JSON; use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $url = 'http://tesla:55556'; # Create a shared scalar string that will hold JSON # data that gets updated by the async event below, which # runs in a separate, unrelated process tie my $fetched_data, 'IPC::Shareable', { key => 'TESLA', create => 1, destroy => 1, }; $fetched_data = ''; # Create an async event that runs in the background. The # 0 parameter means it won't run on an interval, we have to # manually start it each iteration of the loop. We 'start' # it here to send it off on its first run so we have initial # data my $tesla_event = Async::Event::Interval->new(0, \&update_data); $tesla_event->start; my $previous_time = time; my $previous_tesla_data = {charge => -1}; while (1) { # If the background URL fetch is done, start it again. It's probab +ly wise # to time yours to run just prior to your 60 second loop cycle tim +er # expiring. No sense constantly hitting the site every second if y +ou # don't need the data that quick! $tesla_event->start if $tesla_event->waiting; my $current_time = time; if ($current_time - $previous_time > 3) { my $tesla_data = decode_json($fetched_data); if ($tesla_data->{charge} != $previous_tesla_data->{charge}) { # Do stuff with the result print Dumper $tesla_data; $previous_tesla_data = $tesla_data; } $previous_time = $current_time; } } sub update_data { my $server_response = $ua->get($url); if ($server_response->is_success) { $fetched_data = $server_response->decoded_content; } }

Output. The first output is when my car was asleep. The next one was after I sent a wakeup call to it.

$VAR1 = { 'fetching' => 0, 'charge' => 0, 'charging' => 0, 'online' => 0, 'error' => 0, 'gear' => 0, 'garage' => 0, 'rainbow' => 0 }; $VAR1 = { 'fetching' => 0, 'charge' => 61, 'charging' => 0, 'online' => 1, 'error' => 0, 'gear' => 0, 'garage' => 1, 'rainbow' => 0 };

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11140474]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-19 02:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found