This repository has been archived by the owner on Jul 28, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsocketlogger.py
144 lines (121 loc) · 5.27 KB
/
socketlogger.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#
# Copyright (c) 2012 Tom Keffer <[email protected]>
#
# See the file LICENSE.txt for your full rights.
#
# $Revision: 1 $
# $Author: pobrien $
# $Date: 2016-01-14 08:00:00 -0500 (Thu, 14 Jan 2016) $
#
""" This driver connects to a socket (typically on localhost) and waits
for packet data. Once a new line comes into the socket, this will process
the data and submit the packet back to weewx.
Based on the hackulink driver, which was based on the weewx wmr100 driver
"""
import socket
import syslog
import time
import weedb
import weewx.drivers
import weeutil.weeutil
import weewx.wxformulas
def logmsg(dst, msg):
syslog.syslog(dst, 'SocketLogger: %s' % msg)
def loginf(msg):
logmsg(syslog.LOG_INFO, msg)
def logerror(msg):
logmsg(syslog.LOG_ERROR, msg)
def logdebug(msg):
logmsg(syslog.LOG_DEBUG, msg)
def loader(config_dict, engine):
station = SocketLogger(**config_dict['SocketLogger'])
return station
class SocketLogger(weewx.drivers.AbstractDevice):
""" Driver for the SocketLogger station. """
def __init__(self, **stn_dict) :
""" Initialize an object of type SocketLogger. """
self.host_ip = stn_dict.get('host_ip')
self.host_port = int(stn_dict.get('host_port'))
self.timeout = float(stn_dict.get('timeout'))
self.station_hardware = stn_dict.get('hardware')
self.lastrain = None
self.port = None
self.openPort()
def hardware_name(self):
return self.station_hardware
def openPort(self):
try:
loginf("Connecting to socket on %s port %s" % (self.host_ip, self.host_port) )
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(self.timeout)
self.socket.connect( (self.host_ip, self.host_port) )
except (socket.error, socket.timeout, socket.herror), ex:
logerror("Socket error while opening port %d to ethernet host %s." % (self.host_port, self.host_ip))
# Reraise as a weewx I/O error:
raise weewx.WeeWxIOError(ex)
except:
logerror("Unable to connect to host %s on port %d." % (self.host_ip, self.host_port))
raise
logdebug("Connected to host %s on port %d" % (self.host_ip, self.host_port))
self.port = self.socket.makefile()
def closePort(self):
self.port.close()
def check_rain(self, daily_rain_counter):
# *** DO NOT use the &rainin= data! ***
# Handle the rain accum by taking the &dailyrainin= reading ONLY.
# Then submit those minor increments of daily rain to weewx.
rain = 0.0
current_rain = float(daily_rain_counter)
if self.lastrain is not None:
if (current_rain >= self.lastrain):
rain = float(current_rain) - float(self.lastrain)
#loginf("Checking for new rain accumulation")
#loginf(rain)
self.lastrain = current_rain
return rain
#===============================================================================
# LOOP record decoding functions
#===============================================================================
def genLoopPackets(self):
""" Generator function that continuously returns loop packets """
for _packet in self.genPackets():
yield _packet
def genPackets(self):
""" Generate measurement packets from the socket. """
while True:
try:
_line = self.port.readline(4096)
#loginf(_line)
except (socket.timeout, socket.error), ex:
raise weewx.WeeWxIOError(ex)
if _line == None:
break
if _line[0:8] == 'outTemp=':
#loginf("New line on socket, processing weather data.")
yield self._process_message(_line)
else:
#loginf("New line on socket, but did not start with 'outTemp='. Ignoring line.")
pass
def _process_message(self, message):
_packet = {}
# Separate line into a dict
message = message.rstrip() # Strip any newline
line = message.split(',') # Split by comma
data = dict( [ i.split( '=' ) for i in line] ) # Create dictionary of the values
_packet['dateTime'] = int(time.time())
_packet['usUnits'] = weewx.US
_packet['outTemp'] = float( data["outTemp"] )
_packet['outHumidity'] = float( data["outHumidity"] )
_packet['inTemp'] = float( data["inTemp"] )
_packet['inHumidity'] = float( data["inHumidity"] )
_packet['barometer'] = float( data["barometer"] )
_packet['rain'] = self.check_rain( data["dailyrain"] )
_packet['windDir'] = float( data["windDir"] )
_packet['windSpeed'] = float( data["windSpeed"] )
_packet['windGust'] = float( data["windGust"] )
_packet['windGustDir'] = float( data["windDir"] )
_packet['radiation'] = float( data["radiation"] )
_packet['UV'] = float( data["UV"] )
_packet['txBatteryStatus'] = float( data["txBatteryStatus"] )
#loginf(_packet)
return _packet