Adding a "level" to VirtualSwitch objects

I’m working on an easier way for Veralite to share info with my old automation system (MisterHouse).

My plan is to have some virtual switches that I monitor with PLEG. When status changes in Vera, I’ll send an HTTP call to MisterHouse to have MisterHouse update the light. I can do the same from the MisterHouse side and use “variableset” to let Veralite know when the status changes in Misterhouse.

This is pretty straightforward for ON/OFF behaviors.

But now I’m finding that I’d like to implement LEVEL. I figure there are two ways to go:

[ul][li]Update the VirtualSwitch plugin to implement a virtual LoadLevelStatus - I’ve dug through the vswitch plugin files and am overwhelmed[/li]
[li]Add a variable to each VirtualSwitch object to keep track of the level. I realize that this wouldn’t be available in the GUI, but I’d do enough for my needs. I found one thread that discussed adding custom variables, but it didn’t get in-depth enough to include code snippets. I’m concerned about adding the variable in a way that won’t break the virtual switch for use in external apps.[/li][/ul]

Can someone give me some advice here? Is there a better way?

You should be able to create a Virtual Dimmer … Then it will have both on and off
as well as values from 0 - 100.
This should show up on most 3rd party apps as well … and PLEG should be able to interact with it (via actions, triggers, and properties)

I agree.

I’ve dug through the files for the virtual switch plugin and this is definitely beyond my skills. Is that something that I could commission you to help me with?

I will put it on my list … If I get some time to look at it.

You could install MiLightWU1 and either delete the few lines from the implementation file that handle the UDP sending or just give it a non-existent IP address… The plugin is here.

Thanks, RexBeckett - I’ll see if I can work that out. Would that code be in the L_ file?

If it’s clear enough, I may be able to wrangle it to make the HTTP calls directly to MisterHouse w/o intervening PLEG code!

You could do that … but then you will not be able to use the device for other purposes.
Tomorrow you might need two more virtual dimmers for other purposes.

Look in I_MiLightWU1.xml

For a quick test, just delete lines 90-98 (the body of the function keepAlive) and lines 102-107 (the body of the function sendUDP). That will stop it sending anything over UDP. It will still maintain the Target, Status, LoadLevelTarget and LoadLevelStatus variables according to actions that are called or UI buttons and slider.

If you decide to use it long-term, you may want to change the device type and file names in case you ever want to use the original plugin to control a MiLight White LED.

There are files for virtual dimmers arround in this forum, but nobody has published these on apps.mios.com (like I did with the virtual switch, I only uploaded these to apps.mios.com and did some updates and so on). For example here: http://forum.micasaverde.com/index.php/topic,8363.msg53275.html#msg53275. Search the forum to see how to install these.

What I can’t tell is how far these are supported by external apps, but at least it wouldn’t change any existing devices.

A simple example of how to execute a http call directly from the plugin and not by PLEG can be found here: http://forum.micasaverde.com/index.php/topic,16868.msg133554.html#msg133554. In this example the URL’s are defined as variables for each devices, this way you wouldn’t have to creat a specific I_ file with hard coded URL’s for each light you wish to control.

The files provided by MCVFlorin should update the appropriate values for the virtual device and reflect it in the UI. You just need to use the appropriate device type and device xml file for the corresponding virtual device.

See this post on how to upload and create the virtual device. http://forum.micasaverde.com/index.php/topic,8363.msg73557.html#msg73557

  • Garrett

[quote=“garrettwp, post:10, topic:177549”]The files provided by MCVFlorin should update the appropriate values for the virtual device and reflect it in the UI. You just need to use the appropriate device type and device xml file for the corresponding virtual device.

See this post on how to upload and create the virtual device. http://forum.micasaverde.com/index.php/topic,8363.msg73557.html#msg73557

  • Garrett[/quote]

I actually used those very instructions a while back to make a dimmer tied to my FanLincs so I could use the native fan controls in SQ Remote. Just create a device with device file D_DimmableLight1.xml and this implementation file, set your FanLincID under advanced settings and you’re all set. Don’t think I was ever able to get the FanLinc to change the dimmer but since I never use the native control it doesn’t matter to me.

On topic: you can easily change the code in the portions to do anything you want, top is for dimmer and bottom is for on/off, I believe the only required code is the two “luup.variable_set” commands to handle updating the UI

Ok. I’m pretty excited about this. I know my way around some PHP, but the Lua and the Veralite constructs are coming to me slowly. Please point out mistakes.

I started with MiLightWU1.

As RexBecket pointed out, it’s possible that I might want to use a MiLight in the future, so I started by changing:

urn:dcineco-com to urn:scottr
and MiLightWU1 to MHLight
(global search/replace)

Then I gutted the keepalive and sendUDP functions.

Then I updated the setLevel function to use inet.wget functions to talk to my old HA server.

Everything was working great. I was able to set the level and have it report to my HA server. Awesome.

I’m now working on the setOnOff function. And I’ve got it mostly working. OFF works, but with ON, I’m trying to use the existing saved loadlevel in the HTTP call. The pertinent code is:
[tt]
local lls = luup.variable_get(“urn:upnp-org:serviceId:Dimming1”,“LoadLevelStatus”,lul_dev)
luup.log("Returning to previous dim: " … tostring(lls) )
luup.inet.wget(“http://192.168.1.101:8080/bin/SET;&html_list()?$” … item_name … “=” … tostring(lls) … “%”, 1)
[/tt]

But I never see that inet.wget in the logs. I’ve learned that a successful call usually generates a “FileUtils::ReadURL” line in the log.

My guess is that I’m mixing strings with non-strings. My first programming language was Perl, so I’m bad at that kind of thing. Any advice here?

Your URL encoding looks really bad!

I’ve got a variable called item_name that holds “Dining_Room_Chandelier” and I’m getting lls that holds the result of a loadlevelstatus query.

I’m trying to concatenate something that looks like:
http://IPADDRESS:8080/bin/SET;&html_list()?$Dining_Room_Chandelier=50%

(the & in my code is &-a-m-p-; I’ve at least got that part right. )

Are there some characters I should be escaping out? I’m confused, because similar code works in my setLevel code.

It looks like escaping the string was my issue. Weird since nearly identical code (with numbers and a percent sign) worked elsewhere in the same code).

I got the following functions from something tha RTS posted:

[tt]
function to_hex(spec_char)
return string.format(“%%%2X”, spec_char:byte(1))
end
----------------------------------------------------
function escape(in_string)
return string.gsub(in_string, “%W”, to_hex)
end
----------------------------------------------------
[/tt]

And changed my code that assembles & gets the URL to:

[tt]
local args = escape(item_name … “=” … tostring(lls) … “%”)
durl = “http://192.168.1.101:8080/bin/SET;&html_list()?$” … args
luup.inet.wget(durl, 1)
[/tt]

And it appears to be working!

Thanks for everyone’s help on this.

Emboldened by my success this morning, I thought it might be nice to work in some code that periodically polls my MisterHouse server to check and see if the light level has changed over there.

I’ve got it mostly working. I’m getting the value via inet.wget, then I’m setting it locally with

luup.variable_set(“urn:upnp-org:serviceId:Dimming1”,“LoadLevelStatus”,leveln,lul_device)

(leveln is the level). It’s working - the light has the correct level if I check it with PLEG or similar. And the level “slider” is in the right place. But the icon - the bulb with the % - is out of sync. (see attached)

My guess is that I need to hook into the SetLoadLevelTarget action that I see in the XML. But I can’t figure out how to do that.

It starts like:

urn:upnp-org:serviceId:Dimming1 SetLoadLevelTarget .....

In MiLightWU1.json, I use the variable IconState to control the light-bulb icon. I did it this way so that I could leave the dim level set to the last-used value when the lamp is turned off but still have the icon reflect the state of the lamp.

The simple fix is to set IconState when you set LoadLevelStatus - as in the original code. The alternative would be to edit the json to use LoadLevelStatus to control the icon. That would be line 22 in MiLightWU1.json.

It all depends on whether you can turn your lamps off without setting the dim level to 0.

Perfect. Setting inconState worked.

Like you point out, I’m taking advantage of the fact that you were remembering the last level so that when I turn the light back ON, I use that level unless it’s explicitly set to 100%.

Thank you.

I’m glad I could help. Provided you didn’t change the device type or category, your device should be acceptable to remote software packages. Mine works perfectly with AutHomationHD - including the on/off with retained dim level.

Now you know how easy it is to write plugins, I shall expect to see more from you. ;D

Yup - It’s working great wtih AutHomationHD.

Ha! I was just thinking: I’d never be able to pull this off without a good example to work from.

Surely y’all aren’t working in notepad++ and uploading/waiting/testing as your development cycle. I think I need a better development environment. I saw some mentions of a decent Lua interpreter for Windows - I’ll take a look at that.