Page 1 of 1
Map one range of numbers to another
Posted: Sunday 23 May 2021 20:22
by RvdM
With C++ there is a map function which is able to map one range of numbers to another.
An example is like this:
Code: Select all
int percentage = map(300, 500, 0, 100);
300 equals 0 and 500 equals 100 which makes it easy to calculate things like for example percentages.
Is this possible with lua as well because I couldn't find such a function.
Re: Map one range of numbers to another
Posted: Sunday 23 May 2021 20:53
by waaren
RvdM wrote: ↑Sunday 23 May 2021 20:22
Is this possible with lua as well because I couldn't find such a function.
In Lua you can use a table to do that.
Code: Select all
local map =
{
[300] = 0,
[500] = 100,
}
print(map[300])
print(map[500])
Re: Map one range of numbers to another
Posted: Sunday 23 May 2021 21:08
by RvdM
Perhaps i'm doing something wrong but this doesn't work.
Code: Select all
2021-05-23 21:22:00.479 Error: dzVents: Error: (3.1.8) test: ...v-domoticz/scripts/dzVents/generated_scripts/ScriptT.lua:25: attempt to concatenate a nil value (local 'test')
Code: Select all
return {
active = {
true,
},
on = {
timer = { 'every minute' }
},
logging = {
level = domoticz.LOG_DEBUG,
marker = "test"
},
execute = function(domoticz, triggeredItem, info)
local map =
{
[300] = 0,
[500] = 100,
}
local test = map[400]
domoticz.log('test' .. test, LOG_DEBUG)
domoticz.devices('TestCustomSensor').updateCustomSensor(test)
end
}
Re: Map one range of numbers to another
Posted: Sunday 23 May 2021 22:05
by waaren
RvdM wrote:Perhaps i'm doing something wrong but this doesn't work.
Code: Select all
2021-05-23 21:22:00.479 Error: dzVents: Error: (3.1.8) test: ...v-domoticz/scripts/dzVents/generated_scripts/ScriptT.lua:25: attempt to concatenate a nil value (local 'test')
You defined 300 and 500 as keys and then try to call key 400?
or maybe you are looking for something like
Code: Select all
local tMap = { 300, 500, 0, 100 }
local function map(n, decimals)
if n > tMap[2] or n < tMap[1] then return 'out of range' end -- protect range
local integer = type(decimals) ~= 'number'
local decimals = decimals or 2
local result = ( n - tMap[1]) * (tMap[4] - tMap[3]) / (tMap[2] - tMap[1])
return ( ( integer and domoticz.utils.round( result ) ) or ( round ( result, decimals ) ) ) -- rounded to integer or number of decimals
end
print(map(300)) -->> 0
print(map(400)) -->> 50
print(map(401.1357)) -->> 51
print(map(401.1357,4)) -->> 50.5678
print(map(500)) -->> 100
print(map(-299)) -->> out of range
print(map(501)) -->> out of range
Re: Map one range of numbers to another
Posted: Monday 24 May 2021 16:45
by RvdM
Yes thats it.. but I still get an error
Code: Select all
2021-05-24 16:44:00.518 Error: dzVents: Error: (3.1.8) test: ...v-domoticz/scripts/dzVents/generated_scripts/ScriptT.lua:21: attempt to compare number with string
Code: Select all
execute = function(domoticz, triggeredItem, info)
local tMap = { 0, 48, 0, 100 }
local function map(n, decimals)
if n > tMap[2] or n < tMap[1] then return 'out of range' end -- protect range
local integer = type(decimals) ~= 'number'
local decimals = decimals or 2
local result = ( n - tMap[1]) * (tMap[4] - tMap[3]) / (tMap[2] - tMap[1])
return ( ( integer and domoticz.utils.round( result ) ) or ( round ( result, decimals ) ) ) -- rounded to integer or number of decimals
end
niveau = domoticz.devices('Plant - CrotonPetra - WaterNiveau').state
local percentage = map(niveau)
domoticz.devices('Plant - CrotonPetra - Percentage').updateCustomSensor(percentage)
end
Re: Map one range of numbers to another
Posted: Monday 24 May 2021 17:15
by RvdM
Solved
Code: Select all
niveau = tonumber(domoticz.devices('Plant - CrotonPetra - WaterNiveau').state)
I also changed the function so it equals how the function in C++ works
Code: Select all
local function map(n, w, x, y, z, decimals)
if n > x or n < w then return 'out of range' end -- protect range
local integer = type(decimals) ~= 'number'
local decimals = decimals or 2
local result = (n - w) * (z - y) / (x - w)
return ( ( integer and domoticz.utils.round( result ) ) or ( round ( result, decimals ) ) ) -- rounded to integer or number of decimals
end