I'm reading my MikroTik router (RB2011UiAS-2HnD-IN) out through REST-API and get a json readout back like this;
I'm reading all dhcp-server-leases with status 'waiting', those are the devices away/not home/ The switch Earn will turn off then, like you see here;
Code: Select all
[{".id":"*123","address":"192.168.xx.xx","address-lists":"","blocked":"false","client-id":"123456789","comment":"Laptop Earn","dhcp-option":"","disabled":"false","dynamic":"false","host-name":"LAPTOP-2018","last-seen":"14h4m17s","mac-address":"123456789","radius":"false","server":"defconf","status":"waiting"},{".id":"*124","address":"192.168.xx.xx","address-lists":"","age":"6d23h13m33s","blocked":"false","client-id":"123456789","comment":"iPhone_Earn","dhcp-option":"","disabled":"false","dynamic":"false","last-seen":"5h23m42s","mac-address":"123456789","radius":"false","server":"defconf","status":"waiting"}]
Code: Select all
local api_data = domoticz.utils.fromJSON(item.data)
Code: Select all
2022-08-17 12:31:01.922 Status: dzVents: 1:
2022-08-17 12:31:01.922 Status: dzVents: client-id: 123456789
2022-08-17 12:31:01.922 Status: dzVents: last-seen: 11h4m15s
2022-08-17 12:31:01.922 Status: dzVents: .id: *123
2022-08-17 12:31:01.922 Status: dzVents: host-name: LAPTOP-2018
2022-08-17 12:31:01.923 Status: dzVents: disabled: false
2022-08-17 12:31:01.923 Status: dzVents: address: 192.168.xx.xx
2022-08-17 12:31:01.923 Status: dzVents: status: waiting
2022-08-17 12:31:01.923 Status: dzVents: server: defconf
2022-08-17 12:31:01.923 Status: dzVents: radius: false
2022-08-17 12:31:01.923 Status: dzVents: address-lists:
2022-08-17 12:31:01.923 Status: dzVents: blocked: false
2022-08-17 12:31:01.923 Status: dzVents: mac-address: 123456789
2022-08-17 12:31:01.923 Status: dzVents: dynamic: false
2022-08-17 12:31:01.923 Status: dzVents: comment: Laptop Earn
2022-08-17 12:31:01.923 Status: dzVents: dhcp-option:
2022-08-17 12:31:01.923 Status: dzVents: 2:
2022-08-17 12:31:01.923 Status: dzVents: client-id: 123456789
2022-08-17 12:31:01.923 Status: dzVents: last-seen: 4h57m41s
2022-08-17 12:31:01.923 Status: dzVents: .id: *124
2022-08-17 12:31:01.923 Status: dzVents: status: waiting
2022-08-17 12:31:01.923 Status: dzVents: disabled: false
2022-08-17 12:31:01.923 Status: dzVents: address: 192.168.xx.xx
2022-08-17 12:31:01.923 Status: dzVents: age: 5d23h9m9s
2022-08-17 12:31:01.923 Status: dzVents: server: defconf
2022-08-17 12:31:01.923 Status: dzVents: radius: false
2022-08-17 12:31:01.923 Status: dzVents: address-lists:
2022-08-17 12:31:01.923 Status: dzVents: blocked: false
2022-08-17 12:31:01.923 Status: dzVents: mac-address: 123456789
2022-08-17 12:31:01.923 Status: dzVents: dynamic: false
2022-08-17 12:31:01.923 Status: dzVents: comment: iPhone Earn
2022-08-17 12:31:01.923 Status: dzVents: dhcp-option:
Code: Select all
notfound=string.upper(tostring(api_data[index].comment))
If a 'waiting' device doesnt have a comment, and this notfound var is nil, it will show 'NIL' and the loop will return
Now we are at home it keeps the home switch switched on/at home
The problem that's happening is that once the person is away/not home, and the notfound var is filled with the name of the device
The actual value gathered by
Code: Select all
(string.match(notfound, uearn) == uearn
But supposedly there is something going on resulting in this situation Earn is turned on, 5 min later off, then on, then off, etc
I tried so many things already and really don't see what i'm doing wrong, could any of you please help me or point me in the right direction, a hint will be apreciated too
This is the script
Code: Select all
--MAIN
return {
on = {
devices = {'Motion',
'MotionCouch',
--'MotionLiving',
'MotionStairs',
'Maikel',
'PC_Maikel_locked',
'Earn',
'Sleep'
},
timer = {'every 5 minutes'},
shellCommandResponses = {
'restapi' -- must match with the callback passed to the executeShellCommand
},
variables = {},
scenes = {},
groups = {},
security = {},
httpResponses = {},
customEvents = {},
system = {},
},
data = {},
logging = {},
execute = function(domoticz, item)
local motiondev=domoticz.devices('Motion') -- motion sensor
local mocouch=domoticz.devices('MotionCouch')
--local mowork=domoticz.devices('MotionWork')
local motionliv=domoticz.devices('MotionLiving')
local mostairs=domoticz.devices('MotionStairs') --motion to detect upstairs/sleep
local presencebed=domoticz.devices('MotionBed') --switch to register presence in the bedroom + delay
local someone=domoticz.devices('Home') -- info
local sleep=domoticz.devices('Sleep') -- helpswitch gotosleep scene
local sleepmin=120 --minimal amount minutes that sleep switch will be on
local holidaybed=domoticz.devices('HolidayBed') -- holiday
local holiday=domoticz.devices('Holiday') -- holiday
local maikel=domoticz.devices('Maikel') -- maikel home
local earn=domoticz.devices('Earn') -- earn home
local maikellocked=domoticz.devices('PC_Maikel_locked')
local laptopmaikel=domoticz.devices('LaptopMaikel')
local laptopearn=domoticz.devices('LaptopEarn')
local pm25us=domoticz.devices('AirQualityPM25us')
local pm25lvl=domoticz.devices('AirQualityLevel25us')
local pm25unsafe=56
--local camhome=domoticz.devices('SecurityCamHome') --home switch for surveillance camera sw
local dining=domoticz.devices('Dining')
local couch=domoticz.devices('HueCouch') -- light couch
local stairs=domoticz.devices('HueStairs') -- light stairs
local delay=30
local usermaikel=domoticz.variables('user1') --usermaikel.value holds 'Maikel'
local userearn=domoticz.variables('user2') --userearn.value holds 'Earn'
--change MotionLiving according to any motion in the (living) room
if (domoticz.time.matchesRule('every 4 hours') and holiday.state == 'Off' and (motiondev.lastUpdate.hoursAgo >= 15 or mocouch.lastUpdate.hoursAgo >= 15)) then
domoticz.notify('One of the motionsensors is offline')
end
if (motiondev.state == 'On' or mocouch.state == 'On' or maikellocked.state == 'Off') then
motionliv.switchOn().checkFirst()
else
motionliv.switchOff().checkFirst()
end
--turn sleepswitch off and system back on when awake again
if (sleep.state == 'On' and mostairs.state == 'On' and presencebed.state == 'On'
and sleep.lastUpdate.minutesAgo > sleepmin and sleep.lastUpdate.minutesAgo < 1440 --sleep minimal 2 hours, 1440=one day
and not domoticz.time.matchesRule('at 5:40-7:15 on mon,tue,wed,thu,fri') --during going to work
and not domoticz.time.matchesRule('between 90 minutes before sunrise and sunrise') ) then --nighttime
sleep.switchOff()
end
if (sleep.state == 'On' and (sleep.lastUpdate.minutesAgo >= 1440
or (maikel.state == 'Off' and earn.state == 'Off' and maikel.lastUpdate.minutesAgo > 5 and earn.lastUpdate.minutesAgo > 5) )) then
sleep.switchOff()
end
--maikel comes home
if (maikel.lastUpdate.secondsAgo < 5 and maikel.active and maikel.state == 'On' and motiondev.state == 'Off') then --motiondev because its in the middel ot room
if (couch.state == 'Off' or stairs.state == 'Off' or someone.lastUpdate.minutesAgo < 5) then
domoticz.notify('Welcome home Maikel, I turn the lights on for you')
else
domoticz.notify('Welcome home Maikel')
end
--camhome.switchOn().checkFirst().silent()
someone.updateAlertSensor(domoticz.ALERTLEVEL_GREEN,'SOMEONE IS IN THE LIVINGROOM')
--maikel leaves home
elseif (maikel.lastUpdate.secondsAgo < 5 and maikel.active and maikel.state == 'Off') then
if (pm25us.sensorValue > pm25unsafe) then
domoticz.notify('Have a safe trip Maikel, be careful, pm2.5 levels are '..pm25lvl.text..'!')
else
domoticz.notify('Have a safe trip Maikel')
end
--camhome.switchOff().checkFirst().silent()
end
--earn comes home
if (earn.lastUpdate.secondsAgo < 5 and earn.active and earn.state == 'On' and motiondev.state == 'Off') then --motiondev because its in the middel ot room
if (couch.state == 'Off' or stairs.state == 'Off' or someone.lastUpdate.minutesAgo < 5) then
domoticz.notify('Welcome home Earn, I turn the lights on for you')
else
domoticz.notify('Welcome home Earn')
end
--camhome.switchOn().checkFirst().silent()
someone.updateAlertSensor(domoticz.ALERTLEVEL_GREEN,'SOMEONE IS IN THE LIVINGROOM')
--earn leaves home
elseif (earn.lastUpdate.secondsAgo < 5 and earn.active and earn.state == 'Off') then
if (pm25us.sensorValue > pm25unsafe) then
domoticz.notify('Have a safe trip Earn, be careful, pm2.5 levels are '..pm25lvl.text..'!')
else
domoticz.notify('Have a safe trip Earn')
end
--camhome.switchOff().checkFirst().silent()
end
--motion detected, someone home (cats downstair or were upstairs)
--if ((motiondev.state == 'On' or mocouch.state == 'On' or mowork.state == 'On') and (motiondev.lastUpdate.secondsAgo <= 60 or mocouch.lastUpdate.secondsAgo <= 60 or mowork.lastUpdate.secondsAgo <= 60) and someone.lastUpdate.minutesAgo > 5) then --someone.lastUpdate.minutesAgo > 5) then
if (motionliv.state == 'On') then --someone.lastUpdate.minutesAgo > 5) then
someone.updateAlertSensor(domoticz.ALERTLEVEL_GREEN,'SOMEONE IS IN THE LIVINGROOM')
--no motion for 30 min, noone there, if in sleep mode it will not check the motion detectors, the scene will turn off sleep mode after 35 min
--elseif ((maikel.lastUpdate.minutesAgo > 5 and motiondev.state == 'Off' and mocouch.state == 'Off' and mowork.state == 'Off' and someone.lastUpdate.minutesAgo >= delay and someone.lastUpdate.minutesAgo < delay+5 and someone.color == 1) or sleep.state == 'On' and someone.color == 1) then
elseif ((motionliv.state == 'Off' and maikel.lastUpdate.minutesAgo > 5 and someone.lastUpdate.minutesAgo >= delay and
someone.lastUpdate.minutesAgo < delay+5 and someone.color == 1) or sleep.state == 'On' and someone.color == 1) then
--camhome.switchOff().checkFirst()
if (couch.state == 'On' or stairs.state == 'On') then
domoticz.notify('No one is in the Livingroom for '..someone.lastUpdate.minutesAgo..' min, I turn the lights off for you')
end
someone.updateAlertSensor(domoticz.ALERTLEVEL_GREY,'No one is in the Livingroom').silent()
end
--domoticz.log('VALUE: '..someone.color)
--someone.updateAlertSensor(domoticz.ALERTLEVEL_GREY,'No one is in the Livingroom')
--someone.updateAlertSensor(domoticz.ALERTLEVEL_GREEN,'SOMEONE IS IN THE LIVINGROOM')
if (item.isTimer or item.name == 'Motion' or item.name == 'MotionCouch') then
domoticz.executeShellCommand({
command = 'curl --netrc-file /home/pi/domoticz/scripts/bashscrips/fietsdopje._netrc "https://MTrouter/rest/ip/dhcp-server/lease?status=waiting"',
callback = 'restapi', -- see shellCommandResponses above.
timeout = 20, -- Max runtime 20 seconds
})
end --isTimer
if (item.isShellCommandResponse and item.statusCode~=0 and item.callback ~= 'restapi') then
domoticz.log('ERROR item.statusCode: '..item.statusCode..' item.callback'..item.callback, domoticz.LOG_FORCE)
end
--FROM HERE THE MIKROTIK DATA IS PROCESSED
if (item.isShellCommandResponse) then -- and item.statusCode==0 and item.callback == 'restapi') then
local api_data = domoticz.utils.fromJSON(item.data)
local umaikel = string.upper(usermaikel.value)
local uearn = string.upper(userearn.value)
local phone = string.upper('phone')
local laptop = string.upper('laptop')
--local comment1 = api_data[1].comment --array/table
--local comment2 = api_data[2].comment
for index, x in ipairs(api_data) do
--domoticz.log(index .. ': '.. tostring(value), domoticz.LOG_FORCE)
notfound=string.upper(tostring(api_data[index].comment))
notfound2=string.upper(tostring(api_data[index].comment))
--local text=string.match(notfound, uearn)
--local text2=string.match(notfound, phone)
--domoticz.log('earn: '..uearn,domoticz.LOG_FORCE)
--domoticz.log('text: '..text,domoticz.LOG_FORCE)
--domoticz.log('phone: '..text2,domoticz.LOG_FORCE)
if (notfound == 'NIL') then
do return end --break out of loop when item without comment is found
end
domoticz.log('notfound: '..notfound, domoticz.LOG_FORCE)
--earn phone
if ((string.match(notfound, uearn) == uearn) and (string.match(notfound2, phone) == phone)) then
earn.switchOff().checkFirst() --finding EARN and PHONE because not home
elseif not((string.match(notfound, uearn) == uearn) and (string.match(notfound2, phone) == phone)) then
earn.switchOn().checkFirst() --should NOT find earn AND phone when at home: NOT AND = NAND gate
end
--maikel phone
if ((string.match(notfound, umaikel) == umaikel) and (string.match(notfound2, phone) == phone)) then
maikel.switchOff().checkFirst()
elseif not((string.match(notfound, umaikel) == umaikel) and (string.match(notfound2, phone) == phone)) then
maikel.switchOn().checkFirst()
end
--earn laptop
if ((string.match(notfound, uearn) == uearn) and (string.match(notfound2, laptop) == laptop)) then
laptopearn.switchOff().checkFirst()
elseif not((string.match(notfound, uearn) == uearn) and (string.match(notfound2, laptop) == laptop)) then
laptopearn.switchOn().checkFirst()
end
end -- end for
if (api_data == nil) then
maikel.switchOn().checkFirst()
earn.switchOn().checkFirst()
laptopearn.switchOn().checkFirst()
end
end --end shellCommandResponses
end
}
Version: 2022.1
Build Hash: c9526851b
Compile Date: 2022-01-31 15:34:32
dzVents Version: 3.1.8