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

Ok, I’ll give it a try with my variables from heliotrope.
I agree that an automatic generation of dummy devices is far to complicated.
But how about this:
If the user had some kind of wizard on openluup that lets him pick the object on the verabridge wich he wants to mirror and then the wizard determines which device type and hence device file is needed and then creates the device on vera.
For example my use case would be:
I need the heliotrope variables ‘azimuth’ and ‘altitude’ mirrored. So I would start the wizard, pick the ‘heliotrope’ from a list of all devices on verbridge and be presented with a list of all variables from ‘heliotrope’. I then would check all variables needed. Finally clicking on ‘generate devices’ would create all needed devices on vera.
What do you think?

I’m not there yet. :-[
I created a device on vera (GenericSensor, ID 287)
Then I tried to mirror that device to my Heltitrope device (ID 8) on openluup.

luup.attr_set ("openLuup.mirrors", [[ 192.168.2.124 287 = 8.urn:futzle-com:serviceId:AstronomicalPosition_Sun.Azimuth360 ]])

the result in the log showed no errors

2016-07-23 15:15:14.814 openLuup.server:: request completed (100361 bytes, 7 chunks, 3628 ms) tcp{client}: 0x2984618 2016-07-23 15:15:14.919 openLuup.server:: /data_request?id=lu_status2&output_format=json&DataVersion=279384509&Timeout=60&MinimumDelay=1500&_=1469278417325 tcp{client}: 0x2984618 2016-07-23 15:15:17.312 openLuup.server:: /data_request?id=lr_ALTUI_LuaRunHandler&command=run_lua&lua=luup.attr_set%20(%22openLuup.mirrors%22%2C%20%5B%5B%0A192.168.2.124%0A287%20%3D%208.urn%3Afutzle-com%3AserviceId%3AAstronomicalPosition_Sun.Azimuth360%0A%5D%5D)&_=1469278417326 tcp{client}: 0x206db28 2016-07-23 15:15:17.313 luup_log:0: ALTUI: runLua(luup.attr_set ("openLuup.mirrors", [[ 192.168.2.124 287 = 8.urn:futzle-com:serviceId:AstronomicalPosition_Sun.Azimuth360 ]])) 2016-07-23 15:15:17.313 luup_log:0: ALTUI: Evaluation of lua code returned: nil 2016-07-23 15:15:17.315 openLuup.server:: request completed (8 bytes, 1 chunks, 2 ms) tcp{client}: 0x206db28 2016-07-23 15:15:17.820 openLuup.server:: request completed (3117 bytes, 1 chunks, 2901 ms) tcp{client}: 0x2984618 2016-07-23 15:15:17.823 openLuup.server:: /data_request?id=user_data&output_format=json&DataVersion=279371946&_=1469278417327 tcp{client}: 0x2984618 2016-07-23 15:15:17.981 openLuup.server:: request completed (967832 bytes, 61 chunks, 157 ms) tcp{client}: 0x2984618 2016-07-23 15:15:20.023 openLuup.server:: /data_request?id=lu_status2&output_format=json&DataVersion=279384510&Timeout=60&MinimumDelay=1500&_=1469278417328 tcp{client}: 0x2984618 2016-07-23 15:15:21.626 openLuup.server:: request completed (4602 bytes, 1 chunks, 1603 ms) tcp{client}: 0x2984618 2016-07-23 15:15:21.733 openLuup.server:: /data_request?id=lu_status2&output_format=json&DataVersion=279384511&Timeout=60&MinimumDelay=1500&_=1469278417329 tcp{client}: 0x2984618
Alas, the ‘virtual’ device shows no Azimuth value.
Do the pair of devices on vera and openluup have to be of the same type?
Could I create a ‘virtual’ heliotrope on vera without implementation file that just holds the varaibles?
What I thought from your reply is that device types don’t matter.

Is 192.168.2.124 the correct IP for your Vera?

I’ve just set this up on a system bridging to a Vera Edge.

luup.attr_set ("openLuup.mirrors", [[
172.16.42.14
33 = 162.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTemperature
]])

You should see something like this in the startup log for the bridge:

2016-07-23 14:29:54.584   luup.variable_watch:169: callback=VeraBridge_Mirror_Callback, watching=162.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTem\
perature

then when the watched variable changes…

2016-07-23 14:31:51.579   luup.variable_set:0: 162.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTemperature was: 26.4 now: 26.5 #hooks:1
2016-07-23 14:31:51.580   openLuup.server:: request completed (2 bytes, 1 chunks, 1 ms) tcp{client}: 0x22eebb0
2016-07-23 14:31:51.580   luup.watch_callback:: 162.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTemperature function: 0x1ea9f30

and, of course, you should see the variable on the remote Vera.

Is 192.168.2.124 the correct IP for your Vera?
Yes it is. Or do I have to add the port ':3480'?
and, of course, you should see the variable on the remote Vera.
I do. Atteached is how it looks from Vera and AltUI.

Interestingly I can’t find a single entry in the log like

luup.variable_watch

or

luup.watch_callbac

I guess that is the root of the problem.

Where does this go?

luup.attr_set ("openLuup.mirrors", [[ 172.16.42.14 33 = 162.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTemperature ]])

I put mine in Misc > Lua Test Code > in the code window ans submitted it.
Should I have done that differently?

I put mine in Misc > Lua Test Code > in the code window ans submitted it. Should I have done that differently?

Yes, you should. It goes in Misc > Lua Startup Code

I did make a mistake, wrong vera IP :-[
I changed that, put it in Misc > Luas startup Code, restartet, no luck.
The ‘virtual’ device on vera ‘vbm_heliotrope_azimuth’, it is still there showing “value”.
What did change is the fact that the device ‘vbm_heliotrope_azimuth’ on verabridge vanished.
Any ideas what I could try?
Different device type? The device I created on vera has an implementation file. Does that matter?

One step further!
The values from verabridge are actually pushed to virtual device on vera.
That only shows on the advanced tab of the device, whereas I was expecting to see the value on device itself which only showed ‘value’.
I tried to get several to values into one device (Azimuth360 and Altitude).
Onyl after adding a new variable on the advanced tab of the virtual device on vera was the second value transferred.
Is mirroring function supposed to create the variable in the virtual device by itself?
Also, the values on the virtual device seem to be ‘stuck’ at times. When I refresh the browser (ctrl f5) the values are updated.
I wonder if this will affect pleg functioning correctly.
Anyhow, @akbooer, thank you so much for your never ending patience. You literally carried me to this point.
Hopefully I’ll be able to make some steps on my own, soon. :slight_smile:

That’s why I asked :wink:

I changed that, put it in Misc > Luas startup Code, restartet, no luck.

So what does the openLuup log show? That’s what it’s there for… So we don’t have to guess what’s going on.

The 'virtual' device on vera 'vbm_heliotrope_azimuth', it is still there showing "value".

Don’t understand. What ‘value’? Where?

What did change is the fact that the device 'vbm_heliotrope_azimuth' on verabridge vanished.

How did you restart the system? If you specify anything other than the previous user_data.json file (or nothing) then you start from scratch and wipe out previous devices.

Any ideas what I could try? Different device type? The device I created on vera has an implementation file. Does that matter?

The device type is irrelevant, but you do not particularly want to have a running plugin, so best to go without an implementation file.

It’s hard to advise without the full picture. The log is a very good start.

[quote=“pls90, post:27, topic:191689”]One step further!
The values from verabridge are actually pushed to virtual device on vera.[/quote]

Yes, that’s the way it’s supposed to work.

That only shows on the advanced tab of the device, whereas I was expecting to see the value on device itself which only showed 'value'.

What the device shows on its front panel is device dependent. Temperature devices show temperature, humidity shows humidity, dimmers show brightness level… this is nothing to do with what other device variables are around.

I tried to get several to values into one device (Azimuth360 and Altitude). Onyl after adding a new variable on the advanced tab of the virtual device on vera was the second value transferred.

This, I somehow doubt. But what IS true is that variables will only appear once they change value for the first time. Thereafter they should change on every update.

Is mirroring function supposed to create the variable in the virtual device by itself? Also, the values on the virtual device seem to be 'stuck' at times. When I refresh the browser (ctrl f5) the values are updated.

Yes, the mirror creates the variables, but see above for when that happens.

The visual update is purely a function of the UI, and for Vera that often means refreshing a page. Are you not running AltUI on your Vera?

I wonder if this will affect pleg functioning correctly.

PLEG shouldn’t be able to tell the difference between a native variable and one crested and updated by the mirror.

Anyhow, @akbooer, thank you so much for your never ending patience. You literally carried me to this point. Hopefully I'll be able to make some steps on my own, soon. :)

You’re welcome. Knowledge comes with time and perseverance.

Hi akbooer,

Been a while on this topic, but I have two questions. Can I set the openLuup.Mirrors attribute in a plugin as well, or must it be in the startup code?

And is it dynamic, i.e. can I set it without a LUA reload?

I’m thinking about a plugin giving a GUI to set this rather then code it.

Cheers Rene

It has been a while: I had to go and look at the code to remind myself.

Can I set the openLuup.Mirrors attribute in a plugin as well, or must it be in the startup code?

The openLuup attributes can be read/set at any time by anything. However, unlike other system attributes it is not (for good reasons) stored in the user_data.json file between reloads. This is one reason I recommended that the attribute be set in the startup code. For another reason, read on…

And is it dynamic, i.e. can I set it without a LUA reload?

The value is read by VeraBridge at the time the plugin initialisation code is executed. This is so that the device variable callbacks can be set up. It could be implemented another way dynamically, but isn’t at the moment.

As it stands, you couldn’t guarantee that any plugin you wrote to set the attributes would be executed before VeraBridge starts up. What you could do, if all you want is a better interface, is to write whatever configuration you like into one of your plugin’s variables and then get the startup code to use that to initialise openLuup.Mirrors in the Lua Startup code.

As an aside, I’m thinking of adding optional fields to the mirror syntax, to allow arbitrary target values for serviceId and variable names. Thus you could write:

luup.attr_set ("openLuup.mirrors", [[
172.16.42.14
33.urn:whatever-you-like.SomethingElse = 162.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTemperature
]])

Thanks akbooer,

That makes it a bit more tricky. I guess I can have the plugin re-write a bit of LUA and include a call to that in the start up code then.

Ok, plan is forming 8). I will keep you posted.

Cheers Rene

Hold on, I’ve just had a GOOD IDEA (perhaps… perhaps not.)

AltUI already provides an interface to select individual variables for watching. It would be trivial to write a Data Service Provider which then issued the appropriate calls to the remote Vera.

This is a MUCH better approach than the current code in VeraBridge, doesn’t need any Lua Startup code, and doesn’t need a new interface. The only constraint would be that you couldn’t also send a mirrored variable to another Data Storage Provider.

Job done, IMHO.

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