Logic Machine Forum
dt.uint64 - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: dt.uint64 (/showthread.php?tid=4141)



dt.uint64 - DGrandes - 08.07.2022

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


RE: dt.uint64 - admin - 08.07.2022

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


RE: dt.uint64 - DGrandes - 08.07.2022

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.


RE: dt.uint64 - admin - 08.07.2022

Bit shifts operate on int32 (signed) values. You can use multiplication instead of bit shift:
Code:
valH = 0xFF00
valL = 0
val = valH * 0x10000 + valL



RE: dt.uint64 - DGrandes - 08.07.2022

Ok thanks!


RE: dt.uint64 - manos@dynamitec - 19.02.2024

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?


RE: dt.uint64 - admin - 20.02.2024

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.


RE: dt.uint64 - manos@dynamitec - 20.02.2024

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.


RE: dt.uint64 - admin - 20.02.2024

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)



RE: dt.uint64 - manos@dynamitec - 20.02.2024

(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?


RE: dt.uint64 - admin - 20.02.2024

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)



RE: dt.uint64 - manos@dynamitec - 20.02.2024

(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.


RE: dt.uint64 - admin - 20.02.2024

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 ]



RE: dt.uint64 - manos@dynamitec - 20.02.2024

(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