CR10X上传到Weather Underground(等) _Campbellsci论坛问答

我有一些Perl代码要从CR10X上传到Weather Underground,如果有人感兴趣的话,可以使用NL100和Linux盒子。它有点丑,但价格是对的。8*)

Perl是相当标准的,所以如果有人想进行适当的修改,它应该在Windows或OSX上运行。

CR10X上传到Weather Underground(等)
_Campbellsci论坛问答

我在管理Centos,这并不重要。我有一个crontab条目,看起来像:

(Wanda The Weather Woman是COM300语音调制解调器,当您拨打所附电话时,它会读取天气报告)。

该代码还上传到CWOP,跟踪感兴趣的值的最大/最小值,发送每日报告和“;有趣的现象“;电子邮件等。

要使用这段代码,你必须稍微修改一下,因为你的设置与我的不同,如果你对这段代码的各个部分如何工作有任何问题,请随时在这里提问,我一直在添加和改进。

我正在更新的Weather Underground页面位于:
http://www.wunderground.com/cgi-bin/findweather/getForecast?query=pic


享受


#!/usr/bin/perl-w
#
#wanda.pl-从wanda获取天气数据并上传到weather Underground
#
#修订版5.1修复了真实的CSI浮点转换,副本来自Watson 2009年1月2日WPNS

严格使用;
使用插座;
使用XML::简单;
使用数据::自卸车;
使用邮件::Sendmail;
使用LWP;
使用Net::FTP;

要求“/home/Wanda/SimpleGet.pl”;;

my$RevString=“;Wanda.pl_rev_5_1_02/01/09_WPNS”;;


使用常数WakeUpCount=>;2; # 发送CR多少次才能唤醒
使用常数WakeUpDelay=>;1; # 每次唤醒需要等待多少秒
使用常量ReplyDelay=>;1; # 发送后要等待多少秒
使用常量FALSE=>;0; # 不知道为什么Perl没有定义这些
使用常量TRUE=>!错误的

$| = 1; # 打开自动冲洗以进行正常输出

我的($sec,$min,$hour,$mday,$mon,$year,
$wday,$yday,$isdst)=当地时间;

printf(“\n------------------\n%02i:%02i%s\n”,$hour,$min,$RevString);

#打印$LWP::版本;

#从XML文件读取内存
my$Wanda_Mem=XMLin();
#打印转储程序($Wanda_Mem);
$Wanda_Mem->;{RevString}=$RevString;

#初始化主机和端口
我的$port=8097;
我的$服务器=“";;
我的$packed_ip=gethostbyname(“wanda.geekho.com”);
if(已定义$packed_ip)
{
$server=inet_ntoa($packed_ip);
printf(“Wanda IP:%s”,$server);
}
否则,Wanda DNS查找失败

我的$watson_port=8094;
我的$watson_server=“";;
我的$watson_packed_ip=gethostbyname(“watson.geekho.com”);
if(已定义$watson_packed_ip)
{
$watson_server=inet_ntoa($watson_packed_ip);
printf(“Watson IP:%s”,$Watson_server);
}
否则,Watson DNS查找失败

我的$cwop_port=14580;
#我的$cwop_port=23;
我的$cwop_server=“”";;
my$cwop_packed_ip=gethostbyname(“cwop.aprs.net”);
if(定义的$cwop_packed_ip)
{
$cwop_server=inet_ntoa($cwop_packed_ip);
printf(“CWOP IP:%s\n”,$CWOP_server);
}
否则{die";CWOP DNS查找失败!\n"!}

我的$行;

printf(“套接字”);
#创建套接字,连接到端口
套接字(socket、PF_INET、SOCK_STREAM,(getprotobyname('tcp'))[2])
或死亡”;无法创建套接字$!\n〃;;
printf(“创建”);
connect(SOCKET,sockaddr_in($port,inet_aton($server))
或死亡”;无法连接到端口$port!\n〃;;
printf(“打开”);
setsockopt(插座,SOL_SOCKET,SO_REUSEADDR,1);
printf(“设置!”);

printf(“传输”);
for($loop=0;$loop<;WakeUpCount;$loop++)
{
发送(SOCKET,“\r”,0);
printf(“.”);
睡眠(1);
}
printf(“完成!”);

printf(“Rx延迟”);
对于($loop=0;$loop<;(唤醒延迟*唤醒计数)$循环++)
{
printf(“.”);
睡眠(1);
}
printf(“完成!”);
recv(插座,$line,512,0);
printf(“%i字节:$line\n”,长度($line));

if(length($line)!=(3*唤醒次数))
{
printf(“错误唤醒!\n”);
模具“;唤醒响应错误!\n〃;;
}

#发送解锁
printf(“解锁…”);
发送(SOCKET,“1234L\r”,0);
睡眠(ReplyDelay);
recv(插座,$line,512,0);
printf(“$line\n”);

#选择FS A
睡眠(ReplyDelay);
printf(“FSA…”);
发送(SOCKET,“1A\r”,0);
睡眠(ReplyDelay);
recv(插座,$line,512,0);
printf(“$line\n”);

#发送“;J”表示;命令,以选择“”的输出;K”的情况下;
printf(“选择…”);
发送(SOCKET,“2413J\r”,0);
睡眠(ReplyDelay);
recv(插座,$line,512,0);
printf(“$line\n”);

#发送“;J”表示;配置

发送(SOCKET,“\x0\x40\x00\x03\x05\x06\x07\x09\x0a\x0d\x2e\x33\x01\x29\x00”,0);
睡眠(ReplyDelay);
recv(插座,$line,512,0);
#printf(“$line\n”);
printf(“获取%i字节:”,长度($line));
对于($loop=0;$loop<;长度($line)$循环++)
{
printf(“%02x”,ord(substr($line,$loop,1));
}
printf(“\n”);

#使用“转储”;K”的情况下;
printf(“转储…”);
发送(SOCKET,“K\r”,0);
睡眠(ReplyDelay);
recv(插座,$line,512,0);
#printf(“$line\n”);
printf(“获取%i字节:”,长度($line));
对于($loop=0;$loop<;长度($line)$循环++)
{
printf(“%02x”,ord(substr($line,$loop,1));
}
printf(“\n”);

if(length($line)!=57)
{
printf(“错误-行长度不是57!\n”);
模具“;倾卸管线长度!\n〃;;
}
如果(substr($line,0.3)ne”;K\r\n“)
{
printf(“错误-标头不正确!\n”);
模具“;K标题!\n〃;;
}
如果(substr($line,53.2)ne“;\x7f\x00”)
{
printf(“错误-错误的终止符!\n”);
模具“;K终结者!\n〃;;
}

#拔出时间戳
my$minutes=单词(substr($line,3,1))*256+单词(subster($line),4,1));

#把它们分成我们关心的部分
my$SlrW=CSIFPF($line,9);
我的$AirTF=CSIFPF($line,13);
my$RH=CSIFPF($line,17);
我的$BAR_inHg=CSIFPF($line,21);
my$WS_mph=CSIFPF($line,25);
my$WindDir=CSIFPF($line,29);
我的$DewPoint=CSIFPF($line,33);
my$Rain_Day=CSIFPF($line,37);
#现在四舍五入到百分之一英寸
$Rain_Day=(int(($Rain_Day*100)+0.5)/100);
my$WS_Max=CSIFPF($line,41);
my$Vcc=CSIFPF($line,45);
my$Day=int(CSIFPF($line,49));
#我的$Day=$yday+1;

#并打印出来给操作员
printf(“时间%02i:%02i\t”,$分钟/60,$分钟%60);
printf(“温度:%3.0f\t”,$AirTF);
printf(“相对湿度:%3.0f\t\t”,$RH);
printf(“露点:%3.0f\n”,$Dewpoint);
printf(“WSpeed:%3.0f\t”,$WS_mph);
printf(“WDir:%3.0f\t”,$WindDir);
printf(“WSmax:%3.0f\t”,$WS_Max);
printf(“雨:%5.2f\n”,$Rain_Day);
printf(“太阳能:%4.0f\t”,$SlrW);
printf(“气压:%5.2f\t”,$BAR_inHg);
printf(“Vcc:%5.2f\t”,$Vcc);
printf(“天:%i\n”,$Day);

#结束通信
睡眠(ReplyDelay);
printf(“结束…”);
发送(SOCKET,“E\r”,0);
recv(插座,$line,512,0);
printf(“$line”);

关闭SOCKET或模具”;关闭:$";;

#电源故障的东西
如果(($Vcc>;12.85)&&($Wanda_Mem->;{PowerFailFlag}=TRUE)
{
我的$MailPowerOKString=“”;旺达检测到交流电回流!\n〃;;
$MailPowerOKString.=sprintf(“%02i:%02i\n”时的%5.2f伏特,$Vcc,$minute/60,$minute%60);

我的%mailpowerok=(
收件人=>;'person@domain.com',
发件人=>;'dummy@geekho.com',
主题=>";电源返回&”;,
消息=>$MailPowerOK字符串,
#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

sendmail(%mailpowerok)或die$Mail::sendmail::error;

打印“;好的。日志说:“$邮件::发送邮件::日志;

printf(“%s”,$MailPowerOKString);

$Wanda_Mem->;{PowerFailFlag}=FALSE;#并为下次设置标志
}
elsif(($Vcc<;12.80)&&($Wanda_Mem->;{PowerFailFlag}==FALSE))
{

$MailPowerFailString.=sprintf(“%02i:%02i\n”时的%5.2f伏特,$Vcc,$minute/60,$minute%60);

我的%mailpowerfail=(

发件人=>;'dummy@geekho.com',
主题=>";电源故障&”;,
消息=>$MailPowerFailString(邮件电源故障字符串),
#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

打印“;好的。日志说:“$邮件::发送邮件::日志;

printf(“%s”,$MailPowerFailString);

$Wanda_Mem->;{PowerFailFlag}=真;#并为下次设置标志
}


如果(($Vcc>;12.00)&&($Wanda_Mem->;{BatteryCCriticalFlag}=TRUE)
{
my$MailBatteryOKString=“”;Wanda检测到电池正常!\n〃;;
$MailBatteryOKString.=sprintf(“%02i:%02i\n”时的%5.2f伏特,$Vcc,$minute/60,$minute%60);

我的%mailbatteryok=(

发件人=>;'dummy@geekho.com',
主题=>";电池正常&”;,

#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

sendmail(%mailbatteryok)或die$Mail::sendmail::error;

打印“;好的。日志说:“$邮件::发送邮件::日志;

printf(“%s”,$MailBatteryOKString);

$Wanda_Mem->;{BatteryCCriticalFlag}=FALSE;#并为下次设置标志
}
elsif(($Vcc<;11.50)&&($Wanda_Mem->;{BatteryCCriticalFlag}==FALSE))
{
my$MailBatteryCCriticalString=“”;Wanda检测到电池电量严重!\n〃;;
$MailBatteryCCriticalString.=sprintf(“%02i:%02i\n”时的%5.2f伏特,$Vcc,$minute/60,$minute%60);

我的%mailbatteryccritical=(

发件人=>;'dummy@geekho.com',
主题=>";电池严重&”;,

#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

sendmail(%mailbatteryccritical)或die$Mail::sendmail::error;

打印“;好的。日志说:“$邮件::发送邮件::日志;

$Wanda_Mem->;{BatteryCCriticalFlag}=真;#并为下次设置标志
}

if($Wanda_Mem->;{WindDecade}<;int($WS_Max/10))
{
我的$MailWind=“;风速增加!\n〃;;
$MailWind.=sprintf(“%02i:%02i\n时每小时%5.2f英里数”,$WS_Max,$minute/60,$minute%60);


我的%mailwindnotice=(
#收件人=>;'user@domain.com',
收件人=>;'MailingList@mail.domain.com',
发件人=>;'dummy@geekho.com',
主题=>";风速&”;,
消息=>$MailWind公司,
#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

sendmail(%mailwindnotify)或die$Mail::sendmail::error;

打印“;好的。日志说:“$邮件::发送邮件::日志;

printf(“%s”,$MailWind);

$Wanda_Mem->;{WindDecade}=int($WS_Max/10);#还记得你送的那十年
}


if($Wanda_Mem->;{RainReport}<;int($Rain_Day))
#如果($Wanda_Mem->;{RainReport}<;$Rain_Day)
{
我的$MailRain=“;又下了一英寸雨!\n〃;;
$MailRain.=sprintf(“%02i:%02i\n”,$Rain_Day,$minutes/60,$minute%60时的总长度为%5.2f英寸);


我的%mailrainnotice=(
#收件人=>;'user@domain.com',
收件人=>;'MailingList@mail.domain.com',
发件人=>;'dummy@geekho.com',
主题=>";降雨&”;,
消息=>$MailRain公司,
#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

sendmail(%mailrainnotify)或die$Mail::sendmail::error;

打印“;好的。日志说:“$邮件::发送邮件::日志;

#$Wanda_Mem->;{RainReport}=$Rain_Day;#记住你发的那个号码
$Wanda_Mem->;{RainReport}=int($Rain_Day);#记住你送的那一英寸
}

#计算最小/最大物料
如果($Wanda_Mem->;{TMax}<;$AirTF)
{$Wanda_Mem->;{TMax}=$AirTF}
如果($Wanda_Mem->;{TMin}>;$AirTF)
{$Wanda_Mem->;{TMin}=$AirTF}

如果($Wanda_Mem->;{RHMax}<;$RH)
{$Wanda_Mem->;{RHMax}=$RH}
如果($Wanda_Mem->;{RHMin}>;$RH)
{$Wanda_Mem->;{RHMin}=$RH}

如果($Wanda_Mem->;{BaroMax}<;$BAR_inHg)
{$Wanda_Mem->;{BaroMax}=$BAR_inHg}
如果($Wanda_Mem->;{BaroMin}>;$BAR_inHg)

如果($Wanda_Mem->;{SolarMax}<;$SlrW)
{$Wanda_Mem->;{SolarMax}=$SlrW}

如果($Wanda_Mem->;{WSMax}<;$WS_Max)
{$Wanda_Mem->;{WSMax}=$WS_Max}

如果($Wanda_Mem->;{Rain}<;$Rain_Day)
{$Wanda_Mem->;{Rain}=$Rain_Day}

$Wanda_Mem->;{计数器}++;

#打印转储程序($Wanda_Mem);

XMLout($Wanda_Mem,AttrIndent=>;1,OutputFile=>:“/home/Wanda/Wanda.xml&”);

#现在给我寄些邮件
#如果($minutes==0)
#如果午夜过去了(我们从昨天开始有大量的计数)
#if($Wanda_Mem->;{Counter}>;(10+$分钟*1.1))
if($Wanda_Mem->;{Day}!=$Day)
{

我的$MailString=“;昨天的天气,“;;
$MailString.=sprintf(“Julian%i:\n\n”,$Wanda_Mem->;{Day});
$MailString.=sprintf(最大温度:%3.0f华氏度,$Wanda_Mem->;{tMax});
$MailString.=sprintf(“\t最低温度:%3.0f\n\n”,$Wanda_Mem->;{tMin});
$MailString.=sprintf(最大湿度:%3.0f百分比,$Wanda_Mem->;{RHMax});
$MailString.=sprintf(“\t最小湿度:%3.0f\n\n”,$Wanda_Mem->;{RHMin});
$MailString.=sprintf(“\t最大气压计:%5.2f英寸汞柱,$Wanda_Mem->;{BaroMax});
$MailString.=sprintf(“\t最小气压计:%5.2f\n\n”,$Wanda_Mem->;{BaroMin});
$MailString.=sprintf(“\t最大太阳能功率:每平方米%4.0f瓦\n\n&”,$Wanda_Mem->;{SolarMax});
$MailString.=sprintf(“\t峰值风速:%3.0f英里/小时\n\n&”,$Wanda_Mem->;{WSMax});
$MailString.=sprintf(“\t降雨量:%4.2f英寸\n\n&”,$Wanda_Mem->;{Rain});
$MailString.=sprintf(“%s%i/1440个样本,Vcc:%5.2f\n”,$RevString,$Wanda_Mem->;{Counter},$Vcc);

我的%mail=(
#收件人=>;'user@domain.com',
收件人=>;'MailingList@mail.domain.com',
发件人=>;'dummy@geekho.com',
主题=>";每日天气摘要”;,
消息=>$邮件字符串,
#smtp=>;'mail.domain.com',
smtp=>;'192.168.1.90',
);

sendmail(%mail)或die$mail::sendmail::error;

打印“;好的。日志说:“$邮件::发送邮件::日志;

printf(“%s”,$MailString);

#现在重新设置第二天的总数
$Wanda_Mem->;{TMax}=0.0;
$Wanda_Mem->;{TMin}=999.9;
$Wanda_Mem->;{RHMax}=0.0;
$Wanda_Mem->;{RHMin}=9999.9;
$Wanda_Mem->;{BaroMax}=0.0;
$Wanda_Mem->;{BaroMin}=9999.9;
$Wanda_Mem->;{SolarMax}=0.0;
$Wanda_Mem->;{WSMax}=0.0;
$Wanda_Mem->;{Rain}=0.0;
$Wanda_Mem->;{计数器}=0;
$Wanda_Mem->;{Day}=$Day;#还记得我们今天做的吗
$Wanda_Mem->;{WindDecade}=3#为第二天的风速报告设置阈值
$Wanda_Mem->;{RainReport}=0;#零降雨报告

XMLout($Wanda_Mem,AttrIndent=>;1,OutputFile=>:“/home/Wanda/Wanda.xml&”);

}

#现在创建HTTP GET字符串:

my$GetString=“”;http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php";
$GetString.=";?ID=IPINECAY2“密码=秘密”;;
$GetString.="&动作=更新原始”;;
$GetString.=sprintf(“软件类型=%s”,$RevString);
$GetString.=sprintf(“-dateutc=%04i-%02i-%02i+%02i:%02i”,$year+1900,$mon,$mday,$minutes/60,$min分钟%60);
$GetString.=sprintf(“tempf=%03.0f”,$AirTF);
$GetString.=sprintf(“湿度=%03.0f”,$RH);
$GetString.=sprintf(“-dewptf=%03.0f”,$DewPoint);
$GetString.=sprintf(“windspeedmph=%03.0f”,$WS_mph);
$GetString.=sprintf(“&winddir=%03.0f”,$winddir);
$GetString.=sprintf(“windgustmph=%03.0f”,$WS_Max);
$GetString.=sprintf(“dailyrainin=%05.2f”,$Rain_Day);
$GetString.=sprintf(“solarradiation=%04.0f”,$SlrW);
$GetString.=sprintf(“baromin=%05.2f”,$BAR_inHg);

#把它给我看,然后发给WxUnderground
printf(“WxUG:%i个字符:$GetString\n”,长度($GetString));
getprint(“$GetString”);

#=================================================================
#现在是cwop的东西,合并于06/23/08 WPNS
#现在创建输出字符串。注意(重新)使用getString
#来自文件http://www.wxqa.com/faq.html
#注意,其中一些数字在期末考试前需要做一些工作
#释放,因为他们不是很犹太。。。
#printf(“mins以%s\n”结尾,substr($min,(length($min)-1),1);
如果(substr($min,(length($min)-1),1)ne”;8〃)
{
#printf(“%02i:%02i-无CWOP\n”,$hour,$min);
模具“;在$hour:$min\n“;;
}

$GetString=“;DW9999〃;;#你的CW号码

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=gmtime时间;#现在我们想要GMT
$GetString.=sprintf(“@%02i%02i%02iz”,$mday,$hour,$min);#不管怎样,你忽略了我的时间
$GetString.=";2152.12N/07205.42W”;;#你在这里的位置,ddmm.hh,ddmm.h

$GetString.=sprintf(“/%03.0f”,$WS_mph);#风速(瞬时,而非平均!)

$GetString.=sprintf(“g…”);#阵风
$GetString.=sprintf(“t%03.0f”,$AirTF);#温度华氏度
$GetString.=sprintf(“P%03.0f”,($Rain_Day*100));#如果溢出怎么办?我得了4.32,所以不应该,但是。。。
如果($RH==100)
{$GetString.=sprintf(“h00”);}
其他的
{$GetString.=sprintf(“h%02.0f”,$RH);}
#来自http://www.csgnetwork.com/barcorrecthcalc.html
$GetString.=sprintf(“b%05.0f”,(($BAR_inHg+0.0219883866084310615)*33.86377526*10));#英寸汞柱(加上20英尺压力高度)转换为毫巴TENTHS
$GetString.=sprintf(“eCampbellSci_%s\r\n”,$RevString);#标识符

#给我看看
printf(“%i个字符:$GetString”,长度($GetString));

#现在打开与APRS服务器的连接

#创建套接字,连接到端口
套接字(socket、PF_INET、SOCK_STREAM,(getprotobyname('tcp'))[2])
或死亡”;无法创建套接字$!\n〃;;
printf(“创建”);
connect(SOCKET、sockaddr_in($cwop_port、inet_aton($cwop _server))
或死亡”;无法连接到端口$port!\n〃;;
printf(“打开”);
setsockopt(插座,SOL_SOCKET,SO_REUSEADDR,1);
printf(“设置!\n”);

#给我看看提示
recv(插座,$line,512,0);
printf(“%i字节:$line\n”,长度($line));

#发送登录信息
printf(“登录…”);
send(SOCKET,“user DW9999 pass-1 vers$RevString\r\n”,0);
recv(插座,$line,512,0);
printf(“$line\n”);

#发送字符串
printf(“发送…”);
send(SOCKET,“$GetString”,0);
#recv(插座,$line,512,0);
#printf(“$line\n”);

睡眠(3);
printf(“完成!”);

关闭SOCKET或模具”;关闭:$";;

#-----------------------------------
#将Campbell Scientific,Inc.浮点格式中的4个字节转换为浮点
子CSIFPF{
my($linein,$index)=@_;
#printf(“%02x%02x%02x%02x\n”,ord(substr($linein,$index,1)),ord(subtr($linein,$index+1,1)),ord[substr($linein,$index+2,1)],ord[subtr($linein,$index+3,1);
my$sign=(ord(substr($linein,$index,1))&0x80);
#printf(“符号%i\n”,$Sign);
my$index=((ord(substr($linein,$index,1))&0x7f)-64);
#printf(“指数%i\n”,$index);
my$尾数=((ord(substr($linein,$index+1,1);
#printf(“尾数%i\n”,$尾数);

if($符号==0)
{
return($尾数/(2**24))*(2**$指数)
}
其他的
{
return(0-($尾数/(2**24))*(2**$指数))
}
}

*最后更新者:wpns于2009年2月1日下午6:43*

新对话如下:

我使用的是上述软件的7.2版本,所以如果有兴趣,请给我打电话(在这里回复),我会发布最新的更新。

新对话如下:

我有一个“;愚蠢的问题;(请不要让我读Perl脚本…好吧,我浏览过了,但…)——你只上传了Current Conditions,而不是METAR和Aviation数据?

新对话如下:

哇!我认为我在下面论坛帖子中描述的方法对大多数非程序员来说更容易理解。

http://www.campbellsci.com/forum/messages.cfm?threadid=BC6B01A7-078A-156D-C34DA61A57C3E63E

新对话如下:

Dana,

格伦,

是的,考虑到LoggerNet已经在WinDoze机器上运行,我怀疑你是对的。

享受

分享到:

原文链接:,转发请注明来源!
海洋仪器网 仪器使用 CR10X上传到Weather Underground(等) _Campbellsci论坛问答
「CR10X上传到Weather Underground(等) _Campbellsci论坛问答」评论列表

发表评论