Skip to content

feat: Add new Modbus datatypes with correct byte ordering and GUI hints#2390

Open
steve0023 wants to merge 3 commits into
frangoteam:masterfrom
steve0023:64bit-datatype-clean
Open

feat: Add new Modbus datatypes with correct byte ordering and GUI hints#2390
steve0023 wants to merge 3 commits into
frangoteam:masterfrom
steve0023:64bit-datatype-clean

Conversation

@steve0023

Copy link
Copy Markdown
Contributor

📌 Description

Add new Modbus datatypes for 32-bit and 64-bit with correct byte ordering, fix existing parser bugs, and improve the tag type dropdown with byte order hints.

What was changed:

  • New 64-bit datatypes: UInt64, UInt64LE, Int64MBE, UInt64MBE, Int64MLE, UInt64MLE, Float64MBE, Float64MLE
  • New 32-bit byte-swap variants: Int32MBE, UInt32MBE, Float32MBE (Byte order 2,1,4,3)
  • Fix Bool parser: read 2-byte UInt16BE for Holding Registers, fallback to 1 byte for Coils
  • Fix Float32 precision artifacts by applying 7 significant digits rounding
  • Fix _swap: parser now works on a buffer copy to avoid mutating the shared Modbus response buffer
  • Add byte order hints in tag type dropdown (e.g. Int32MLE (32bit INT, Byte order 3,4,1,2))
  • Sort ModbusTagType enum by bit-width group then endianness

Byte order reference (validated against MBslave simulator):

Type Byte order MBslave format
Int32MLE 3,4,1,2 Little endian byte swap (already present)
Int32MBE 2,1,4,3 Big endian byte swap
Int64MBE 7,8,5,6,3,4,1,2 Little endian byte swap
Int64MLE 5,6,7,8,1,2,3,4 Big endian byte swap

🧪 Type of Change

  • Bug fix
  • New feature
  • Refactoring
  • Documentation
  • Other

🚫 Build Artifacts Check

  • I did NOT commit /client/dist
  • I did NOT commit generated Angular build output
  • Only source files are included

🔍 Checklist

  • Code follows project coding standards
  • I tested my changes locally
  • Documentation updated if required
  • Issue opened (for major changes)

📝 Additional Notes

Tested with MBslave simulator:

  • Bool (Holding Register + Coil)
  • 32Bit variants: Int / UInt / Float (LE, MBE, MLE)
  • 64Bit variants: Int / UInt / Float (LE, MBE, MLE)

Not tested (requires little-endian device):

  • Int16LE, UInt16LE

Known limitation: JavaScript Number precision limits Int64/UInt64 to ~15 significant digits. Very large 64-bit values will be approximated.

With a lot of help of Claude Sonnet 4.6

steve0023 and others added 3 commits June 4, 2026 23:00
- Add UInt64, UInt64LE, Int64MLE, UInt64MLE, Int64MBE, UInt64MBE datatypes
- Fix _swap to support swapType=4 (MLE 64-bit: reverse all 4 words)
- Add swapType=3 (MBE: swap words between halves)
- Add byte order hints in Modbus tag type dropdown (Teltonika notation)
- Update ModbusTagType enum with all new types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New datatypes added:
- UInt64, UInt64LE: 64-bit unsigned integers (BE and LE)
- Int64MBE, UInt64MBE: 64-bit signed/unsigned, byte order 7,8,5,6,3,4,1,2 (validated: MBslave 'little endian byte swap')
- Int64MLE, UInt64MLE: 64-bit signed/unsigned, byte order 5,6,7,8,1,2,3,4 (validated: MBslave 'big endian byte swap')
- Float64MBE, Float64MLE: 64-bit double with matching byte orders
- Int32MBE, UInt32MBE, Float32MBE: 32-bit byte order 2,1,4,3 (validated: MBslave 'big endian byte swap')

Fixes:
- Bool: read 2 bytes (UInt16BE) for Holding Registers, fallback to 1 byte for Coils
- Float32/Float32LE/Float32MLE/Float32MBE: apply precision=7 to avoid float32 rounding artifacts
- _swap: parser now works on a buffer copy to avoid corrupting shared Modbus response buffer

GUI improvements:
- ModbusTagType enum sorted by: Bool, 16-bit, 32-bit, 64-bit groups (BE, LE, MLE, MBE)
- Byte order hints added to tag type dropdown using byte order notation (e.g. 'Byte order 2,1,4,3')

Not tested (no LE simulator available):
- Int16LE, UInt16LE, Int64LE, UInt64LE

With a lot of help of Claude Sonnet 4.6
@unocelli

Copy link
Copy Markdown
Member

Hi @steve0023 Thanks for the PR.
I agree with the goal of improving 64-bit Modbus datatype support, but we need to avoid changing the behavior of existing datatypes in a way that could silently break current projects.
The direction makes sense, especially adding explicit 32-bit/64-bit byte-order variants and improving the dropdown hints.

I have just added regression tests for the current Modbus datatype conversions so we can protect existing behavior while reviewing this PR.

There are a couple of compatibility issues we need to handle before merging:

  1. Existing datatypes should not change behavior silently

Even if the new byte ordering is more correct for some devices, changing an already existing datatype can break existing FUXA projects. In particular, the current Float64MLE already exists and currently behaves as byte order 5,6,7,8,1,2,3,4.

So if this PR needs a different 64-bit order, please add it as a new datatype instead of changing the meaning of the existing one.

  1. Bool parsing regression

The PR changes Bool.bytes from 1 to 2 and reads UInt16BE when two bytes are available. This breaks packed coil/discrete-input parsing, because coil reads are bit-packed by byte.

Holding-register boolean support is useful, but it should not change the existing Bool behavior for coils/discrete inputs. We probably need either:

  • keep Bool as the existing packed-bit type, or
  • introduce a separate register-based boolean type for holding/input registers.
  1. 64-bit integers and BigInt

FUXA currently does not support BigInt end-to-end. Returning Number is acceptable for now, but values outside Number.MAX_SAFE_INTEGER cannot be represented safely. We should either document this limitation or avoid implying full safe UInt64/Int64 support.

  1. Parser buffer-copy fix

The change to parse from a buffer copy is good. Avoiding mutation of the shared Modbus response buffer is a real fix and should stay.

  1. Float32 precision rounding

This may be useful for display noise, but it changes raw parsed values. I would prefer keeping raw parsing exact and applying display/format rounding elsewhere, unless we have a specific bug this fixes.

Preferred path:

  • keep all existing datatype semantics unchanged;
  • keep the buffer-copy parser fix;
  • keep/add the new byte-order variants as additive datatypes;
  • do not repurpose existing Float64MLE;
  • do not change packed Bool behavior;
  • add tests for every new byte order introduced.

With that approach we can merge the useful new datatype support without causing regressions for existing projects.

This is a valuable improvement and it is very close; we just need to make it additive and regression-safe so existing users do not get unexpected value changes after upgrading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants