Thank you. It looks like the code to connect to your SMTP server and send 
the message is failing, since this code is run in a separate thread any 
exceptions are not seen by WeeWX so the SMTP thread appears to fail 
silently. Makes troubleshooting difficult :)

I have quickly reworked the alarm_multi.py that I posted earlier. The 
attached version will work with WeeWX 3.x and 4.x (only real change for 4.x 
is logging) and also supports both python2/3 under WeeWX 4.x. I have also 
added some code to catch any exceptions raised in the SMTP thread and log 
them. So we should now see why the code is failing. Could you replace your 
alarm_multi.py with the attached version then restart WeeWX and force some 
alarm conditions. The log should give you details of the error, if you 
can't solve the problem post the log here.

Gary

On Monday, 21 September 2020 at 06:09:29 UTC+10 pligg...@gmail.com wrote:

> Gary, 
>
> here's the syslog with 2 cycle's recorded in debug = 1. 
> And my mail.log shows that the system have sent mail for some other events 
> I have on my machine, like when the "raspibackup" has run att night. But no 
> record for sent mail when 
> the conditions in alarm are being met. And no logs in mail.err or 
> mail.info.
>
> There must be some difference in the two scripts (alarm.py and 
> alarm_multi.py) in handling the send mail function.
>
> Which is the best way to compare two scripts?   
>
> Can I provide more info from my system?
>
> //Mikael
>
>
> Sep 20 21:40:21 raspberrypi weewxd: pond: found value of 51.9116
> Sep 20 21:40:21 raspberrypi weewxd: pond: found value of 66.0866
> Sep 20 21:40:21 raspberrypi weewxd: pond: found value of 99.9000
> Sep 20 21:40:21 raspberrypi weewxd: pond: found value of 56.1866
> Sep 20 21:40:21 raspberrypi weewx[21830] INFO weewx.manager: Added record 
> 2020-09-20 21:40:00 CEST (1600630800) to database 'weewx.sdb'
> Sep 20 21:40:21 raspberrypi weewx[21830] INFO weewx.manager: Added record 
> 2020-09-20 21:40:00 CEST (1600630800) to daily summary in 'weewx.sdb'
> Sep 20 21:40:21 raspberrypi weewxd: forecast: MainThread: Zambretti: 
> starting thread
> Sep 20 21:40:21 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> generating forecast for 2020-09-20 09:00:00 CEST (1600585200)
> Sep 20 21:40:21 raspberrypi weewxd: forecast: MainThread: OWM: starting 
> thread
> Sep 20 21:40:21 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> using winddir from 2020-09-20 08:30:00 CEST (1600583400) to 2020-09-20 
> 09:00:00 CEST (1600585200)
> Sep 20 21:40:21 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> using pressure from 2020-09-20 06:00:00 CEST (1600574400) to 2020-09-20 
> 09:00:00 CEST (1600585200)
> Sep 20 21:40:21 raspberrypi weewxd: forecast: MainThread: UKMO: starting 
> thread
> Sep 20 21:40:21 raspberrypi weewxd: forecast: OWMThread: OWM: download 
> forecast from '
> http://api.openweathermap.org/data/2.5/forecast?APPID=XXXXXXXXXXXXXXXXXXXXXXXXXXXX2250&lat=57.961878399999996&lon=13.750314399999999
> '
> Sep 20 21:40:21 raspberrypi weewxd: forecast: UKMOThread: UKMO: download 
> forecast from '
> http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/2337?res=3hourly&key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5b92
> '
> Sep 20 21:40:21 raspberrypi weewxd: alarm: Alarm expression "extraTemp1 > 
> 40 " evaluated True at 2020-09-20 21:40:00 CEST (1600630800)
> Sep 20 21:40:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> reports for latest time in the database.
> Sep 20 21:40:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'StandardReport'
> Sep 20 21:40:22 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> units=1 winddir=201.384659129 pressure=30.1827110769 first_p=30.1893485695 
> last_p=30.1772155811
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> pressure=1022.10375392 month=8 winddir=8 trend=-0.136956693595 north=True
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> code is R
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> generated 1 forecast record
> Sep 20 21:40:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Bjurdammen/skin.conf for report 
> 'StandardReport'
> Sep 20 21:40:22 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.forecast.ForecastVariables', 
> u'user.stats.MyStats', u'user.historygenerator.MyXSearch', 
> u'user.lastrain.lastRainTags']
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> saving 1 forecast records
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> forecast failure: addRecord() got an unexpected keyword argument 'log_level'
> Sep 20 21:40:22 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> terminating thread
> Sep 20 21:40:22 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:40:22 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:40:22 raspberrypi weewxd: forecast: OWMThread: OWM: got 40 
> forecast records
> Sep 20 21:40:22 raspberrypi weewxd: forecast: OWMThread: OWM: saving 40 
> forecast records
> Sep 20 21:40:22 raspberrypi weewxd: forecast: OWMThread: OWM: forecast 
> failure: addRecord() got an unexpected keyword argument 'log_level'
> Sep 20 21:40:22 raspberrypi weewxd: forecast: OWMThread: OWM: terminating 
> thread
> Sep 20 21:40:22 raspberrypi weewx[21830] INFO weewx.restx: WeatherCloud: 
> Published record 2020-09-20 21:40:00 CEST (1600630800)
> Sep 20 21:40:22 raspberrypi weewx[21830] INFO weewx.restx: Windy: 
> Published record 2020-09-20 21:40:00 CEST (1600630800)
> Sep 20 21:40:22 raspberrypi weewxd: forecast: UKMOThread: UKMO: missing 
> field 'Location'
> Sep 20 21:40:22 raspberrypi weewxd: forecast: UKMOThread: UKMO: got 0 
> forecast records
> Sep 20 21:40:22 raspberrypi weewxd: forecast: UKMOThread: UKMO: saving 0 
> forecast records
> Sep 20 21:40:22 raspberrypi weewxd: forecast: UKMOThread: UKMO: forecast 
> failure: addRecord() got an unexpected keyword argument 'log_level'
> Sep 20 21:40:22 raspberrypi weewxd: forecast: UKMOThread: UKMO: 
> terminating thread
> Sep 20 21:40:23 raspberrypi weewx[21830] INFO weewx.restx: 
> Wunderground-PWS: Published record 2020-09-20 21:40:00 CEST (1600630800)
> Sep 20 21:40:23 raspberrypi weewxd: historygenerator.pyc: Generated 19 
> tables in 1.09 seconds
> Sep 20 21:40:29 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 8 files for report StandardReport in 6.82 seconds
> Sep 20 21:40:29 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:40:32 raspberrypi weewx[21830] DEBUG weewx.restx: WOW: Failed 
> upload attempt 1: timed out
> Sep 20 21:40:37 raspberrypi weewx[21830] INFO weewx.restx: WOW: Published 
> record 2020-09-20 21:40:00 CEST (1600630800)
> Sep 20 21:40:40 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 16 images for report StandardReport in 11.32 seconds
> Sep 20 21:40:40 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 3 
> files to /var/www/html/weewx
> Sep 20 21:40:40 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'Sofaskin-FW2205-master'
> Sep 20 21:40:40 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Sofaskin-FW2205-master/skin.conf for 
> report 'Sofaskin-FW2205-master'
> Sep 20 21:40:40 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.historygenerator.MyXSearch']
> Sep 20 21:40:40 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:40:40 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:40:40 raspberrypi weewxd: historygenerator.pyc: Generated 8 
> tables in 0.36 seconds
> Sep 20 21:40:47 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 10 files for report Sofaskin-FW2205-master in 7.02 seconds
> Sep 20 21:40:47 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:40:47 raspberrypi weewx[21830] DEBUG PIL.PngImagePlugin: STREAM 
> 'IHDR' 16 13
> Sep 20 21:40:47 raspberrypi weewx[21830] DEBUG PIL.PngImagePlugin: STREAM 
> 'IDAT' 41 1216
> Sep 20 21:40:47 raspberrypi weewx[21830] DEBUG PIL.PngImagePlugin: STREAM 
> 'IHDR' 16 13
> Sep 20 21:40:47 raspberrypi weewx[21830] DEBUG PIL.PngImagePlugin: STREAM 
> 'IDAT' 41 1216
> Sep 20 21:40:48 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 9 images for report Sofaskin-FW2205-master in 0.97 seconds
> Sep 20 21:40:48 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 8 
> files to /var/www/html/weewx/Sofaskin-FW2205-master
> Sep 20 21:40:48 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'Bjurdammen'
> Sep 20 21:40:48 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Bjurdammen/skin.conf for report 
> 'Bjurdammen'
> Sep 20 21:40:48 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.forecast.ForecastVariables', 
> u'user.stats.MyStats', u'user.historygenerator.MyXSearch', 
> u'user.lastrain.lastRainTags']
> Sep 20 21:40:48 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:40:48 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:40:49 raspberrypi weewxd: historygenerator.pyc: Generated 19 
> tables in 0.81 seconds
> Sep 20 21:40:51 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 8 files for report Bjurdammen in 3.17 seconds
> Sep 20 21:40:51 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:01 raspberrypi systemd[1]: Started Session c78307 of user 
> pliggen.
> Sep 20 21:41:02 raspberrypi systemd[1]: Started Session c78308 of user 
> pliggen.
> Sep 20 21:41:03 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 16 images for report Bjurdammen in 11.28 seconds
> Sep 20 21:41:03 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 3 
> files to /var/www/html/weewx/Bjurdammen
> Sep 20 21:41:03 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'SeasonsReport'
> Sep 20 21:41:03 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Bjurdammen/skin.conf for report 
> 'SeasonsReport'
> Sep 20 21:41:03 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.forecast.ForecastVariables', 
> u'user.stats.MyStats', u'user.historygenerator.MyXSearch', 
> u'user.lastrain.lastRainTags']
> Sep 20 21:41:03 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:03 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:41:04 raspberrypi weewxd: historygenerator.pyc: Generated 19 
> tables in 0.81 seconds
> Sep 20 21:41:06 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 8 files for report SeasonsReport in 3.20 seconds
> Sep 20 21:41:06 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:17 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 16 images for report SeasonsReport in 11.30 seconds
> Sep 20 21:41:17 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 3 
> files to /var/www/html/weewx
> Sep 20 21:41:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Report 
> 'SmartphoneReport' not enabled. Skipping.
> Sep 20 21:41:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Report 
> 'MobileReport' not enabled. Skipping.
> Sep 20 21:41:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'BigImages'
> Sep 20 21:41:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Images/skin.conf for report 'BigImages'
> Sep 20 21:41:18 raspberrypi weewxd: translategenerator.pyc: No language 
> override specified.
> Sep 20 21:41:18 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:20 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 6 images for report BigImages in 2.96 seconds
> Sep 20 21:41:20 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'SmallImages'
> Sep 20 21:41:21 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Images/skin.conf for report 
> 'SmallImages'
> Sep 20 21:41:21 raspberrypi weewxd: translategenerator.pyc: No language 
> override specified.
> Sep 20 21:41:21 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:22 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 6 images for report SmallImages in 1.08 seconds
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'StackedWindRose'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/StackedWindRose/skin.conf for report 
> 'StackedWindRose'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:22 raspberrypi weewx[21830] INFO user.stackedwindrose: 
> Generated 2 images for StackedWindRose in 0.60 seconds
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'lastrain'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/lastrain/skin.conf for report 'lastrain'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.lastrain.lastRainTags']
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:22 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 1 files for report lastrain in 0.08 seconds
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'HighchartsAverages'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/HighchartsAverages/skin.conf for report 
> 'HighchartsAverages'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Report 
> 'HighchartsAverages' skipped due to report_timing setting
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'wxobs'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/wxobs/skin.conf for report 'wxobs'
> Sep 20 21:41:22 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.wxobs.wxobs']
> Sep 20 21:41:23 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:41:26 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 1 files for report wxobs in 3.05 seconds
> Sep 20 21:41:26 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 8 
> files to /var/www/html/weewx/wxobs
> Sep 20 21:41:26 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'FTP'
> Sep 20 21:41:26 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Ftp/skin.conf for report 'FTP'
> Sep 20 21:41:26 raspberrypi weewx[21830] DEBUG weewx.reportengine: 
> ftpgenerator: FTP upload not requested. Skipped.
> Sep 20 21:41:26 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'RSYNC'
> Sep 20 21:41:26 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Rsync/skin.conf for report 'RSYNC'
> Sep 20 21:41:26 raspberrypi weewx[21830] DEBUG weewx.reportengine: 
> rsyncgenerator: Rsync upload not requested. Skipped.
> Sep 20 21:42:01 raspberrypi systemd[1]: Started Session c78309 of user 
> pliggen.
> Sep 20 21:42:02 raspberrypi systemd[1]: Started Session c78310 of user 
> pliggen.
> Sep 20 21:43:01 raspberrypi systemd[1]: Started Session c78311 of user 
> pliggen.
> Sep 20 21:43:02 raspberrypi systemd[1]: Started Session c78312 of user 
> pliggen.
> Sep 20 21:44:02 raspberrypi systemd[1]: Started Session c78313 of user 
> pliggen.
> Sep 20 21:44:02 raspberrypi systemd[1]: Started Session c78314 of user 
> pliggen.
> Sep 20 21:45:01 raspberrypi CRON[22732]: (pliggen) CMD (/usr/bin/php7.0 
> /var/www/html/weewx/smhi_warnings_bjurdammen.php > /dev/null 2>&1)
> Sep 20 21:45:01 raspberrypi systemd[1]: Started Session c78315 of user 
> pliggen.
> Sep 20 21:45:02 raspberrypi systemd[1]: Started Session c78316 of user 
> pliggen.
> Sep 20 21:46:01 raspberrypi systemd[1]: Started Session c78317 of user 
> pliggen.
> Sep 20 21:46:02 raspberrypi systemd[1]: Started Session c78318 of user 
> pliggen.
> Sep 20 21:47:01 raspberrypi systemd[1]: Started Session c78319 of user 
> pliggen.
> Sep 20 21:47:02 raspberrypi systemd[1]: Started Session c78320 of user 
> pliggen.
> Sep 20 21:48:01 raspberrypi CRON[23003]: (pliggen) CMD (/usr/bin/python3 
> /var/www/html/weewx/smhiheader.py)
> Sep 20 21:48:01 raspberrypi CRON[23002]: (pliggen) CMD (/usr/bin/python3 
> /var/www/html/weewx/smhitext.py)
> Sep 20 21:48:01 raspberrypi CRON[23007]: (pliggen) CMD (/usr/bin/python3 
> /var/www/html/weewx/smhitime.py)
> Sep 20 21:48:02 raspberrypi systemd[1]: Started Session c78321 of user 
> pliggen.
> Sep 20 21:48:02 raspberrypi systemd[1]: Started Session c78322 of user 
> pliggen.
> Sep 20 21:49:01 raspberrypi systemd[1]: Started Session c78323 of user 
> pliggen.
> Sep 20 21:49:02 raspberrypi systemd[1]: Started Session c78324 of user 
> pliggen.
> Sep 20 21:50:01 raspberrypi systemd[1]: Started Session c78325 of user 
> pliggen.
> Sep 20 21:50:01 raspberrypi CRON[23234]: (pliggen) CMD (sh 
> /home/pliggen/Dokument/rename.sh > /dev/null 2>&1)
> Sep 20 21:50:02 raspberrypi systemd[1]: Started Session c78326 of user 
> pliggen.
> Sep 20 21:50:24 raspberrypi weewxd: pond: found value of 51.9116
> Sep 20 21:50:24 raspberrypi weewxd: pond: found value of 66.2
> Sep 20 21:50:24 raspberrypi weewxd: pond: found value of 99.9000
> Sep 20 21:50:24 raspberrypi weewxd: pond: found value of 55.9616
> Sep 20 21:50:24 raspberrypi weewx[21830] INFO weewx.manager: Added record 
> 2020-09-20 21:50:00 CEST (1600631400) to database 'weewx.sdb'
> Sep 20 21:50:24 raspberrypi weewx[21830] INFO weewx.manager: Added record 
> 2020-09-20 21:50:00 CEST (1600631400) to daily summary in 'weewx.sdb'
> Sep 20 21:50:25 raspberrypi weewxd: forecast: MainThread: Zambretti: 
> starting thread
> Sep 20 21:50:25 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> forecast was already calculated for 2020-09-20 09:00:00 CEST (1600585200)
> Sep 20 21:50:25 raspberrypi weewxd: forecast: MainThread: OWM: starting 
> thread
> Sep 20 21:50:25 raspberrypi weewxd: forecast: ZambrettiThread: Zambretti: 
> terminating thread
> Sep 20 21:50:25 raspberrypi weewxd: forecast: OWMThread: OWM: download 
> forecast from '
> http://api.openweathermap.org/data/2.5/forecast?APPID=XXXXXXXXXXXXXXXXXXXXXXXXXXXX2250&lat=57.961878399999996&lon=13.750314399999999
> '
> Sep 20 21:50:25 raspberrypi weewxd: forecast: MainThread: UKMO: starting 
> thread
> Sep 20 21:50:25 raspberrypi weewxd: forecast: UKMOThread: UKMO: download 
> forecast from '
> http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/2337?res=3hourly&key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5b92
> '
> Sep 20 21:50:25 raspberrypi weewxd: alarm: Alarm expression "extraTemp1 > 
> 40 " evaluated True at 2020-09-20 21:50:00 CEST (1600631400)
> Sep 20 21:50:25 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> reports for latest time in the database.
> Sep 20 21:50:25 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'StandardReport'
> Sep 20 21:50:25 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Bjurdammen/skin.conf for report 
> 'StandardReport'
> Sep 20 21:50:25 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.forecast.ForecastVariables', 
> u'user.stats.MyStats', u'user.historygenerator.MyXSearch', 
> u'user.lastrain.lastRainTags']
> Sep 20 21:50:25 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:25 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:50:25 raspberrypi weewxd: forecast: OWMThread: OWM: got 40 
> forecast records
> Sep 20 21:50:25 raspberrypi weewxd: forecast: OWMThread: OWM: saving 40 
> forecast records
> Sep 20 21:50:25 raspberrypi weewxd: forecast: OWMThread: OWM: forecast 
> failure: addRecord() got an unexpected keyword argument 'log_level'
> Sep 20 21:50:25 raspberrypi weewxd: forecast: OWMThread: OWM: terminating 
> thread
> Sep 20 21:50:25 raspberrypi weewx[21830] INFO weewx.restx: Windy: 
> Published record 2020-09-20 21:50:00 CEST (1600631400)
> Sep 20 21:50:25 raspberrypi weewx[21830] INFO weewx.restx: WOW: Published 
> record 2020-09-20 21:50:00 CEST (1600631400)
> Sep 20 21:50:25 raspberrypi weewx[21830] INFO weewx.restx: 
> Wunderground-PWS: Published record 2020-09-20 21:50:00 CEST (1600631400)
> Sep 20 21:50:25 raspberrypi weewxd: historygenerator.pyc: Generated 19 
> tables in 0.75 seconds
> Sep 20 21:50:26 raspberrypi weewxd: forecast: UKMOThread: UKMO: missing 
> field 'Location'
> Sep 20 21:50:26 raspberrypi weewxd: forecast: UKMOThread: UKMO: got 0 
> forecast records
> Sep 20 21:50:26 raspberrypi weewxd: forecast: UKMOThread: UKMO: saving 0 
> forecast records
> Sep 20 21:50:26 raspberrypi weewxd: forecast: UKMOThread: UKMO: forecast 
> failure: addRecord() got an unexpected keyword argument 'log_level'
> Sep 20 21:50:26 raspberrypi weewxd: forecast: UKMOThread: UKMO: 
> terminating thread
> Sep 20 21:50:27 raspberrypi weewx[21830] INFO weewx.restx: WeatherCloud: 
> Published record 2020-09-20 21:50:00 CEST (1600631400)
> Sep 20 21:50:28 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 8 files for report StandardReport in 3.31 seconds
> Sep 20 21:50:28 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:39 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 16 images for report StandardReport in 11.31 seconds
> Sep 20 21:50:39 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 0 
> files to /var/www/html/weewx
> Sep 20 21:50:39 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'Sofaskin-FW2205-master'
> Sep 20 21:50:39 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Sofaskin-FW2205-master/skin.conf for 
> report 'Sofaskin-FW2205-master'
> Sep 20 21:50:39 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.historygenerator.MyXSearch']
> Sep 20 21:50:39 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:39 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:50:40 raspberrypi weewxd: historygenerator.pyc: Generated 8 
> tables in 0.25 seconds
> Sep 20 21:50:42 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 10 files for report Sofaskin-FW2205-master in 2.68 seconds
> Sep 20 21:50:42 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:43 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 9 images for report Sofaskin-FW2205-master in 0.85 seconds
> Sep 20 21:50:43 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 0 
> files to /var/www/html/weewx/Sofaskin-FW2205-master
> Sep 20 21:50:43 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'Bjurdammen'
> Sep 20 21:50:43 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Bjurdammen/skin.conf for report 
> 'Bjurdammen'
> Sep 20 21:50:43 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.forecast.ForecastVariables', 
> u'user.stats.MyStats', u'user.historygenerator.MyXSearch', 
> u'user.lastrain.lastRainTags']
> Sep 20 21:50:43 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:43 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:50:44 raspberrypi weewxd: historygenerator.pyc: Generated 19 
> tables in 0.69 seconds
> Sep 20 21:50:46 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 8 files for report Bjurdammen in 3.02 seconds
> Sep 20 21:50:46 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:58 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 16 images for report Bjurdammen in 11.42 seconds
> Sep 20 21:50:58 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 0 
> files to /var/www/html/weewx/Bjurdammen
> Sep 20 21:50:58 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'SeasonsReport'
> Sep 20 21:50:58 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Bjurdammen/skin.conf for report 
> 'SeasonsReport'
> Sep 20 21:50:58 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.forecast.ForecastVariables', 
> u'user.stats.MyStats', u'user.historygenerator.MyXSearch', 
> u'user.lastrain.lastRainTags']
> Sep 20 21:50:58 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:50:58 raspberrypi weewxd: historygenerator.pyc: No bootstrap 
> specific labels found
> Sep 20 21:50:58 raspberrypi weewxd: historygenerator.pyc: Generated 19 
> tables in 0.73 seconds
> Sep 20 21:51:01 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 8 files for report SeasonsReport in 3.12 seconds
> Sep 20 21:51:01 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:51:02 raspberrypi systemd[1]: Started Session c78327 of user 
> pliggen.
> Sep 20 21:51:02 raspberrypi systemd[1]: Started Session c78328 of user 
> pliggen.
> Sep 20 21:51:12 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 16 images for report SeasonsReport in 11.40 seconds
> Sep 20 21:51:12 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 0 
> files to /var/www/html/weewx
> Sep 20 21:51:12 raspberrypi weewx[21830] DEBUG weewx.reportengine: Report 
> 'SmartphoneReport' not enabled. Skipping.
> Sep 20 21:51:12 raspberrypi weewx[21830] DEBUG weewx.reportengine: Report 
> 'MobileReport' not enabled. Skipping.
> Sep 20 21:51:12 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'BigImages'
> Sep 20 21:51:12 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Images/skin.conf for report 'BigImages'
> Sep 20 21:51:12 raspberrypi weewxd: translategenerator.pyc: No language 
> override specified.
> Sep 20 21:51:12 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:51:15 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 6 images for report BigImages in 3.00 seconds
> Sep 20 21:51:15 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'SmallImages'
> Sep 20 21:51:15 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Images/skin.conf for report 
> 'SmallImages'
> Sep 20 21:51:15 raspberrypi weewxd: translategenerator.pyc: No language 
> override specified.
> Sep 20 21:51:15 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:51:16 raspberrypi weewx[21830] INFO weewx.imagegenerator: 
> Generated 6 images for report SmallImages in 1.06 seconds
> Sep 20 21:51:16 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'StackedWindRose'
> Sep 20 21:51:16 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/StackedWindRose/skin.conf for report 
> 'StackedWindRose'
> Sep 20 21:51:16 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:51:17 raspberrypi weewx[21830] INFO user.stackedwindrose: 
> Generated 2 images for StackedWindRose in 0.59 seconds
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'lastrain'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/lastrain/skin.conf for report 'lastrain'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.lastrain.lastRainTags']
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:51:17 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 1 files for report lastrain in 0.12 seconds
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'HighchartsAverages'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/HighchartsAverages/skin.conf for report 
> 'HighchartsAverages'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Report 
> 'HighchartsAverages' skipped due to report_timing setting
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'wxobs'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/wxobs/skin.conf for report 'wxobs'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.cheetahgenerator: 
> Using search list ['weewx.cheetahgenerator.Almanac', 
> 'weewx.cheetahgenerator.Station', 'weewx.cheetahgenerator.Current', 
> 'weewx.cheetahgenerator.Stats', 'weewx.cheetahgenerator.UnitInfo', 
> 'weewx.cheetahgenerator.Extras', u'user.wxobs.wxobs']
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.manager: Daily 
> summary version is 2.0
> Sep 20 21:51:17 raspberrypi weewx[21830] INFO weewx.cheetahgenerator: 
> Generated 1 files for report wxobs in 0.21 seconds
> Sep 20 21:51:17 raspberrypi weewx[21830] INFO weewx.reportengine: Copied 0 
> files to /var/www/html/weewx/wxobs
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'FTP'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Ftp/skin.conf for report 'FTP'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: 
> ftpgenerator: FTP upload not requested. Skipped.
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Running 
> report 'RSYNC'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: Found 
> configuration file /etc/weewx/skins/Rsync/skin.conf for report 'RSYNC'
> Sep 20 21:51:17 raspberrypi weewx[21830] DEBUG weewx.reportengine: 
> rsyncgenerator: Rsync upload not requested. Skipped.
>
> lördag 19 september 2020 kl. 23:33:06 UTC+2 skrev gjr80:
>
>> If the condition is being triggered and logged its possible the issue is 
>> with the email transport. Any clues will be in the logs. Set debug = 1 in 
>> weewx.conf and restart WeeWX then cause one of the conditions to be 
>> triggered. Post the WeeWX log. Look in the emails logs for your system, 
>> which log will depend on your system but syslog, mail.err, mail.log and 
>> mail.info may be good places to look.
>>
>> Gary
>> On Saturday, 19 September 2020 at 17:57:45 UTC+10 pligg...@gmail.com 
>> wrote:
>>
>>>
>>> Tried this again today but it doesn't send email. I see the expression 
>>> true in the logs. Has anyone got some idea why the old alarm.py works fine 
>>> but not the "new" alarm_multi.py?
>>> First tried on weewx 3.9.1 and now on 4.0.0 but still the same result.
>>> //Mikael
>>> tisdag 12 mars 2019 kl. 09:06:50 UTC+1 skrev pligg...@gmail.com:
>>>
>>>> Hi!
>>>>
>>>> Does anyone got this to work on weewx 3.9.1?
>>>>
>>>> I had the original alarm.py working, but this one doesn't send email. I 
>>>> get the alarm expression true in the log but it never sends an email.
>>>> I double checked the credentials and the smtp settings.
>>>>
>>>> /Mikael
>>>>
>>>>
>>>> Den onsdag 1 maj 2013 kl. 19:06:00 UTC+2 skrev William Phelps:
>>>>>
>>>>> I modified the example "alarm.py" to support multiple alarms.  The 
>>>>> entries in weewx.conf now look like this:
>>>>>
>>>>> [Alarm]
>>>>>   time_wait = 3600
>>>>>   smtp_host = smtp.mymailserver.com
>>>>>   smtp_user = myusername
>>>>>   smtp_password = mypassword
>>>>>   mailto = au...@adomain.com, anoth...@someplace.com
>>>>>   from = m...@mydomain.com
>>>>>
>>>>>   count = 2
>>>>>   expression.0 = "outTemp < 40.0"
>>>>>   subject.0 = "Alarm message from weewx - Low temperature!"
>>>>>   expression.1 = "outTemp > 90.0"
>>>>>   subject.1 = "Alarm message from weewx- High temperature!"
>>>>>
>>>>> I've attached a zip of alarm.py
>>>>>
>>>>> It's still "static" - to change the alarms, you have to restart weewx 
>>>>> after editing weewx.conf.  I thought about having alarm.py re-fetch the 
>>>>> config data but that seems like it might be a performance hit since the 
>>>>> code is attached to the NEW_ARCHIVE_RECORD event.  Maybe attach another 
>>>>> event to re-read the config data?
>>>>>
>>>>> William
>>>>>
>>>>

-- 
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 weewx-user+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/weewx-user/891392cc-c85e-4472-b5ad-53cb483bab40n%40googlegroups.com.
#    Copyright (c) 2009-2015 Tom Keffer <tkef...@gmail.com>
#    See the file LICENSE.txt for your rights.

"""Example of how to implement multiple email alarms in weewx.

Based on the code by user William Phelps in this user group post:
https://groups.google.com/d/msg/weewx-user/-IGQC3CpXAE/ItUpebyZlL8J

Modified 6 April 2017 by Gary Roderick to work under WeeWX 3.7.1
Modified 21 September 2020 by Gary Roderick to work under WeeWX 4.x and python 2/3

*******************************************************************************

To use this alarm, add the following to the weewx configuration file:

[Alarm]
    time_wait = 3600
    smtp_host = smtp.mymailserver.com
    smtp_user = myusername
    smtp_password = mypassword
    mailto = au...@adomain.com, anotheru...@someplace.com
    from = m...@mydomain.com
    count = 2
    expression.0 = "outTemp < 40.0"
    subject.0 = "Alarm message from weewx - Low temperature!"
    expression.1 = "outTemp > 90.0"
    subject.1 = "Alarm message from weewx- High temperature!"

In this example, if the outside temperature falls below 40, or rises above 90,
it will send an email to the the comma separated list specified in option
"mailto", in this case au...@adomain.com, anot...@somewhere.com

The example assumes that your SMTP email server is at smtp.mymailserver.com
that requires login.  If the SMTP server does not require login, leave out the
lines for smtp_user and smtp_password.

Setting an email "from" is optional. If not supplied, one will be filled in,
but your SMTP server may or may not accept it.

Setting an email "subject" is optional. If not supplied, one will be filled in.

To avoid a flood of emails, one will only be sent every 3600 seconds (one
hour).

*******************************************************************************

To enable this service:

1) copy this file to the user directory

2) modify the weewx configuration file by adding this service to the option
"report_services", located in section [Engine][[Services]].

[Engine]
  [[Services]]
    ...
    report_services = weewx.engine.StdPrint, weewx.engine.StdReport, user.alarm_multi.MyAlarm

*******************************************************************************

If you wish to use both this example and the lowBattery.py example, simply
merge the two configuration options together under [Alarm] and add both
services to report_services.

*******************************************************************************
"""

# python imports
from __future__ import print_function

import smtplib
import sys
import threading
import time
from email.mime.text import MIMEText

# WeeWX imports
import weewx
from weewx.engine import StdService
from weeutil.weeutil import timestamp_to_string, option_as_list

# import/setup logging, WeeWX v3 is syslog based but WeeWX v4 is logging based,
# try v4 logging and if it fails use v3 logging
try:
    # WeeWX4 logging
    import logging
    from weeutil.logger import log_traceback

    log = logging.getLogger(__name__)

    def logdbg(msg):
        log.debug(msg)

    def logerr(msg):
        log.error(msg)

    def loginf(msg):
        log.info(msg)

    # log_traceback() generates the same output but the signature and code is
    # different between v3 and v4. We only need log_traceback at the log.error
    # level so define a suitable wrapper function.

    def log_traceback_error(prefix=''):
        log_traceback(log.error, prefix=prefix)

except ImportError:
    # WeeWX legacy (v3) logging via syslog
    import syslog
    from weeutil.weeutil import log_traceback

    def logmsg(level, msg):
        syslog.syslog(level, 'alarm: %s' % msg)

    def logdbg(msg):
        logmsg(syslog.LOG_DEBUG, msg)

    def logerr(msg):
        logmsg(syslog.LOG_ERR, msg)

    def loginf(msg):
        logmsg(syslog.LOG_INFO, msg)

    # log_traceback() generates the same output but the signature and code is
    # different between v3 and v4. We only need log_traceback at the log.error
    # level so define a suitable wrapper function.

    def log_traceback_error(prefix=''):
        log_traceback(prefix=prefix, loglevel=syslog.LOG_ERR)

# 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)

        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.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.FROM = config_dict['Alarm'].get('from', 'al...@example.com')
            self.TO = option_as_list(config_dict['Alarm']['mailto'])

            self.count = int(config_dict['Alarm']['count'])
            self.last_msg_ts = {}
            self.expression = {}
            self.subject = {}
            for i in range(self.count):
                self.last_msg_ts[i] = 0
                self.expression[i] = config_dict['Alarm']['expression.'+str(i)]
                self.subject[i] = config_dict['Alarm'].get('subject.'+str(i),
                                                           "Alarm message from weewx")
                loginf("Alarm set for expression %s: \"%s\"" % (str(i),self.expression[i]))

            # If we got this far, it's ok to start intercepting events:
            self.bind(weewx.NEW_ARCHIVE_RECORD, self.newArchiveRecord) # NOTE 1
        except KeyError as e:
            loginf("No alarm set.  Missing parameter: %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:
        for i in range(self.count):
            if not self.last_msg_ts[i] or abs(time.time() - self.last_msg_ts[i]) >= 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
                    # Evaluate the expression in the context of the event
                    # archive record. Sound the alarm if it evaluates true:
                    if eval(self.expression[i], 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=MyAlarm.soundTheAlarm,
                                             args=(self,record,self.expression[i],self.subject[i]))
                        t.start()
                        # Record when the message went out:
                        self.last_msg_ts[i] = time.time()
                except NameError as e:
                    # The record was missing a named variable. Write a debug
                    # message, then keep going
                    logdbg("%s" % e)

    def soundTheAlarm(self, rec, expr, subj):
        """This function is called when the given expression evaluates True."""

        # We are running in a thread so any serious unhandled exceptions may
        # cause the thread to silently die and we will never know anything
        # about it. Wrap in a try..except to log the traceback of any unhandled
        # exceptions so at least there is something in the log.
        try:
            # Get the time and convert to a string:
            t_str = timestamp_to_string(rec['dateTime'])

            # Log it
            loginf("Alarm expression \"%s\" evaluated True at %s" % (expr, t_str))

            # Form the message text:
            msg_text = "Alarm expression \"%s\" evaluated True at %s\nRecord:\n%s" % (expr,
                                                                                      t_str,
                                                                                      str(rec))
            # Convert to MIME:
            msg = MIMEText(msg_text)

            # Fill in MIME headers:
            msg['Subject'] = subj
            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()
                logdbg("using encrypted transport")
            except smtplib.SMTPException:
                logdbg("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)
                    logdbg("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 as e:
                logerr("SMTP mailer refused message with error %s" % (e,))
                raise

            # Log sending the email:
            loginf("email sent to: %s" % self.TO)
        except Exception as e:
            # Some unknown exception occurred. This is probably a serious
            # problem. Exit with some notification.
            logerr("Unexpected exception of type %s" % (type(e), ))
            log_traceback_error('rtgd: **** ')
            logerr("Thread exiting. Reason: %s" % (e, ))


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("No [Alarm] section in the configuration file %s" % config_path,
              file=sys.stderr)
#        print >>sys.stderr, "No [Alarm] section in the configuration file %s" % config_path
        exit(1)

    engine = None
    alarm = MyAlarm(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)

Reply via email to