how-to: mirroring select openLuup devices/variables on real Vera

Yup, this works well… see attached

Ok, I’ll give that a shot then. Thx.

So, I’ve actually implemented this in bridge already (in testing as we speak.)

What are you planning?

I was trying to push some config changes over for a bridged plugin device.

Do you have the JSON used in the DataStorage provider variable for ALTUI? It’s my first look at this.

Cheers Rene

The code I’m using for the mirrors (which doesn’t generate a plot, so that JSON variable is commented out) is lifted directly fromthe DataYours DataWatcher daemon and looks like this:

-- register VeraBridge as an AltUI Data Storage Provider
local function register_AltUI_Data_Storage_Provider ()
  local MirrorCallback    = "HTTP_VeraBridgeMirror_" .. ip
  local MirrorCallbackURL = "http://127.0.0.1:3480/data_request?id=lr_" .. MirrorCallback
  
  local AltUI
  for devNo, d in pairs (luup.devices) do
    if d.device_type == "urn:schemas-upnp-org:device:altui:1" 
    and d.device_num_parent == 0 then   -- look for it on the LOCAL machine (might be bridged to another!)
      AltUI = devNo
      break
    end
  end
  
  if not AltUI then return end
  
  luup.log ("registering with AltUI [" .. AltUI .. "] as Data Storage Provider")
  _G[MirrorCallback] = MirrorHandler
  luup.register_handler (MirrorCallback, MirrorCallback)
  
  local newJsonParameters = {
    {
        default = "device.serviceId.name",
        key = "mirror",
        label = "Mirror",
        type = "text"
--      },{
----        default = "http://"..ip..":3480/data_request?id=lr_render&target={0}&hideLegend=true&height=250&from=-y",
--        default = "/data_request?id=lr_" .. MirrorCallback,
--        key = "graphicurl",
--        label = "Graphic Url",
--        type = "url"
      }
    }
  local arguments = {
    newName = "Vera@" .. ip,
    newUrl = MirrorCallbackURL .. "&target={0}",
    newJsonParameters = json.encode (newJsonParameters),
  }

  luup.call_action ("urn:upnp-org:serviceId:altui1", "RegisterDataProvider", arguments, AltUI)
end

Note that:

[ul][li]HTTP handlers for plugins (like VeraBridge) which can have multiple instances need unique request names[/li]
[li]You may have machines bridged to openLuup which, themselves, run AltUI, so you need to ensure that the AltUI plugin you register with is the one on your own machine![/li]
[li]Only one JSON parameter is actually needed for the AltUI DSP registration. In the case of this implementation it is the device.serviceId.name of the remote target variable[/li]
[li]You need to write your own callback handler to deal with the variable changes from the AltUI request.[/li][/ul]

So now, each instance of VeraBridge creates its own mirror ‘data storage provider’ which may be selected by AltUI as per the attached screen shot.

I’ve just updated the development branch with the latest VeraBridge code which implements the above change to Mirroring.

Simply select the variable you want to mirror using the AltUI Device > Variables menu and select Vera@… for the Data Service Provider. The single parameter Mirror is of the form device.serviceId.name, with everything but the device number as options.

Thus to mirror a selected variable to a remote Vera’s device #42, for example, and retaining the same serviceId and variable name, you simply enter 42 into the Mirror parameter box. To change its serviceId and name, you’d put something like: 42.urn:whatever:serviceId:you-like.NewVariableName

The advantages of this over the previous method are:

[ul][li]no Startup Lua code required[/li]
[li]dynamically stop/start mirroring. Changes are immediate.[/li]
[li]easy (existing) interface.[/li][/ul]

All mirrored variables appear in the More > Watch Display table.

In due course, I will probably deprecate the previous method for defining mirrored variables, but for the time being, both work.

As with ALL mirroring, take care that you specify the correct remote device number (using its native Vera value, not the assigned openLuup one.)

Hi akbooer,

I’m thinking about a solution to get solar irradiation value from a sensor (using the modbus/rs485 interface) and send these values to a Vera Controller.

In general a solution that interfaces devices with modbus protocol over rs485 and send values to Vera Controller (in this manner many industrial sensors, meters, devices will be visible on Vera Controller).

I’ve setup a RPI with a USB-RS485 converter (one like this http://www.dx.com/p/usb-to-rs485-adapter-black-green-296620#.WdJj5Gh-pPY0) , Openluup and ALTUI. The converter is connected with a PowerMeter (rs485/modbus). At the moment I can get the value and display it on a virtual device on ALTUI.

Can I replicated these values on a device defined on Vera Controller ?

tnks

[quote=“d55m14, post:40, topic:191689”]I’ve setup a RPI with a USB-RS485 converter (one like this http://www.dx.com/p/usb-to-rs485-adapter-black-green-296620#.WdJj5Gh-pPY0) , Openluup and ALTUI. The converter is connected with a PowerMeter (rs485/modbus). At the moment I can get the value and display it on a virtual device on ALTUI.

Can I replicated these values on a device defined on Vera Controller ?[/quote]

Absolutely.

Mirroring of openLuup device variables to a Vera connected by VeraBridge is trivial and described in this post:
http://forum.micasaverde.com/index.php/topic,36971.msg317026.html#msg317026

Is there an easy way to mirror a global variable? Before reading this thread, I have been using scenes on both units to do it which is a bit cumbersome.

Well, you could easily write the variable to a device variable which itself is mirrored.

A function in the metatable of the variable could detect access and write the variable when it is changed. It would be totally transparent to users of the variable.

Do you need this to work bidirectionally between machines?

[quote=“akbooer, post:43, topic:191689”]Well, you could easily write the variable to a device variable which itself is mirrored.

A function in the metatable of the variable could detect access and write the variable when it is changed. It would be totally transparent to users of the variable.

Do you need this to work bidirectionally between machines?[/quote]

Thanks for the quick reply.
Ideally yes, I would like them to mirror in both directions. I have it setup as 4 scenes right now, 2 on each unit for an on off flag which is a bit tedious.
I was thinking about creating a virtual switch with a few variables so the changes can be pushed from one unit to the other.

Just to be clear, you were referring to a global variable in the Lua context, rather than just a device variable that could be the same on both?

Could you clarify the functionality of your scenes? I?m not sure, now, that I?m clear on your use case.

[quote=“akbooer, post:45, topic:191689”]Just to be clear, you were referring to a global variable in the Lua context, rather than just a device variable that could be the same on both?

Could you clarify the functionality of your scenes? I?m not sure, now, that I?m clear on your use case.[/quote]

@akbooer.

The global variable is indeed in the Lua context. I am using it as a status flag.
The specific application is this:
I have scenes which turn on my home theatre depending on what other devices are playing. For example if I play music on the SONOS all house group, I want my home theatre to turn on and play it there too. The problem is, I also have TTS announcements through the house for which case I do not want the home theatre to turn on so I created a global variable in the vera to report the TTS status. If the SONOS is running a TTS, then the flag is on, after some delay, specific to that particular TTS, the scene turns the flag off. I then have the scene turning on the home theatre check the flag.

Now I am starting to split my automation with Openluup and I want this flag to be synchronized between the openluup and the vera. Most TTS are still triggered by the vera while the home theatre is controlled by Openluup.

I have other similar examples where I used a global variable as a status flag.
Right now, I am using Luup code with scenes to call a scene on the other device to toggle the flag which works fine but I was wondering if there is more elegant ways to do this.

One other thought, and you may have some input on it:
The reason for me to split the logic is response lag from triggers: All my Zwave triggered automation is still on the vera because there is a lag between when a variable is changed on the vera and when it is reported on openluup as it appears due to polling frequency and response delay. If the vera was actively pushing all the device states to openluup then maybe I would move all my scenes to openluup but I am wondering if this would be too much of a load for the vera to watch this many variables.

[quote=“rafale77, post:46, topic:191689”]One other thought, and you may have some input on it:
The reason for me to split the logic is response lag from triggers: All my Zwave triggered automation is still on the vera because there is a lag between when a variable is changed on the vera and when it is reported on openluup as it appears due to polling frequency and response delay. If the vera was actively pushing all the device states to openluup then maybe I would move all my scenes to openluup but I am wondering if this would be too much of a load for the vera to watch this many variables.[/quote]

If I thought that pushing data from Vera was a good idea, I would have written the bridge to do that! You’re right, of course, about the lag due to polling, but this did meet my original design criteria of no code required to be run on the Vera. You have to realise that even if you push something to openLuup, it might be doing something else (running somebody’s plugin code doing I/O, for example) which may take some time. In the end, it is all single-threaded.

The transition of logic between Vera and openLuup is certainly an interesting topic. Race conditions are a potential issue, but then, if your logic is timing critical, there’s either something wrong with your design, or you simply shouldn’t be doing it like that.

I have a long-held (and long-term) plan to rewrite the bridge using asynchronous I/O which would mitigate this problem, but it seems like an awful lot of effort for little gain.

You can certainly write code which sends specific variable changes immediately to the remote machine (be it Vera or openLuup) but there will always be some delay. My favorite handshake-free protocol for this is UDP, which is what DataYours uses to push data around its modular, and possibly multi-processor, architecture in a much, much more efficient manner than a TCP or, heaven forfend, HTML protocol stack.

Old discussion but just wanted to post that I ended up testing this idea.
My openLuup instance is currently installed on a VM running on a single thread along with a number of other things (ha bridge, sonos API, airsonos and homekit bridge) of an Core i7 6700K. The single thread is actually quite fast.
Having moved all the scenes I could move from the vera to openLuup, I am indeed seeing a lag from the polling rate of openLuup to the vera. There is only one type of variable I want “instantly” mirror from the vera to openLuup and it is currently the “Tripped” variable from all of my door and motion sensors.

I added the following code to my vera startup lua and it seems to have eliminated the lag. I will report if I see other issues but so far so good. Eventually I will be replacing the vera at least as a zwave bridge with zway but I thought it is an interesting experiment.

function updatetrip(lul_device, lul_service, lul_variable, lul_value_old, lul_value_new)
     local tgt = tonumber(lul_device) + 10000
     local message = string.format("http://**openLuup_ip**:3480/data_request?id=variableset&DeviceNum=%s&serviceId=urn:micasaverde-com:serviceId:SecuritySensor1&Variable=Tripped&Value=%s",tgt,lul_value_new)
     luup.inet.wget(message)
end

for k, v in pairs(luup.devices) do
   if v.category_num == 4 and (v.subcategory_num == 1 or v.subcategory_num == 3) then 
      luup.variable_watch("updatetrip", "urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", k)
   end
end

Yes, you can certainly do that.

The central tenet of openLuup was that NO code should be required on Vera, and I did the best I could with that. If it’s not fast enough you could certainly make the polling faster, but you won’t beat the ‘instant status’ approach here.

Horses for courses.


Edit: You could, in fact, make it even faster by sending a UDP datagram to a UDP listener on openLuup, which would then set the necessary variable, overcoming the HTTP handshake lag inherent in that protocol.

AK: don’t get me wrong. It is working awesomely well. I am just a bit picky and found the response lag a bit longer than I wanted. It is amazingly fast now. It is even faster than when I had all the logic on the vera itself which goes to validate if it was needed that the vera is inefficient and overloaded!

zwave trigger → Vera variable change → wget to openLuup → openLuup scene logic → wget to vera → zwave action

is much faster and more reliable than

zwave trigger → Vera variable change → vera scene logic → zwave action.

No, that’s all good.

It’s actually surprising that the bridge works as well as it does. Its design was a prototype “proof of concept” that was originally written to run on Vera to get around the native bridging problems that they had.

It doesn’t run on Vera now, but the basic architecture hasn’t changed. A properly written bridge could be about as fast as your work-around, receiving a Vera HTTP response pretty much as soon as a variable changes. It requires an asynchronous HTTP GET implementation, which I have never got around to doing, but one day, perhaps…

More urgently, the native digest authentication is in hand, but you have another work-around for that already.

indeed 8)
I am doing what I can to make this whole setup work. I just made a discovery on the vera which appears to fix almost all the problems I have had with it. I posted it in the general thread. It seems like the event sync calls to the mios server is the main culprit for the slowness and instability of the vera. I have always felt that the mios cloud was one of the source of the random luup reloads along with the number of devices which is what drove me to try to firewall the vera. I will verify in the next few days but so far it looks promising.

Just as a postscript to this conversation, I should note that with the new(-ish) asynchronous VeraBridge and a reduction in openLuup’s scheduler latency, the whole system should be more responsive, although YMMY depending on your particular system configuration.