simonrg wrote:ThinkPad wrote:On the Dutch forum 'Tweakers' i also mentioned this script. 'MikeOO' came with a good comment: what if the connection stays down for a while? The script will keep interrupting power to the modem. If the connection is down the whole day, this could mean hundreds of power interruptions.....
Does anyone know how to add some logic to prevent this? Maybe a sort of counter which adds +1 to a .txt file every time a powercycle is done, and then check in the script if the counter is smaller than xx before proceeding, and if counter greater than xx stop powercycling/lower interval to once per hour or so
But i am not that handy, would be great if someone could help.....
Ok perhaps my Lua script is not quite so over engineered after all, just incorrectly engineered for exactly what you want. Time to learn some Lua
It is time to learn some Lua I guess, as this script is not complicated but is a bit convoluted to do what I think you want to do.
In order to use the script you need to create a Domoticz integer user variable initialised to 0 (zero). Create the script ~/home/domoticz/scripts/lua/script_time_modem.lua based on the script below. just changing this line (3rd line from the end).
Code: Select all
MonitorAndControl('ModemFail','8.8.8.8','Modem Switch','Internet',5)
Where the parameter of MonitorAndControl in order are thename of Domoticz variable, the IP address to ping, the name of the Domoticz switch which controls the modem, the connection description text to display in messages and the number of minutes to increase retry time by after each off /on cycle failure.
If you don't want notifications just comment out the notifications.
script_time_modem is a time script, so Domoticz will execute it once a minute.
When ping fails then the modem switch will be turned off and you will be alerted, after a minute the modem will be switched back on, after a minute the script will check if the internet connection has been restored, if so it will alert you.
If after switching on and awaiting for 1 minute the ping still fails, then the script will wait for 5 minutes (retry time can be changed see above) and try on/off again, if still fails will try again after 10 minutes, then 15, then 20, then 25, ......... until successful.
Hopefully this is what you were looking for
Code: Select all
-- ~/home/pi/domoticz/scripts/lua/script_time_modem.lua
function timedifference(s)
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)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
function timeCount(numSec)
-- Function turns seconds into hours, minutes, seconds
local nSeconds = numSec
if nSeconds == 0 then
return "0seconds"
else
local sTime = ""
local nHours = math.floor(nSeconds/3600)
local nMins = math.floor(nSeconds/60 - (nHours*60))
if(nHours > 0) then
sTime = sTime .. nHours
if(nHours == 1) then
sTime = sTime .. "hour "
else
sTime = sTime .. "hours "
end
end
if(nMins > 0) then
sTime = sTime .. nMins
if(nMins == 1) then
sTime = sTime .. "minute "
else
sTime = sTime .. "minutes "
end
end
local nSecs = math.floor(nSeconds - nHours*3600 - nMins *60)
if(nSecs > 0) then
sTime = sTime .. nSecs
if(nSecs == 1) then
sTime = sTime .. "second"
else
sTime = sTime .. "seconds"
end
end
return sTime
end
end
function numbersum(n)
if n<0 then
return 0
else
return n + numbersum(n-1)
end
end
function MonitorAndControl(failvariable, ip, modemswitch, description,retrytime)
-- failvariable is name of Domoticz variable create and set to 0
-- ip address to test for connectivity
-- modemswitch name of Domoticz switch which connects
-- description the text to put into the status message
-- retrytime minutes to increase time before next off / on
print('Checking ' .. description)
local failstate = tonumber(uservariables[failvariable])
local ping_success=os.execute('ping -c1 -W1 ' .. ip )
local interval = timedifference(uservariables_lastupdate[failvariable])
if ping_success then
print('Ping success')
if(failstate > 0) then
interval = 60 *(math.floor(failstate/2)+retrytime*numbersum(math.floor(failstate/2)-1)) + timedifference(uservariables_lastupdate[failvariable])
print('Link to '..description..' restored after ' .. timeCount(interval))
-- os.execute(TelegramScript..' msg '..TelegramTo..' "Restored - back in contact with '.. description ..' after ' .. timeCount(interval) .. '"')
commandArray['SendNotification']=description..'#Restored - back in contact with '.. description ..' after ' .. timeCount(interval) .. '#0'
commandArray['Variable:'..failvariable] = '0'
end
else
print('Ping fail: '..failstate)
-- Failstate is even
if(failstate-2*math.floor(failstate/2)==0) then
if(failstate == 0) then
-- Only just failed so switch off the switch
print(description .. ' Failed')
-- os.execute(TelegramScript..' msg '..TelegramTo..' "Failed - lost contact with ' .. description .. '"')
commandArray['SendNotification']=description..'#Failed - lost contact with ' .. description .. '#0'
commandArray[modemswitch] = 'Off'
-- Ping failed so increment failstate
commandArray['Variable:'..failvariable] = tostring(failstate+1)
elseif(failstate > 1 and interval > (math.floor(failstate/2)*retrytime*60)-30) then
-- Still no response after (n / 2 * retrytime) so switch off again
commandArray[modemswitch] = 'Off'
-- Ping failed so increment failstate
commandArray['Variable:'..failvariable] = tostring(failstate+1)
print('Switching off: '..interval..'seconds - even - failed # '..failstate)
end
else
-- Failstate is odd
-- Switch been off for a minute so time to switch it on again
commandArray[modemswitch] = 'On'
-- Ping failed so increment failstate
commandArray['Variable:'..failvariable] = tostring(failstate+1)
print('Switching On: '..interval..'seconds - odd - failed # '..failstate)
end
end
return
end
commandArray = {}
--TelegramScript=os.getenv("TelegramScript")
--TelegramTo=os.getenv("TelegramTo")
print('About to monitor things')
MonitorAndControl('ModemFail','8.8.8.8','Modem Switch','Internet',5)
print('Finished monitoring things')
return commandArray
In fact it would nice to write a Bash script to do this, as the need for integration with Domoticz is fairly weak and it would be one less load on Domoticz which cron could cope with very well. However, the logic to allow increasing times between retries / keeping track of time etc. is not what Bash is meant for, hence more sensible to do in Lua.
Raspberry Pi 2 B - 2A@5V PSU - Raspbian + Domoticz + RFXtrx(89), LightwaveRF House(dimmers, sockets, wireless/mood switches), Owl CM113, 4 LaCross Temp / Humidity Sensors, 4 Siemens PIR, Smappee, Solaredge, ESP8266