Don't pay attention to my previous post. It was just a bracket missing.
Now I get the following error :
déc. 22 19:13:15 raspberry weewx[7261]: **** File
"/usr/share/weewx/weewx/engine.py", line 570, in post_loop
déc. 22 19:13:15 raspberry weewx[7261]: **** self._software_catchup()
déc. 22 19:13:15 raspberry weewx[7261]: **** File
"/usr/share/weewx/weewx/engine.py", line 634, in _software_catchup
déc. 22 19:13:15 raspberry weewx[7261]: ****
self.engine.dispatchEvent(weewx.Event(weewx.NEW_ARCHIVE_RECORD, ...are'))
déc. 22 19:13:15 raspberry weewx[7261]: **** File
"/usr/share/weewx/weewx/engine.py", line 224, in dispatchEvent
déc. 22 19:13:15 raspberry weewx[7261]: **** callback(event)
déc. 22 19:13:15 raspberry weewx[7261]: **** File
"/usr/share/weewx/user/alarm.py", line 116, in newArchiveRecord
déc. 22 19:13:15 raspberry weewx[7261]: **** time_binder =
weewx.tags.TimeBinder(db_lookup, event.record['dateTime'])
déc. 22 19:13:15 raspberry weewx[7261]: **** AttributeError: 'module'
object has no attribute 'tags'
déc. 22 19:13:15 raspberry weewx[7261]: **** Exiting.
Hint: Some lines were ellipsized, use -l to show in full.
And this is my service (it s badly written, i know):
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
sumwater = "/var/tmp/SumWater"
# Inherit from the base class StdService:
class MyAlarm(StdService):
"""Service that sends email if an arbitrary expression evaluates true"""
def __init__(self, engine, config_dict):
# Pass the initialization information on to my superclass:
super(MyAlarm, self).__init__(engine, config_dict)
# This will hold the time when the last alarm message went out:
self.last_msg_ts = 0
#self.water_period = 1200 #20 minutes
#self.water_alarm = 100 # seuil en litre d'envoi du mail
self.water_events = []
self.archive_water_events = []
# self.bind(weewx.NEW_ARCHIVE_RECORD, self.new_archive_record)
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']['expression']
self.water_period =
int(config_dict['Alarm'].get('water_period'))
self.water_alarm =
int(config_dict['Alarm'].get('water_alarm'))
self.time_wait = int(config_dict['Alarm'].get('time_wait',
3600))
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('subject', "Alarm
message from weewx")
self.FROM = config_dict['Alarm'].get('from',
'[email protected]')
self.TO =
option_as_list(config_dict['Alarm']['mailto'])
syslog.syslog(syslog.LOG_INFO, "alarm: Alarm set for
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. Missing
parameter: %s" % e)
def newArchiveRecord(self, event):
"""Gets called on a new archive record event."""
db_lookup = self.engine.db_binder.bind_default()
time_binder = weewx.tags.TimeBinder(db_lookup,
event.record['dateTime'])
todays_water = time_binder.day().water.sum
with open(sumwater,'w') as new_file:
# new_file.write(time_binder)
new_file.write(todays_water)
# 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:
AlarmWater = MyAlarm.CheckAlarmWater(self, record)
try:
# NOTE 2
# Evaluate the expression in the context of the event
archive record.
# Sound the alarm if it evaluates true:
if eval(self.expression, None, record) or AlarmWater :
# NOTE 3
# Sound the alarm!
# Launch in a separate thread so it doesn't block the
main LOOP thread:
t = threading.Thread(target = MyAlarm.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
syslog.syslog(syslog.LOG_INFO, "alarm: Water issue or Alarm
expression \"%s\" evaluated True at %s" % (self.expression, t_str))
# Form the message text:
msg_text = "Water issue or \nAlarm 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, "alarm: using encrypted
transport")
except smtplib.SMTPException:
syslog.syslog(syslog.LOG_DEBUG, "alarm: 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, "alarm: 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, "alarm: email sent to: %s" % self.TO)
def CheckAlarmWater(self, data):
#data=event.record
data_type = 'archive'
if data_type == 'loop':
# punt any old events from the loop event list...
if (self.rain_events and self.water_events[0][0] <=
data['dateTime'] - self.water_period):
events = []
for e in self.water_events:
if e[0] > data['dateTime'] - self.water_period:
events.append((e[0], e[1]))
self.water_events = events
# ...then add new rain event if there is one
if 'water' in data and data['water']:
self.water_events.append((data['dateTime'], data['water']))
elif data_type == 'archive':
# punt any old events from the archive event list...
if (self.archive_water_events and
self.archive_water_events[0][0] <= data['dateTime'] - self.water_period):
events = []
for e in self.archive_water_events:
if e[0] > data['dateTime'] - self.water_period:
events.append((e[0], e[1]))
self.archive_water_events = events
# ...then add new rain event if there is one
if 'water' in data and data['water']:
self.archive_water_events.append((data['dateTime'],
data['water']))
# for both loop and archive, add up the rain...
watersum = 0
if len(self.water_events) != 0:
# we have loop rain events so add them up
for e in self.water_events:
watersum += e[1]
elif data_type == 'archive':
# no loop rain events but do we have any archive rain events
for e in self.archive_water_events:
watersum += e[1]
# ...then divide by the period and scale to an hour
#data['URasp'] = watersum
if watersum > self.water_alarm :
return True
else:
return False
Le vendredi 21 décembre 2018 13:19:47 UTC+1, Thomas Keffer a écrit :
>
> Thanks, that's what we needed.
>
> Schematically, this would look something like the following. I've left out
> details, but if you've already done one service, you should be able to
> follow it. If not, let me know. NOT TESTED!
>
>
> class WaterConsumption(StdService):
> """Service that sends email if my water consumption is too high"""
>
> def __init__(self, engine, config_dict):
> # Pass the initialization information on to my superclass:
> super(WaterConsumption, self).__init__(engine, config_dict)
>
> # Get email info, as in the alarm.py example
> ...
>
> # Bind to the NEW_ARCHIVE_RECORD event
> self.bind(weewx.NEW_ARCHIVE_RECORD, self.new_archive_record)
>
> def new_archive_record(self, event):
> """Called when a new archive record has arrived."""
>
> db_lookup = self.engine.db_binder.bind_default()
> time_binder = weewx.tags.TimeBinder(db_lookup,
> event.record['dateTime']
>
> todays_water = time_binder.day().water.sum
> if todays_water > 2000:
> # Send an email (as in the alarm.py example)
> ...
>
>
>
>
>
> On Fri, Dec 21, 2018 at 1:15 AM Mic G77 <[email protected] <javascript:>>
> wrote:
>
>> Thank you for your interest in my problem.
>>
>> I' m creating a new service.
>> I've already created a data record 'water' which gives me my water
>> consumption.
>> It works on the basis of the electricity.py exemple.
>> Now i want to create an email alarm when my total day consumption is
>> above a certain amount. (Here, my service will be built on the alarm.py
>> exemple).
>>
>> If I was using a Template, i would write $day.water.sum but as it is in a
>> service, I don't have access to this kind of tag. (at least I don't know
>> how to do it).
>>
>> So, the easiest way seems to me to have access the day table of the
>> archive.
>> I would like to do it properly (for exemple, i don't want to write
>> '/var/lib/weews/archive' in an sql command).
>> Thank you in advance.
>>
>>
>>
>>
>> Le vendredi 21 décembre 2018 10:01:59 UTC+1, Andrew Milner a écrit :
>>
>>> As tom says - a little more information would be helpful.
>>>
>>> If you just want to retrieve data from the database then a python
>>> program can of course access any table in the weewx database by using sql
>>> search commands. All depends what you are actually trying to do and what
>>> you want to do with the data once it has been retrieved.
>>>
>>>
>>>
>>> On Friday, 21 December 2018 10:20:38 UTC+2, Mic G77 wrote:
>>>>
>>>> Hello.
>>>> I just want to gain access to daily summaries.
>>>>
>>>>
>>>> Le jeudi 20 décembre 2018 23:31:49 UTC+1, Thomas Keffer a écrit :
>>>>
>>>>> Hello,
>>>>>
>>>>> There are a lot of ways to do this, so it would help if we knew a
>>>>> little more about what you want to do with the data. For example, are you
>>>>> trying to calculate an aggregate? Or, just gain access to the daily
>>>>> summaries?
>>>>>
>>>>> -tk
>>>>>
>>>>> On Thu, Dec 20, 2018 at 1:38 PM Mic G77 <[email protected]> wrote:
>>>>>
>>>>>> Hello,
>>>>>> i'm trying to do a new service. I'm rather a beginner in python
>>>>>> although i have already developped some services in the
>>>>>> /usr/share/weewx/user/ folder;
>>>>>> In one of them, i would like to have access to some date which are in
>>>>>> the archive_day_outTemp.
>>>>>>
>>>>>> I don't know how to do. It seems that in the event that is send in
>>>>>> the new_archive_record function, there is only the actual record stored
>>>>>> in
>>>>>> the database.
>>>>>> If someone could send a simple exemple, it would help me.
>>>>>>
>>>>>> Thanks in advance.
>>>>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "weewx-user" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to [email protected].
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>> --
>> You received this message because you are subscribed to the Google Groups
>> "weewx-user" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
--
You received this message because you are subscribed to the Google Groups
"weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.