or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client.mdconstants.mdindex.mdserver.mdutils.md

utils.mddocs/

0

# Data Utilities

1

2

Utility functions for data type conversion, bit manipulation, IEEE 754 floating point encoding/decoding, and protocol validation. These functions are essential for working with Modbus data types and converting between different representations.

3

4

## Capabilities

5

6

### Data Type Conversion

7

8

Functions for converting between different data representations commonly used in industrial automation.

9

10

```python { .api }

11

def word_list_to_long(val_list, big_endian=True, long_long=False):

12

"""

13

Convert word list to long integers.

14

15

Parameters:

16

val_list (list[int]): List of 16-bit words (0-65535)

17

big_endian (bool): Byte order (default: True)

18

long_long (bool): Use 64-bit integers instead of 32-bit (default: False)

19

20

Returns:

21

list[int]: List of 32-bit or 64-bit integers

22

"""

23

24

def long_list_to_word(val_list, big_endian=True, long_long=False):

25

"""

26

Convert long integers to word list.

27

28

Parameters:

29

val_list (list[int]): List of 32-bit or 64-bit integers

30

big_endian (bool): Byte order (default: True)

31

long_long (bool): Input integers are 64-bit (default: False)

32

33

Returns:

34

list[int]: List of 16-bit words (0-65535)

35

"""

36

37

def get_2comp(val_int, val_size=16):

38

"""

39

Convert unsigned integer to two's complement signed integer.

40

41

Parameters:

42

val_int (int): Unsigned integer value

43

val_size (int): Bit size (8, 16, 32, or 64, default: 16)

44

45

Returns:

46

int: Signed integer in two's complement format

47

"""

48

49

def get_list_2comp(val_list, val_size=16):

50

"""

51

Convert list of unsigned integers to two's complement signed integers.

52

53

Parameters:

54

val_list (list[int]): List of unsigned integer values

55

val_size (int): Bit size for each value (default: 16)

56

57

Returns:

58

list[int]: List of signed integers in two's complement format

59

"""

60

```

61

62

### IEEE 754 Floating Point

63

64

Functions for encoding and decoding IEEE 754 floating point numbers commonly used in Modbus applications.

65

66

```python { .api }

67

def decode_ieee(val_int, double=False):

68

"""

69

Decode IEEE 754 floating point from integer representation.

70

71

Parameters:

72

val_int (int): Integer representation of IEEE 754 float

73

double (bool): Use double precision (64-bit) instead of single (32-bit, default: False)

74

75

Returns:

76

float: Decoded floating point value

77

"""

78

79

def encode_ieee(val_float, double=False):

80

"""

81

Encode floating point value as IEEE 754 integer representation.

82

83

Parameters:

84

val_float (float): Floating point value to encode

85

double (bool): Use double precision (64-bit) instead of single (32-bit, default: False)

86

87

Returns:

88

int: IEEE 754 integer representation

89

"""

90

```

91

92

### Bit Manipulation

93

94

Functions for working with individual bits within integers.

95

96

```python { .api }

97

def get_bits_from_int(val_int, val_size=16):

98

"""

99

Extract bit list from integer value.

100

101

Parameters:

102

val_int (int): Integer value

103

val_size (int): Number of bits to extract (default: 16)

104

105

Returns:

106

list[bool]: List of bit values (LSB first)

107

"""

108

109

def test_bit(value, offset):

110

"""

111

Test if a specific bit is set in an integer.

112

113

Parameters:

114

value (int): Integer value to test

115

offset (int): Bit position (0 = LSB)

116

117

Returns:

118

bool: True if bit is set, False otherwise

119

"""

120

121

def set_bit(value, offset):

122

"""

123

Set a specific bit in an integer.

124

125

Parameters:

126

value (int): Original integer value

127

offset (int): Bit position to set (0 = LSB)

128

129

Returns:

130

int: Integer with specified bit set

131

"""

132

133

def reset_bit(value, offset):

134

"""

135

Clear a specific bit in an integer.

136

137

Parameters:

138

value (int): Original integer value

139

offset (int): Bit position to clear (0 = LSB)

140

141

Returns:

142

int: Integer with specified bit cleared

143

"""

144

145

def toggle_bit(value, offset):

146

"""

147

Toggle a specific bit in an integer.

148

149

Parameters:

150

value (int): Original integer value

151

offset (int): Bit position to toggle (0 = LSB)

152

153

Returns:

154

int: Integer with specified bit toggled

155

"""

156

157

def byte_length(bit_length):

158

"""

159

Calculate the number of bytes needed to store a given number of bits.

160

161

Parameters:

162

bit_length (int): Number of bits

163

164

Returns:

165

int: Number of bytes needed

166

"""

167

```

168

169

### Protocol Utilities

170

171

Functions for protocol validation and checksum calculation.

172

173

```python { .api }

174

def crc16(frame):

175

"""

176

Calculate CRC16 checksum for Modbus RTU frames.

177

178

Parameters:

179

frame (bytes): Frame data to calculate checksum for

180

181

Returns:

182

int: CRC16 checksum value

183

"""

184

185

def valid_host(host_str):

186

"""

187

Validate hostname or IP address format.

188

189

Parameters:

190

host_str (str): Hostname or IP address string

191

192

Returns:

193

bool: True if format is valid, False otherwise

194

"""

195

```

196

197

## Usage Examples

198

199

### Working with Floating Point Values

200

201

```python

202

from pyModbusTCP.utils import encode_ieee, decode_ieee, long_list_to_word, word_list_to_long

203

from pyModbusTCP.client import ModbusClient

204

205

client = ModbusClient(host="192.168.1.100", auto_open=True)

206

207

# Write a floating point value

208

temperature = 23.45

209

encoded_temp = encode_ieee(temperature)

210

register_list = long_list_to_word([encoded_temp], big_endian=True)

211

client.write_multiple_registers(100, register_list)

212

213

# Read and decode floating point value

214

registers = client.read_holding_registers(100, 2)

215

if registers:

216

temp_as_int = word_list_to_long(registers, big_endian=True)[0]

217

decoded_temp = decode_ieee(temp_as_int)

218

print(f"Temperature: {decoded_temp}°C")

219

```

220

221

### Bit Manipulation Example

222

223

```python

224

from pyModbusTCP.utils import get_bits_from_int, set_bit, reset_bit, test_bit

225

226

# Extract individual bits from a register value

227

register_value = 0b1101001010110011 # 54451

228

bits = get_bits_from_int(register_value, 16)

229

print(f"Bits: {bits}") # [True, True, False, False, ...]

230

231

# Manipulate individual bits

232

value = 0b00001111 # 15

233

value = set_bit(value, 4) # Set bit 4: 0b00011111 (31)

234

value = reset_bit(value, 0) # Clear bit 0: 0b00011110 (30)

235

is_set = test_bit(value, 1) # Test bit 1: True

236

print(f"Final value: {value}, bit 1 set: {is_set}")

237

```

238

239

### Data Type Conversion Example

240

241

```python

242

from pyModbusTCP.utils import word_list_to_long, long_list_to_word, get_2comp

243

244

# Convert 32-bit integers to register pairs

245

values_32bit = [1234567890, -987654321]

246

registers = long_list_to_word(values_32bit, big_endian=True)

247

print(f"Registers: {registers}") # [18838, 722, 50042, 35023]

248

249

# Convert back to 32-bit integers

250

converted_back = word_list_to_long(registers, big_endian=True)

251

print(f"Converted back: {converted_back}") # [1234567890, 4265312975]

252

253

# Handle signed values with two's complement

254

signed_values = [get_2comp(val, 32) for val in converted_back]

255

print(f"Signed values: {signed_values}") # [1234567890, -987654321]

256

```

257

258

### Working with Double Precision Floats

259

260

```python

261

from pyModbusTCP.utils import encode_ieee, decode_ieee, long_list_to_word, word_list_to_long

262

263

# Encode double precision float (64-bit)

264

precise_value = 3.141592653589793

265

encoded = encode_ieee(precise_value, double=True)

266

print(f"Encoded: {encoded}")

267

268

# Convert to 4 registers for Modbus transmission

269

registers = long_list_to_word([encoded], big_endian=True, long_long=True)

270

print(f"Registers: {registers}") # List of 4 registers

271

272

# Decode back to double precision

273

combined = word_list_to_long(registers, big_endian=True, long_long=True)[0]

274

decoded = decode_ieee(combined, double=True)

275

print(f"Decoded: {decoded}") # 3.141592653589793

276

```

277

278

### Protocol Validation

279

280

```python

281

from pyModbusTCP.utils import valid_host, crc16

282

283

# Validate host addresses

284

hosts = ["192.168.1.1", "localhost", "invalid@host", "::1", "example.com"]

285

for host in hosts:

286

is_valid = valid_host(host)

287

print(f"{host}: {'valid' if is_valid else 'invalid'}")

288

289

# Calculate CRC16 for Modbus RTU frame

290

frame = b'\x01\x03\x00\x00\x00\x0A' # Read holding registers request

291

checksum = crc16(frame)

292

print(f"CRC16: 0x{checksum:04X}")

293

294

# Complete frame with CRC

295

full_frame = frame + checksum.to_bytes(2, 'little')

296

print(f"Complete frame: {full_frame.hex()}")

297

```

298

299

### Bit Pattern Analysis

300

301

```python

302

from pyModbusTCP.utils import get_bits_from_int, byte_length

303

304

# Analyze status register bits

305

status_register = 0b1010001100110101 # 41269

306

status_bits = get_bits_from_int(status_register, 16)

307

308

# Define bit meanings

309

bit_names = [

310

"System Ready", "Error Active", "Manual Mode", "Auto Mode",

311

"Motor 1 Run", "Motor 2 Run", "Pump Active", "Heater On",

312

"Alarm 1", "Alarm 2", "Service Required", "Door Open",

313

"Temperature OK", "Pressure OK", "Flow OK", "Reserved"

314

]

315

316

print("System Status:")

317

for i, (name, state) in enumerate(zip(bit_names, status_bits)):

318

print(f" Bit {i:2d} - {name:15s}: {'ON' if state else 'OFF'}")

319

320

# Calculate storage requirements

321

num_status_bits = 16

322

bytes_needed = byte_length(num_status_bits)

323

print(f"Storage required: {bytes_needed} bytes for {num_status_bits} bits")

324

```

325

326

## Integration with Client/Server

327

328

These utility functions integrate seamlessly with the client and server operations:

329

330

```python

331

from pyModbusTCP.client import ModbusClient

332

from pyModbusTCP.server import ModbusServer, DataBank

333

from pyModbusTCP.utils import encode_ieee, decode_ieee, word_list_to_long, long_list_to_word

334

335

# Server side: Store floating point values

336

data_bank = DataBank()

337

temp_values = [23.45, 24.67, 22.89] # Temperature readings

338

339

for i, temp in enumerate(temp_values):

340

encoded = encode_ieee(temp)

341

registers = long_list_to_word([encoded], big_endian=True)

342

data_bank.set_holding_registers(i * 2, registers) # 2 registers per float

343

344

server = ModbusServer(data_bank=data_bank)

345

server.start()

346

347

# Client side: Read and decode floating point values

348

client = ModbusClient(auto_open=True)

349

temperatures = []

350

351

for i in range(3):

352

registers = client.read_holding_registers(i * 2, 2)

353

if registers:

354

temp_int = word_list_to_long(registers, big_endian=True)[0]

355

temperature = decode_ieee(temp_int)

356

temperatures.append(temperature)

357

358

print(f"Temperatures: {temperatures}")

359

```