PDA

View Full Version : How do I get a boolen from the registry or convert a string "false" to boolean false?



Mastiff
February 14th, 2015, 08:47 AM
I need to fill a table from the system registry at startup, and for that I'm using this:


LydogBilde.Forsterkere = {
[1] = win.CreateRegistry('HKCU', 'Software\\Automatisering\\Lydogbilde\\Forsterkere ', 0):Read('1'),
[2] = win.CreateRegistry('HKCU', 'Software\\Automatisering\\Lydogbilde\\Forsterkere ', 0):Read('2'),
}

Of course there are many more lines, but that's the syntax anyway. The problem comes because it's getting a string. I can of course do another "if then" for each table entry in this startup script to make it into a boolean (which I need for set of true/false stuff to check if amps are on), but it's both untidy and complicating, and I'm trying to make everything as easy to understand as possible now since I'm planning to sell the house as a full on smarthouse next yea. If I try to write as a boolean the registry gets 0/1 values, and that comes back in string 0/1 in the scipt. Isn't there a nice, little command to fix this? I tried the opposite of tostring, like this:


toboolean(win.CreateRegistry('HKCU', 'Software\\Automatisering\\Lydogbilde\\Forsterkere ', 0):Read('1'))

That did of course not work. Any tips on how I do this?

(It's really for Girder 5, but I figured it should be pretty much the same stuff for G6, and this forum is a bit more active...)

Mastiff
February 15th, 2015, 04:46 AM
To elaborate (since I have a few reads but no answers...), this is the closest I have gotten so far:


LydogBilde.Forsterkere [1] = win.CreateRegistry('HKCU', 'Software\\Automatisering\\Lydogbilde\\Forsterkere ', 0):Read(1)
if LydogBilde.Forsterkere [1] == "true" then LydogBilde.Forsterkere [1] = true else LydogBilde.Forsterkere [1] = false end

it is only two lines per entry in the table, but it's ugly as hell. ;)

At the same time is it possible to get the table out of the registry in one line for the full table, or do I have to do it like this, with one line per entry?

Mastiff
March 5th, 2015, 02:41 AM
Can nobody help me out with this? Please? Especially the last part, about populating a table from the registry. I know how to interact with the registry, I would just like to populate a nested table from a registry key that's formatted the same way (with subkeys from 1 to whatever, and each subkey has DWORDS named the correct way, with it's values being the nested part).

harleydude
March 5th, 2015, 08:55 AM
You can try something like this



LydogBilde.Forsterkere = {
[1] = (win.CreateRegistry('HKCU', 'Software\\Automatisering\\Lydogbilde\\Forsterkere ', 0):Read('1') == "true" and true) or false,
[2] = (win.CreateRegistry('HKCU', 'Software\\Automatisering\\Lydogbilde\\Forsterkere ', 0):Read('2') == "true" and true) or false,
}


I think I have all the right bits in the right places. I cannot test as I do not have those strings in my registry.

Mastiff
March 5th, 2015, 12:51 PM
Yep, that works, thanks a lot! :) Is it possible to pick a nested table out from the registry in the same way? The nested table would be built on this registry setup:


Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t]
"1"="22"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\1]
"1"="22"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\10]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\11]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\12]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\13]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\2]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\3]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\4]
"1"="21"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\5]
"1"="10"
"2"="16"
"3"="5"
"4"="20"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\6]
"1"="23"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\7]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\8]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""

[HKEY_CURRENT_USER\Software\Automatisering\Termosta t\9]
"1"="20"
"2"="16"
"3"="5"
"4"="-"
"0"=""


So the "outer" table is the room number, and the inner table is the different temperatures. The actual nested table looks like this:


Temperaturstyring.Nettside.SettTemperatur ={
[1] = {[1] = "22", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[2] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[3] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[4] = {[1] = "21", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[5] = {[1] = "10", [2] = "16", [3] = "5", [4] = "20", [0] = ""},
[6] = {[1] = "23", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[7] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[8] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[9] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[10] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[11] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[12] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[13] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""}
}

I can put the nested table into the registry like this:


for x in Temperaturstyring.Nettside.SettTemperatur do
for y,z in Temperaturstyring.Nettside.SettTemperatur[x] do
win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\'..x, 1):Write(y,z)
print (x,y,z)
end
end

I just cant get it out.

Ron
March 15th, 2015, 07:07 PM
So you want to read the registry back in and end up with a lua table?

Mastiff
March 16th, 2015, 04:10 AM
Yep, that's it. End up with a nested LUA table like the one I got when I put stuff into the registry. It's for reboots and restarts of Girder, since these settings have to be preserved and not change except when I actually do somethign to change them (from the web page or with a timer).

Ron
March 16th, 2015, 08:22 AM
I wanna say there is an easier way to do this. Store the whole table as one entry then reload the whole table in one go. OF the top of my head there is the "pickle"



local pickled = pickle(Temperaturstyring)
local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\Pickle", 1)
reg:Write("Value", pickled)
reg:CloseKey()




local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\Pickle", 0);
local pickled = reg:Read("Value")
Temperaturstyring = unpickle(pickled)
reg:CloseKey()

Mastiff
March 16th, 2015, 08:25 AM
Thanks for answering! The problem is that I do not write to the registry in one go, I write the changed state each time one of the states is changed, in case of a power outage or other form of unexpected shutdown. Wouldn't that crash with this way of doing it?

Ron
March 16th, 2015, 08:28 AM
As long as the whole table is available at the time of the write I don't see any difference between writing each value individually and writing them all at once.

Mastiff
March 16th, 2015, 08:34 AM
Aha, I see! So you mean that instead of just writing the one thing that's changed after a change I write the whole table in?

Ron
March 16th, 2015, 08:37 AM
Indeed, that's it.

Mastiff
March 16th, 2015, 09:00 AM
Well, that works, thanks! Butg I forgot why I needed it in a room for room basis. :( I have EventGhost reading from those registry keys at startup as well (Girder controls the changes and then sends them to EventGhost, that runs the RFXtrx and Tellstick that gets the temperature sensor input and turns on and off the ovens). Does it mean that the way I hoped to do it isn't possible? If not I may be able (by nagging people on the EG Forum) to read the Pickle thing into a table.

Ron
March 16th, 2015, 09:25 AM
I don't have time to test the code but reading is something like below:



if not Temperaturstyring then
Temperaturstyring = {}
end

if not Temperaturstyring.Nettside then
Temperaturstyring.Nettside = {}
end

if not Temperaturstyring.Nettside.SettTemperatur then
Temperaturstyring.Nettside.SettTemperatur = {}
end


local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\", 0);
local keys = reg:ListKeys()
reg:CloseKey()
for i,key in pairs(keys) do
local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\" .. key, 0);
local valueNames = reg:ListValues()
local t = {}
for j, valueName in pairs( valueNames ) do
t[ valueName ] = reg:Read( valueName )
end
Temperaturstyring.Nettside.SettTemperatur[ key ] = t
reg:CloseKey()
end


Hopefully that gets you started.

Mastiff
March 16th, 2015, 10:02 AM
It even got me finished! :) Thanks a lot, that worked perfectly!

Mastiff
April 9th, 2015, 04:50 PM
Unfortunately it only seemed to work perfectly, there's one problem with this code. I left it alone for a while, trying to solve it myself, but that was rather futile. ;) The result of that code reads the numbers in the registry as a string, while I need it to be integers for the outer table. I have tried to find out how to convert table values to integers, but to no avail. The main table numbers designate the rooms, and a string there makes it impossible to get to the next step, which is to use this number in some other code (that works as long as the it's integers). I have a regular table creation that works, but it's of course static. So just as an example (which it has been, the regsitry setup is the final piece to get it into active use):


Temperaturstyring.Nettside.SettTemperatur ={
[1] = {[1] = "22", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[2] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[3] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[4] = {[1] = "21", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[5] = {[1] = "10", [2] = "16", [3] = "5", [4] = "20", [0] = ""},
[6] = {[1] = "23", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[7] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[8] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[9] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[10] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[11] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[12] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""},
[13] = {[1] = "20", [2] = "16", [3] = "5", [4] = "-", [0] = ""}
}

Here's the table.print output of that:


{ -- #0
[1] = { -- #1
[1] = "22",
[2] = "16",
[3] = "5",
[4] = "-",
[0] = "",
} -- #1,

--and so on


This works in the setup that I am going to use it for. The numbers are room numbers, which are used together with another table to give the current target temperature for the room. The code gives this table.print, where the room numbers are strings:


{ -- #0
["1"] = { -- #1
["1"] = "22",
["0"] = "Av",
["3"] = "5",
["2"] = "12",
["4"] = "0",
["Modus"] = "1",
} -- #1,
--and so on



Can you please help me so the result of your code is an integer in the outer table in the nested table?

Mastiff
April 10th, 2015, 02:46 AM
Also I have this table that I am getting from the registry:


Temperaturstyring.Nettside.status ={
[1] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\1', 0):Read('Modus')),
[2] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\2', 0):Read('Modus')),
[3] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\3', 0):Read('Modus')),
[4] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\4', 0):Read('Modus')),
[5] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\5', 0):Read('Modus')),
[6] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\6', 0):Read('Modus')),
[7] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\7', 0):Read('Modus')),
[8] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\8', 0):Read('Modus')),
[9] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\9', 0):Read('Modus')),
[10] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\10', 0):Read('Modus')),
[11] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\11', 0):Read('Modus')),
[12] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\12', 0):Read('Modus')),
[13] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\13', 0):Read('Modus'))
}

I'm guessing that this would be possible to do in the same way, right? The right code for this one could actually solve several things for me in one go. Perhaps even so many that I wouldn't have to beg for help again in a month, like I do now! :D

Ron
April 10th, 2015, 09:57 AM
I'm not 100% clear on what it is you are looking for but to get a number just use "tonumber" most likely on this line




if not Temperaturstyring then
Temperaturstyring = {}
end

if not Temperaturstyring.Nettside then
Temperaturstyring.Nettside = {}
end

if not Temperaturstyring.Nettside.SettTemperatur then
Temperaturstyring.Nettside.SettTemperatur = {}
end


local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\", 0);
local keys = reg:ListKeys()
reg:CloseKey()
for i,key in pairs(keys) do
local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\" .. key, 0);
local valueNames = reg:ListValues()
local t = {}
for j, valueName in pairs( valueNames ) do
t[ valueName ] = tonumber(reg:Read( valueName ))
end
Temperaturstyring.Nettside.SettTemperatur[ key ] = t
reg:CloseKey()
end

but that would set the string values to 0,....

Mastiff
April 10th, 2015, 10:13 AM
Hi, Ron! This is one of the things I tried myself, actually. It gives this error:


[string "VM-Girder som hovedmaskin.gml:\Lys, ovner o..."]:22: bad argument #2 to `tonumber' (number expected, got string)
stack traceback:
[C]: in function `tonumber'
[string "VM-Girder som hovedmaskin.gml:\Lys, ovner o..."]:22: in main chunk



As for strings there are no strings attached (ha-ha...) in the outer table, only the nested part. And it's only the outer table I need as integers/numbers.

Ron
April 10th, 2015, 10:19 AM
if not Temperaturstyring then
Temperaturstyring = {}
end

if not Temperaturstyring.Nettside then
Temperaturstyring.Nettside = {}
end

if not Temperaturstyring.Nettside.SettTemperatur then
Temperaturstyring.Nettside.SettTemperatur = {}
end


local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\", 0);
local keys = reg:ListKeys()
reg:CloseKey()
for i,key in pairs(keys) do
local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\" .. key, 0);
local valueNames = reg:ListValues()
local t = {}
for j, valueName in pairs( valueNames ) do
t[ valueName ] = reg:Read( valueName )
t[ valueName ] = tonumber( t[valueName] )
end
Temperaturstyring.Nettside.SettTemperatur[ key ] = t
reg:CloseKey()
end


I guess that Read function returns more than one value.

Mastiff
April 10th, 2015, 10:27 AM
No error message this time. :) But it does the opposite: It makes the inner part of the nested table to an integer, instead of the outer part. If that makes any sense.

Probably not, so it's better to show it:


{ -- #0
this-> ["1"] = { -- #1
["1"] = 22,
["3"] = 5,
["2"] = 12,
["4"] = 0,
["Modus"] = 1,
} -- #1,
and this-> ["3"] = { -- #2
["1"] = 20,
["3"] = 5,
["2"] = 16,
["4"] = 0,
["Modus"] = 1,



As you see it's the four temperatures that are numbers now, not the room number, in this case I have only shown rooms 1 and 3, and the room numbers are shown with "this and this".

Ron
April 10th, 2015, 10:35 AM
if not Temperaturstyring then
Temperaturstyring = {}
end

if not Temperaturstyring.Nettside then
Temperaturstyring.Nettside = {}
end

if not Temperaturstyring.Nettside.SettTemperatur then
Temperaturstyring.Nettside.SettTemperatur = {}
end


local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\", 0);
local keys = reg:ListKeys()
reg:CloseKey()
for i,key in pairs(keys) do
local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\" .. key, 0);
local valueNames = reg:ListValues()
local t = {}
for j, valueName in pairs( valueNames ) do

t[ tonumber(valueName) ] = reg:Read( valueName )

end
Temperaturstyring.Nettside.SettTemperatur[ key ] = t
reg:CloseKey()
end

Mastiff
April 10th, 2015, 10:40 AM
An error again, this time different:

[string "VM-Girder som hovedmaskin.gml:\Lys, ovner o..."]:23: table index is nil
stack traceback:
[string "VM-Girder som hovedmaskin.gml:\Lys, ovner o..."]:23: in main chunk


The printout is empty:

{ -- #0
} -- #0

Ron
April 10th, 2015, 10:44 AM
then not all keys are numbers.

t[ tonumber(valueName) or valueName ] = reg:Read( valueName )

Mastiff
April 10th, 2015, 10:48 AM
And now I saw why. :) All the room number are numbers, but this code actually works on the middle level of the nested table. So the first code did the inner level (the temperatures of the different modes of the rooms), while this changes the middle level (the modes of the rooms). So if it's possible to go one more level out it will be what I'm
looking for! :)

Ron
April 10th, 2015, 10:59 AM
if not Temperaturstyring then
Temperaturstyring = {}
end

if not Temperaturstyring.Nettside then
Temperaturstyring.Nettside = {}
end

if not Temperaturstyring.Nettside.SettTemperatur then
Temperaturstyring.Nettside.SettTemperatur = {}
end


local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\", 0);
local keys = reg:ListKeys()
reg:CloseKey()
for i,key in pairs(keys) do
local reg = win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\" .. key, 0);
local valueNames = reg:ListValues()
local t = {}
for j, valueName in pairs( valueNames ) do

t[ tonumber(valueName) or valueName ] = reg:Read( valueName )

end
Temperaturstyring.Nettside.SettTemperatur[ tonumber(key) or key ] = t
reg:CloseKey()
end

Mastiff
April 10th, 2015, 11:13 AM
Yes, yes, YES! That's it! :o It had the second level to number as well, but I managed to change that without messing up anything, so now it is exactly the way I wanted it! Thank you very much for this one, Ron! I think I will get the full system running this weekend now!

The only thing I would like (yeah, I'm a bit greedy on your time now, I know) is if doesn't take too long to do the other one I had on the previous page. The registry read stuff that I had as a bunch of lines, since I can use that for more than one thing (in audio video as well as the heat control). Since the thread is a bit cluttered here's what it was:


Temperaturstyring.Nettside.status ={
[1] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\1', 0):Read('Modus')),
[2] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\2', 0):Read('Modus')),
[3] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\3', 0):Read('Modus')),
[4] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\4', 0):Read('Modus')),
[5] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\5', 0):Read('Modus')),
[6] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\6', 0):Read('Modus')),
[7] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\7', 0):Read('Modus')),
[8] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\8', 0):Read('Modus')),
[9] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\9', 0):Read('Modus')),
[10] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\10', 0):Read('Modus')),
[11] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\11', 0):Read('Modus')),
[12] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\12', 0):Read('Modus')),
[13] = tonumber (win.CreateRegistry('HKEY_CURRENT_USER', 'Software\\Automatisering\\Termostat\\13', 0):Read('Modus'))
}