This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

dt.uint64
#1
Hi,

I need to show an uint 64 bytes in logic machine. I know that int64 exist but not uint.64.

Is there any way to do that?

Thanks
Reply
#2
Just use dt.int64. It's very unlikely that the value you need to display is larger than 9 223 372 036 854 775 807 (maximum for int64) Smile
Reply
#3
Sorry, it was my mistake.

I´m trying to do that:

valH = 0xFF00
valL = 0

val = bit.bor(bit.lshift(valH, 16), valL)

grp.update("32/1/4",val)  --dt.uint32
grp.update("32/1/5",val)  --dt.int32


In "32/1/4" it write "-16777216"
In "32/1/5" it write "0"

But when i write it in a dt.int64 and I change it to an dt.uint32, it shows right value "4278190080". If I write again, it shows "0" in dt.uint32.
Reply
#4
Bit shifts operate on int32 (signed) values. You can use multiplication instead of bit shift:
Code:
valH = 0xFF00
valL = 0
val = valH * 0x10000 + valL
Reply
#5
Ok thanks!
Reply
#6
Hello Admin,

I have multiple modbus energy meters iEM3150 / 3350 where the energy values are int64 in Wh. Although this datatype can be nicely handled by the LM, I would like to present those values on a visualization device that supports int32 or 8byte double (which probably is a f64 value) and or 14byte string. Now as a quick solution I can apply the code below to divide the value by 1000 so get kWh in the end and write it as string to show it in the visualization.
Code:
if not values then
values = {
    { input = '32/1/24', output = '10/0/24' },
    { input = '32/1/25', output = '10/0/25' },
    { input = '32/1/26', output = '10/0/26' }
}
end


for _, value in ipairs(values) do
  Wh = grp.getvalue(value.input)
  kWh = tostring(Wh / 1000)
    grp.checkwrite(value.output, kWh)
end

 
I am wondering since the int64 has a max value of 9223372036854774784 which consists of 19 bytes and - 3 bytes because of /1000 to get value as kWh, leaves us with 16 bytes, there are two bytes that are lost in the string 14bytes translation. Is there a solution to this issue or can we translate the int64 to f64 somehow?
Reply
#7
It's very unlikely that your counter value can go high enough to overflow 14 characters. What is the data type for 8 byte double? It's not in the KNX standard.
Reply
#8
Hello Admin,

It doesn't seem like I can set any datatype on it. 
If this helps when on LM I set value 25 Wh (int64) the visualization shows 6.9169E-0323 (factor here is set to 0.001 hoping to show the value in kWh).
Another example is if I set value 25000 Wh (int64) the visualization shows 1.0226E-0315 again with factor 0.001.

I will ask the developer of the visu server to get more info on this and maybe there is another solution for this.

I was hoping to use LM to convert the value since its very powerful using lua. But for now I guess in the worst case the string value will do the job.

Thank you for your support.
Reply
#9
This example writes a numeric value in double floating point format using raw datatype. If the resulting value is incorrect try removing the line with reverse() call.

Code:
val = 123456.67890

ffi = require('ffi')

dst = ffi.new('unsigned char[8]')
src = ffi.new('double[1]')

src[ 0 ] = tonumber(val) or 0

ffi.copy(dst, src, 8)

res = ffi.string(dst, 8)
res = res:reverse()

grp.write('2/2/2', res, dt.raw)
Reply
#10
(20.02.2024, 09:01)admin Wrote: This example writes a numeric value in double floating point format using raw datatype. If the resulting value is incorrect try removing the line with reverse() call.

Code:
val = 123456.67890

ffi = require('ffi')

dst = ffi.new('unsigned char[8]')
src = ffi.new('double[1]')

src[ 0 ] = tonumber(val) or 0

ffi.copy(dst, src, 8)

res = ffi.string(dst, 8)
res = res:reverse()

grp.write('2/2/2', res, dt.raw)


Thank you admin, it worked with reverse() call removed.

Now how can I use this script to be able to process a table?
I want to use the table from the original script because I have around 50 values to process.

Code:
if not values then
values = {
    { input = '32/1/24', output = '10/0/24' },
    { input = '32/1/25', output = '10/0/25' },
    { input = '32/1/26', output = '10/0/26' }
}
end


for _, value in ipairs(values) do
  Wh = grp.getvalue(value.input)
  kWh = tostring(Wh / 1000)
    grp.checkwrite(value.output, kWh)
end

How this would be then?
Reply
#11
You can use an event script attached to a tag if input/output group addresses follow the same structure.
Code:
id = event.dst:split('/')[3]
addr = '10/0/' .. id

val = event.getvalue() / 1000

ffi = require('ffi')

dst = ffi.new('unsigned char[8]')
src = ffi.new('double[1]')

src[ 0 ] = tonumber(val) or 0

ffi.copy(dst, src, 8)
res = ffi.string(dst, 8)

grp.write(addr, res, dt.raw)
Reply
#12
(20.02.2024, 09:46)admin Wrote: You can use an event script attached to a tag if input/output group addresses follow the same structure.
Code:
id = event.dst:split('/')[3]
addr = '10/0/' .. id

val = event.getvalue() / 1000

ffi = require('ffi')

dst = ffi.new('unsigned char[8]')
src = ffi.new('double[1]')

src[ 0 ] = tonumber(val) or 0

ffi.copy(dst, src, 8)
res = ffi.string(dst, 8)

grp.write(addr, res, dt.raw)

Although this is a very clean, quick and smart solution, unfortunately the standard energy objects are having a different pattern than just changing the last part. The raw data objects will be created according to a table I would say in the range of 30/3/1->58 or something. I have to use 30 because the visu server cannot receive virtual addresses 32+/*/*.
I have attached all 58 objects to be processed. This is the reason why I would prefer in my application to use a table.

Attached Files
.pdf   Energy GAs.pdf (Size: 75.99 KB / Downloads: 5)
Reply
#13
You can place mapping table in the event script. Using event script is preferable because you cannot use grp.checkwrite() with raw datatype.

Code:
addrs = {
  ['32/1/24'] = '10/0/24',
  ['32/1/25'] = '10/0/25',
  ['32/1/26'] = '10/0/26',
}

addr = addrs[ event.dst ]
Reply
#14
(20.02.2024, 10:13)admin Wrote: You can place mapping table in the event script. Using event script is preferable because you cannot use grp.checkwrite() with raw datatype.

Code:
addrs = {
  ['32/1/24'] = '10/0/24',
  ['32/1/25'] = '10/0/25',
  ['32/1/26'] = '10/0/26',
}

addr = addrs[ event.dst ]

Super! Thank you very much for your time and solution Smile
Reply


Forum Jump: