value-types.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. const {
  2. DATA_TYPE_OPTIONS,
  3. DEFAULT_DATA_TYPE,
  4. DEFAULT_TEXT_BYTE_LENGTH,
  5. GROUP_LAYOUT_STRUCT,
  6. MAX_TEXT_BYTE_LENGTH
  7. } = require('./constants.js')
  8. function getDataType(dataType) {
  9. return DATA_TYPE_OPTIONS.find((item) => item.key === dataType)
  10. || DATA_TYPE_OPTIONS.find((item) => item.key === DEFAULT_DATA_TYPE)
  11. || DATA_TYPE_OPTIONS[0]
  12. }
  13. function getDataTypeIndex(dataType) {
  14. return Math.max(0, DATA_TYPE_OPTIONS.findIndex((item) => item.key === getDataType(dataType).key))
  15. }
  16. function normalizeTextByteLength(value, fallback = DEFAULT_TEXT_BYTE_LENGTH) {
  17. const numberValue = Number(value)
  18. const rounded = Number.isFinite(numberValue) ? Math.round(numberValue) : fallback
  19. return Math.min(Math.max(rounded, 1), MAX_TEXT_BYTE_LENGTH)
  20. }
  21. function alignEvenByteLength(byteLength) {
  22. const length = Math.max(1, Math.round(Number(byteLength) || 1))
  23. return length % 2 === 0 ? length : length + 1
  24. }
  25. function getRegisterTextByteLength(register = {}) {
  26. return normalizeTextByteLength(register.textByteLength, DEFAULT_TEXT_BYTE_LENGTH)
  27. }
  28. function isStructLayout(layout) {
  29. return layout === GROUP_LAYOUT_STRUCT
  30. }
  31. function isBitFieldRegister(register = {}) {
  32. return !!register.isBitField
  33. }
  34. function normalizeBitOffset(value) {
  35. const numberValue = Math.floor(Number(value) || 0)
  36. return Math.min(Math.max(numberValue, 0), 7)
  37. }
  38. function normalizeBitWidth(value) {
  39. const numberValue = Math.round(Number(value) || 1)
  40. return Math.min(Math.max(numberValue, 1), 32)
  41. }
  42. function getBitFieldByteLength(register = {}) {
  43. const bitOffset = normalizeBitOffset(register.bitOffset)
  44. const bitWidth = normalizeBitWidth(register.bitWidth)
  45. return Math.max(1, Math.ceil((bitOffset + bitWidth) / 8))
  46. }
  47. function getBitFieldMaxValue(register = {}) {
  48. const bitWidth = normalizeBitWidth(register.bitWidth)
  49. return bitWidth >= 32 ? 0xFFFFFFFF : Math.pow(2, bitWidth) - 1
  50. }
  51. function getRegisterByteLength(dataType, register = {}) {
  52. if (isBitFieldRegister(register)) return getBitFieldByteLength(register)
  53. const type = getDataType(dataType)
  54. if (type.kind === 'text') {
  55. const byteLength = getRegisterTextByteLength(register)
  56. return isStructLayout(register.layout) ? byteLength : alignEvenByteLength(byteLength)
  57. }
  58. return type.byteLength || ((type.wordCount || 1) * 2)
  59. }
  60. function getRegisterWordCount(dataType, register = {}) {
  61. return Math.max(1, Math.ceil(getRegisterByteLength(dataType, register) / 2))
  62. }
  63. function getByteSpanWordCount(byteOffset, byteLength) {
  64. return Math.max(1, Math.ceil((Math.max(0, Number(byteOffset) || 0) + Math.max(1, Number(byteLength) || 1)) / 2))
  65. }
  66. function getRegisterWordCountAtOffset(dataType, byteOffset, register = {}) {
  67. const byteLength = getRegisterByteLength(dataType, register)
  68. return getByteSpanWordCount(byteOffset, byteLength)
  69. }
  70. function isTextRegister(dataType) {
  71. return getDataType(dataType).kind === 'text'
  72. }
  73. function getEncodeByteLimit(register) {
  74. return isTextRegister(register.dataType) ? getRegisterTextByteLength(register) : getRegisterByteLength(register.dataType, register)
  75. }
  76. function isByteRegister(dataType) {
  77. const key = getDataType(dataType).key
  78. return key === 'int8_t' || key === 'uint8_t'
  79. }
  80. function isBitRegisterType(registerType) {
  81. return registerType === 'coil' || registerType === 'discrete'
  82. }
  83. function isHexRegister(dataType) {
  84. return getDataType(dataType).key === 'hex'
  85. }
  86. function isNumericRegister(dataType) {
  87. return getDataType(dataType).kind === 'number'
  88. }
  89. function supportsRange(dataType) {
  90. return isNumericRegister(dataType) || isHexRegister(dataType)
  91. }
  92. function supportsUnit(dataType) {
  93. return isNumericRegister(dataType)
  94. }
  95. function getRegisterValueTypeLabel(dataType) {
  96. return getDataType(dataType).label
  97. }
  98. module.exports = {
  99. alignEvenByteLength,
  100. getBitFieldByteLength,
  101. getBitFieldMaxValue,
  102. getDataType,
  103. getDataTypeIndex,
  104. getEncodeByteLimit,
  105. getRegisterByteLength,
  106. getRegisterTextByteLength,
  107. getRegisterValueTypeLabel,
  108. getRegisterWordCount,
  109. getRegisterWordCountAtOffset,
  110. isBitFieldRegister,
  111. isBitRegisterType,
  112. isByteRegister,
  113. isHexRegister,
  114. isNumericRegister,
  115. isTextRegister,
  116. normalizeBitOffset,
  117. normalizeBitWidth,
  118. normalizeTextByteLength,
  119. supportsRange,
  120. supportsUnit
  121. }