Round-function

Topics (not sure which fora)
when not sure where to post, post here and mods will move it to right forum.

Moderators: leecollings, remb0

Post Reply
Toulon7559
Posts: 859
Joined: Sunday 23 February 2014 17:56
Target OS: Raspberry Pi / ODroid
Domoticz version: <2025
Location: Hengelo(Ov)/NL
Contact:

Round-function

Post 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?
Last edited by Toulon7559 on Sunday 02 August 2020 15:28, edited 1 time in total.
Set1 = RPI-Zero+RFXCom433+S0PCM+Shield for BMP180/DS18B20/RS485+DDS238-1ZNs
Set2 = RPI-3A++RFLinkGTW+ESP8266s+PWS_WS7000
Common = KAKUs+3*PVLogger+PWS_TFA_Nexus
plus series of 'satellites' for dedicated interfacing, monitoring & control.
User avatar
jvdz
Posts: 2445
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: Round-function

Post 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
Toulon7559
Posts: 859
Joined: Sunday 23 February 2014 17:56
Target OS: Raspberry Pi / ODroid
Domoticz version: <2025
Location: Hengelo(Ov)/NL
Contact:

Re: Round-function

Post 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
Last edited by Toulon7559 on Sunday 02 August 2020 16:24, edited 10 times in total.
Set1 = RPI-Zero+RFXCom433+S0PCM+Shield for BMP180/DS18B20/RS485+DDS238-1ZNs
Set2 = RPI-3A++RFLinkGTW+ESP8266s+PWS_WS7000
Common = KAKUs+3*PVLogger+PWS_TFA_Nexus
plus series of 'satellites' for dedicated interfacing, monitoring & control.
User avatar
jvdz
Posts: 2445
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: Round-function

Post 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
Toulon7559
Posts: 859
Joined: Sunday 23 February 2014 17:56
Target OS: Raspberry Pi / ODroid
Domoticz version: <2025
Location: Hengelo(Ov)/NL
Contact:

Re: Round-function

Post 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!
Last edited by Toulon7559 on Sunday 02 August 2020 16:25, edited 6 times in total.
Set1 = RPI-Zero+RFXCom433+S0PCM+Shield for BMP180/DS18B20/RS485+DDS238-1ZNs
Set2 = RPI-3A++RFLinkGTW+ESP8266s+PWS_WS7000
Common = KAKUs+3*PVLogger+PWS_TFA_Nexus
plus series of 'satellites' for dedicated interfacing, monitoring & control.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Round-function

Post 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
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest