Add-on - Aviosys IPPower 9258
-
Ok, thanks @toggledbits , that makes sense, I’d like to get the
<files>
approach working at some point, but let’s try one with modules too.. Which means myI_IPPower.xml
will now be something like this..? With theL_IPPower.lua
having the seeall declaration this time..?<?xml version="1.0"?> <!-- I_IPPower.xml; Vera/openLuup "IPPower 9258" Plug-in V1.1 Nov 2021 --> <implementation> <functions> function initialiseIPPowerPlugin(lul_device) luup.log("IPPower Plugin START-UP!") IPPower = require("L_IPPower1") return IPPower.IPPowerStartup(lul_device) end </functions> <startup>initialiseIPPowerPlugin</startup> <actionList>
-
Oh no., somethings gone wrong, it’s now finding the start up but it’s going into some sort of loop of child device creations - and continual luup.reloads !!??
The function called by the implementation file is still this..
-- Initialize plug-in function IPPowerStartup(lul_device) -- set attributes for parent device luup.attr_set( "name", "IPPower 9258", lul_device) luup.attr_set( "category_num", "3", lul_device) luup.attr_set( "subcategory_num", "1", lul_device) luup.variable_set("urn:nodecentral-net:serviceId:IPPower1", "Icon", 1, lul_device) luup.variable_set("urn:nodecentral-net:serviceId:IPPower1", "PluginVersion", PV, lul_device) log("Start up, Parent device created...") child_devices = luup.chdev.start(lul_device) -- Tells Luup to start enumerating children for this device based on it's dev_id for v = OUTLET_START,OUTLET_END do luup.chdev.append(lul_device,child_devices, "P" .. v, " Outlet " .. v, "urn:nodecentral-net:device:IPPower:1", "D_IPPower1.xml", "", "", false) debug("Child device created with id = P" .. v, " and description = Switch" .. v) end luup.chdev.sync(lul_device, child_devices) for k, v in pairs(luup.devices) do if (v.device_num_parent == lul_device) then -- populate child device table childDeviceIndex[v.id]=k end end checkIPPowerSetUp(lul_device) end
-
From what I can see for the Log file extract, it seems to keep incrementing (deleting and creating) the child devices ?
50 11/14/21 21:06:20.986 luup_log:600: IPPower Plugin START-UP! <0x76db4520> 06 11/14/21 21:06:20.990 Device_Variable::m_szValue_set device: 600 service: urn:nodecentral-net:serviceId:IPPower1 variable: Icon was: 1 now: 1 #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:1 <0x76db4520> 06 11/14/21 21:06:20.990 Device_Variable::m_szValue_set device: 600 service: urn:nodecentral-net:serviceId:IPPower1 variable: PluginVersion was: 1.1 now: 1.1 #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:1 <0x76db4520> 01 11/14/21 21:06:20.990 luup_log:600: IPPower: Start up, Parent device created... <0x76db4520> 50 11/14/21 21:06:20.991 luup_log:600: IPPower: debug: Child device created with id = P61 <0x76db4520> 50 11/14/21 21:06:20.991 luup_log:600: IPPower: debug: Child device created with id = P62 <0x76db4520> 50 11/14/21 21:06:20.992 luup_log:600: IPPower: debug: Child device created with id = P63 <0x76db4520> 50 11/14/21 21:06:20.992 luup_log:600: IPPower: debug: Child device created with id = P64 <0x76db4520> 50 11/14/21 21:06:20.992 luup_log:600: IPPower: debug: Child device created with id = P65 <0x76db4520> 50 11/14/21 21:06:20.992 luup_log:600: IPPower: debug: Child device created with id = P66 <0x76db4520> 50 11/14/21 21:06:20.993 luup_log:600: IPPower: debug: Child device created with id = P67 <0x76db4520> 50 11/14/21 21:06:20.993 luup_log:600: IPPower: debug: Child device created with id = P68 <0x76db4520> 09 11/14/21 21:06:20.993 Child_Devices::ProcessChildDevice deleting device 889 id P61 room 0 desc Outlet 61 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.011 UserData::CommitToDatabase data size 86066 86066 <0x76db4520> 02 11/14/21 21:06:21.107 Device_Basic::m_sDescription_set device 897. description: Outlet 61 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 61 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.109 Child_Devices::ProcessChildDevice created device 897 id P61 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.110 Child_Devices::ProcessChildDevice deleting device 890 id P62 room 0 desc Outlet 62 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.234 UserData::CommitToDatabase data size 85500 85500 <0x76db4520> 02 11/14/21 21:06:21.240 Device_Basic::m_sDescription_set device 898. description: Outlet 62 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 62 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.244 Child_Devices::ProcessChildDevice created device 898 id P62 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.244 Child_Devices::ProcessChildDevice deleting device 891 id P63 room 0 desc Outlet 63 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.376 UserData::CommitToDatabase data size 84934 84934 <0x76db4520> 02 11/14/21 21:06:21.381 Device_Basic::m_sDescription_set device 899. description: Outlet 63 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 63 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.386 Child_Devices::ProcessChildDevice created device 899 id P63 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.386 Child_Devices::ProcessChildDevice deleting device 892 id P64 room 0 desc Outlet 64 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.491 UserData::CommitToDatabase data size 84368 84368 <0x76db4520> 02 11/14/21 21:06:21.494 Device_Basic::m_sDescription_set device 900. description: Outlet 64 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 64 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.497 Child_Devices::ProcessChildDevice created device 900 id P64 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.497 Child_Devices::ProcessChildDevice deleting device 893 id P65 room 0 desc Outlet 65 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.568 UserData::CommitToDatabase data size 83802 83802 <0x76db4520> 02 11/14/21 21:06:21.572 Device_Basic::m_sDescription_set device 901. description: Outlet 65 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 65 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.575 Child_Devices::ProcessChildDevice created device 901 id P65 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.575 Child_Devices::ProcessChildDevice deleting device 894 id P66 room 0 desc Outlet 66 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.645 UserData::CommitToDatabase data size 83236 83236 <0x76db4520> 02 11/14/21 21:06:21.649 Device_Basic::m_sDescription_set device 902. description: Outlet 66 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 66 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.652 Child_Devices::ProcessChildDevice created device 902 id P66 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.652 Child_Devices::ProcessChildDevice deleting device 895 id P67 room 0 desc Outlet 67 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.722 UserData::CommitToDatabase data size 82670 82670 <0x76db4520> 02 11/14/21 21:06:21.726 Device_Basic::m_sDescription_set device 903. description: Outlet 67 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 67 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.728 Child_Devices::ProcessChildDevice created device 903 id P67 under 600 topmost parent 600 <0x76db4520> 09 11/14/21 21:06:21.729 Child_Devices::ProcessChildDevice deleting device 896 id P68 room 0 desc Outlet 68 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 under 600 topmost parent 600 because type o:urn:schemas-micasaverde-com:device:GenericIO:1!=n:urn:nodecentral-net:device:IPPower:1 or file o:D_IPPower1.xml!=n:D_IPPower1.xml embedded o:0!=n:0 ok:0/1 <0x76db4520> 02 11/14/21 21:06:21.798 UserData::CommitToDatabase data size 82104 82104 <0x76db4520> 02 11/14/21 21:06:21.802 Device_Basic::m_sDescription_set device 904. description: Outlet 68 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 exist already, new Description: Outlet 68 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <0x76db4520> 09 11/14/21 21:06:21.805 Child_Devices::ProcessChildDevice created device 904 id P68 under 600 topmost parent 600 <0x76db4520> 06 11/14/21 21:06:21.805 Device_Variable::m_szValue_set device: 1 service: urn:micasaverde-com:serviceId:ZWaveNetwork1 variable: LastDongleBackup was: now: #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:1 <0x76db4520> 01 11/14/21 21:06:21.830 UserData::WriteUserData saved--before move File Size: 22154 save size 22154 <0x76bb4520> 02 11/14/21 21:06:21.831 UserData::TempLogFileSystemFailure start 0 <0x76bb4520> 02 11/14/21 21:06:21.847 UserData::TempLogFileSystemFailure (not failure, only WriteUserData) 0 <0x76bb4520> 02 11/14/21 21:06:21.848 UserData::TempLogFileSystemFailure 699 res:1
-
You have to be super-careful with how you structure your luup.chdev work. If the loop creates or deletes any child, then the
sync()
will cause a restart, so it's very easy to get reload loops. -
You have to be super-careful with how you structure your luup.chdev work. If the loop creates or deletes any child, then the
sync()
will cause a restart, so it's very easy to get reload loops.@toggledbits said in Add-on - Aviosys IPPower 9258:
You have to be super-careful with how you structure your luup.chdev work. If the loop creates or deletes any child, then the
sync()
will cause a restart, so it's very easy to get reload loops.Agreed, and it’s my first attempt at doing this, and i even remember making a note of the warning on the wiki - http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#Module:_luup.chdev .
When the final luup.chdev.sync is executed the children are checked. Any additions, changes or deletions will result in a Luup engine restart. Any incorrect coding of luup.chdev.append may result in a situation where the engine goes into a loop and continually restarts. As an example, if two children are added with the same id parameter, this will occur. To recover, you need to quickly upload a new file that has the faulty "append" code commented out. In the interim the engine will be incrementing the device ID numbers with no end in sight.
I can’t work out why the chdev is doing that , can you see any issue with my chdev.start and append that would cause the sync to do that ?
local OUTLET_START = 61 -- API returns the first socket as P61 local OUTLET_END = 68 -- depending on your device, it can be a 4 or 8 port, so 64 or 68 child_devices = luup.chdev.start(lul_device) -- Tells Luup to start enumerating children for this device based on it's dev_id , this returns: ptr (binary object) which is used in the cheer.append. for v = OUTLET_START,OUTLET_END do luup.chdev.append(lul_device,child_devices, "P" .. v, " Outlet " .. v, "urn:nodecentral-net:device:IPPower:1", "D_IPPower1.xml", "", "", false) debug("Child device created with id = P" .. v, " and description = Switch" .. v) end luup.chdev.sync(lul_device, child_devices) for k, v in pairs(luup.devices) do if (v.device_num_parent == lul_device) then -- populate child device table childDeviceIndex[v.id]=k end end
-
I’ve discovered that if I change the chdev.append so it creates a different device (see below), i don’t seem to get the loop issue.
I assume this is likely due to the previous set up had the append calling the same implementation file as the parent, which looks to create children - thus triggers a loop ?
for v = OUTLET_START,OUTLET_END do luup.chdev.append(lul_device,child_devices, "P" .. v, " Outlet " .. v, "urn:schemas-upnp-org:device:BinaryLight:1", "D_BinaryLight1.xml", "", "", false) end
-
Since you have
handleChildren
set to 1 in the D_.xml (device) file, the children should not receive an implementation file at all (it should be blank/empty string inappend()
). And it seems right that the children also should not have the same device type as the parent. -
Agreed, many thanks .
Well it looks like I’m almost there now, the only thing left to fix is the the luup.call_timer I have on the main polling function in L_IPPower1.lua file .
Here’s the function..
function IPPowerPoller() -- Call IPPower to return state of each outlet local user = "admin" local pass = "12345678" debug("Started Polling IPPower Device") local url = "http://" .. ipAddress .. "/set.cmd?user=".. user .. "+pass=" .. pass .. "+cmd=getpower" debug("Calling URL " .. url) local status, data = luup.inet.wget(url) if (data) then debug("Response received " .. data) -- Example response is "P61=0,P62=1,P63=0,P64=0,P65=1,P66=0,P67=0,P68=0" else log("Empty response returned") end for v = OUTLET_START,OUTLET_END do local value = string.match(data, "P"..v.."=(%d)") if (value) then luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", value, childDeviceIndex["P"..v]) else log("Empty value returned") end end debug("Finished Polling IPPower Device") luup.call_timer("IPPowerPoller", 1, 30, "", "") end
Which returns this..
01 11/15/21 0:00:58.100 LuaInterface::CallFunction_Timer-5 function IPPowerPoller failed attempt to call a nil value <0x74e48520>
I might just be tired, but I can’t work out the cause here, any ideas?
I’ve made it a local and a global function, called it with and without the module name, all return the same nil value error?
-
Agreed, many thanks .
Well it looks like I’m almost there now, the only thing left to fix is the the luup.call_timer I have on the main polling function in L_IPPower1.lua file .
Here’s the function..
function IPPowerPoller() -- Call IPPower to return state of each outlet local user = "admin" local pass = "12345678" debug("Started Polling IPPower Device") local url = "http://" .. ipAddress .. "/set.cmd?user=".. user .. "+pass=" .. pass .. "+cmd=getpower" debug("Calling URL " .. url) local status, data = luup.inet.wget(url) if (data) then debug("Response received " .. data) -- Example response is "P61=0,P62=1,P63=0,P64=0,P65=1,P66=0,P67=0,P68=0" else log("Empty response returned") end for v = OUTLET_START,OUTLET_END do local value = string.match(data, "P"..v.."=(%d)") if (value) then luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", value, childDeviceIndex["P"..v]) else log("Empty value returned") end end debug("Finished Polling IPPower Device") luup.call_timer("IPPowerPoller", 1, 30, "", "") end
Which returns this..
01 11/15/21 0:00:58.100 LuaInterface::CallFunction_Timer-5 function IPPowerPoller failed attempt to call a nil value <0x74e48520>
I might just be tired, but I can’t work out the cause here, any ideas?
I’ve made it a local and a global function, called it with and without the module name, all return the same nil value error?
@parkerc said in Add-on - Aviosys IPPower 9258:
I might just be tired, but I can’t work out the cause here, any ideas?
I’ve made it a local and a global function, called it with and without the module name, all return the same nil value error?If you're getting the same
nil
error, you're somehow not making a global, or making it with the correct name/using the correct name. In order to help there, I'd need to see the current I_ and L_ files in their entirety.But before you do that, I think you said you were looking at the SiteSensor code as an example, and you invoked the "module" word, so... in the I_SiteSensor file, look at how I create a global called
siteSensorWatch
that is an alias for the module's function. This creates a global, which must be done in the scope of the implementation (I_) file if the L_ file is a module. Then in my L_SiteSensor module, you can see in theluup.variable_watch
statements where I'm using that name -- the function name parameter for that works the same as it does forcall_delay
andcall_timer
. Check that out, and see if you can work out what you didn't get to there. -
@parkerc said in Add-on - Aviosys IPPower 9258:
I might just be tired, but I can’t work out the cause here, any ideas?
I’ve made it a local and a global function, called it with and without the module name, all return the same nil value error?If you're getting the same
nil
error, you're somehow not making a global, or making it with the correct name/using the correct name. In order to help there, I'd need to see the current I_ and L_ files in their entirety.But before you do that, I think you said you were looking at the SiteSensor code as an example, and you invoked the "module" word, so... in the I_SiteSensor file, look at how I create a global called
siteSensorWatch
that is an alias for the module's function. This creates a global, which must be done in the scope of the implementation (I_) file if the L_ file is a module. Then in my L_SiteSensor module, you can see in theluup.variable_watch
statements where I'm using that name -- the function name parameter for that works the same as it does forcall_delay
andcall_timer
. Check that out, and see if you can work out what you didn't get to there.@toggledbits said in Add-on - Aviosys IPPower 9258:
…… in the I_SiteSensor file, look at how I create a global called
siteSensorWatch
that is an alias for the module's function. This creates a global, which must be done in the scope of the implementation (I_) file if the L_ file is a module.I had a look in your Implementation file , but could not see anything called
siteSensorWatch
listed?Here is the opening of my a I_IPPower.xml` Implementation file..
<?xml version="1.0"?> <!-- I_IPPower.xml; Vera/openLuup "IPPower 9258" Plug-in V1.1 Nov 2021 --> <implementation> <functions> function initialiseIPPowerPlugin(lul_device) luup.log("IPPower: IPPower Plugin STARTING-UP!") IPPower = require("L_IPPower1") return IPPower.IPPowerStartup(lul_device) end </functions> <startup>initialiseIPPowerPlugin</startup> <actionList> <action>
@toggledbits said in Add-on - Aviosys IPPower 9258:
Then in my L_SiteSensor module, you can see in the
luup.variable_watch
statements where I'm using that name -- the function name parameter for that works the same as it does forcall_delay
andcall_timer
. Check that out, and see if you can work out what you didn't get to there.Right, I’m on it, I couldn’t find any luup.variable_watch calls, but I did find a
luup.call_delay
in yourL_SiteSensor
luup.call_delay("siteSensorRunQuery", delay, string.format("%d:%d", stamp, dev))
Which links to the following assocation in your siteSensor Implementation file
siteSensorRunQuery = SiteSensor.runQuery
So that’s where I’ll focus..
-
Sorry, I'm always looking at the development version, but you've followed the right trail.
runQuery
works the same way. -
Thanks @toggledbits - it’s all working now !!
My last piece is back to my other post around error handling, and how I can present that better to the user, and so for that topic, I;ll revert back to that thread.. - > https://smarthome.community/topic/777/luup-error-handling/9