tag:blogger.com,1999:blog-37085773237174937092024-03-12T19:11:56.594-07:00Don Pedro d'AlfaroubeiraDon Pedro d'Alfaroubeira is a sailing boat, a 42' ketch, based in the San Francisco Bay Area (Half Moon Bay).<br>
Misc Sailing trips and various navigation techniques.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.comBlogger234125tag:blogger.com,1999:blog-3708577323717493709.post-9878557442313033652015-11-19T16:49:00.000-08:002015-11-19T16:49:50.752-08:00Monitor the Boat, remotelyWith a <a href="https://www.adafruit.com/products/1963" target="Adafruit">FONA</a> connected on the Raspberry PI (where the NMEA Console is running), you can remotely monitor what's going on.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK__9gA1CyAwxFcAxLA0rGtTyFCMvRvWobCTZFW9V0XVsFIREhvmGvpcI0ngBBCRky7EAJq7tqkvAylLxP6AbQXviRM0E9I3t7S0NhvLHbXSM3lBKWeAgs5ejXxUue7DKbESsmtEEJBWw/s1600/IMG_20151119_162539.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK__9gA1CyAwxFcAxLA0rGtTyFCMvRvWobCTZFW9V0XVsFIREhvmGvpcI0ngBBCRky7EAJq7tqkvAylLxP6AbQXviRM0E9I3t7S0NhvLHbXSM3lBKWeAgs5ejXxUue7DKbESsmtEEJBWw/s320/IMG_20151119_162539.jpg" /></a></div>
The feature has been implemented - as usual - as a UserExit.
This UserExit is in the <a href="https://github.com/OlivierLD/navigation-desktop-user-exits" target="Oliv">Desktop repo</a>, the FONA Java interface is <a href="https://github.com/OlivierLD/raspberry-pi4j-samples/tree/master/FONA" target="Oliv">here</a>.
<br/><br/>
Just by sending an SMS, you can retrieve the data read by the Raspberry PI on board, like True Wind Speed, Battery Voltage, Air and Water Temperature, etc, all you need is a smart phone that can send and receive SMSs.
<br/> <br/>
That sounds promising...
<br/><br/>
This assumes that the boat is docked in a place where there is SMS coverage, of course.
I'm working on an Internet version...Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com1tag:blogger.com,1999:blog-3708577323717493709.post-37564866235902703702015-09-12T11:56:00.000-07:002015-09-12T12:20:18.246-07:00Ephemeris emailsAlong with the headless mode, you can now send ephemeris emails to whoever you want.
<hr/>
The email you'd receive would look like this:
<div id="status" style="padding:5px; background:#ddd; border-radius:5px; overflow-y: scroll; border:1px solid #CCC; margin-top:10px;">
<h2>Ephemeris for 12 Sep 2015</h2>
<pre>
At N 37°46.00' / W 122°31.00'
Sun Rise:12 Sep 2015 06:52
Sun Set :12 Sep 2015 19:20
Moon Phase: 28 day(s).
</pre>
<hr/>
<pre>
Tide at Ocean Beach:
LW Sat Sep 12 04:52:00 PDT 2015 : +0.40 feet
HW Sat Sep 12 11:34:00 PDT 2015 : +5.27 feet
LW Sat Sep 12 17:09:00 PDT 2015 : +1.45 feet
HW Sat Sep 12 23:14:00 PDT 2015 : +5.47 feet
<hr/>
</pre>
</div>
<br/>
For this, you need to set some preferences:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCnFxiuRrXNzcsWc3pcC1HgZAhlQ4mWEPnAPXc1JmYfO4rb-zpYJCsgHhYGorjBlzviqymXF7ZNFa0gmnzujbzGxCkjsHj5hntNTYz-3Km7RSS8u1Rj2DL8-pJh1f1GaehbIONo2nBAO8/s1600/preferences.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCnFxiuRrXNzcsWc3pcC1HgZAhlQ4mWEPnAPXc1JmYfO4rb-zpYJCsgHhYGorjBlzviqymXF7ZNFa0gmnzujbzGxCkjsHj5hntNTYz-3Km7RSS8u1Rj2DL8-pJh1f1GaehbIONo2nBAO8/s320/preferences.jpg" /></a></div>
<ul>
<li>The position is used for the sun rise and set</li>
<li>The tide station must be spelled exactly as in the tide application (in the Navigation Console)</li>
<li>You can send to several recepients, separated with a semi-column</li>
<li>The timezone is used to display the sun ephemeris</li>
<li>The email provider refers to the file <code>ephemeris.email.properties</code>, see below</li>
</ul>
<code>ephemeris.email.properties</code>, this file must be in the <code>all-scripts</code> directory.
<pre style="padding:5px; background:#ddd; border-radius:5px; overflow-y: scroll; border:1px solid #CCC; margin-top:10px;">
ee.yahoo.mail.protocol=pop3
ee.yahoo.incoming.server=pop.mail.yahoo.com
ee.yahoo.outgoing.server=smtp.mail.yahoo.com
ee.yahoo.mail.smtpauth=true
ee.yahoo.outgoing.server.port=587
ee.yahoo.mail.username=olivier.lediouris
ee.yahoo.mail.password=XXXXXX
ee.yahoo.mail.replyto=olivier@lediouris.net
#
ee.google.mail.protocol=pop3
ee.google.incoming.server=pop.gmail.com
ee.google.outgoing.server=smtp.gmail.com
ee.google.mail.smtpauth=true
ee.google.outgoing.server.port=465
ee.google.incoming.server.port=995
ee.google.mail.username=olivier.lediouris@gmail.com
ee.google.mail.password=XXXXXX
ee.google.mail.replyto=olivier.lediouris@gmail.com
#
ee.oracle.mail.protocol=imap
ee.oracle.incoming.server=stbeehive.oracle.com
ee.oracle.outgoing.server=stbeehive.oracle.com
ee.oracle.mail.smtpauth=true
ee.oracle.outgoing.server.port=465
ee.oracle.incoming.server.port=993
ee.oracle.mail.username=olivier.lediouris@oracle.com
ee.oracle.mail.password=XXXXXX
ee.oracle.mail.replyto=olivier.lediouris@oracle.com
#
</pre>
The <b>email provider</b> mentionned in the preferences can be <i>in this example</i> <code>yahoo</code>, <code>google</code>, or <code>oracle</code>.
<br/>
When all this is set, you have to modify the command line that starts the Weather Wizard in headless mode:
<pre>
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dheadless=true -Dephemeris.email=true -Dstart.ephemeris.loop.at=05:00
</pre>
This will generate the email displayed above every day at 5am local time.
<br/>
Enjoy!
<br/>
PS: The code is in github, see below for details.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-36951068270779830452015-04-08T08:26:00.001-07:002015-04-18T15:24:25.344-07:00GoogleCode going out of businessGoogleCode will close soon, I moved everything on <a href="https://github.com/OlivierLD/">github</a>.
For the navigation part, you can build everything for yourself from <a href="https://github.com/OlivierLD/oliv-soft-project-builder">here</a>.
<p>
This could be the opportunity to move things around, and do some cleanup, to make the distribution and the result of such builds identical.
<br>
With the integration of the Raspberry PI in the navigation console, the paradign has slightly shifted, the architecture becomes more hub-and-spoke oriented.
<br>
It makes the data avaiable to any software able to understand non-serial protocols like TCP, UDP, etc.
<br>
<a href="http://opencpn.org">OpenCPN</a>, <a href="http://www.seawimarine.net/">SeaWi</a>, fall in that category, specially that now, I found a way to create an Access-Point network from the Raspberry PI, it makes it available to Android devices.
<br>
For the Raspberry, the easiest seems to post SD Card images, like <a href="https://drive.google.com/open?id=0B1OXF1qWHj9mdG1WeG1ISmFZNGs&authuser=0">here</a>.
</p>
More to come, stay tuned.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-30196297722419897452015-01-08T10:15:00.002-08:002015-01-08T10:16:24.382-08:00Version 3.0.1.5 availableNew version - for both the <a href="https://code.google.com/p/weatherwizard/">Weather Wizard</a> and the <a href="https://code.google.com/p/navigation-desktop/">Navigation Console</a> - 3.0.1.5 is available, at the usual place.
<br/>
Few new features, minor UI improvements, and big uptake for the Raspberry PI.
<br/>
A new feature for the Weather Wizard in headless mode, you can download <i>several</i> composites at the same time (one after the other actually). Use the <code>-composite:</code> and <code>-pattern:</code> parameters, separate each value with a comma.
<br/>
For example, on Windows:
<pre>
set PRMS=-composite:./patterns/01.Favorites/01.3.00.Pacific.Sfc.500.Tropic.GRIB.ptrn
set PRMS=%PRMS%<b style="color: red;">,</b>./patterns/01.Favorites/06.01.AllPac.Faxes.Satellite.ptrn
set PRMS=%PRMS% -interval:360
set PRMS=%PRMS% "-pattern:/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific | waz<b style="color: red;">,</b>/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific.SatPic | waz"
::
set command=java %JAVA_OPTIONS% -client -classpath "%CP%" -Dheadless=true main.splash.Splasher %PRMS%
</pre>
On Linux and Mac:
<pre>
PRMS=-composite:./patterns/01.Favorites/01.3.00.Pacific.Sfc.500.Tropic.GRIB.ptrn
PRMS=$PRMS<b style="color: red;">,</b>./patterns/01.Favorites/06.01.AllPac.Faxes.Satellite.ptrn
PRMS=$PRMS -interval:360
PRMS=$PRMS "-pattern:/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific | waz<b style="color: red;">,</b>/yyyy/MM-MMM | | yyyy-MM-dd_HHmmss_z | _Pacific.SatPic | waz"
#
command=java $JAVA_OPTIONS -client -classpath "$CP" -Dheadless=true main.splash.Splasher $PRMS
</pre>
Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-48431537961540058382014-12-21T16:19:00.000-08:002014-12-22T09:38:15.350-08:00Un peu de finesse, dans ce monde de brutes<h3>Trois poëtes, trois poëmes</h3>
<br/>
Ah seja como for, seja por onde for, partir!<br/>
Largar por aì fora, pelas ondas, pelo perigo, pelo mar. <br/>
Ir para Longe, ir para Fora, para a Distância Abstrata, <br/>
Indefinidamente, pelas noites misteriosas e fundas, <br/>
Levado, como a poeira, plos ventos, plos vendavais! <br/>
Ir, ir, ir, ir de vez! <br/>
<br/>
<i>
Ah, n'importe comment et n'importe où, partir !<br/>
Larguer les amarres hors d'ici, cap sur les vagues, le péril et la mer.<br/>
S'en aller au Large, au Dehors, à l'Abstraite Distance,<br/>
Indéfiniment, dans les nuits mystérieuses et profondes,<br/>
Emporté, comme la poussière, par les vents, par les ouragans !<br/>
S'en aller, s'en aller, s'en aller une bonne fois !<br/>
(Traduit par Patrick Quillier)<br/>
</i>
<br/>
<i>Fernando Pessoa</i>, Ode maritime
<br/><br/>
VIII
<br/><br/>
Ô Mort, vieux capitaine, il est temps ! Levons l'ancre !<br/>
Ce pays nous ennuie, ô Mort ! Appareillons !<br/>
Si le ciel et la mer sont noirs comme de l'encre,<br/>
Nos cœurs que tu connais sont remplis de rayons !<br/>
<br/>
Verse-nous ton poison pour qu'il nous réconforte !<br/>
Nous voulons, tant ce feu nous brûle le cerveau,<br/>
Plonger au fond du gouffre, Enfer ou Ciel, qu'importe ?<br/>
Au fond de l'inconnu pour trouver du <i>nouveau !</i><br/>
<br/>
<i>Charles Baudelaire</i>, Les Fleurs du Mal, La Mort, Le Voyage.
<br/><br/>
Avec ses quatre dromadaires<br/>
Don Pedro d'Alfaroubeira<br/>
Courut le monde et l'admira<br/>
Il fit ce que je voudrais faire<br/>
Si j'avais quatre dromadaires<br/>
<br/>
<i>Guillaume Appollinaire</i>, Alcools, Le Dromadaire
<br/>Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com1tag:blogger.com,1999:blog-3708577323717493709.post-52409535368538572232014-08-12T08:40:00.001-07:002014-08-12T08:46:09.963-07:00Raspberry PI on board: the numbers!Using the <a href="https://www.adafruit.com/product/1852" target="Adafruit">Charger Doctor</a> from Adafruit, I was able to see how much the Raspberry PI is drawing when at work.
<br/>
When it boots, with the 7" RCA screen on, it takes 0.24 Amps.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifez2kUsohIXt-msa41VbhsBV8agLCjSlQgzjg45biToa-usre_CMIyAJpK6G9TFZJYWJTdLOTG1FSQ5d7XCHSsBluKCAV1mbcVWDzE2cFAyPyPmxV1mwPJK5W8ZEQKe17vY-y1w-dpdk/s1600/IMAG0646.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifez2kUsohIXt-msa41VbhsBV8agLCjSlQgzjg45biToa-usre_CMIyAJpK6G9TFZJYWJTdLOTG1FSQ5d7XCHSsBluKCAV1mbcVWDzE2cFAyPyPmxV1mwPJK5W8ZEQKe17vY-y1w-dpdk/s320/IMAG0646.jpg" /></a></div>
This remains the same when starting the Headless Console, with user-exits, battery monitoring, and re-broadcasting on HTTP and TCP.
<br/>
When the small RCA screen is turned off, the consumption drops to 0.19 to 0.20 Amps.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh037lRQkCyf_7TBVf-csks7wEncYo78sW4i2u7CiXO2kVAF1gZFIXreHe5wAO6gMswxOJFG97wxJwWgbqZ4trHCSuDnrOVwphWxZ3svotE1R8azaidLMe37v0IzNl_6PyCme4ucB1n4KE/s1600/IMAG0649.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh037lRQkCyf_7TBVf-csks7wEncYo78sW4i2u7CiXO2kVAF1gZFIXreHe5wAO6gMswxOJFG97wxJwWgbqZ4trHCSuDnrOVwphWxZ3svotE1R8azaidLMe37v0IzNl_6PyCme4ucB1n4KE/s320/IMAG0649.jpg" /></a></div>
<br/>
As <code>P = UI</code>, that means that the Raspberry PI at works takes about 1 Watt (5v × 0.2 A).
<br/>
This even below what the Raspberry PI documentation is saying!
Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-59150384028521415162014-06-21T08:32:00.000-07:002014-06-24T13:40:21.009-07:00Raspberry Sailing. How the Raspberry Pi makes sense on board.A computer can be helpful on board, for several reasons.
<ul>
<li>Some useful navigation softwares need one to run (SailMail, for example, that allows you to receive faxes through the SSB, send and receive emails, all kinds of useful things)</li>
<li>Some chart plotter softwares (like OpenCPN, the best) require a computer to run as well, to plot the current position on an electronic chart.</li>
<li>The on-board electronics can be read from a computer (through NMEA, or some other proprietary protocols), and the data they emit can be used as parameters for calculations, like performance evaluation, routing, current estimation (tricky, but so useful).</li>
</ul>
<br/>
Electricity can be precious on board (specially on a sail boat, where it is in short supply), it is required to run several important devices, like the autopilot, the water maker, and to some extend, the fridge. A laptop can draw a substantial amount of current, specially if its battery is old (2 to 3 amps and more, I have evidences). In those conditions, leaving it on all the time can be questionable. On top of that, turning it down, and turning it back up takes time...
<br/>
<h3>Serial port access</h3>
The data we are interested in usually (like in 99% of the cases) come from a Serial port (USB, or 9-pins). A big detail to mention is that a Serial port can only be accessed by one process at a time. That means that when your chart plotter accesses the serial port, no other program can access it, even it is is not the same data the other program is interested in.
<br/>
The chart plotter will be interested in the GPS data, another soft might be interested in the wind data; but there is no way around, one program, one port.
<br/>
GPSd does not address this issue (even if it pretends to), and - in my opinion - makes things more complex. It's only interested in GPS data (not in Speed Through Water, not in Wind Data, etc), but it locks the port like everyone else, and just rebroadcasts them <i>in another bloody format!</i> Why isn't it just rebroadcasting the NMEA sentences as they've been read?.., I have no idea.
<br/>
<h3>Introducing the Raspberry PI</h3>
The Raspberry PI does much more than the boards like Arduino, Sparkfun, Beaglebones, and others (those are great, don't get me wrong, I am not spitting in the soup), it is a fully featured Linux (Debian) computer, that can - as such - do all a computer can do, like multi tasking, multi threading, remote access (SSH, VNC), network access (Ethernet and Wireless). It only has 512 Mb of RAM. But that is enough, as we will see. Its hard disk is replaced by an SD card, ranging from 4GB to whatever you want. I use 16Gb cards.
And at work, it draws less than 500mA, which is ridiculous.
You can plug several kinds of screen on the Raspberry PI, a TV screen using an HDMI port, or a rear camera car monitor (3.5", 4.3", or 7") using an RCA port. Turning those screens off when not needed will also contribute to save some energy.
<br/>
The Raspberry PI can read the serial port - Ok, exclusively - and re-broadcast the data on whatever channel (TCP, HTTP, UDP, RMI, whatever). This way they can be accessed from this channel, the data remaining the same.
As soon as a device is turned on, it can join the ad-hoc network created by the Raspberry PI, and immediately read the data it broadcasts.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjni30nTyjZUSTT_BkzD2uae-jOYKjWT8YN6DD-KLDLIPckZAMNoFONmNFpoXQoLuF5ZRCKWroR8Wrc7o2jtcRj_o1JwPnVapyjOIkzRAJGjh_33tDLG_kk0-no9AUpuhOcdFI5CT5vtFw/s1600/Snap1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjni30nTyjZUSTT_BkzD2uae-jOYKjWT8YN6DD-KLDLIPckZAMNoFONmNFpoXQoLuF5ZRCKWroR8Wrc7o2jtcRj_o1JwPnVapyjOIkzRAJGjh_33tDLG_kk0-no9AUpuhOcdFI5CT5vtFw/s320/Snap1.png" /></a></div>
<br/>
A program like OpenCPN is smart enough to support several kinds of channels.
<br/>
HTTP is also an option to consider, smart phones and tablets are ready for that, without any modifications.
HTML5 and CCS3 will do the job. Those devices have browsers that understand those technologies.
It is very easy to display the data read by the Raspberry PI <a href="http://donpedrodalfaroubeira.blogspot.com/2013/11/multiple-access-for-real.html">on an iPhone</a>.
<br/>
In addition, the Raspberry PI can log the data read from the NMEA Port, its SD card is big enough to log several days of data.
Another feature of the Raspberry PI is its GPIO Header. This is the bridge to the world of sensors.
For example, the <a href="https://www.adafruit.com/search?q=bmp180" target="Adafruit">BMP180</a> will allow the Raspberry PI to read the air temperature and the atmospheric pressure. Those data can very well be injected in the NMEA stream (they both have an NMEA equivalent).
Some navigation station already provide this kind of interfaces, but in case yours does not, you will then get those data for less than $10.
<br/>
See some implementation details <a href="http://www.lediouris.net/RaspberryPI/RasPI-ue/readme.html" target="RC">here</a>.
<br/><br/>
Even further, it is not difficult to come up with a <a href="http://www.lediouris.net/RaspberryPI/ADC/monitor-12v.html" target="RC">small setting</a> the Raspberry PI can use to monitor the tension of the batteries on the boat. This one does not - as far as I know - have an NMEA equivalent. It can be injected in the NMEA stream though, it will be considered as a custom sentence. And it can be logged too, along with the rest.
<br/>
If needed, the data can be displayed on the Raspberry PI as they are read.
I did some tests with a graphical interface, as well as in <a href="http://donpedrodalfaroubeira.blogspot.com/2014/06/character-mode-console-for-raspberry-pi.html">character mode</a>, just to keep the energy consumption as low as possible. The screen is turned off when not needed, for the same reason.
<br/>
<h3>Useful links</h3>
<ul>
<li><a href="http://opencpn.org">OpenCPN</a></li>
<li><a href="http://raspberrypi.org">Raspberry PI</a></li>
<li><a href="http://adafruit.com">Adafruit</a></li>
<li><a href="https://code.google.com/p/navigation-desktop/">NMEA Console</a>, that runs on the Raspberry PI</li>
</ul>
<br/>
<br/>
Basically, you can reproduce the settings used during the last Aremica's Cup, for a tiny fraction of their budget!
The Raspberry PI is less than $40.
<br/>
Compare with <a href="http://en.bellesmontres.com/tag-heuer/america-s-cup-a-smartwatch-on-the-wrist-21-09-2013-1733799_998.php" target="AC">this</a>...
<p>
If it does not work for you, <b>do</b> let me know, it should. I might be able to help.
</p>Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-80787868383189905722014-06-11T08:44:00.000-07:002014-06-23T09:07:22.500-07:00Character Mode Console, for the Raspberry PIWorking on low consumption setup...
<br/>
The laptop is quite demanding on the batteries, but the Raspberry PI is not.
<br/>
The thing is that the laptop can do many calculations, for example for the current speed and direction, using real time triangulation, dead reckoning on 1 minute, dead reckoning on 10 minutes, etc...
<br/>
Being written in Java, the console runs - theorically - also on the Raspberry PI. This is true, but the Swing UI is definitely too demanding on the RasPI.
<br/>
<br/>
Well, the is now available in character mode, driven by the file named <code>char.console.properties</code>.
<div class="separator" style="clear: both; text-align: center;">3.5" monitor<br/><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-iks4NMzYY90S6mo6AzkKkOe9948K_fRixjYgccJO_km1zDhPfPlQOhhEqyvK5mk9Wt5L8Rgp_dh82GXCb6ItWPKiw5RO8H-GaTvDiLmaHSAirtLLsGzqT7tzOBoGBsBURchhav4KMT4/s1600/IMAG0619.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-iks4NMzYY90S6mo6AzkKkOe9948K_fRixjYgccJO_km1zDhPfPlQOhhEqyvK5mk9Wt5L8Rgp_dh82GXCb6ItWPKiw5RO8H-GaTvDiLmaHSAirtLLsGzqT7tzOBoGBsBURchhav4KMT4/s320/IMAG0619.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLIIUPQ1MLfOnM7IQIUtWZPF89E_4GgIj6Cnh-HCXS0aEeTKrrD5hGIYh4vTFSUZx5zu-SjLCZ2uwOiDLS3t3RZMRyzU7oLvsNecEl4GhgWnO4XsQ7HljhptymW5lIqtaeQD9uDrRITAQ/s1600/IMAG0618.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLIIUPQ1MLfOnM7IQIUtWZPF89E_4GgIj6Cnh-HCXS0aEeTKrrD5hGIYh4vTFSUZx5zu-SjLCZ2uwOiDLS3t3RZMRyzU7oLvsNecEl4GhgWnO4XsQ7HljhptymW5lIqtaeQD9uDrRITAQ/s320/IMAG0618.jpg" /></a></div>
Notice on the screen, some data come from some sensors that can be attached to the RasPi, like air temperature, atmospheric pressure, battery voltage.
<br/>
The RasPi can rebroadcast the NMEA - and calculated - data on TCP, UDP, http, etc. So, the laptop can use them (from OpenCPN for example), as well as tablets or other devices, as shown in <a href="http://donpedrodalfaroubeira.blogspot.com/2013/11/multiple-access-for-real.html">earlier posts</a>.
<br/>
All this - along with the routing on archived GRIB files - is available in a new version (3.0.1.4), available at the usual place (<a href="https://code.google.com/p/navigation-desktop/">Navigation Desktop</a>, and <a href="https://code.google.com/p/weatherwizard/">Weather Wizard</a>).
One detail though, Google Code does not support the downloads anymore, I moved the new ones to Google Drive. Use the link you'll find in the "Featured" section on the project pages.
<br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3MFw6ZmZYTcsLIf2YUzWZW1tA0k7FlaM7vNd7hm2xJMxzPqzVQcu65muK0Ar4_5WBw18HZO7YuMjcsaBdEbG3V0XcyvNjI3Fhgwu7K-4eSkrJ8sVCVINnW4wscfNYWB6u8zx280DtrBA/s1600/IMAG0620.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3MFw6ZmZYTcsLIf2YUzWZW1tA0k7FlaM7vNd7hm2xJMxzPqzVQcu65muK0Ar4_5WBw18HZO7YuMjcsaBdEbG3V0XcyvNjI3Fhgwu7K-4eSkrJ8sVCVINnW4wscfNYWB6u8zx280DtrBA/s320/IMAG0620.jpg" /></a><br/>At work on board, 7" monitor</div>Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-15914582161481080372014-06-02T14:11:00.001-07:002014-06-02T14:48:51.514-07:00Introducing the "Archived GRIB Routing"The idea here is like replacing the pilot charts with some GRIBs stored in some composites you have already archived, to plan a trip for example.
<br/>
At sea, the GRIBs you will download will provide a reliable forecast for about 3 days. After that, it's more like science fiction...
<br/>
By looking into your archived composites, you can have a look at the weather that <b>actually</b> happened.
<br/>
This brings us back to the importance of naming conventions, mentioned in the <a href="http://donpedro.lediouris.net/software/structure/datafiles/manual/WeatherWizardUserManual.2nd.edition.pdf">User's Manual</a>.
<br/>
<h4>Here is a quick step-by-step introduction to the feature.</h4>
Click on the images to see them in full size, easier to read.
<br/><br/>
Open the Weather Wizard as usual, without loading any data.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Oi4LSa2vqgu93QzQ9BFlSwDfLiwCjU4xHS42ScqF-PiiRYRRLoXVtDxyyISooPDgxtdmEl4c53Vsq5uGunbSpU79bItLX70ZEGpsXRwZmGithTNH8UJBN1hVSvtG6Llr2wQdn_PVJsY/s1600/Snap1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Oi4LSa2vqgu93QzQ9BFlSwDfLiwCjU4xHS42ScqF-PiiRYRRLoXVtDxyyISooPDgxtdmEl4c53Vsq5uGunbSpU79bItLX70ZEGpsXRwZmGithTNH8UJBN1hVSvtG6Llr2wQdn_PVJsY/s320/Snap1.png" /></a></div>
Re-locate the chart to the desired area, if needed.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC0opgLT0o4u0vfLVWfeSzBm_y_xaRogCZPXxlSRY3JucInLj4kP-nyVtmCYR6F1MAD-yxCzagLFVoclKPTR6lSRkQ9iQ4L9C2-Cd0MRnSg6RuctGTt6RuCI1hN8AVbMaxW81ZTRpXhzU/s1600/Snap2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC0opgLT0o4u0vfLVWfeSzBm_y_xaRogCZPXxlSRY3JucInLj4kP-nyVtmCYR6F1MAD-yxCzagLFVoclKPTR6lSRkQ9iQ4L9C2-Cd0MRnSg6RuctGTt6RuCI1hN8AVbMaxW81ZTRpXhzU/s320/Snap2.png" /></a></div>
Next, plot the start and arrival points. Let's try here to go from the SF Bay Area to the Christmas Island, in the Kiribati Republic.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJF74uAmC9EEkLUCJVUAnQMVR7CWBnTKtF6ZNJM5BKSy-T72_CGnAoYlbddNHpvuANZzTAVH-se4OnSMJIhT5JdLB44lXXvlRAWab2n0lsMhbo-hA3HwlnNmv-EBw4inzc0bKM_tnHVJU/s1600/Snap3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJF74uAmC9EEkLUCJVUAnQMVR7CWBnTKtF6ZNJM5BKSy-T72_CGnAoYlbddNHpvuANZzTAVH-se4OnSMJIhT5JdLB44lXXvlRAWab2n0lsMhbo-hA3HwlnNmv-EBw4inzc0bKM_tnHVJU/s320/Snap3.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRnWZmNaBr55Dnq72TaQvAkbga446HJZgqaLpvNMATt882EvzI_fJ_25SogutmzIaGWrUBy8Ird1nRG48p41HU8yRC7CC59Rf4AprijqmGkjGqZ29GTHhbGRJ9Q58-yq35TB8gyKKQigo/s1600/Snap4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRnWZmNaBr55Dnq72TaQvAkbga446HJZgqaLpvNMATt882EvzI_fJ_25SogutmzIaGWrUBy8Ird1nRG48p41HU8yRC7CC59Rf4AprijqmGkjGqZ29GTHhbGRJ9Q58-yq35TB8gyKKQigo/s320/Snap4.png" /></a></div>
Next, go to the menu Tools > Routing > Routing from Archived GRIBs
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGt24stjxhoJ-ByhQLNrojanWpxljRWyGxl-1uYSp1h1xqGOY0vhnK0BvvLRzt550Yn-R5CKs8xz94-Ah2mWFuyjBKzGp45q4gVPujn6K1vvN-WKAiVl5rShrkEmo4fbVZu-MtvCLlH7o/s1600/Snap5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGt24stjxhoJ-ByhQLNrojanWpxljRWyGxl-1uYSp1h1xqGOY0vhnK0BvvLRzt550Yn-R5CKs8xz94-Ah2mWFuyjBKzGp45q4gVPujn6K1vvN-WKAiVl5rShrkEmo4fbVZu-MtvCLlH7o/s320/Snap5.png" /></a></div>
You will be prompted to choose the directory containing the <b>composites</b> containing the GRIBs you are interested in, and the <i>Regular Expression</i> filtering them. Just in case you forgot, <b><code>".*"</code></b> will select everything (no filter).
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgjNM5rVWaLtVXJTjLuvGZU_Mw3934jGt1krC1XemRRGPTTPZCZcuIIdR647ZpjhN_BISG-pT1kEPWiDuwTm3EuRlJn994myjJR2KVECxTQZ2SPf03zGNMG2uAFYc7YuxRqfcHvCKpOYU/s1600/Snap6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgjNM5rVWaLtVXJTjLuvGZU_Mw3934jGt1krC1XemRRGPTTPZCZcuIIdR647ZpjhN_BISG-pT1kEPWiDuwTm3EuRlJn994myjJR2KVECxTQZ2SPf03zGNMG2uAFYc7YuxRqfcHvCKpOYU/s320/Snap6.png" /></a></div>
The application will tell you how many composites your selection will return, they will be used to build <i>one single BIG GRIB document</i> that will be used to compute the routing.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQA6N0sWDxzJhzFbsTG8Wf5KbKyyXpgjbfA4NoM4K3-7A3K1Z06DXEY-T2tp35AyWq_ya6gQiXOQjRmkPQVG6bT8aVp_Ll10qQbiymxrJD2Y1dHgPO5TwEHhEKShiN9dw4wVQGIX1ZRKs/s1600/Snap7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQA6N0sWDxzJhzFbsTG8Wf5KbKyyXpgjbfA4NoM4K3-7A3K1Z06DXEY-T2tp35AyWq_ya6gQiXOQjRmkPQVG6bT8aVp_Ll10qQbiymxrJD2Y1dHgPO5TwEHhEKShiN9dw4wVQGIX1ZRKs/s320/Snap7.png" /></a></div>
<b>One important thing to be careful with</b>: By default, the application suggests you to start the routing <i>at the current time and date</i>. As you can see on the dialog, the GRIB start and end dates <i>do not contain</i> the current date. You need to change the date you want to start the routing from, so it is within the GRIB date range.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgonb8wYvuLFg-R9YjuHk9EGe6hvzM1UQ1llYj0yOe8eFWE02rUMWFmIKOBWUJFxVYiBz_Dx9RSditNOr3xzFBNFq7P08wWt4gAcBurQINysytmHEFSX2QYHfGPwhBOimMh_QdX5xEV28I/s1600/Snap8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgonb8wYvuLFg-R9YjuHk9EGe6hvzM1UQ1llYj0yOe8eFWE02rUMWFmIKOBWUJFxVYiBz_Dx9RSditNOr3xzFBNFq7P08wWt4gAcBurQINysytmHEFSX2QYHfGPwhBOimMh_QdX5xEV28I/s320/Snap8.png" /></a></div>
Now, the routing start date is <i>within</i> the GRIB's range.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9f3JTAMijlSnP3qTvPjhiLVX0H6sGcVj5zdEYB9FQPLfelR8nEEF44q9DyAgHPr-b5_KDwM8eQdsrZC7nLPy2HrsYlucsokhFKhdLyLFSDlpW8kf9AmfpqNAQd2zHzNic5AP2CbQrwBk/s1600/Snap9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9f3JTAMijlSnP3qTvPjhiLVX0H6sGcVj5zdEYB9FQPLfelR8nEEF44q9DyAgHPr-b5_KDwM8eQdsrZC7nLPy2HrsYlucsokhFKhdLyLFSDlpW8kf9AmfpqNAQd2zHzNic5AP2CbQrwBk/s320/Snap9.png" /></a></div>
From now on, the process is the usual routing one. Except that the GRIB will probably <i>not</i> expire.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUNZlysQJheLzIoC0VLIskMTfn485VVttv2McH3WqJEKM-BtQarVmaYi_2jZ2UkwbaCVTG4KXWR4e83ZEbEKbsrnYgy6M46Lcg0E_sjprvOm-QhFF2Ir9kFmhFQUNc31gq8lReqFzLqBU/s1600/Snap10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUNZlysQJheLzIoC0VLIskMTfn485VVttv2McH3WqJEKM-BtQarVmaYi_2jZ2UkwbaCVTG4KXWR4e83ZEbEKbsrnYgy6M46Lcg0E_sjprvOm-QhFF2Ir9kFmhFQUNc31gq8lReqFzLqBU/s320/Snap10.png" /></a></div>
You can tell by the color of the isochrones that the GRIB did indeed <i>not</i> expire.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoUoxUaLLg6PPdlXUXDjp-0sL02KhCm-B4aoMV_-IyO0vyQC-xmzcTNrdJlXMuLut8KxjtaThn_-RR4dM9CPF96osaIUCmKEp0FUz7lqzQReazRqWDDTiAQbp0U0phelRTYTDx0a488UM/s1600/Snap11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoUoxUaLLg6PPdlXUXDjp-0sL02KhCm-B4aoMV_-IyO0vyQC-xmzcTNrdJlXMuLut8KxjtaThn_-RR4dM9CPF96osaIUCmKEp0FUz7lqzQReazRqWDDTiAQbp0U0phelRTYTDx0a488UM/s320/Snap11.png" /></a></div>
<i>Note</i>: Once the big GRIB has been generated, it is loaded in the application, just like if it had been downloaded from the net, or read from the disc. You can re-launch a routing computation <i>without</i> having to re-generate it, until you close the tab it lives in.
<br/><br/>
This feature is still in development, it will be available very soon.
<br/>
Hope you will lilke it!Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-62822263781236681322014-05-14T10:14:00.002-07:002014-05-14T13:23:55.232-07:00Kiting the Bay<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMPhcoElKhf7hLQPK-goN19v0wBakm09W5Sw_IFWXCmklJtJsBUCyMM9mU5v1yv-LEBLW_i4LBB4A5OdaUSzTtFOrj4cOqYOU9ogR2Cfi2mbOZghlyVw0uePfWTDoUJH3kzA3vzEmAhIk/s1600/2014-05-13_KiteSurf.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMPhcoElKhf7hLQPK-goN19v0wBakm09W5Sw_IFWXCmklJtJsBUCyMM9mU5v1yv-LEBLW_i4LBB4A5OdaUSzTtFOrj4cOqYOU9ogR2Cfi2mbOZghlyVw0uePfWTDoUJH3kzA3vzEmAhIk/s320/2014-05-13_KiteSurf.jpg" /></a></div>
Warm weather in the SF Bay Area this week, the wind picks up around 3 in the afternoon, easily reaching 20 knots near Treasure Island.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK2fyObQLGf1YulzjUkrbpH4KzmAve51_-PJIWTWna5YlvB1BcYFG_sgLE16m6u6FE4gvRiKjy6jm2boJEsaBEPuANf0aLJ6d-Oy_Gi9pmdvaP-EGIQAzn7Jll2Bwx2sRiQxxwHF5QAec/s1600/2014-05-13_KiteSurf.01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK2fyObQLGf1YulzjUkrbpH4KzmAve51_-PJIWTWna5YlvB1BcYFG_sgLE16m6u6FE4gvRiKjy6jm2boJEsaBEPuANf0aLJ6d-Oy_Gi9pmdvaP-EGIQAzn7Jll2Bwx2sRiQxxwHF5QAec/s320/2014-05-13_KiteSurf.01.jpg" /></a></div>Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com2tag:blogger.com,1999:blog-3708577323717493709.post-71253034150477918432014-05-12T08:29:00.001-07:002014-05-12T08:29:43.898-07:00Monitoring the batteries with the Raspberry PIIt turned out to be easy and inexpensive.
<br/>
See the details <a href="http://www.lediouris.net/RaspberryPI/ADC/monitor-12v.html">here</a>.
<br/>
The next step will be to log all this, along with the wind speed, to see how the wind generator works with the solar panel.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-67008653362383477252014-04-10T13:23:00.000-07:002014-04-10T13:24:42.088-07:00Introducing live wallpaper in the Navigation DesktopThe foreground data were not very convenient, they are now replaced with a "Live Wallpaper".
<br>
And there is also an option to put the desktop in full screen.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjni30nTyjZUSTT_BkzD2uae-jOYKjWT8YN6DD-KLDLIPckZAMNoFONmNFpoXQoLuF5ZRCKWroR8Wrc7o2jtcRj_o1JwPnVapyjOIkzRAJGjh_33tDLG_kk0-no9AUpuhOcdFI5CT5vtFw/s1600/Snap1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjni30nTyjZUSTT_BkzD2uae-jOYKjWT8YN6DD-KLDLIPckZAMNoFONmNFpoXQoLuF5ZRCKWroR8Wrc7o2jtcRj_o1JwPnVapyjOIkzRAJGjh_33tDLG_kk0-no9AUpuhOcdFI5CT5vtFw/s320/Snap1.png" /></a></div>Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-81273093668417950562014-04-01T11:44:00.000-07:002014-04-01T11:44:44.236-07:00NMEA Multiplexing, with Raspberry PI and sensorsThis is a first test, but already promising...
See details <a href="http://www.lediouris.net/RaspberryPI/RasPI-ue/readme.html">here</a>.
Still working on the Atmospheric Pressure for OpenCPN, trying to manage the MDA NMEA Sentence.
More to come, stay tuned.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-22106000878926888392014-03-25T12:08:00.000-07:002014-03-25T12:08:54.474-07:00SPOT Parser in the ConsoleWe already had one Web version of a <a href="http://donpedrodalfaroubeira.blogspot.com/2013/07/spot-grib-request.html">SPOT Parser</a>, we now have one embedded in the Navigation Console.
It allows the manipulation of the SPOT bulletins even if you are far from the Internet...
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlPAyJSBvL2H4azHr884FPn99RkxOW_IYw-AKffvi0424zVYbGE46vXGV7SbdlNk6iYIwmzrd10YWW_WAEqyZW9QFb2aN-9Ya5LVfjjKmgKsMTaqumNHhXcoYJRaf20XT-2kwhexXtTFo/s1600/spot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlPAyJSBvL2H4azHr884FPn99RkxOW_IYw-AKffvi0424zVYbGE46vXGV7SbdlNk6iYIwmzrd10YWW_WAEqyZW9QFb2aN-9Ya5LVfjjKmgKsMTaqumNHhXcoYJRaf20XT-2kwhexXtTFo/s320/spot.png" /></a></div>
It also comes with a possibility to compose your own SPOT request.
<br>
At sea, you would compose your request (possibly with the data from the GPS), paste it into your Airmail client to send it through SailMail.
<br>
Once the response is in your inbox, you paste it in the utility featured above, and you have a graphical rendering of the SPOT data.
<br>
Enjoy!Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-55576654190814539442013-12-18T12:00:00.000-08:002013-12-20T08:21:14.923-08:00Introducing the Headless Weather WizardTwo things:
<ul>
<li>The Weather Wizard runs on a Raspberry PI</li>
<li>It can load (and save) a default composite, and reload it on a regular base</li>
</ul>
The idea is to run the Weather Wizard in some sort of batch mode, so it generates and stores composites on its file system, as long as you let it go.
<br>
You just need to run it this way:
<br><b>On Windows:</b>
<div id="div-01" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
set MEM_OPTIONS=-XX:NewSize=512m -XX:MaxNewSize=512m -Xmn768m -Xms1024m -Xmx1024m
set MEM_OPTIONS=%MEM_OPTIONS% -XX:SurvivorRatio=1 -XX:PermSize=30m -XX:+UseParallelGC
set JAVA_OPTIONS=%EXTRA_JVM_PRM% %MEM_OPTIONS% %JAVA_OPTIONS%
::
<b>set PRMS=-composite:./patterns/01.Favorites/01.3.00.Pacific.Sfc.500.Tropic.GRIB.ptrn
set PRMS=%PRMS% -interval:360
set PRMS=%PRMS% "-pattern:/yyyy/MM-MMM | Auto_ | yyyy_MM_dd_HH_mm_ss_z | waz"</b>
::
set command=java %JAVA_OPTIONS% -client -classpath "%CP%" <b>-Dheadless=true</b> main.splash.Splasher %PRMS%
start "Headless Weather Wizard" %command%
</pre>
</div>
</div>
<b>On Linux:</b>
<div id="div-01" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
MEM_OPTIONS=-XX:NewSize=512m -XX:MaxNewSize=512m -Xmn768m -Xms1024m -Xmx1024m
MEM_OPTIONS=$MEM_OPTIONS -XX:SurvivorRatio=1 -XX:PermSize=30m -XX:+UseParallelGC
JAVA_OPTIONS=$EXTRA_JVM_PRM $MEM_OPTIONS $JAVA_OPTIONS
#
<b>PRM1=-composite:./patterns/01.Favorites/01.3.00.Pacific.Sfc.500.Tropic.GRIB.ptrn
PRM2=-interval:360
PRM3="-pattern:/yyyy/MM-MMM | Auto_ | yyyy_MM_dd_HH_mm_ss_z | waz"</b>
#
java $JAVA_OPTIONS -client -classpath "$CP" <b>-Dheadless=true</b> main.splash.Splasher $PRM1 $PRM2 "$PRM3" &
</pre>
</div>
</div>
Notice the parameters <code>-composite:</code>, <code>-interval:</code>, and <code>-pattern:</code>.
Same for the System variable <code>-Dheadless=true</code>.
<br>
This means that the pattern mentioned in <code>-composite:</code> will be reloaded every 360 minutes, and stored as stated in the <code>-pattern:</code> parameter.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-56407268065382949152013-12-16T08:36:00.001-08:002013-12-20T08:49:33.950-08:00Introducing Console User-Exits There are many things to do with the NMEA Data available in the cache, and the console
is just doing a little - obvious - part of them.
<br>
In order for the users to implement their own features and ideas, we now provide a "user-exit" mechanism.
<br>
The user-exits are to be written in Java, and implement a specific interface named <code>olivsoftdesktop.DesktopUserExitInterface</code>,
and defined as foillow:
<div id="div-01" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
<!-- Generated code pasted below -->
<font color='gray' style='text-align:right; background-color:lightgray;'> 1 </font> <font color='#ffff66'><b>package</b></font> olivsoftdesktop;
<font color='gray' style='text-align:right; background-color:lightgray;'> 2 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 3 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>interface</b></font> DesktopUserExitInterface
<font color='gray' style='text-align:right; background-color:lightgray;'> 4 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 5 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> start();
<font color='gray' style='text-align:right; background-color:lightgray;'> 6 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> stop();
<font color='gray' style='text-align:right; background-color:lightgray;'> 7 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> describe();
<font color='gray' style='text-align:right; background-color:lightgray;'> 8 </font> }
<!-- End of generated code -->
</pre></div></div>
It could probably not be any simpler.
<h2>A Simple User-exit implementation</h2>
To develop your own features, you would need to put - at least - into your classpath:
<ul>
<li><code>desktop.jar</code></li>
</ul>
And probably, to access the NMEA Data Cache:
<ul>
<li><code>nmeaparser.jar</code></li>
<li><code>nmeareader.jar</code></li>
<li><code>coreutilities</code></li>
<li><code>geomutil.jar</code></li>
</ul>
Then, write your code, and archive it into a jar-file.
<br>
Here is a simple implementation of this interface. This one evaluates the True Wind Speed
<i>every</i> time a sentence is received from the NMEA station, and displays a message if the
TWS is above 10 knots.
<br>
See how the <code>NMEAReaderListener</code> is registered.
<div id="div-02" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
<!-- Generated code pasted below -->
<font color='gray' style='text-align:right; background-color:lightgray;'> 1 </font> <font color='#ffff66'><b>package</b></font> olivsoftdesktop.sampleue;
<font color='gray' style='text-align:right; background-color:lightgray;'> 2 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 3 </font> <font color='#ffff66'><b>import</b></font> nmea.event.NMEAReaderListener;
<font color='gray' style='text-align:right; background-color:lightgray;'> 4 </font> <font color='#ffff66'><b>import</b></font> nmea.server.ctx.NMEAContext;
<font color='gray' style='text-align:right; background-color:lightgray;'> 5 </font> <font color='#ffff66'><b>import</b></font> nmea.server.ctx.NMEADataCache;
<font color='gray' style='text-align:right; background-color:lightgray;'> 6 </font> <font color='#ffff66'><b>import</b></font> ocss.nmea.parser.<font color='cyan'>Angle360</font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 7 </font> <font color='#ffff66'><b>import</b></font> ocss.nmea.parser.Speed;
<font color='gray' style='text-align:right; background-color:lightgray;'> 8 </font> <font color='#ffff66'><b>import</b></font> olivsoftdesktop.DesktopUserExitInterface;
<font color='gray' style='text-align:right; background-color:lightgray;'> 9 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 10 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>class</b></font> UserExitSample
<font color='gray' style='text-align:right; background-color:lightgray;'> 11 </font> <font color='#ffff66'><b>implements</b></font> DesktopUserExitInterface
<font color='gray' style='text-align:right; background-color:lightgray;'> 12 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 13 </font> <font color='#ffff66'><b>public</b></font> UserExitSample()
<font color='gray' style='text-align:right; background-color:lightgray;'> 14 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 15 </font> <font color='#ffff66'><b>super</b></font>();
<font color='gray' style='text-align:right; background-color:lightgray;'> 16 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 17 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 18 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 19 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> start()
<font color='gray' style='text-align:right; background-color:lightgray;'> 20 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 21 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"User exit is starting..."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 22 </font> NMEAContext.getInstance().addNMEAReaderListener(<font color='#ffff66'><b>new</b></font> NMEAReaderListener()
<font color='gray' style='text-align:right; background-color:lightgray;'> 23 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 24 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 25 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> manageNMEAString(<font color='cyan'><b><i>String</i></b></font> nmeaString)
<font color='gray' style='text-align:right; background-color:lightgray;'> 26 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 27 </font> <font color='orange'><i>// System.out.println(" ... From user exit, got NMEA Data [" + nmeaString + "]");</i></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 28 </font> NMEADataCache dc = NMEAContext.getInstance().getCache();
<font color='gray' style='text-align:right; background-color:lightgray;'> 29 </font> <font color='#ffff66'><b>double</b></font> tws = ((Speed) dc.get(NMEADataCache.TWS)).getValue();
<font color='gray' style='text-align:right; background-color:lightgray;'> 30 </font> <font color='#ffff66'><b>double</b></font> twd = ((<font color='cyan'>Angle360</font>) dc.get(NMEADataCache.TWD)).getValue();
<font color='gray' style='text-align:right; background-color:lightgray;'> 31 </font> <font color='#ffff66'><b>if</b></font> (tws > <font color='cyan'>10</font> && !<font color='cyan'><b><i>Double</i></b></font>.isInfinite(tws))
<font color='gray' style='text-align:right; background-color:lightgray;'> 32 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 33 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Wind is over 10 kts:"</i></font> + tws + <font color='orange'><i>", TWD:"</i></font> + twd);
<font color='gray' style='text-align:right; background-color:lightgray;'> 34 </font> <font color='gray'><i>// TODO Send an email...</i></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 35 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 36 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 37 </font> });
<font color='gray' style='text-align:right; background-color:lightgray;'> 38 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 39 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 40 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 41 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> stop()
<font color='gray' style='text-align:right; background-color:lightgray;'> 42 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 43 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Terminating User exit"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 44 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 45 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 46 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 47 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> describe()
<font color='gray' style='text-align:right; background-color:lightgray;'> 48 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 49 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"This is a simple user-exit example that shows howto register an NMEAReaderListener from your code."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 50 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 51 </font> }
<!-- End of generated code -->
</pre>
</div></div>
<h2>User-exit runtime</h2>
To have your user-exit to be taken care if, you need to:
<ul>
<li>
Archive it in a jar-file, and put the jar (along with the ones it may depend on) in one of the following directories
<ul>
<li><code>all-user-exits</code> (recommended)</li>
<li><code>all-libs</code></li>
<li><code>all-3rd-party</code></li>
</ul>
</li>
<li>
Mention the name of the user-exit in the command-line parameters, like <code>-ue:myspecial.feature.SuperUserExit</code>.
For the example above, the parameter would be <code>-ue:olivsoftdesktop.sampleue.UserExitSample</code>.
</li>
</ul>
And that's it. This works from the console, as well as from the headless one.
<h2>A more complex sample</h2>
Here is the scenario:
<br>
<b>You have an internet connection</b> on the boat, it is docked or anchored in the harbor.
<br>
From wherever you are, you want to know what the wind is like where the boat is.
<br>
This user-exit monitors the True Wind Speed (TWS), and send an email when it is above a given threshold.
It looks at the wind speed every X minutes, the X comes from a configuration file (<code>email.properties</code>) that can be edited.
<div id="div-03" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
<!-- Generated code pasted below -->
<font color='gray' style='text-align:right; background-color:lightgray;'> 1 </font> <font color='#ffff66'><b>package</b></font> olivsoftdesktopuserexits;
<font color='gray' style='text-align:right; background-color:lightgray;'> 2 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 3 </font> <font color='#ffff66'><b>import</b></font> java.io.FileInputStream;
<font color='gray' style='text-align:right; background-color:lightgray;'> 4 </font> <font color='#ffff66'><b>import</b></font> java.text.DecimalFormat;
<font color='gray' style='text-align:right; background-color:lightgray;'> 5 </font> <font color='#ffff66'><b>import</b></font> java.text.SimpleDateFormat;
<font color='gray' style='text-align:right; background-color:lightgray;'> 6 </font> <font color='#ffff66'><b>import</b></font> java.util.Calendar;
<font color='gray' style='text-align:right; background-color:lightgray;'> 7 </font> <font color='#ffff66'><b>import</b></font> java.util.Date;
<font color='gray' style='text-align:right; background-color:lightgray;'> 8 </font> <font color='#ffff66'><b>import</b></font> java.util.Properties;
<font color='gray' style='text-align:right; background-color:lightgray;'> 9 </font> <font color='#ffff66'><b>import</b></font> java.util.TimeZone;
<font color='gray' style='text-align:right; background-color:lightgray;'> 10 </font> <font color='#ffff66'><b>import</b></font> nmea.server.ctx.NMEAContext;
<font color='gray' style='text-align:right; background-color:lightgray;'> 11 </font> <font color='#ffff66'><b>import</b></font> nmea.server.ctx.NMEADataCache;
<font color='gray' style='text-align:right; background-color:lightgray;'> 12 </font> <font color='#ffff66'><b>import</b></font> ocss.nmea.parser.<font color='cyan'>Angle360</font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 13 </font> <font color='#ffff66'><b>import</b></font> ocss.nmea.parser.GeoPos;
<font color='gray' style='text-align:right; background-color:lightgray;'> 14 </font> <font color='#ffff66'><b>import</b></font> ocss.nmea.parser.Speed;
<font color='gray' style='text-align:right; background-color:lightgray;'> 15 </font> <font color='#ffff66'><b>import</b></font> ocss.nmea.parser.UTCDate;
<font color='gray' style='text-align:right; background-color:lightgray;'> 16 </font> <font color='#ffff66'><b>import</b></font> olivsoftdesktop.DesktopUserExitInterface;
<font color='gray' style='text-align:right; background-color:lightgray;'> 17 </font> <font color='#ffff66'><b>import</b></font> olivsoftdesktopuserexits.emailutil.EmailSender;
<font color='gray' style='text-align:right; background-color:lightgray;'> 18 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 19 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>class</b></font> DesktopEmailSender
<font color='gray' style='text-align:right; background-color:lightgray;'> 20 </font> <font color='#ffff66'><b>implements</b></font> DesktopUserExitInterface
<font color='gray' style='text-align:right; background-color:lightgray;'> 21 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 22 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>final</b></font> <font color='#ffff66'><b>static</b></font> SimpleDateFormat SDF = <font color='#ffff66'><b>new</b></font> SimpleDateFormat(<font color='orange'><i>"yyyy-MMM-dd HH:mm:ss"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 23 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>final</b></font> <font color='#ffff66'><b>static</b></font> DecimalFormat <font color='cyan'>DF22</font> = <font color='#ffff66'><b>new</b></font> DecimalFormat(<font color='orange'><i>"##0.00 'kts'"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 24 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>final</b></font> <font color='#ffff66'><b>static</b></font> DecimalFormat <font color='cyan'>DF30</font> = <font color='#ffff66'><b>new</b></font> DecimalFormat(<font color='orange'><i>"##0'\272'"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 25 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>static</b></font> <font color='cyan'><b><i>String</i></b></font> SEND_PROVIDER = <font color='orange'><i>"google"</i></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 26 </font> <font color='#ffff66'><b>private</b></font> Thread watcher = null;
<font color='gray' style='text-align:right; background-color:lightgray;'> 27 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>boolean</b></font> keepWatching = <font color='pink'><b><i>true</i></b></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 28 </font> <font color='#ffff66'><b>private</b></font> EmailSender sender = null;
<font color='gray' style='text-align:right; background-color:lightgray;'> 29 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 30 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>double</b></font> windThreshold = -<font color='cyan'>1</font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 31 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>long</b></font> betweenLoops = <font color='cyan'>600</font> * <font color='cyan'>1000L</font>; <font color='gray'><i>// 10 minutes default</i></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 32 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 33 </font> <font color='#ffff66'><b>public</b></font> DesktopEmailSender()
<font color='gray' style='text-align:right; background-color:lightgray;'> 34 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 35 </font> <font color='#ffff66'><b>super</b></font>();
<font color='gray' style='text-align:right; background-color:lightgray;'> 36 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 37 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 38 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 39 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> start()
<font color='gray' style='text-align:right; background-color:lightgray;'> 40 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 41 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Method 'start':"</i></font> + <font color='#ffff66'><b>this</b></font>.getClass().getName() + <font color='orange'><i>" User exit is starting..."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 42 </font> Properties props = <font color='#ffff66'><b>new</b></font> Properties();
<font color='gray' style='text-align:right; background-color:lightgray;'> 43 </font> <font color='cyan'><b><i>String</i></b></font> propFile = <font color='orange'><i>"email.properties"</i></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 44 </font> <font color='#ffff66'><b>try</b></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 45 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 46 </font> FileInputStream fis = <font color='#ffff66'><b>new</b></font> FileInputStream(propFile);
<font color='gray' style='text-align:right; background-color:lightgray;'> 47 </font> props.load(fis);
<font color='gray' style='text-align:right; background-color:lightgray;'> 48 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 49 </font> <font color='#ffff66'><b>catch</b></font> (<font color='cyan'><b><i>Exception</i></b></font> e)
<font color='gray' style='text-align:right; background-color:lightgray;'> 50 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 51 </font> <font color='cyan'><b><i>System</i></b></font>.err.println(<font color='orange'><i>"email.properies file problem..., from "</i></font> + <font color='cyan'><b><i>System</i></b></font>.getProperty(<font color='orange'><i>"user.dir"</i></font>));
<font color='gray' style='text-align:right; background-color:lightgray;'> 52 </font> <font color='#ffff66'><b>throw</b></font> <font color='#ffff66'><b>new</b></font> RuntimeException(<font color='orange'><i>"File not found:email.properies"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 53 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 54 </font> SEND_PROVIDER = props.getProperty(<font color='orange'><i>"ue.preferred.provider"</i></font>, SEND_PROVIDER);
<font color='gray' style='text-align:right; background-color:lightgray;'> 55 </font> sender = <font color='#ffff66'><b>new</b></font> EmailSender(SEND_PROVIDER);
<font color='gray' style='text-align:right; background-color:lightgray;'> 56 </font> <font color='#ffff66'><b>try</b></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 57 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 58 </font> windThreshold = <font color='cyan'><b><i>Double</i></b></font>.parseDouble(props.getProperty(<font color='orange'><i>"ue.wind.threshold"</i></font>));
<font color='gray' style='text-align:right; background-color:lightgray;'> 59 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Will send emails when the wind is above ["</i></font> + windThreshold + <font color='orange'><i>"]"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 60 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 61 </font> <font color='#ffff66'><b>catch</b></font> (NumberFormatException nfe)
<font color='gray' style='text-align:right; background-color:lightgray;'> 62 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 63 </font> <font color='#ffff66'><b>throw</b></font> <font color='#ffff66'><b>new</b></font> RuntimeException(<font color='orange'><i>"Bad wind threshold:"</i></font> + props.getProperty(<font color='orange'><i>"ue.wind.threshold"</i></font>));
<font color='gray' style='text-align:right; background-color:lightgray;'> 64 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 65 </font> <font color='#ffff66'><b>try</b></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 66 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 67 </font> betweenLoops = Long.parseLong(props.getProperty(<font color='orange'><i>"ue.between.loops.in.minute"</i></font>));
<font color='gray' style='text-align:right; background-color:lightgray;'> 68 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 69 </font> <font color='#ffff66'><b>catch</b></font> (NumberFormatException nfe)
<font color='gray' style='text-align:right; background-color:lightgray;'> 70 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 71 </font> <font color='#ffff66'><b>throw</b></font> <font color='#ffff66'><b>new</b></font> RuntimeException(<font color='orange'><i>"Bad Loop interval:"</i></font> + props.getProperty(<font color='orange'><i>"ue.between.loops.in.minute"</i></font>));
<font color='gray' style='text-align:right; background-color:lightgray;'> 72 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 73 </font> <font color='#ffff66'><b>final</b></font> <font color='#ffff66'><b>long</b></font> _betweenLoops = betweenLoops;
<font color='gray' style='text-align:right; background-color:lightgray;'> 74 </font> watcher = <font color='#ffff66'><b>new</b></font> Thread()
<font color='gray' style='text-align:right; background-color:lightgray;'> 75 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 76 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>boolean</b></font> started = <font color='pink'><b><i>false</i></b></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 77 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>final</b></font> <font color='#ffff66'><b>long</b></font> BETWEEN_LOOPS = _betweenLoops * <font color='cyan'>60</font> * <font color='cyan'>1000</font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 78 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>final</b></font> <font color='#ffff66'><b>long</b></font> TEN_SECONDS = <font color='cyan'>10000L</font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 79 </font> <font color='#ffff66'><b>private</b></font> <font color='#ffff66'><b>long</b></font> waitTime = BETWEEN_LOOPS;
<font color='gray' style='text-align:right; background-color:lightgray;'> 80 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> run()
<font color='gray' style='text-align:right; background-color:lightgray;'> 81 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 82 </font> <font color='#ffff66'><b>while</b></font> (keepWatching)
<font color='gray' style='text-align:right; background-color:lightgray;'> 83 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 84 </font> waitTime = BETWEEN_LOOPS;
<font color='gray' style='text-align:right; background-color:lightgray;'> 85 </font> NMEADataCache dc = NMEAContext.getInstance().getCache();
<font color='gray' style='text-align:right; background-color:lightgray;'> 86 </font> <font color='#ffff66'><b>try</b></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 87 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 88 </font> <font color='#ffff66'><b>double</b></font> tws = ((Speed) dc.get(NMEADataCache.TWS)).getValue();
<font color='gray' style='text-align:right; background-color:lightgray;'> 89 </font> <font color='#ffff66'><b>double</b></font> twd = ((<font color='cyan'>Angle360</font>) dc.get(NMEADataCache.TWD)).getValue();
<font color='gray' style='text-align:right; background-color:lightgray;'> 90 </font> <font color='cyan'><b><i>String</i></b></font> date = <font color='orange'><i>""</i></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 91 </font> UTCDate utcDate = (UTCDate)NMEAContext.getInstance().getCache().get(NMEADataCache.GPS_DATE_TIME);
<font color='gray' style='text-align:right; background-color:lightgray;'> 92 </font> <font color='#ffff66'><b>if</b></font> (utcDate != null && utcDate.getValue() != null)
<font color='gray' style='text-align:right; background-color:lightgray;'> 93 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 94 </font> Date d = utcDate.getValue();
<font color='gray' style='text-align:right; background-color:lightgray;'> 95 </font> Calendar cal = Calendar.getInstance();
<font color='gray' style='text-align:right; background-color:lightgray;'> 96 </font> cal.setTime(d);
<font color='gray' style='text-align:right; background-color:lightgray;'> 97 </font> cal.setTimeZone(TimeZone.getTimeZone(<font color='orange'><i>"Etc/UTC"</i></font>));
<font color='gray' style='text-align:right; background-color:lightgray;'> 98 </font> date = SDF.format(cal.getTime());
<font color='gray' style='text-align:right; background-color:lightgray;'> 99 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 100 </font> <font color='cyan'><b><i>String</i></b></font> pos = <font color='orange'><i>""</i></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 101 </font> <font color='#ffff66'><b>try</b></font> { pos = ((GeoPos)dc.get(NMEADataCache.POSITION)).toString(); } <font color='#ffff66'><b>catch</b></font> (<font color='cyan'><b><i>Exception</i></b></font> ex) {}
<font color='gray' style='text-align:right; background-color:lightgray;'> 102 </font> <font color='#ffff66'><b>if</b></font> (!started)
<font color='gray' style='text-align:right; background-color:lightgray;'> 103 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 104 </font> started = <font color='pink'><b><i>true</i></b></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 105 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>" -- User exit started for good."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 106 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 107 </font> <font color='#ffff66'><b>if</b></font> (tws > windThreshold && !<font color='cyan'><b><i>Double</i></b></font>.isInfinite(tws))
<font color='gray' style='text-align:right; background-color:lightgray;'> 108 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 109 </font> <font color='cyan'><b><i>String</i></b></font> alertMessage =
<font color='gray' style='text-align:right; background-color:lightgray;'> 110 </font> (date.trim().length() > <font color='cyan'>0</font> ? <font color='orange'><i>"Date:"</i></font> + date + <font color='orange'><i>"\n"</i></font>: <font color='orange'><i>""</i></font>) +
<font color='gray' style='text-align:right; background-color:lightgray;'> 111 </font> (pos.trim().length() > <font color='cyan'>0</font> ? <font color='orange'><i>"Pos:"</i></font> + pos + <font color='orange'><i>"\n"</i></font> : <font color='orange'><i>""</i></font>) +
<font color='gray' style='text-align:right; background-color:lightgray;'> 112 </font> <font color='orange'><i>"Wind is over "</i></font> + <font color='cyan'>DF22</font>.format(windThreshold) + <font color='orange'><i>":"</i></font> + <font color='cyan'>DF22</font>.format(tws) + <font color='orange'><i>", TWD:"</i></font> + <font color='cyan'>DF30</font>.format(twd);
<font color='gray' style='text-align:right; background-color:lightgray;'> 113 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(alertMessage);
<font color='gray' style='text-align:right; background-color:lightgray;'> 114 </font> <font color='gray'><i>// Send an email...</i></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 115 </font> <font color='#ffff66'><b>try</b></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 116 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 117 </font> sender.send(alertMessage);
<font color='gray' style='text-align:right; background-color:lightgray;'> 118 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Email sent."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 119 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 120 </font> <font color='#ffff66'><b>catch</b></font> (<font color='cyan'><b><i>Exception</i></b></font> ex)
<font color='gray' style='text-align:right; background-color:lightgray;'> 121 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 122 </font> <font color='cyan'><b><i>System</i></b></font>.err.println(<font color='orange'><i>"Sending email failed through ["</i></font> + SEND_PROVIDER + <font color='orange'><i>"]"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 123 </font> ex.printStackTrace();
<font color='gray' style='text-align:right; background-color:lightgray;'> 124 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 125 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 126 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 127 </font> <font color='#ffff66'><b>catch</b></font> (NullPointerException npe)
<font color='gray' style='text-align:right; background-color:lightgray;'> 128 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 129 </font> <font color='gray'><i>// Just wait til next time...</i></font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 130 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Cache not initialized (yet)"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 131 </font> waitTime = TEN_SECONDS;
<font color='gray' style='text-align:right; background-color:lightgray;'> 132 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 133 </font> <font color='#ffff66'><b>synchronized</b></font> (<font color='#ffff66'><b>this</b></font>)
<font color='gray' style='text-align:right; background-color:lightgray;'> 134 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 135 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>" ...User exit going to wait, at "</i></font> + <font color='#ffff66'><b>new</b></font> Date().toString() + <font color='orange'><i>" (will wait for "</i></font> + (waitTime / <font color='cyan'>1000</font>) + <font color='orange'><i>" s)"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 136 </font> <font color='#ffff66'><b>try</b></font> { wait(waitTime); }
<font color='gray' style='text-align:right; background-color:lightgray;'> 137 </font> <font color='#ffff66'><b>catch</b></font> (InterruptedException ie)
<font color='gray' style='text-align:right; background-color:lightgray;'> 138 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 139 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Told to stop!"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 140 </font> keepWatching = <font color='pink'><b><i>false</i></b></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 141 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 142 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 143 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 144 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Stop waiting."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 145 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 146 </font> };
<font color='gray' style='text-align:right; background-color:lightgray;'> 147 </font> keepWatching = <font color='pink'><b><i>true</i></b></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 148 </font> watcher.start();
<font color='gray' style='text-align:right; background-color:lightgray;'> 149 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 150 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 151 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 152 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> stop()
<font color='gray' style='text-align:right; background-color:lightgray;'> 153 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 154 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='#ffff66'><b>this</b></font>.getClass().getName() + <font color='orange'><i>" is terminating"</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 155 </font> keepWatching = <font color='pink'><b><i>false</i></b></font>;
<font color='gray' style='text-align:right; background-color:lightgray;'> 156 </font> <font color='#ffff66'><b>synchronized</b></font> (watcher)
<font color='gray' style='text-align:right; background-color:lightgray;'> 157 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 158 </font> watcher.notify();
<font color='gray' style='text-align:right; background-color:lightgray;'> 159 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 160 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 161 </font>
<font color='gray' style='text-align:right; background-color:lightgray;'> 162 </font> @Override
<font color='gray' style='text-align:right; background-color:lightgray;'> 163 </font> <font color='#ffff66'><b>public</b></font> <font color='#ffff66'><b>void</b></font> describe()
<font color='gray' style='text-align:right; background-color:lightgray;'> 164 </font> {
<font color='gray' style='text-align:right; background-color:lightgray;'> 165 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Polls the NMEA Cache on a regular base, and sends an email if the TWS is above a given threshold."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 166 </font> <font color='cyan'><b><i>System</i></b></font>.out.println(<font color='orange'><i>"Driven by a properties file named email.properties, in the all-scripts directory."</i></font>);
<font color='gray' style='text-align:right; background-color:lightgray;'> 167 </font> }
<font color='gray' style='text-align:right; background-color:lightgray;'> 168 </font> } <!-- End of generated code -->
</pre>
</div></div>
<a href="http://donpedro.lediouris.net/software/blog/src.zip">All the sources</a> of this example.
<br><br>
Possibilities are endless. The limit is your imagination.
<br>
Combining the two examples above, you can as well gather all the data into a single document (XML, json, etc), and send it through email on
a regular base, so it can be rendered by the receipient.
<br>
Etc, etc...
<h2>How to do it for yourself, step by step</h2>
<ol>
<li>Download all the sources, in the <a href="http://donpedro.lediouris.net/software/blog/src.zip">zip</a> mentionned above</li>
<li>Extract it is a new clean directory</li>
<li>Make sure the jar <code>mail.jar</code> is in your <code>all-3rd-party</code> directory</li>
<li>Make sure you have installed a JDK in your environment</li>
<li>In a system console, navigate to the directory where you unzipped the sources</li>
<li>If it does not exist, create a <code>classes</code> directory. Make sure it is empty</li>
<li>
Compile the code:
<br><b>On Windows</b>
<div id="div-01" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> set OLIV_HOME=D:\OlivSoft
Prompt> set CP=%OLIV_HOME%\all-3rd-party\mail.jar
Prompt> set CP=%CP%;%OLIV_HOME%\all-libs\nmeaparser.jar
Prompt> set CP=%CP%;%OLIV_HOME%\all-libs\nmeareader.jar
Prompt> set CP=%CP%;%OLIV_HOME%\all-libs\desktop.jar
Prompt> set CP=%CP%;%OLIV_HOME%\all-libs\geomutil.jar
Prompt> javac -d classes -sourcepath src -cp %CP% src\olivsoftdesktopuserexits\*.java
</pre></div></div>
<b>On Linux</b>
<div id="div-01" style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 150px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> bash
Prompt> OLIV_HOME=/usr/OlivSoft
Prompt> CP=$OLIV_HOME/all-3rd-party/mail.jar
Prompt> CP=$CP:$OLIV_HOME/all-libs/nmeaparser.jar
Prompt> CP=$CP:$OLIV_HOME/all-libs/nmeareader.jar
Prompt> CP=$CP:$OLIV_HOME/all-libs/desktop.jar
Prompt> CP=$CP:$OLIV_HOME/all-libs/geomutil.jar
Prompt> javac -d classes -sourcepath src -cp $CP src/olivsoftdesktopuserexits/*.java
</pre></div></div>
Make sure you do not see any error.
</li>
<li>
Archive the generated classes:
<br><b>On Windows</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> cd classes
Prompt> jar -cvf ..\emailUserExit.jar *
</pre></div></div>
<b>On Linux</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> cd classes
Prompt> jar -cvf ../emailUserExit.jar *
</pre></div></div>
</li>
<li>
Copy the archive in the <code>all-user-exits</code> directory
<br><b>On Windows</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> cd ..
Prompt> copy *.jar %OLIV_HOME%\all-user-exits
</pre></div></div>
<b>On Linux</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> cd ..
Prompt> cp *.jar $OLIV_HOME/all-user-exits
</pre></div></div>
Copy <code>email.properties</code> in the <code>all-scripts</code> directory
<br><b>On Windows</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> copy email.properties %OLIV_HOME%\all-scripts
</pre></div></div>
<b>On Linux</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
Prompt> cp email.properties $OLIV_HOME/all-scripts
</pre></div></div>
You are almost done...
</li>
<li>
Modify the line that starts the console, so it takes your work in account:
<br><b>On Windows</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
set COMMAND=java %JAVA_OPTIONS% -classpath %CP% olivsoftdesktop.OlivSoftDesktop %HEADLESS_OPTIONS% -ue:olivsoftdesktopuserexits.DesktopEmailSender
start "Headless Console (User-Exit)" %COMMAND%
</pre></div></div>
<b>On Linux</b>
<div style="padding:5px; background:#ddd; border-radius:5px; overflow-x: scroll; overflow-y: scroll;border:1px solid #CCC; margin-top:10px; height: 80px; resize:both;">
<div style='width:1200px'>
<pre style="font-family:'Source Code Pro', 'Courier New'; font-size:11px; color:white; background-color:#1e1e1e;">
java $JAVA_OPTIONS -classpath $CP olivsoftdesktop.OlivSoftDesktop $HEADLESS_OPTIONS -ue:olivsoftdesktopuserexits.DesktopEmailSender &
</pre></div></div>
That's it!
<br>
<i><b>Important</b></i>: Do not forget to edit and modify <code>email.properties</code>, so it matches your environment, and your needs.
</li>
</ol>
And all this runs just fine on a Raspberry PI, I've tested it.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-84689913171323800502013-11-18T17:09:00.000-08:002013-11-19T16:32:30.404-08:00Multiple Access, for realNow we've setup the ad-hoc network from the Raspberry PI reading the NMEA Data, we can simultaneously access the data, from several devices connected on the ad-hoc network defined on the boat, from the Raspberry PI itself:
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib4Dsc2PsZBXx5VgUM3X-wbxXFqf92mQVjYdL3B0EyI-I-nLIZ_dPCzisVoxq-z01h3QsJTyWHzP3DrUUv2BF323CLQGiYh3_XGM6A2EyLWfZzzoQOscfQJ6scADKRlC-uo4nSWPxoarM/s1600/IMAG0446.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib4Dsc2PsZBXx5VgUM3X-wbxXFqf92mQVjYdL3B0EyI-I-nLIZ_dPCzisVoxq-z01h3QsJTyWHzP3DrUUv2BF323CLQGiYh3_XGM6A2EyLWfZzzoQOscfQJ6scADKRlC-uo4nSWPxoarM/s320/IMAG0446.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Swing Console from a laptop</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihrSb4DoXwKsqkzjKsSts3H6e9IQvNPvhRv_L6WGjlQGKnByI6byRVuAAyIhFds8g7Z44veJqLvwOK0hz2zA39oPHaqNttPP63klmGvFb9NPRpEvY7hOnT8Kfk7Cj30eZwoz4YGORj_JA/s1600/IMAG0447.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihrSb4DoXwKsqkzjKsSts3H6e9IQvNPvhRv_L6WGjlQGKnByI6byRVuAAyIhFds8g7Z44veJqLvwOK0hz2zA39oPHaqNttPP63klmGvFb9NPRpEvY7hOnT8Kfk7Cj30eZwoz4YGORj_JA/s320/IMAG0447.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
OpenCPN from a laptop</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJqKGZ3_U1SQKdwJ5H_eAe2K7fkL55y5k6e6iFdmSwa9TUX3EYVK2EjKPg9gHW6pnhY7VVz-NyxciMEW2fbfS2d3xm7SjdjWbE9c_5F53rZlj5ykBk1M67asC_vi5RSt9MrGavNiAcqD0/s1600/IMAG0442.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJqKGZ3_U1SQKdwJ5H_eAe2K7fkL55y5k6e6iFdmSwa9TUX3EYVK2EjKPg9gHW6pnhY7VVz-NyxciMEW2fbfS2d3xm7SjdjWbE9c_5F53rZlj5ykBk1M67asC_vi5RSt9MrGavNiAcqD0/s320/IMAG0442.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
HTML Console from a laptop</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVuhQTZgDkcdiADdSziYi1BGJyQpZHLN4dMPYMC7bB6RHFbfw9jI_p-kLv5ttHMLQAm13mY4Kv1y9gegaV3Of3BnMwA7ciZz9eL-GYiywFziVEhPFmlxb4671lz7jj6GxNCvFGfigg-eg/s1600/IMAG0444.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVuhQTZgDkcdiADdSziYi1BGJyQpZHLN4dMPYMC7bB6RHFbfw9jI_p-kLv5ttHMLQAm13mY4Kv1y9gegaV3Of3BnMwA7ciZz9eL-GYiywFziVEhPFmlxb4671lz7jj6GxNCvFGfigg-eg/s320/IMAG0444.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
HTML Console from an iPad</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjUBK3bs5LriFfyhqLmcciel9Q7OZFIGnfKTp0vgbcAPqnB1B9y2tuUa0eLV5W7Kfe_tEUCcKBTYPJ-7im2zX4LRSxIh7QBgoyE0SUrvZkThTq1vwVq0zOlf4rypRKb1faNI20JCpqq34/s1600/IMAG0449.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjUBK3bs5LriFfyhqLmcciel9Q7OZFIGnfKTp0vgbcAPqnB1B9y2tuUa0eLV5W7Kfe_tEUCcKBTYPJ-7im2zX4LRSxIh7QBgoyE0SUrvZkThTq1vwVq0zOlf4rypRKb1faNI20JCpqq34/s320/IMAG0449.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
HTML Console from an iPhone</div>
All the pictures above were taken with all the programs on the devices running simultaneously.
<br>
A small glitch I need to address: Android does not want to connect to an ad-hoc network. I need to fix that, more to come soon.
Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-4248683479365287602013-11-09T17:50:00.001-08:002013-11-14T18:27:19.029-08:00NMEA with Raspberry PI: All Good!The last step - after <a href="http://donpedrodalfaroubeira.blogspot.com/2013/11/from-scratch-to-nmea-re-broadcasting-on.html">this one</a> - was not as straight forward. But finally, everything works fine.
<br>
The idea was to use <a href="http://pi4j.com">PI4J</a> to read the serial port (<code>/dev/ttyAMA0</code>). All the tests I made with PI4J were all very positive, <b><i>but</i></b> apparently, there is a bug when the baud rate is 4800. And unfortunately, this is <b>the</b> one we need.
<br>
But as reading a USB port (<code>/dev/ttyUSB0</code>) was not a problem, a simple adapter (serial 9 pin to USB) fixed everything. And on Linux (Raspberry PI runs Linux, a tweaked version of Debian), no driver or any such thing is required. Plug it in, and boom! It works.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh8GEeJ5dvpOo64utL8AltQ5qTLoy4HwLxKlckHscMnOq68yJoEPA5zxQ3t2OWc76YClYLF1v7qLVamJZvB24dEQJ-jMNME95tJgPU8Ss5PEl9bylj7tkRVH_1W4R4RtSUp_JgUF9BPLc/s1600/IMAG0428.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh8GEeJ5dvpOo64utL8AltQ5qTLoy4HwLxKlckHscMnOq68yJoEPA5zxQ3t2OWc76YClYLF1v7qLVamJZvB24dEQJ-jMNME95tJgPU8Ss5PEl9bylj7tkRVH_1W4R4RtSUp_JgUF9BPLc/s320/IMAG0428.jpg" /></a></div>
The Raspberry PI reads the serial port with the headless console, and rebroadcasts everything appropriately.
<br>
The NMEA Console and OpenCPN can use TCP to get the data, The html5 Console uses HTML..., everything goes seamlessly. For less than 700mA. And around $50.
<br>
We will detail later all the steps to go through to get this done anywhere. This is just an easy check list.
<br>
And we'll built a nice box to host all this. The Raspberry, an optional small screen, and possibly a small keyboard.
<br>
More soon.
<br>
<br>
And just to give you a taste of what will come next,<a href="http://nodejs.org/">node.js</a> works like a charm on the Raspberry PI, and the WebSocket protocol works as if it had been designed for this platform... That is going to seriously rock.
<h3>To summarize</h3>
This project goes along with the NMEA console, found <a href="https://code.google.com/p/fullnmeaconsole/">here</a>.
<br><br>
The main points this project addresses:
<ul>
<li>Serial ports (most of the data we're interested in come through a serial port) are accessed exclusively. Only one program at a time can access the data. I had the problem on the ketch, when the cartography soft was accessing the data port (to plot the boat on the chart), the console (the one evaluating current and performances) had to wait.</li>
<li>The laptop you can use to read the data draws a substantial amount of electricity (around 10W is not unusual).</li>
<li>Several devices on the boat (tactician, driver, navigator, trimmers) might need to have simultaneous access to the data, and they might need to be already processed and smoothed (damped)</li>
</ul>
The various devices needing access to the data might not run the same Operating System (MacOS, iOS, Android, Windows, Linux...). We assumed here that they have a network access, and a browser supporting HTML5 (the tests I made for this particular point are positive).
<br>
So, here is the story:
<ol>
<li>The Raspberry PI creates its own ad-hoc network when it boots, and you start on it a utility that reads the data from the serial (or whatever) port connected to the NMEA station</li>
<li>The data are read, and stored on the raspberry in some cache (a hashmap).</li>
<li>The data are logged (optional), and processed (true wind is calculated, current is evaluated, VMG - on the wind or on the mark, performance, are evaluated). Those data are cached as well. Those calculations require some parameters to be set (max leeway, deviation curves, polars of the boat, some coefficients for the instruments, etc), they are available on the Raspberry PI.</li>
<li>The data rebroadcasted on TCP, UDP, and HTML (also possibly RMI; I dropped GPSd). You can select one or more of those channels for rebroadcasting.</li>
</ol>
Basically, this is all the RaspPi is doing.
<br>
<br>
The SD card containing the OS of the PI needs to be 4Gb big, minimal recommended. Mine is 8, and it can go beyond 32. This allows DAYS of logging.
<br>
<br>
Now, when a device from the boat wants to see what's going on (i.e. visualize the data), it connects to the boat's ad-hoc network.
Then, depending on its possibilities and needs, it can use the NMEA Console (that one can read any channel for its data input), or the HTML5 Console (at the bottom of <a href="https://code.google.com/p/fullnmeaconsole/">this page</a>).
<br>
<br>
The chart plotting program (like OpenCPN) can use the exact same data stream.
<br>
And when you're done watching your device, you can turn it off, hibernate it, what not, the RaspPi keeps reading and broadcasting.
<br>
<br>
The RaspPi does not take more than 700mA.
<br>
And it costs less than $50.
<br>
The RaspPi does not need any keyboard or screen. (I use SSH from a laptop to start the reading program on it).
<br>
The main points are:
<ul>
<li>Low consumption (and low price, if it makes any sense in this context)</li>
<li>Data rebroadcasting</li>
<li>
Logging (<b><i>ages</i></b> of logging).
<br>
<small>
<font color="blue">I log VWR, RMC, MWV, RMB, VHW, VLW, HDG, MTW and GLL. It's about 1 Mb per hour.
<br>
One day would be 24 Mb. One week around 168 Mb. Peanuts.</font>
</small>
</li>
</ul>
I have a lot of data, some logged during our Polynesian trip, I can replay them. This story seems to work.
<br>
<br>
I was very interested during the recent America's Cup, to see all the crews watching several kind of devices..., many had those displays on their fore-arms, tacticians had some iPad-like devices, fasten on their bellies with some shock-cords and velcro..., it kind of rang a bell!
Those boats had for sure way more sensors that just an NMEA station (up to 3000 sensors for Oracle, I heard), but I believe that there is already a LOT to do with the data you can get from a regular NMEA station.
<br>
<br>
Once the ad-hoc network is setup, the crew members can even use their smart phone to access it, and visualize the HTML5 Console.
That actually enhances one point: All the technology is here - nothing has been built or invented specially for this project. It's all about getting access to it with existing devices and techniques. Everyone (including me!) now has a smartphone, Linux has been around for ages, NMEA is one of the (if not <b>THE</b>) oldest standards in IT... And again, a small device you can get for less that $50 makes it all possible!
<br>
I like that.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-48002894068512588142013-11-08T14:17:00.001-08:002013-12-26T09:58:46.475-08:00Tropical phenomenons, Pacific, fall 2013We've had quite a few tropical phenomenons in the Pacific since the end of August...
Here is a list - still open - of what we've had, along with the time they were active, and their highest strength.
Wind speeds are in knots. 60 G 75 is to be read 60 knots, gusting 75 knots.
<table border="1" width="100%">
<tr>
<td valign="top">Sep 01-02</td>
<td valign="top">TS Kiko, 60 G 75</td>
<tr>
<tr>
<td valign="top">Sep 13-16</td>
<td valign="top">TS Man-Yi, 60 G 75</td>
<tr>
<tr>
<td valign="top">Sep 17-18</td>
<td valign="top">Typhoon Usagi, 65 G 80</td>
<tr>
<tr>
<td valign="top">Sep 13-16</td>
<td valign="top">TS Man-Yi, 60 G 75</td>
<tr>
<tr>
<td valign="top">Sep 19</td>
<td valign="top">Hurricane Manuel, 65 G 80</td>
<tr>
<tr>
<td valign="top">Sep 21-27</td>
<td valign="top">Typhoon Pabuk, 90 G 110</td>
<tr>
<tr>
<td valign="top">Oct 01-04</td>
<td valign="top">Typhoon Fitow, 85 G 105</td>
<tr>
<tr>
<td valign="top">Oct 04-06</td>
<td valign="top">Typhoon Danas, 95 G 115</td>
<tr>
<tr>
<td valign="top">Oct 11-16</td>
<td valign="top">Typhoon Wipha, 115 G 140</td>
<tr>
<tr>
<td valign="top">Oct 16-30</td>
<td valign="top">
Super Typhoon Francisco, 140 G 170<br>
Super Typhoon Lekima, 140 G 170,<br>
Hurricane Raymond, 95 G 105
</td>
<tr>
<tr>
<td valign="top">Nov 04-now</td>
<td valign="top">Super Typhoon Haiwan, 165 G <b>200</b></td>
<tr>
</table>
As a reminder, a hurricane (force 12 on the Beaufort scale) is over 64 knots.
<br>
Over 64 knots, it's a Category One hurricane.
<br>
Over 82 knots, it's a Category Two hurricane.
<br>
Over 95 knots, it's a Category Three hurricane.
<br>
Over 112 knots, it's a Category Four hurricane.
<br>
Over 136 knots, it's a Category Five hurricane.
<br>
<br>
Hurricanes and Typhoons are similar phenomenons. Hurricanes belong to the East Pacific, Typhoons to the West Pacific.
<br>
<br>
We also note that the <a href="http://en.wikipedia.org/wiki/Beaufort_scale" target="wiki">Beaufort scale</a> does not mention any such thing as a "Super Storm". You have Storm, Violent Storm, and Hurricane...
<br>
"Super Storm" is something invented by some journalists.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-10068466739340706372013-11-07T09:25:00.000-08:002013-11-07T09:30:26.617-08:00For Navigatrix users of the WeatherWizardApparently, the soft has been installed as root, and some write permissions are not granted to everyone.
<br>
That makes it difficult to write on the file system, like when downloading a file!
<br>
To fix that, you need to go to a Console, and enter the following commands:
<pre>
Prompt> cd /opt/WeatherWizard
Prompt> sudo find . -name '*' -exec chown $USER {} \;
</pre>
You might as well change the group of the same files.
If your group is "mygrp", then just type:
<pre>
Prompt> cd /opt/WeatherWizard
Prompt> sudo find . -name '*' -exec chgrp mygrp {} \;
</pre>
Be careful, all characters are important.
<br>
That's a bit cryptic, but that should work!
Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-39669466202423780052013-11-04T09:53:00.000-08:002013-11-17T17:08:32.910-08:00From Scratch to NMEA Re-broadcasting on TCP, with a Raspberry PI This post will demonstrate how to connect a Raspberry PI on some NMEA input - a GPS in this case - to re-broadcast all its data using other protocols, HTTP and TCP in this case.
<br>
The cool thing about this configuration is that:
<ul>
<li type="disc">As many devices as you want can access the NMEA data</li>
<li type="disc">The Raspberry PI only draws 700 mA</li>
<li type="disc">When they're done using rthe NMEA data, devices (laptops, tablets...) can shutdown, the NMEA data will still be read and available whenever a device connects on the Raspberry Pi's network</li>
</ul>
The NMEA data being read can also be logged on the Raspberry PI, if necessary.
<br><br>
We assume that you already have a Raspberry PI, along with its power supply (AC or DC, whatever).
<br>
We will show how to setup everything so the Raspberryt PI reads the NMEA data, and re-broadcasts them. As an example, we will show how to consume them from OpenCPN.
<br>
We will also need to edit several configuration files and other scripts. You can use any editor you wish, "nano" can do the job, I myself prefer "vi". At the end of the day, that's the same, only the result is important.
<h2>Requirements</h2>
First, flash the SD card, as explained <a href="http://www.raspberrypi.org/downloads">here</a>.
I used the Raspbian image. Comes with Java.
<br>
Next, we will require several softwares to be installed on the Raspberry PI, some are necessary, others are convenient.
<h4>An FTP server</h4>
This one will be <b>very</b> convenient when you will need to transfer files on you Raspberry PI.
<br>
To install, type:
<pre>
Prompt> sudo apt-get install vsftpd
</pre>
Then edit (sudo edit) <code>/etc/vsftpd.conf</code>:
<pre>
anonymouse_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
chroot_local_user=YES
user_sub_token=$USER
local_root=/home/$USER/ftp
</pre>
Start this ftp as a service on the PI:
<pre>
Prompt> sudo service vsftpd restart
</pre>
<h4>Install RXTX Java libraries</h4>
Read this <a href="http://eclipsesource.com/blogs/2012/10/17/serial-communication-in-java-with-raspberry-pi-and-rxtx/">good article</a>.
<br>
Just type:
<pre>
Prompt> sudo apt-get install librxtx-java
</pre>
We will see in the next section what to do with this.
<h4>Fing</h4>
A very cool utility. Combination of Find and Ping.
<pre>
Prompt> wget http://www.overlooksoft.com/packages/download?plat=arm
Prompt> sudo dpkg -i overlook-fing-2.3.deb
Prompt> sudo apt-get install libpcap*
</pre>
and finally:
<pre>
Prompt> sudo fing
</pre>
<h4>OlivSoft</h4>
You have just installed the libraries you need to use the serial ports (Serial or USB), now we need to modify the launching script to take that in account.
<br>
Make sure you have the last version of the soft, up to date.
<br>
It is available on <a href="https://code.google.com/p/navigation-desktop/">Google Code</a>, in the download section.
<br>
The best way to do that is probably to install it on a box connected to the internet, and to let the software update itself.
<br>
Then you can transfer all the directory where it is installed (using FTP) on the Raspberry PI.
<br>
Once this is done, navigate to the <code>all-scripts</code> directory, and edit the script named <code>olivsoft</code>.
<br>
You can add a line in the menu:
<pre>
echo \| P for Weather Wizard, with http proxy
echo \| S for NMEA Sniffer
<b>echo \| H for Headless NMEA Console</b>
echo \| POL for Polar Tool
</pre>
... and then the corresponding execution definition:
<pre>
...
elif [ $choice = "H" ] || [ $choice = "h" ]
then
JAVA_OPTIONS="$JAVA_OPTIONS -Dverbose=false"
JAVA_OPTIONS="$JAVA_OPTIONS -Dheadless=yes"
<b>JAVA_OPTIONS="$JAVA_OPTIONS -Dserial.port=/dev/ttyUSB0"</b>
JAVA_OPTIONS="$JAVA_OPTIONS -Djava.library.path=/usr/lib/jni"
#
HEADLESS_OPTIONS="-output=HTTP:9999"
HEADLESS_OPTIONS="$HEADLESS_OPTIONS -output=TCP:7001"
# HEADLESS_OPTIONS="$HEADLESS_OPTIONS -output=FILE:.\logged-data\headless.nmea
java -client -Xms512m -Xmx1024m -classpath $CP $JAVA_OPTIONS olivsoftdesktop.OlivSoftDesktop $HEADLESS_OPTIONS
elif ...
</pre>
Notice that <code>/dev/ttyUSB0</code> is the USB port the GPS in connected on. In this case, the data will be re-broadcasted on TCP, port 7001, as well as on HTTP port 9999.
<br>
We will see below how to start the program.
<h4>Create an ad-hoc network, <b>from</b> the Raspberry PI</h4>
Read this <a href="See http://spin.atomicobject.com/2013/04/22/raspberry-pi-wireless-communication/">good article</a>.
<br>
Make a backup:
<pre>
Prompt> sudo cp /etc/network/interfaces /etc/network/interfaces_backup
</pre>
Then edit (sudo edit) <code>/etc/network/interfaces</code>:
<pre>
auto lo
iface lo inet loopback
iface eth0 inet dhcp
auto wlan0
iface wlan0 inet static
address <b><a name="IP">192.168.1.1</a></b>
netmask 255.255.255.0
wireless-channel 1
wireless-essid <b><a name="SSID">RPiOnTheBoat</a></b>
wireless-mode ad-hoc
</pre>
In the lines above, <code>RPiOnTheBoat</code> will be the name of your ad-hoc network.
<br>
Restart <code>wlan0</code> (wlan0 is the name of the wireless network interface).
<pre>
Prompt> sudo ifdown wlan0
Prompt> sudo ifup wlan0
</pre>
(reboot in case you have an error message)
<br><br>
Then we might need a DHCP Server:
<pre>
Prompt> sudo apt-get update
Prompt> sudo apt-get install dhcp3-server
</pre>
Then edit (sudo edit) <code>/etc/dhcp/dhcpd.conf</code>
<pre>
ddns-update-style interim;
default-lease-time 600;
max-lease-time 7200;
authoritative;
log-facility local7;
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.5 192.168.1.150;
}
</pre>
Reboot..., all should be all set!
<br>
Let's if that's true.
<h2>Run it</h2>
Connect the things first:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ831408Q6M5ACrBhBm9mrk8X8h5SQ1HMlbRYDrsc1Lmy4EQgcV1pYi02bf_l4BfRyC94d21mLXCV0TZFbO5aN2ktuL1AA-GlGwhoTZdzGUYSK4hfHgDkLl_NAWsKeiHM7pUm5A5FNo7c/s1600/01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ831408Q6M5ACrBhBm9mrk8X8h5SQ1HMlbRYDrsc1Lmy4EQgcV1pYi02bf_l4BfRyC94d21mLXCV0TZFbO5aN2ktuL1AA-GlGwhoTZdzGUYSK4hfHgDkLl_NAWsKeiHM7pUm5A5FNo7c/s320/01.jpg" /></a><br>Only the Wireless dongle is in</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinn44amSQcnARDjR5GxnKM8dgY5b_8KUSnbioDakjlTO2cXh2cPKolkKG26dfb8NHXHrO6fbCcjFQ8xMZsz7j1gSTAKW2naCtlNRnfZjtjdqU24hkSgPTM8ob8HqxBVD2JrMIN18mOiRU/s1600/02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinn44amSQcnARDjR5GxnKM8dgY5b_8KUSnbioDakjlTO2cXh2cPKolkKG26dfb8NHXHrO6fbCcjFQ8xMZsz7j1gSTAKW2naCtlNRnfZjtjdqU24hkSgPTM8ob8HqxBVD2JrMIN18mOiRU/s320/02.jpg" /></a><br>Plug the SD Card in (contains the OS)</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihg0dzBR4YTePbFBZleU3rTkGgrb6zFZRsUtLZGQaQOSPjg3y1Tr2GmSNLzqd_Axo6CQGQ29odRW83K-2mbfej9gRLDhnv8_B3PR87GJWF3v9ccw_KWjLpmUlClIiapf4ZR5zGsXqoFR4/s1600/03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihg0dzBR4YTePbFBZleU3rTkGgrb6zFZRsUtLZGQaQOSPjg3y1Tr2GmSNLzqd_Axo6CQGQ29odRW83K-2mbfej9gRLDhnv8_B3PR87GJWF3v9ccw_KWjLpmUlClIiapf4ZR5zGsXqoFR4/s320/03.jpg" /></a><br>Plug in the GPS</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Sc7jbHGwhBk_CwEpzWp3TU7YXQ_C9I88FLSTD_5kIIIkfUIZWdGIuSyIDT_W6HxmfS5mR5diAI6a04h2fUR12R59qNrFUooKPeGRL3X2nd9TitDE9mHMC5qiMzyfVaDJMu7bAHm5tpQ/s1600/04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Sc7jbHGwhBk_CwEpzWp3TU7YXQ_C9I88FLSTD_5kIIIkfUIZWdGIuSyIDT_W6HxmfS5mR5diAI6a04h2fUR12R59qNrFUooKPeGRL3X2nd9TitDE9mHMC5qiMzyfVaDJMu7bAHm5tpQ/s320/04.jpg" /></a><br>Connect the power supply</div>
Connecting the power supply will boot the device. Now, wait a couple of seconds for Linux to boot, and we are going to connect to the Raspberry PI from another machine, using <code>ssh</code>.
<br>
Notice in the steps above, that there is no mouse, no keyboard, and no screen connected on the Raspberry PI. We could have done so.
But we didn't.
<br>
To demonstarte the full compatibility of this scenario, we will do the subsequent operations from a Windows box.
<h4>Connect to the Raspberry PI's ad-hoc network</h4>
The wireless networks are usually available in the Windows taskbar. If not, open your Network Control Panel, you'll find it there.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkdfEf2M4Q08GT-4bXw0vobMOYnELd4qR29yR3g0zB_WXdXbzO-6mEMynPPTs3SRltmQ8akYhEqoGd6754zWGVxiQYvd0fNFGT8jxtDsBa8tibajGIDZziA0oM5Ia9RFmlFi-dJxB32b4/s1600/05.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkdfEf2M4Q08GT-4bXw0vobMOYnELd4qR29yR3g0zB_WXdXbzO-6mEMynPPTs3SRltmQ8akYhEqoGd6754zWGVxiQYvd0fNFGT8jxtDsBa8tibajGIDZziA0oM5Ia9RFmlFi-dJxB32b4/s320/05.JPG" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgie8T2GRBOsanJQFg-5az4YoPneCISt0WK27m0OrLoqp09T5OnujiepE4uZdPWY9il2gMS8hVM2aGB0mgHmDE_5Pm709n3Hd44nQXP622vZmCOo5h8aixU29qidW8EDJQ6OAH-3QJKCjA/s1600/06.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgie8T2GRBOsanJQFg-5az4YoPneCISt0WK27m0OrLoqp09T5OnujiepE4uZdPWY9il2gMS8hVM2aGB0mgHmDE_5Pm709n3Hd44nQXP622vZmCOo5h8aixU29qidW8EDJQ6OAH-3QJKCjA/s320/06.JPG" /></a></div>
Notice the network's name (<code>RPiOnTheBoat</code>), this is the one <a href="#SSID">you defined</a>.<br>
Then, we will use ssh (PuTTY) to start the re-broadcast:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvlR4cw0Ca5t6X-DLKy6WKKv7cg4Kqh5naquAa7p089ZWNaodUar3lImusr0drpYrjfXfQolqDrVLx_P1XSVePEmCShudnhRhv_ntqRyxweLC-t-E5SUJLQ-sXRORm45v1IRQ_zUomjKQ/s1600/07.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvlR4cw0Ca5t6X-DLKy6WKKv7cg4Kqh5naquAa7p089ZWNaodUar3lImusr0drpYrjfXfQolqDrVLx_P1XSVePEmCShudnhRhv_ntqRyxweLC-t-E5SUJLQ-sXRORm45v1IRQ_zUomjKQ/s320/07.JPG" /></a></div>
Connect with your username (default: pi) and password (default: raspberry), and cd to <code>olivsoft</code>, and start the script <code>olivsoft</code>:
<pre>
Prompt> ./olivsoft
</pre>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPNO-34xOrWvLDXFe8DF94QtvxEOTmWHoRryoL1iLVbbuq5_2iWLA24RaogvnHV4DK99mHhcaR8HD5ljS2LDniFjqz9t6W9-GWeMnFOLmbLc6v-MMJmjjNSZmp5-dsWdKoGZnE6s2QGpo/s1600/08.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPNO-34xOrWvLDXFe8DF94QtvxEOTmWHoRryoL1iLVbbuq5_2iWLA24RaogvnHV4DK99mHhcaR8HD5ljS2LDniFjqz9t6W9-GWeMnFOLmbLc6v-MMJmjjNSZmp5-dsWdKoGZnE6s2QGpo/s320/08.JPG" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkNcqLD7BTd-dydytdvojwwOBRaUO5gt_WUoQof9jS-jMJYXHzH0UJ2nVSsnJtfXGFNk4Ut5SE4TItdUn5Ygqcz-Fx1fMboTWClMN097Nfyt_j28wPQxN0iqZkA1tJBxB2DSlfMFh7Y48/s1600/09.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkNcqLD7BTd-dydytdvojwwOBRaUO5gt_WUoQof9jS-jMJYXHzH0UJ2nVSsnJtfXGFNk4Ut5SE4TItdUn5Ygqcz-Fx1fMboTWClMN097Nfyt_j28wPQxN0iqZkA1tJBxB2DSlfMFh7Y48/s320/09.JPG" /></a></div>
It's on its way! You can leave the session if you wish, the process will keep going.
<br>
To stop it:
<br>
Re-connect on the Raspberry PI with <code>ssh</code>
<br>
Find the process, by typing:
<pre>
Prompt> ps -ef | grep java
</pre>
Then send it a <code>SIGTERM</code> signal:
<pre>
Prompt> kill -SIGTERM 2493
</pre>
Where <code>2493</code> is the process id. This way, the process will shut down nicely (by design, it understands that signal, which would be a Ctrl+C from the command line).
<br><br>
The process being up and running, define a network connection in OpenCPN:
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih8i8K8qCPPkTdBmkNqVqRrV_PPR7Fb2qYA8YosaQyacvlPU8iCEqag4Cq9vh6c9rIRYqu2CgUhKZ5xbO90aGK0QiLDy4lfsj7FeEcoWa9EMO0dfOCgJ87pB4rvM-nuzgZaKFux5_gAdA/s1600/10.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih8i8K8qCPPkTdBmkNqVqRrV_PPR7Fb2qYA8YosaQyacvlPU8iCEqag4Cq9vh6c9rIRYqu2CgUhKZ5xbO90aGK0QiLDy4lfsj7FeEcoWa9EMO0dfOCgJ87pB4rvM-nuzgZaKFux5_gAdA/s320/10.JPG" /></a></div>
Notice the Address, the one you have defined.<br>
Click Apply...
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLehUaiWf0gmFi_UqidUqpKvqQ0l0xUrjakKVavvSaEh8lx2xkp9_10bjq5F-hvcG_Gc47aAQ5wY6VnDUqM4QdboZIn_G_IfveG2q9Yaipcz12Ms_y2Rf9jKjaJNLm-KPbIMbSr9XPJ2s/s1600/11.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLehUaiWf0gmFi_UqidUqpKvqQ0l0xUrjakKVavvSaEh8lx2xkp9_10bjq5F-hvcG_Gc47aAQ5wY6VnDUqM4QdboZIn_G_IfveG2q9Yaipcz12Ms_y2Rf9jKjaJNLm-KPbIMbSr9XPJ2s/s320/11.JPG" /></a></div>
See the top right, the GPS is connected. As you can see in the NMEA log.
<br>
You can connect like this with as many devices as you want.
<br>
Voilà!
<br><br>
Next, we will try with the full NMEA station, with <a href="http://pi4j.com/">Pi4j</a>.
Then the HTML5 <a href="https://code.google.com/p/fullnmeaconsole/">console</a> will also be available, from http://192.168.1.1:9999/html5/console.html.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-18942830022232789012013-10-26T08:43:00.000-07:002013-11-14T18:30:32.267-08:00Investigating the Raspberry PIThe more I play with it, the more I like it...
It's so small - and so cheap - and it is a real Linux system, based on Debian.
It comes with Java. It runs from a small SD card (4Gb recommended minimum).
All the info are available on the <a href="http://raspberrypi.org" target="RPi">Raspberry PI</a> web site.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQmkq7HZIRHP7O_a5eODrEg7zZo5FuKqdkSpACCUOCkNX9tKOCZKJGS-tUy3fjpWMpeInsaBzSn7e7VBLvYaoHc2xuzGT7tBtT8PKXnsDGPX3IomNS_9G_EwR1syFPHUsOhDxyf8t_bkI/s1600/IMAG0410.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQmkq7HZIRHP7O_a5eODrEg7zZo5FuKqdkSpACCUOCkNX9tKOCZKJGS-tUy3fjpWMpeInsaBzSn7e7VBLvYaoHc2xuzGT7tBtT8PKXnsDGPX3IomNS_9G_EwR1syFPHUsOhDxyf8t_bkI/s320/IMAG0410.jpg" /></a><br/>Development config</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKlRfGqKgYKbBmrcDCjZncoYoSdkuS86uKsFkdvXGh6XPJwaMWKiRoOMf5PlGTvDR-BThQYjI3FZiw_K2oRNJI9QNSiOXPZ-MfuDLusFNAws8sRUjbD3pZWeDpyH_f512MQpzIW00BkyI/s1600/IMAG0411.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKlRfGqKgYKbBmrcDCjZncoYoSdkuS86uKsFkdvXGh6XPJwaMWKiRoOMf5PlGTvDR-BThQYjI3FZiw_K2oRNJI9QNSiOXPZ-MfuDLusFNAws8sRUjbD3pZWeDpyH_f512MQpzIW00BkyI/s320/IMAG0411.jpg" /></a><br/>Minimal config</div>
<br>
The GPIO can be managed with <a href="http://pi4j.com/" target="pi4j">PI4J</a>, works like a charm.
Example:
<pre>
----------------------------------------------------
HARDWARE INFO
----------------------------------------------------
Serial Number : 00000000a36c8782
CPU Revision : 7
CPU Architecture : 7
CPU Part : 0xb76
CPU Temperature : 49.8
CPU Core Voltage : 1.2
MIPS : 697.95
Processor : ARMv6-compatible processor rev 7 (v6l)
Hardware Revision : 000e
Is Hard Float ABI : true
Board Type : ModelB_Rev2
----------------------------------------------------
MEMORY INFO
----------------------------------------------------
Total Memory : 459505664
Used Memory : 240529408
Free Memory : 219484160
Shared Memory : 0
Memory Buffers : 20328448
Cached Memory : 141778944
SDRAM_C Voltage : 1.2
SDRAM_I Voltage : 1.2
SDRAM_P Voltage : 1.23
----------------------------------------------------
OPERATING SYSTEM INFO
----------------------------------------------------
OS Name : Linux
OS Version : 3.6.11+
OS Architecture : arm
OS Firmware Build : 4f9d19896166f46a3255801bc1834561bf092732 (clean) (release)
OS Firmware Date : Sep 1 2013 23:31:02
----------------------------------------------------
JAVA ENVIRONMENT INFO
----------------------------------------------------
Java Vendor : Oracle Corporation
Java Vendor URL : http://java.oracle.com/
Java Version : 1.7.0_40
Java VM : Java HotSpot(TM) Client VM
Java Runtime : Java(TM) SE Runtime Environment
----------------------------------------------------
NETWORK INFO
----------------------------------------------------
Hostname : raspberrypi
IP Addresses : 192.168.1.251
FQDN : raspberrypi.att.net
Nameserver : 192.168.1.254
----------------------------------------------------
CODEC INFO
----------------------------------------------------
H264 Codec Enabled: true
MPG2 Codec Enabled: false
WVC1 Codec Enabled: false
----------------------------------------------------
CLOCK INFO
----------------------------------------------------
ARM Frequency : 700000000
CORE Frequency : 250000000
H264 Frequency : 0
ISP Frequency : 250000000
V3D Frequency : 250000000
UART Frequency : 3000000
PWM Frequency : 0
EMMC Frequency : 100000000
Pixel Frequency : 108000000
VEC Frequency : 0
HDMI Frequency : 163683000
DPI Frequency : 0
</pre>
The first goal will be to have such a device running in the chart table, reading the NMEA Data (connected on the NMEA Station through its serial port, read with GPIO, as mentioned above), and re-broadcasting the data on HTTP, TCP or UDP. The re-broadcasting part has been tested (see <a href="https://code.google.com/p/navigation-desktop/wiki/NewsPage" target="gc">here</a>), with logged data.
<br/>
Next:
<ul>
<li type="disc">Connect the serial port, and read it from Pi4J</li>
<li type="disc">Create an ad-hoc network <b><i>FROM</i></b> the Raspberry PI</li>
</ul>
This way, several applications can use the NMEA Data, simultaneously. It has been tested with the <a href="https://code.google.com/p/navigation-desktop/" target="gc">NMEA Console</a>, and <a href="http://opencpn.org" target="oc">OpenCPN</a>, with TCP and UDP. The HTTP re-broadcast can be used from an HTML5 browser, from a laptop or a tablet, connected on the boat's ad-hoc network.
<div class="separator" style="clear: both; text-align: center;"><a href="http://donpedro.lediouris.net/software/img/html5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://donpedro.lediouris.net/software/img/html5.png" width="260" height="170"/></a><br>HTML5 NMEA Console, on a tablet</div>Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-9658133246762316292013-08-21T04:34:00.001-07:002013-08-21T04:35:10.789-07:00South California Free AnchoragesWorking on it. There is <a href="http://www.blueanarchy.org/cruising/" target="ba">this site</a>, quite interesting, and I'm trying to use Google Maps as well.
<p style="text-align: center;">
<iframe style="float: none;" width="450" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps/ms?msid=202112525371982675880.0004e47337adfe52306ee&msa=0&ie=UTF8&t=k&ll=37.011326,-121.673584&spn=3.070309,4.943848&z=7&output=embed"></iframe><br /><small>View <a href="https://maps.google.com/maps/ms?msid=202112525371982675880.0004e47337adfe52306ee&msa=0&ie=UTF8&t=k&ll=37.011326,-121.673584&spn=3.070309,4.943848&z=7&source=embed" style="color:#0000FF;text-align:left">Free anchorages</a> in a larger map</small>
</p>
More to come soon, stay tuned.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-72245091044633805232013-07-06T14:16:00.000-07:002013-07-06T14:16:13.434-07:00Part of Navigatrix!As of July 3, 2013, the Weather Wizard is part of <a href="http://navigatrix.net/viewtopic.php?f=3&t=399" target="Navigatrix">Navigatrix</a>! Cool recognition ;0).
And the user manual is now available directly from the soft, as a pdf file, downloadable from the Internet.
<a href="http://www.lulu.com/shop/olivier-le-diouris/weather-wizard-user-manual/paperback/product-20094204.html" target="lulu">Lulu.com</a> still provides the binded version of the document.Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0tag:blogger.com,1999:blog-3708577323717493709.post-5235097731452182422013-07-04T11:58:00.000-07:002013-07-09T08:40:41.899-07:00Spot GRIB Requestsaildocs provides support for the Spot GRIB requests. Spot requests returns forecasts for a given location. Let's say you just dropped the hook, and you want to know what your night is going to look like...
<br>
If you send an email to query@saildocs.com, with a body like this:
<pre>
send spot:37.5N,122.5W|5,3|PRMSL,WIND,RAIN
</pre>, you will receive a response like that one:
<pre>
Data extracted from file gfs130704-12z.grb dated 2013/07/04 16:52:56
request code: spot:37.5N,122.5W|5,3|PRMSL,WIND,RAIN
Forecast for 37°30N 122°30W (see notes below)
Date Time PRESS WIND DIR RAIN
utc hPa kts deg mm/h
----------- ------ ----- --- ----
07-05 00:00 1005.7 9.8 288 0.0
07-05 03:00 1005.7 11.5 297 0.0
07-05 06:00 1006.8 12.9 302 0.0
07-05 09:00 1006.7 13.0 303 0.0
07-05 12:00 1006.7 12.6 303 0.0
07-05 15:00 1007.0 11.7 299 0.0
07-05 18:00 1007.7 10.3 280 0.0
07-05 21:00 1007.2 11.4 270 0.0
... etc
</pre>
This is "human readable", as they call it, but not that catchy, hey?
<br/>
The cool thing is that this content can be parsed, using basic regular expressions.
<br>
If you drop the content of the request's response in the box below, you will have a chance to render it visually.
<br>
<small><a href="http://donpedro.lediouris.net/software/html5/spot/spot.parser.html" target="_new">See in full</a></small>
<iframe src="http://donpedro.lediouris.net/software/html5/spot/spot.parser.html" width="510" height="600"></iframe>
<br>
The browser you use must support HTML5 for that.
Olivhttp://www.blogger.com/profile/06171035084159450627noreply@blogger.com0