1

I am working with a third party device which has some implementation of Lua, and communicates in BACnet. The documentation is pretty janky, not providing any sort of help for any more advanced programming ideas. It's simply, "This is how you set variables...". So, I am trying to just figure it out, and hoping you all can help.

I need to set a long list of variables to certain values. I have a userdata 'ME', with a bunch of variables named MVXX (e.g. - MV21, MV98, MV56, etc).

(This is all kind of background for BACnet.) Variables in BACnet all have 17 'priorities', i.e., every BACnet variable is actually a sort of list of 17 values, with priority 16 being the default. So, typically, if I were to say ME.MV12 = 23, that would set MV12's priority-16 to the desired value of 23.

However, I need to set priority 17. I can do this in the provided Lua implementation, by saying ME.MV12_PV[17] = 23. I can set any of the priorities I want by indexing that PV. (Corollaries - what is PV? What is the underscore? How do I get to these objects? Or are they just interpreted from Lua to some function in C on the backend?)

All this being said, I need to make that variable name dynamic, so that i can set whichever value I need to set, based on some other code. I have made several attempts.

This tells me the object(MV12_PV[17]) does not exist:

x = 12
ME["MV" .. x .. "_PV[17]"] = 23

But this works fine, setting priority 16 to 23:

x = 12
ME["MV" .. x] = 23

I was trying to attempt some sort of what I think is called an evaluation, or eval. But, this just prints out function followed by some random 8 digit number:

x = 12
test = assert(loadstring("MV" .. x .. "_PV[17] = 23"))
print(test) 

Any help? Apologies if I am unclear - tbh, I am so far behind the 8-ball I am pretty much grabbing at straws.

lukehawk
  • 1,423
  • 3
  • 22
  • 48
  • That is certainly a very wonky API. I wonder why they created hundreds of `MVXX` variables instead of just a single `MV` array that you can index with `MV[XX]`. – hugomg Mar 18 '18 at 21:41

2 Answers2

1

Underscores can be part of Lua identifiers (variable and function names). They are just part of the variable name (like letters are) and aren't a special Lua operator like [ and ] are.

In the expression ME.MV12_PV[17] we have ME being an object with a bunch of fields, ME.MV12_PV being an array stored in the "MV12_PV" field of that object and ME.MV12_PV[17] is the 17th slot in that array.

If you want to access fields dynamically, the thing to know is that accessing a field with dot notation in Lua is equivalent to using bracket notation and passing in the field name as a string:

-- The following are all equivalent:
x.foo

x["foo"]

local fieldname = "foo"
x[fieldname]

So in your case you might want to try doing something like this:

local n = 12
ME["MV"..n.."_PV"][17] = 23
hugomg
  • 68,213
  • 24
  • 160
  • 246
0

BACnet "Commmandable" Objects (e.g. Binary Output, Analog Output, and o[tionally Binary Value, Analog Value and a handful of others) actually have 16 priorities (1-16). The "17th" you are referring to may be the "Relinquish Default", a value that is used if all 16 priorities are set to NULL or "Relinquished".

Perhaps your system will allow you to write to a BACnet Property called "Relinquish Default".

Edward
  • 334
  • 1
  • 3
  • Yes, you are correct. 'RelinquishDefualt' is 'priority 17' in this device. It lets me write to `ME.MV18_PV[17]`, it just doesn't let me make that dynamic in anyway i can find. – lukehawk Mar 21 '18 at 17:55