Page 1 of 1
Round-function
Posted: Saturday 27 June 2020 16:16
by Toulon7559
To get rid of too many decimal digits a Round-function is useful.
Till recently the 2 lua-functions below helped me
Code: Select all
local function Round(num, idp)
return tonumber(string.format("%." ..(idp or 0).. "f", num))
end
function round(num, dec)
if num == 0 then
return 0
else
local mult = 10^(dec or 0)
return math.floor(num * mult + 0.5) / mult
end
end
As part of a recent fresh install of a RPI3B+ with latest Raspian_Buster + latest Domoticz-stable I shifted a number of error-free scripts from another RPI to the new configuration.
Now these scripts react differently.
For the fresh install the Round-functions get confronted with num = nil => error-report
Obviously a nil-check should proceed the calling of the Round-function, but in the fresh install that does not happen for unknown reasons.
If calling the Round-function with a valid value num, for idp=0 or for dec=0 still 1 decimal appears.
Checking with slightly earlier versions of Buster+Domoticz, the same effect visible for the decimals.
Somebody knowing a solution?
Something related with the upgrade of lua?
Re: Round-function
Posted: Saturday 27 June 2020 16:41
by jvdz
The Round function will also trigger an error in an old setup when num=nil.
You could avoid that by doing something like this:
Code: Select all
function Round(num, dec)
return tonumber(string.format("%." ..(dec or 0).. "f", num or 0))
end
Edit: Just tested with this simple script in the build-in LUA script editor on an Buster/Domoticz 2020.2 test setup:
Code: Select all
commandArray = {}
function Round(num, dec)
return tonumber(string.format("%." ..(dec or 0).. "f", num or 0))
end
print(Round(nil,nil))
print(Round(nil,0))
print(Round(0,nil))
print(Round(1.12345,0))
print(Round(1.14345,1))
print(Round(1.16345,1))
return commandArray
Output:
Code: Select all
2020-06-27 17:50:00.166 Status: LUA: 0
2020-06-27 17:50:00.166 Status: LUA: 0
2020-06-27 17:50:00.166 Status: LUA: 0
2020-06-27 17:50:00.166 Status: LUA: 1
2020-06-27 17:50:00.166 Status: LUA: 1.1
2020-06-27 17:50:00.166 Status: LUA: 1.2
So all looks correct. Do you have some simple test script that fails for you so I can test?
Jos
Re: Round-function
Posted: Saturday 27 June 2020 18:52
by Toulon7559
This is a script example which for unknown reasons gets 1 decimal in the uploadstring towards an ESP8266-with-OLED:
the round-function is the extended version in my earlier message.
Comparing with other scripts nothing strange.
Code: Select all
sPwr2, sEnergy2 = otherdevices_svalues[Consumption]:match("([^;]+);([^;]+)")
sPwr2 = round(tonumber(sPwr2),0)
print ('Pwr2 = '.. sPwr2)
-- sEnergy2 = round(tonumber(sEnergy2),0);
-- print ('Energy2 = '.. sEnergy2)
if sPwr2 > 999 then
UploadURL2 = baseurl .. ",6,1,In=".. sPwr2 .."W"
else
UploadURL2 = baseurl .. ",6,1,Vb=0".. sPwr2 .."W"
end
if sPwr2 <100 then
UploadURL2 = baseurl .. ",6,1,Vb=00".. sPwr2 .."W"
end
print (UploadURL2)
Will try your variation on the short formula and see what happens.
Added after testing:
Correct operation with
Round1 instead of
round with
Round1 as below
Code: Select all
function Round1(num, dec)
return tonumber(string.format("%." ..(dec or 0).. "f", num or 0))
end
Re: Round-function
Posted: Saturday 27 June 2020 19:01
by jvdz
in this script you have round() in stead of Round(), so do you have 2 different functions as LUA is case sensitive?
Jos
Re: Round-function
Posted: Saturday 27 June 2020 19:26
by Toulon7559
@jvdz
Correct!
Have corrected my previous message to point to the applicable Round1-function.
Result of application of your variation in the example script: correct rounding!
Thanks!
Re: Round-function
Posted: Saturday 27 June 2020 19:50
by waaren
Toulon7559 wrote: Saturday 27 June 2020 19:26
Correct,
Have corrected my previous message to point to the applicable Round1-function.
The Lua round function as used in dzVents:
Code: Select all
function round(value, decimals)
local nVal = tonumber(value)
local nDec = ( decimals == nil and 0 ) or tonumber(decimals)
if nVal >= 0 and nDec > 0 then
return math.floor( (nVal * 10 ^ nDec) + 0.5) / (10 ^ nDec)
elseif nVal >=0 then
return math.floor(nVal + 0.5)
elseif nDec and nDec > 0 then
return math.ceil ( (nVal * 10 ^ nDec) - 0.5) / (10 ^ nDec)
else
return math.ceil(nVal - 0.5)
end
end