forked from rje1974/alerta_temperatura
-
Notifications
You must be signed in to change notification settings - Fork 0
/
temp.py
216 lines (169 loc) · 8.87 KB
/
temp.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# -*- coding: utf-8 -*-
# Copyright (c) 2016 RAMPBA
#
# Vea el archivo LICENSE.txt para comprender sus derechos.
#
"""Ejemplo de como implementar una alarma en weewx.
********************************************************************************
Para usar esta alarma, agregue el siguiente código en su archivo de configuración weewx.conf:
[Alarm]
expression = "outTemp < 40.0"
time_wait = 3600
smtp_host = smtp.mymailserver.com
smtp_user = myusername
smtp_password = mypassword
mailto = auser@adomain.com, anotheruser@someplace.com
from = me@mydomain.com
subject = "Alarm message from weewx!"
En este ejemplo, si la temperatura exterior cae debajo de los 40 F°, se enviara un correo electrónico
a la lista separada por comas especificada en la opcion "mailto", en este caso
auser@adomain.com, another@somewhere.com
El ejemplo asume que su servidor de correo SMTP se encuentra en smtp.mymailserver.com y
que utiliza un logeo seguro (secure logins). Si esto no fuera asi, deje libres las lines
para smtp_user y smtp_password y no se intentara ningun logeo de acceso.
La configuracion del remitente en el correo es opcional. Si Usted no brinda la misma, una de facto sera instroducida; pero
su servidor SMTP puede que no la acepte
La configuracion del valor "asunto" (subjet) en el correo electronico es opcional. Si Usted no brinda la misma, una de facto sera instroducida.
Para evitar una catarata de correos electrónicos, se configuró el valor time_wait para que mande uno cada 3600 segundos (una hora).
********************************************************************************
Para especificar que este nuevo servicio se cargue y sea ejecutador, se debe agregar el mismo a la
configuración (weewx.conf) dentro de la seccion de configuración "report_services", localizada en la sub-sección [Engine][[Services]].
[Engine]
[[Services]]
...
report_services = weewx.engine.StdPrint, weewx.engine.StdReport, examples.alarm.TempAlarm
********************************************************************************
Si Usted desea usar a la vez este ejemplo de alerta y el ejemplo lowBattery.py, simplemente debera fusionar
las dos opciones de configuracion bajo [Alarm] y agregar los dos servicios a
report_services.
********************************************************************************
"""
import time
import smtplib
from email.mime.text import MIMEText
import threading
import syslog
import weewx
from weewx.engine import StdService
from weeutil.weeutil import timestamp_to_string, option_as_list
# Inherit from the base class StdService:
class TempAlarm(StdService):
"""Custom service that sounds an alarm if an arbitrary expression evaluates true"""
def __init__(self, engine, config_dict):
# Pass the initialization information on to my superclass:
super(TempAlarm, self).__init__(engine, config_dict)
# This will hold the time when the last alarm message went out:
self.last_msg_ts = 0
try:
# Dig the needed options out of the configuration dictionary.
# If a critical option is missing, an exception will be raised and
# the alarm will not be set.
self.expression = config_dict['Alarm']['temp_expression']
self.time_wait = int(config_dict['Alarm']['temp_time_wait'])
self.smtp_host = config_dict['Alarm']['smtp_host']
self.smtp_user = config_dict['Alarm'].get('smtp_user')
self.smtp_password = config_dict['Alarm'].get('smtp_password')
self.SUBJECT = config_dict['Alarm'].get('temp_subject', "Alarm message from weewx")
self.FROM = config_dict['Alarm'].get('from', 'alarm@weewx.com')
self.TO = option_as_list(config_dict['Alarm']['mailto'])
syslog.syslog(syslog.LOG_INFO, "alarm: Alarm set for temp_expression: '%s'" % self.expression)
# If we got this far, it's ok to start intercepting events:
self.bind(weewx.NEW_ARCHIVE_RECORD, self.newArchiveRecord) # NOTE 1
except KeyError, e:
syslog.syslog(syslog.LOG_INFO, "alarm: No alarm set. %s" % e)
def newArchiveRecord(self, event):
"""Gets called on a new archive record event."""
# To avoid a flood of nearly identical emails, this will do
# the check only if we have never sent an email, or if we haven't
# sent one in the last self.time_wait seconds:
if not self.last_msg_ts or abs(time.time() - self.last_msg_ts) >= self.time_wait :
# Get the new archive record:
record = event.record
# Be prepared to catch an exception in the case that the expression contains
# a variable that is not in the record:
try: # NOTE 2
syslog.syslog(syslog.LOG_INFO, "TEMPERATURA ----- Try eval")
# Evaluate the expression in the context of the event archive record.
# Sound the alarm if it evaluates true:
if eval(self.expression, None, record): # NOTE 3
# Sound the alarm!
# Launch in a separate thread so it doesn't block the main LOOP thread:
t = threading.Thread(target = TempAlarm.soundTheAlarm, args=(self, record))
t.start()
# Record when the message went out:
self.last_msg_ts = time.time()
except NameError, e:
# The record was missing a named variable. Write a debug message, then keep going
syslog.syslog(syslog.LOG_DEBUG, "alarm: %s" % e)
def soundTheAlarm(self, rec):
"""This function is called when the given expression evaluates True."""
# Get the time and convert to a string:
t_str = timestamp_to_string(rec['dateTime'])
# Log it in the system log:
syslog.syslog(syslog.LOG_INFO, "-- TEMP -- alarm: Alarm expression \"%s\" evaluated True at %s" % (self.expression, t_str))
# Form the message text:
msg_text = "Alarm expression \"%s\" evaluated True at %s\nRecord:\n%s" % (self.expression, t_str, str(rec))
# Convert to MIME:
msg = MIMEText(msg_text)
# Fill in MIME headers:
msg['Subject'] = self.SUBJECT
msg['From'] = self.FROM
msg['To'] = ','.join(self.TO)
# Create an instance of class SMTP for the given SMTP host:
s = smtplib.SMTP(self.smtp_host)
try:
# Some servers (eg, gmail) require encrypted transport.
# Be prepared to catch an exception if the server
# doesn't support it.
s.ehlo()
s.starttls()
s.ehlo()
syslog.syslog(syslog.LOG_DEBUG, " **** using encrypted transport")
except smtplib.SMTPException:
syslog.syslog(syslog.LOG_DEBUG, " **** using unencrypted transport")
try:
# If a username has been given, assume that login is required for this host:
if self.smtp_user:
s.login(self.smtp_user, self.smtp_password)
syslog.syslog(syslog.LOG_DEBUG, " **** logged in with user name %s" % (self.smtp_user,))
# Send the email:
s.sendmail(msg['From'], self.TO, msg.as_string())
# Log out of the server:
s.quit()
except Exception, e:
syslog.syslog(syslog.LOG_ERR, "alarm: SMTP mailer refused message with error %s" % (e,))
raise
# Log sending the email:
syslog.syslog(syslog.LOG_INFO, " **** email sent to: %s" % self.TO)
if __name__ == '__main__':
"""This section is used for testing the code. """
import sys
import configobj
from optparse import OptionParser
usage_string ="""Usage:
alarm.py config_path
Arguments:
config_path: Path to weewx.conf"""
parser = OptionParser(usage=usage_string)
(options, args) = parser.parse_args()
if len(args) < 1:
sys.stderr.write("Missing argument(s).\n")
sys.stderr.write(parser.parse_args(["--help"]))
exit()
config_path = args[0]
weewx.debug = 1
try :
config_dict = configobj.ConfigObj(config_path, file_error=True)
except IOError:
print "Unable to open configuration file ", config_path
exit()
if 'Alarm' not in config_dict:
print >>sys.stderr, "No [Alarm] section in the configuration file %s" % config_path
exit(1)
engine = None
alarm = TempAlarm(engine, config_dict)
rec = {'extraTemp1': 1.0,
'outTemp' : 38.2,
'dateTime' : int(time.time())}
event = weewx.Event(weewx.NEW_ARCHIVE_RECORD, record=rec)
alarm.newArchiveRecord(event)