Interesting Use-Case Scenario for Livecode Server

Are you using LiveCode to create server scripts or CGIs?

Moderators: Klaus, FourthWorld, heatherlaine, kevinmiller, robinmiller

Post Reply
ghettocottage
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 248
Joined: Tue Apr 10, 2012 9:18 am

Interesting Use-Case Scenario for Livecode Server

Post by ghettocottage » Fri Apr 08, 2016 4:17 pm

I live in Northern California, which is a major agricultural area. Recently, an almond farmer approached me with a simple problem: At certain times each year almond farmers are allotted water. Each almond-field has a pump ( that runs on a generator) which distributes that water throughout the field.

Since water is allotted, and because of the drought, it is important that the farmer knows immediately if the pump turns off...which happens occasionally for various reasons...runs out of diesel, loses water pressure, malfunction, etc...

The farmer wanted to know if I could create a system that would alert him as soon as the pump turned off. Apparently there are services that do such things, but are more geared for industrial farming and cost prohibitive.

There is a house on the farm that has internet, and the almond fields sort of spread out from around the house.

Are your idea-wheels turning? I spent last month working out the mechanics of this project.

Here is what I have so far:
  • a series of dd-wrt routers in bridge-mode allowed me to get internet all the way to the pump.
  • The final dd-wrt router at the pump is connected to a solenoid so that if the pump stops, the router turns off.
  • This router has openvpn in client-mode, which connects to a server on DigitalOcean that has Livecode server installed.
  • From that server, I can ping the router that is connected to the pump (when the pump is running)
Now I just need to write a little application that will email (or perhaps text) the farmer if the router becomes un-pingable. I did a quick thing in PHP just to see if my idea would work. The following pings the router every few seconds and if it fails it changes the css class of a div, and displays the status of the router. You can see it in action here: http://dragonfli.de/ping

PING FUNCTION:

Code: Select all

<?php

    /* a simple php ping function */
    function ping($host)
    {
            exec(sprintf('ping -c 1 -W 5 %s', escapeshellarg($host)), $res, $rval);
            return $rval === 0;
    }

?>

PHP TO DISPLAY STATUS

Code: Select all

	<?php  /* check if the host is up  */
	    $host = '10.8.0.13';
	    $up = ping($host);
	    $status = "Uh OH!!";
	    if($up){ //if event is up 
		 $status = "Things are good!"; 
			//read the file to see if it has an up or down date
			 $myFile = "ping";
			 $fr = fopen($myFile, 'r');
			 $event_name = fread($fr, 4); 
			 fclose($fr);

			
				//mark the current up time so we can calculate
				$up_time = "up_time";
				$ut = fopen($up_time, 'w') or die("can't open file");
				$time = time();
				fwrite($ut, $time);
				fclose($ut);     


			    if( $event_name == "Down" ) {  //if event is down get an up date
				$pretty_date = date(" g:ia D, F d" );
				$myFile = "ping";
				$fh = fopen($myFile, 'w') or die("can't open file");
				$stringData = "Up since ".$pretty_date;
				fwrite($fh, $stringData);
				fclose($fh);

				}
		}


	    if(!$up ) {  //if down
    		//read the file to see what the last date/event was
		 $myFile = "ping";
		 $fr = fopen($myFile, 'r');
		 $event_name = fread($fr, 2);
		 fclose($fr);  
		//read the file to see the last uptime for calculating
		 $up_time = "up_time";
		 $ut = fopen($up_time, 'r');
		 $up_time = fread($ut, 10);
		 fclose($ut);  
		     //if current time minus last up_time is greater than 5 minutes
		     if( date() - $up_time >= 300){  echo "HELLO IT HAS BEEN 5 MINUTES";  

				


			 }



	    	    if( $event_name == "Up" ) {  //if event is up get a down date
			$pretty_date = date(" g:ia D, F d" );
			$myFile = "ping";
			$fh = fopen($myFile, 'w') or die("can't open file");
			$stringData = "Down at";
			fwrite($fh, $stringData);
			$stringData = $pretty_date;
			fwrite($fh, $stringData);
			fclose($fh);   


			}
		 } //end if down

		$myFile = "ping";
		$fr = fopen($myFile, 'r');
		$event_date = fread($fr, 100); 
		fclose($fr);


   	  /* give the div a class of up or down and echo status */
   	 echo '<div  class="'.($up ? 'up' : 'down').'" >';  ?>
	   <span class="status">
		<?php echo $status; ?>
	  </span>
	   <span class="event-date">
		<?php echo $event_date; ?>
	  </span>
	</div>



The above is a good start, but for various reasons I want this to be in Livecode rather than PHP. Also, I need to change a few things:
  • It should send an email (or text if that is possible) when things do go down
  • It should wait five minutes if it cannot ping the router BEFORE sending out the email..I have noticed that sometimes there are very short down-times which are probably just brief wireless interruptions ...so I want to ignore those
  • Currently it saves down-times in a simple text-file, but I think it would be good to make a database for it so there is a record of down-times
I will be working on this over the next week. Water allotments are starting this month, so it would be cool to have something more than a simple web-interface.

I should also mention that this is a free and open-source project...meaning I am not making any money off this, and will gladly share my code if anyone wants it. The farmer paid me with two truckloads of almond wood and a 25 pound bag of raw shelled almonds.

Any thoughts or ideas are appreciated.

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4156
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Interesting Use-Case Scenario for Livecode Server

Post by jacque » Sat Apr 09, 2016 8:22 pm

I'm really terrible with hardware so I shouldn't be answering, but I can ping my router this way:

Code: Select all

get url "http://192.168.0.1"
Which returns the html for the default login page. If it returns an error in the result then you've lost the connection. You could also use a terminal command using LC's "shell" function, I assume using the same parameters in your PHP script.

For email, I use Andre Garzia's email handler which works well if you have a server with sendmail installed. Instructions are in this LiveCode lesson:
http://lessons.livecode.com/m/4070/l/81 ... er-scripts
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

jiml
Posts: 145
Joined: Sat Dec 09, 2006 1:27 am
Location: Los Angeles

Re: Interesting Use-Case Scenario for Livecode Server

Post by jiml » Sat Apr 09, 2016 11:25 pm

A little late now, but you may have been able to use directional antennas to avoid the need of intervening bridge routers. In the early WiFi days tin can antennas actually worked wonders for sending signals relatively long distances.
You're currently monitoring the state of the router at the pump. There could be lots of reasons you can't ping the router beside the pump being down. It is the Internet after all! :)
Using an Arduino with solenoid at the pump might be better, since it could monitor the state of the pump itself and report that data.
If there is no electric line at the pump (just a diesel generator), the Arduino could have battery backup in case the generator itself goes down. In fact, with multiple sensors you could get more discrete feedback, e.g., diesel generator down vs. pump down.

For your current setup, Jacque's advice is perfect.
I wouldn't monkey with a database. A text file is sufficient in my opinion.
Poll the URL at some interval, say, once every 20 minutes.
Prepend the results to a text file. You can just view that in a browser at any time to see the full history.
Then Email any alerts as the need arises.

ghettocottage
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 248
Joined: Tue Apr 10, 2012 9:18 am

Re: Interesting Use-Case Scenario for Livecode Server

Post by ghettocottage » Tue Apr 12, 2016 6:08 pm

jiml wrote:A little late now, but you may have been able to use directional antennas to avoid the need of intervening bridge routers. In the early WiFi days tin can antennas actually worked wonders for sending signals relatively long distances...
I attempted to use an expensive directional antenna, and had a gaggle of problems. I tested the antenna at my house first, and was able to get it working if I had direct line-of-sight. However, at the farm, the main router with internet was around the corner of the house, and I was not able to get the directional antenna to establish a solid connection.

By using a series of WRT54g routers in bridge-mode, I was able to get the connection to wrap around the house, out to the garage, and then to the pump. Using the routers was cheaper than the directional antenna, which I was able to return for a full refund.

Using an Arduino with solenoid at the pump might be better, since it could monitor the state of the pump itself and report that data.
If there is no electric line at the pump (just a diesel generator), the Arduino could have battery backup in case the generator itself goes down. In fact, with multiple sensors you could get more discrete feedback, e.g., diesel generator down vs. pump down.
I agree..might be a future endeavour if this project turns out to be practical. At the moment I don’t want to invest any more into hardware, but it would not be difficult to swap out the router for an different board should I get to that point. I have nice weather-proof boxes on a pole next to the pump.

jiml
Posts: 145
Joined: Sat Dec 09, 2006 1:27 am
Location: Los Angeles

Re: Interesting Use-Case Scenario for Livecode Server

Post by jiml » Wed Apr 13, 2016 5:47 pm

Yep, the directional antennas are best for direct line of sight.

ghettocottage
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 248
Joined: Tue Apr 10, 2012 9:18 am

Re: Interesting Use-Case Scenario for Livecode Server

Post by ghettocottage » Fri Apr 15, 2016 12:45 am

jacque wrote:I'm really terrible with hardware so I shouldn't be answering, but I can ping my router this way:

Code: Select all

get url "http://192.168.0.1"
Which returns the html for the default login page. If it returns an error in the result then you've lost the connection. You could also use a terminal command using LC's "shell" function..
jacque wrote: For email, I use Andre Garzia's email handler which works well if you have a server with sendmail installed. Instructions are in this LiveCode lesson:
http://lessons.livecode.com/m/4070/l/81 ... er-scripts

Thanks for the tips jacque. I found shell scripts easier to use, so I just wrote a bash script for pinging the router, and another bash script for emailing, but you put me on the right track
My bash script uses SMTP, so I was able to create a gMail account for this, which can send texts. So the farmer gets a text message when the pump goes down.

Here is my lc script (and see it in action here: http://dragonfli.de/ping)

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
	<head>
	 	<meta http-equiv="refresh" content="5; URL=/ping">
	  	<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
		<meta content="utf-8" http-equiv="encoding">
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script>
		<link href="css/ping.css" rel=stylesheet type="text/css">
	</head>
 <body>

<?lc  

	#check if the server is up or down
	put shell("./functions/check") into tStatus
	#get the most recent status from the time file
	put line 1 of  URL "file:time" into tLastEvent
	put line 2 of  URL "file:time" into tDate
	put line 3 of  URL "file:time" into tTime
	put "Things Are Good!" into Comment
	put "up" into tClass

	if "up" is in tStatus then
	--do things if the server is up
		put the seconds into line 4 of URL "file:time"

			if tLastEvent is "down" then
				put shell("./functions/mail.sh Up") into tMail
				put "up" into tLastEvent
				put the date into tDate
				put the time into tTime
				#update the time file
				put "up" into line 1 of URL "file:time"
				put the date into line 2 of URL "file:time"
				put the time into line 3 of URL "file:time"
				put "false" into line 5 of URL "file:time"
			end if


	else if "down" is in tStatus then
	--do this if server is down
		put the seconds into timeDown
		put line 4 of URL "file:time" into lastUp
		subtract lastUp from timeDown
		if timeDown >  360 then
			
			put "Uh Oh!" into Comment
			put "down" into tClass
			if tLastEvent is "up" then
				put shell("./functions/mail.sh Down") into tMail
				put "down" into tLastEvent
				put the date into tDate
				put the time into tTime
				--update the time file
				put "down" into line 1 of URL "file:time"
				put the date into line 2 of URL "file:time"
				put the time into line 3 of URL "file:time"
				put "false" into line 5 of URL "file:time"
			end if --tLastEvent is "up"

		end if  --timeDown > 360

	end if  --"up" is in tStatus 
?>

	<div  class="<?lc put tClass  ?>" >
		   <span class="status">
			<?lc put Comment; ?>
		  </span>
		   <span class="event-date">
			<span class="last-event"><?lc put tLastEvent  ?></span> since: <?lc put tTime  ?> 	<?lc put tDate  ?>
		  </span>
	</div>
			<div class="hide countdown"><?lc put timeDown; ?></div>
 </body>
</html>




I have this running on a cron job, like so:

Code: Select all

*/2 * * * *  cd /path/to/website/folder; /usr/lib/cgi-bin/livecode-community-server ping.lc >/dev/null 2>&1

Post Reply

Return to “CGIs and the Server”