Unexpected e-mails sent by Lua script

Moderator: leecollings

Post Reply
agynna
Posts: 4
Joined: Thursday 19 November 2015 14:06
Target OS: Windows
Domoticz version: 2.3563
Location: Sweden
Contact:

Unexpected e-mails sent by Lua script

Post by agynna »

Hi all awesome Lua-Domoticz experts,

I have a problem where my script produces an e-mail when it's not supposed to, with partly unexpected content. I have implemented a simple freezer alarm with 5 Proove 433 MHz thermometers, a RFXcom, a Windows 7 computer, Domoticz 2.3563 and Lua. The main part consists of a device script that monitors the reported temperatures and raises an alarm if out of bounds, which works fine. In addition to this there is a watchdog time script that should check that the thermometers have reported recently, and otherwise should notify me by e-mail.

The problem is that an e-mail is always sent, regardless of if the conditions that lead there are true, and the content is incorrect.

Script: script_time_checkdevices.lua

Code: Select all

¨-- Checks periodically if all sensors have been received recently, and 
-- otherwise sends an e-mail to tell us to go check the lost one. 

CheckInterval = 10 -- How often we should check for lost devices(min)
DeviceTimeout = 30*60 -- After how long time a device is considered lost (s)
MessageInterval = 20 --8*3600 -- Minimum interval between e-mails (s) 
MessageEmail = '[email protected];[email protected]' -- Where messages should be sent. 


commandArray = {}
now = os.time()

-- Run every 'CheckInterval' as long no e-mail has already been sent the last 'MessageInterval' seconds
if (os.date('%M') % CheckInterval) == 0 then 
	print('Checking that sensors are alive...')
	for i, v in pairs(otherdevices) do print(otherdevices_lastupdate[i]) end -- Debug

	-- Get last update time for each device
	for i, v in pairs(otherdevices) do  
		s = otherdevices_lastupdate[i]
		print(i) -- Debug
		print(s) -- Debug
		year = string.sub(s, 1, 4)
		month = string.sub(s, 6, 7)
		day = string.sub(s, 9, 10)
		hour = string.sub(s, 12, 13)
		minutes = string.sub(s, 15, 16)
		seconds = string.sub(s, 18, 19)
		lastAlive = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}	
		
		-- If not seen since timeout, send an email
		if (lastAlive + DeviceTimeout) < now then
			
			print(i .. ' has not been seen since ' .. s .. '.')
			print('Debug msg 1')
			-- If an email was sent recently, don't send one
			if uservariables['MessageTime'] + MessageInterval < now then
				subject = i .. ' sensor has been lost'
				message = 'The temperature sensor ' .. i .. ' has not been seen since '.. s .. '. Now it´s ' .. os.date('%c', now) .. '. The sensor is maybe out of batteries?'
				print('Debug msd 2: ' .. s)
				
				commandArray['SendEmail'] = subject .. '#' .. message .. '#' .. MessageEmail
				commandArray['Variable:MessageTime'] = tostring(os.time())
			end
		end
	end
	if next(commandArray) == nil then print ('All OK.') end
end

return commandArray
A typical log entry from when this ran is

Code: Select all

2015-11-19 14:20:00.222 LUA: Checking that sensors are alive...
2015-11-19 14:20:00.223 LUA: 2015-11-19 14:19:40
2015-11-19 14:20:00.223 LUA: 2015-11-19 14:19:41
2015-11-19 14:20:00.223 LUA: 2015-11-19 14:18:42
2015-11-19 14:20:00.223 LUA: 2015-11-19 14:19:42
2015-11-19 14:20:00.223 LUA: 2015-11-19 14:19:36
2015-11-19 14:20:00.223 LUA: Freezer5
2015-11-19 14:20:00.224 LUA: 2015-11-19 14:19:40
2015-11-19 14:20:00.224 LUA: Freezer2
2015-11-19 14:20:00.224 LUA: 2015-11-19 14:19:41
2015-11-19 14:20:00.224 LUA: Freezer3
2015-11-19 14:20:00.224 LUA: 2015-11-19 14:18:42
2015-11-19 14:20:00.224 LUA: Freezer1
2015-11-19 14:20:00.224 LUA: 2015-11-19 14:19:42
2015-11-19 14:20:00.224 LUA: Freezer4
2015-11-19 14:20:00.224 LUA: 2015-11-19 14:19:36
2015-11-19 14:20:00.224 LUA: All OK.
This run generated this e-mail (the identity of the sensor changes randomly, prob depending on their order in the table)
Freezer2 sensor has been lost
[email protected] <[email protected]> 20 november 2015 01:20
Svara: [email protected]
Till: [email protected]
Kopia: [email protected]
The temperature sensor Freezer2 has not been seen since 2015-11-19 11:41:17. Now it´s Thu Nov 19 14:20:00 2015. The sensor is maybe out of batteries?
The strange things, to my understanding, are
- The e-mail is sent although the condition "(lastAlive + DeviceTimeout) < now" is false (line 32)
- "s" is written as another time in the e-mail than it's otherwise defined to, as seen in the log entry. 2015-11-19 11:41:17 is roughly when the system was restarted. Before this restart it printed the time of restart before that.
- "All OK" at the end of the log is printed (line 47), even though this is only supposed to be printed if the "commandArray" is empty
- "Debug msg 1" and "Debug msg 2" (lines 34-35 & 40) are not printed to the log, although the e-mail is sent

For some time I thought that the Lua interpreter or Domoticz server somehow kept the command array or the e-mail content in cache between the runs, but if I edit the "message" string, the content of the e-mail changes. The string "s" is still however written out as "2015-11-19 11:41:17".

Any thoughts on this?
Cheers, Arvid
agynna
Posts: 4
Joined: Thursday 19 November 2015 14:06
Target OS: Windows
Domoticz version: 2.3563
Location: Sweden
Contact:

Re: Unexpected e-mails sent by Lua script

Post by agynna »

Oh, also no email is sent if line 42 is commented out. This implies that lines 39 and 42 are interpreted. The MessageTime uservariable is also updated, but only when the e-mail is sent, i e not when line 42 is commented out.
agynna
Posts: 4
Joined: Thursday 19 November 2015 14:06
Target OS: Windows
Domoticz version: 2.3563
Location: Sweden
Contact:

Re: Unexpected e-mails sent by Lua script

Post by agynna »

Hello again!

I have discovered some other weird e-mail related behaviour on the same system. This makes me think the problem is not in the scrips, but in the setup.

There is a main device script that checks every temperature reported, and if outside bound alerts me by playing sound and sending a notification and an e-mail. The relevant part is pasted below. This should send an e-mail, which works (although line breaks was difficult to achieve). But currently two e-mails are sent every time this script executes, the expected one and an older version of the e-mail. There is no code in the Domoticz folder that could generate this second e-mail. There are no other scripts in the lua folder except those pasted here and the demo scripts. Even stranger, "device" is reinterpreted every time also for the incorrect e-mail, i e it always gives the correct name for the sensor out of bounds. My naive understanding is that the "email" string should become fixed when a string is saved into it, but somehow a line that not longer exists is interpreted and sent in an e-mail by another line that no longer exists.

Is there any way to force a reinitialisation of the LUA interpreter between each execution of the script?

The code that is run if a thermometer reports a temperature outside bounds

Code: Select all

	-- Play sound only once every few minutes
	if os.time() > (uservariables['SoundTime'] + SoundInterval) then
		cmd = [[""c:\Program Files (x86)\VIDEOLAN\VLC\vlc.exe" --play-and-exit "c:\Program Files (x86)\Domoticz\scripts\lua\alarm.wav" "c:\Program Files (x86)\Domoticz\scripts\lua\alarm.wav" "c:\Program Files (x86)\Domoticz\scripts\lua\alarm.wav""]]
		os.execute(cmd)
		
		commandArray['Variable:SoundTime'] = tostring(os.time())
	end
	
	-- Only send mail and notif ications if 
	-- none has been sent for some time
	if os.time() > (uservariables['AlarmTime'] + AlarmInterval) then
	
		temperature = string.format("%.0f", temperature)
		subject = ('FREEZER ALARM: ' .. device .. ' is at ' .. temperature .. ' degrees!')
		message = ('The temperature sensor ' .. device .. ' is at ' .. temperature .. ' degrees! Go check whats going on!')
		
		print(subject)
		email = (subject .. '#' .. message .. '#' .. AlarmEmail)
		notification = ('FREEZER ALARM' .. '#' .. subject)
		commandArray['SendEmail'] = email
		commandArray['SendNotification'] = notification
		
		commandArray['Variable:AlarmTime'] = tostring(os.time())
	end
	
	return commandArray
The correct e-mail:
From: [email protected]
Subject: FREEZER ALARM: Freezer5 is at -10 degrees!
The temperature sensor Freezer5 is at -10 degrees! Go check whats going on!
The incorrect e-mail:
From: [email protected]
Subject: FREEZER ALARM
FREEZER ALARM: Freezer5 is at -10 degrees!
agynna
Posts: 4
Joined: Thursday 19 November 2015 14:06
Target OS: Windows
Domoticz version: 2.3563
Location: Sweden
Contact:

Re: Unexpected e-mails sent by Lua script

Post by agynna »

I have now found that theses problems were solved by updating to Domoticz 3.4843. It thus seems that the bug(s) were not in my scripts above, but in Domoticz. Anyway they seem to be resolved now.
jmleglise
Posts: 192
Joined: Monday 12 January 2015 23:27
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: FRANCE
Contact:

Re: Unexpected e-mails sent by Lua script

Post by jmleglise »

Hi,

Your script inspires me and I have adapted it to my needs.

I check only the device I need, with an different timeout for each)

So I share it here :

Code: Select all

-- Checks if a list of device have been received recently, and
-- otherwise sends an e-mail to tell to go check the lost one.

destEmail = '[email protected]' -- Where messages should be sent.
bodyMail=""

if time.hour==23 and  time.hour==23 then

now = os.time()

commandArray = {}

local tableDeviceToCheck = {
MailBox=259200, -- 3 days  3*24*60*60, 
["Motion"]=86400, -- 1 days   1*24*60*60, 
["Alert"]=28800, -- 8 hours  8*60*60, 
Ferie=86400, 
Lux=3600, 
CPU=3600, 
["WU Barometre"]=28800, 
["Sonde"]=3600,
["Sonde THGN500"]=3600,
["Sonde Sol2"]=3600,
["Sonde Sol1"]=3600
}

for deviceName, deviceTimeOut in pairs(tableDeviceToCheck) do
	--print(deviceName .." delay"..deviceTimeOut)
	s = otherdevices_lastupdate[deviceName]
	year = string.sub(s, 1, 4)
	month = string.sub(s, 6, 7)
	day = string.sub(s, 9, 10)
	hour = string.sub(s, 12, 13)
	minutes = string.sub(s, 15, 16)
	seconds = string.sub(s, 18, 19)
	lastAlive = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}

    -- If not seen since timeout, send an email
	if (lastAlive + deviceTimeOut) < now then
		bodyMail=bodyMail..deviceName.. ' has not been seen since ' .. s .. '.<br>\n'
	end
end

if bodyMail~="" then
	subject = 'Domoticz check : Device has been lost !'
	commandArray['SendEmail'] = subject .. '#' .. bodyMail .. '#' .. destEmail
end
end

return commandArray

   
My script : https://github.com/jmleglise
RFXTRX433E: Blind Somfy RTS, Portal Somfy Evolvia, chacon IO, Oregon, PIR sensor PT2262
My Last project : Location de vacances a Ouistreham vue mer
KMTronic USB relay
Chinese Z-WAVE: Neo CoolCam
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest