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 };

In reply to Re: making a loop script with a remote URL call faster by stevieb
in thread making a loop script with a remote URL call faster by brandonm78

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.