Skip to content

Instantly share code, notes, and snippets.

@joefaron
Last active April 25, 2023 16:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joefaron/c8362025d84075a0de12773c0616ff2b to your computer and use it in GitHub Desktop.
Save joefaron/c8362025d84075a0de12773c0616ff2b to your computer and use it in GitHub Desktop.
<?php
// host on own server, just replace getUrl() to properly get/cache html from magicseaweed which has closed down it's api
// create custom "My Data" function that calls this script.. works nice.
// https://developer.lametric.com/applications/createdisplay#create-popup
// Lametric TIME clock custom app for displaying surf swell, tide, sea temp data..
// smart clock: https://lametric.com/en-US
/* example return: (displays current sea temp, current swell, current wind, next best day in next 4 days)
{"frames":[{"text":"60\u00b0 sea","icon":10497},{"text":"9a 2.6f","icon":19478},{"text":"8 se","icon":20015},{"text":"Fri 6a","icon":7756},{"text":"3.1f\u26054","icon":19479},{"text":"8a .2f","icon":19480},{"index":6,"chartData":[0,0,1,3,4,6,7,8]},{"text":"3p 2.6f","icon":19481}]}
*/
$html=getUrl("https://magicseaweed.com/Cottons-Surf-Report/4899/",3600*12);//cache the curl call for 12 hours..
$s=query($html,'//*[@class="list-group-item"]');
foreach($s as $ss){$c=0;
foreach($ss->getElementsByTagName('strong') as $span){$c++;
if($c==2)$sea_temp=trim($span->nodeValue);
}
}
$e=explode("forecast: ",$html);
$ee=explode(",\n",$e[1]);
$forecast=$ee[0];
$forecasts=json_decode($forecast,1);
foreach($forecasts as $forecast){
//get timestamp
if($forecast['threeHourTimeText']=='12am'||$forecast['threeHourTimeText']=='3am'||$forecast['threeHourTimeText']=='9pm'){//skip these times
continue;
}elseif($forecast['timestamp'] > time()+(86400*4)){
break;
}
$diff=abs($forecast['timestamp']-time());
$forecast_diffs[$diff]=$forecast;
//get highest rating in next 4 days?
$rating=getRating($forecast);
if($rating > $highest_rating){
$highest_rating=$rating;
$best_forecast=$forecast;
}
}
//take closest time
ksort($forecast_diffs);
foreach($forecast_diffs as $forecast){
$next_forecast=$forecast;break;
}
$icons=array(
'water_temp'=>10497,
'flame'=>7756,
'wave'=>8652,
'low_tide'=>19480,
'high_tide'=>19481,
'wind'=>864,
'beach'=>386,
'star'=>635,
'1star_wave'=>19476,//red
'2star_wave'=>19477,//orange
'3star_wave'=>19478,//yellow/green
'4star_wave'=>19479,//green
'5star_wave'=>19361,//blue
'wind_s'=>20001,
'wind_n'=>20002,
'wind_w'=>20003,
'wind_e'=>20010,
'wind_ne'=>20011,
'wind_nw'=>20013,
'wind_sw'=>20014,
'wind_se'=>20015,
);
function getRating($forecast){
$ret= $forecast['solidRating']+($forecast['fadedRating']/2);
//instead make it range from 0-9? easier display..
if($ret<1)$ret=1;
return $ret;
}
function forecastToNice($f,$is_best=0,$part=0,$icons){
$nice=$f['en_threeHourTimeText'];
//strip last character off.. always an "m"
$nice=substr($nice,0,-1);
if($is_best){//need to add in date to front? whats shortest? 2 letter day? MO, TU, WE, TH, FR, SA, SU
$nice=date("D", $f['timestamp'])." ".$nice;
}
$swell=$f['swell']['minBreakingHeight'];
$swell=str_replace("0.",".",round( ($f['swell']['absMinBreakingHeight']+$f['swell']['absMaxBreakingHeight'])/2,1)+0);
$swell.="f";
if($part==1) {
$nice = "";
$rating = getRating($f);//if it's a .5, instead display a plus?
if (strstr($rating, ".5")) {
$rating = "☆".str_replace(".5", "", ceil($rating));// half star and round it up.
}else{
$rating="★".$rating;
}
$nice .= " $swell$rating";
$nice=trim($nice);
}elseif(!$is_best){
$nice.=" $swell";
}
$text= $nice;
$icon=$icons[getRating($f)."star_wave"];
if($is_best && $part==0) {
$icon = $icons['flame'];
}
return array('text'=>$text,
'icon'=>$icon,
);
}
if(is_numeric($sea_temp))
$frames[]=array(
'text'=>$sea_temp."° sea",
'icon'=>$icons['water_temp'],
);
$frames[]=forecastToNice($next_forecast,0,0,$icons);
// get current wind
$wind=strtolower($next_forecast['wind']['compassDirection']);
//gust
if($next_forecast['wind']['gusts']&&$next_forecast['wind']['gusts']!=$next_forecast['wind']['speed']){
$gust="-".$next_forecast['wind']['gusts'];
}
$wind_text=$next_forecast['wind']['speed'].$gust."";
//if its three characters strip first char
if(strlen($wind)==3){
$wind=substr($wind,1);
}
$frames[]=array(
'text'=> $wind_text." ".$wind,
'icon'=>$icons['wind_'.$wind]?$icons['wind_'.$wind]:$icons['wind'],
);
$frames[]=forecastToNice($best_forecast,1,0,$icons);
$frames[]=forecastToNice($best_forecast,1,1,$icons);
$e=explode("tide: ",$html);
$ee=explode(",\n",$e[1]);
$tide=$ee[0];
$tides=json_decode($tide,1);
$time=strtotime(date("Y-m-d H").":00:00");//get current hour..
foreach($tides as $date=>$tide){
// get current tide and then the next 8 hrs? for tide chart?
foreach($tide['levels'] as $level){
if($last_shift){
if($last_shift < $level['shift']){
$level['direction']="up";
}else{
$level['direction']="down";
}
}
if($time > $level['unixtime']){//skip
}elseif($time+(3600*8) > $level['unixtime']) {
if(!$current_tide){
$current_tide=$level;// up or down?
}
$tideChart[] = (round($level['shift'], 2) + 0);
$last_tide=$level;
}
$last_shift=$level['shift'];
}
break;
}
//get the min/max, and normalize it from 1-8
$min=min($tideChart);
$max=max($tideChart);
$range=$max-$min;
foreach($tideChart as $k=>$v){
$chartData[]=round((($v-$min)/$range)*8);
}
$frames[]=tideToNice($current_tide,$icons);
$frames[]=array(
"index"=>count($frames),
"chartData"=>$chartData
);
// display the final tide?
$frames[]=tideToNice($last_tide,$icons);
echo json_encode(array("frames"=>$frames));
function tideToNice($tide,$icons){
$ft=str_replace("0.",".",(round($tide['shift'],1)+0));
return array(
"text"=>rtrim(date("ga",$tide['unixtime']),"m")." ".$ft."f",
"icon"=>($tide['direction']=="up")?$icons['high_tide']:$icons['low_tide']
);
}
function query($html,$path){
$dom = new DOMDocument();
@$dom->loadHTML($html);
$x = new DOMXPath($dom);
// }
return $x->query($path);
}
function getUrl($url,$cache_time){
// my code saves url to memcache for $cache_time.... don't want to keep calling magicseaweed, as they may rate limit you
return file_get_contents($url);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment