Last active
July 20, 2016 01:44
-
-
Save mumblepins/34ea03f02f03aa384506df11a6a3441d to your computer and use it in GitHub Desktop.
UDP WeatherStation (WS-1400-IP) Parser->Influxdb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import socket, sys, json, urllib2 | |
from pprint import pprint | |
from urlparse import parse_qs, urlparse | |
import time | |
import calendar | |
from math import exp,log, pow, sqrt | |
import requests | |
#pp = pprint.PrettyPrinter(indent=4) | |
UDP_PORT = 30303 | |
sock = socket.socket(socket.AF_INET, # Internet | |
socket.SOCK_DGRAM) # UDP | |
sock.bind(("10.0.0.255", UDP_PORT)) | |
tempString="" | |
database="WeatherDB" | |
n=0 | |
def int_float_str(s): | |
if s.lstrip('-').isdigit(): | |
return int(s) | |
else: | |
try: | |
return float(s) | |
except ValueError: | |
return s | |
def c_to_f(c): | |
return c*1.8+32.0 | |
def f_to_c(f): | |
return (f-32.0)/1.8 | |
def calc_rh(temp,dewpoint): | |
temp=f_to_c(temp) | |
dewpoint=f_to_c(dewpoint) | |
rh=100.0*(exp((17.625*dewpoint)/(243.04+dewpoint))/exp((17.625*temp)/(243.04+temp))) | |
return rh | |
def calc_dewpoint(temp,rh): | |
temp=f_to_c(temp) | |
dewpoint =243.04*(log(rh/100.0)+((17.625*temp)/(243.04+temp)))/(17.625-log(rh/100.0)-((17.625*temp)/(243.04+temp))) | |
return c_to_f(dewpoint) | |
def calc_heatindex(temp,rh): | |
hi=(-42.379 + 2.04901523*temp + 10.14333127 * rh - 0.22475541*temp*rh | |
- 6.83783E-3*temp*temp- 5.481717E-2*rh*rh + 1.22874E-3*temp*temp*rh | |
+ 8.5282E-4*temp*rh*rh - 1.99E-6*temp*temp*rh*rh) | |
print hi | |
print temp | |
print rh | |
return max(hi,temp) | |
def calc_windchill(temp,windspeed): | |
wc=35.74+0.6215*temp-35.75*pow(windspeed,0.16)+0.4275*temp*pow(windspeed,0.16) | |
print wc | |
return min(wc,temp) | |
def calc_feelslike(temp,rh,windspeed): | |
if temp>77: | |
return calc_heatindex(temp,rh) | |
elif temp<51: | |
return calc_windchill(temp,windspeed) | |
else: | |
return temp | |
def realfeel(W, #windspeed mph | |
A, #pressure mb | |
T, # temperature F | |
UV, # UV Index | |
D, # Dew Point F | |
P2, # preciptation Factor from 0-5 | |
): | |
if W<4: | |
Wa=W/2+2 | |
elif W<56: | |
Wa=W | |
else: | |
Wa=56 | |
# print Wa | |
WSP2=(80-T)*(0.566+0.25*sqrt(Wa)-0.0166*Wa)*((sqrt(A/10))/10) | |
WSP1=sqrt(W)*((sqrt(A/10))/10) | |
# print WSP2 | |
SI2 = UV # UV index is already in hectoJoules/m^2 ? | |
if D >= (55+sqrt(W)): | |
Da=D | |
else: | |
Da=55+sqrt(W) | |
# print Da | |
H2=(Da-55-sqrt(W))**2/30 | |
# print H2 | |
if T>= 65: | |
MFT=80-WSP2+SI2+H2-P2 | |
else: | |
MFT=T-WSP1+SI2+H2-P2 | |
return MFT | |
while True: | |
data, addr = sock.recvfrom(1024) # buffer size is 1024 byte | |
if data: | |
print "yes" | |
influxString="" | |
data=parse_qs(data) | |
data=dict((k,int_float_str(v[0])) for k, v in data.iteritems()) | |
data.pop('ID', None) | |
data.pop('PASSWORD', None) | |
data.pop('action', None) | |
data.pop('realtime', None) | |
data.pop('rtfreq', None) | |
data.pop('softwaretype', None) | |
dt=time.strptime(data['dateutc'], "%Y-%m-%d %H:%M:%S") | |
timestamp= calendar.timegm(dt) | |
# pprint(data) | |
temp=data.pop('indoortempf') | |
humidity =data.pop('indoorhumidity') | |
dewpoint=calc_dewpoint(temp,humidity) | |
influxString += "temp,zone=indoors,type=dry value={} {}\n".format(temp,timestamp) | |
influxString += "humidity,zone=indoors value={} {}\n".format(humidity,timestamp) | |
influxString += "temp,zone=indoors,type=dewpoint value={} {}\n".format(dewpoint,timestamp) | |
temp=data.pop('tempf') | |
dewpoint=data.pop('dewptf') | |
humidity=data.pop('humidity') | |
windspeed=data.pop('windspeedmph') | |
barometer=data.pop('baromin') | |
UVI=data.pop('UV') | |
rainin=data.pop('rainin') | |
feelslike=calc_feelslike(temp,humidity,windspeed) | |
rftemp=realfeel(windspeed,33.8639*barometer,temp,UVI,dewpoint,1 if rainin>0 else 0) | |
influxString += "temp,zone=outdoors,type=dry value={} {}\n".format(temp,timestamp) | |
influxString += "humidity,zone=outdoors value={} {}\n".format(humidity,timestamp) | |
influxString += "temp,zone=outdoors,type=dewpoint value={} {}\n".format(dewpoint,timestamp) | |
influxString += "temp,zone=outdoors,type=feelslike value={} {}\n".format(feelslike,timestamp) | |
influxString += "temp,zone=outdoors,type=realfeel value={} {}\n".format(rftemp,timestamp) | |
influxString += "temp,zone=outdoors,type=windchill value={} {}\n".format(data.pop('windchillf'),timestamp) | |
influxString += "wind,type=speed,sub_type=const value={} {}\n".format(windspeed,timestamp) | |
influxString += "wind,type=speed,sub_type=gust value={} {}\n".format(data.pop('windgustmph'),timestamp) | |
influxString += "wind,type=dir value={} {}\n".format(data.pop('winddir'),timestamp) | |
influxString += "rain,timescale=current value={} {}\n".format(rainin,timestamp) | |
influxString += "rain,timescale=daily value={} {}\n".format(data.pop('dailyrainin'),timestamp) | |
influxString += "rain,timescale=weekly value={} {}\n".format(data.pop('weeklyrainin'),timestamp) | |
influxString += "rain,timescale=monthly value={} {}\n".format(data.pop('monthlyrainin'),timestamp) | |
influxString += "rain,timescale=yearly value={} {}\n".format(data.pop('yearlyrainin'),timestamp) | |
influxString += "sun,type=uv value={} {}\n".format(UVI,timestamp) | |
influxString += "sun,type=radiation value={} {}\n".format(data.pop('solarradiation'),timestamp) | |
influxString += "barometer value={} {}\n".format(barometer,timestamp) | |
influxString += "battery_status value={} {}".format(data.pop('lowbatt'),timestamp) | |
print influxString | |
try: | |
res =requests.post(url='http://localhost:8086/write?db='+database+'&precision=s',data=influxString) | |
# print res | |
print res.status_code | |
# print res.headers | |
# print res.text | |
except: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment