xarm-python-sdk 1.15.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xarm/__init__.py +2 -0
- xarm/build_backend.py +17 -0
- xarm/core/__init__.py +2 -0
- xarm/core/comm/__init__.py +5 -0
- xarm/core/comm/base.py +303 -0
- xarm/core/comm/serial_port.py +44 -0
- xarm/core/comm/socket_port.py +150 -0
- xarm/core/comm/uxbus_cmd_protocol.py +100 -0
- xarm/core/config/__init__.py +0 -0
- xarm/core/config/x_code.py +1427 -0
- xarm/core/config/x_config.py +553 -0
- xarm/core/utils/__init__.py +3 -0
- xarm/core/utils/convert.py +124 -0
- xarm/core/utils/crc16.py +76 -0
- xarm/core/utils/debug_print.py +21 -0
- xarm/core/utils/log.py +98 -0
- xarm/core/version.py +1 -0
- xarm/core/wrapper/__init__.py +11 -0
- xarm/core/wrapper/uxbus_cmd.py +1457 -0
- xarm/core/wrapper/uxbus_cmd_ser.py +94 -0
- xarm/core/wrapper/uxbus_cmd_tcp.py +305 -0
- xarm/tools/__init__.py +0 -0
- xarm/tools/blockly/__init__.py +1 -0
- xarm/tools/blockly/_blockly_base.py +416 -0
- xarm/tools/blockly/_blockly_handler.py +1338 -0
- xarm/tools/blockly/_blockly_highlight.py +94 -0
- xarm/tools/blockly/_blockly_node.py +61 -0
- xarm/tools/blockly/_blockly_tool.py +480 -0
- xarm/tools/blockly_tool.py +1864 -0
- xarm/tools/gcode.py +90 -0
- xarm/tools/list_ports.py +39 -0
- xarm/tools/modbus_tcp.py +205 -0
- xarm/tools/threads.py +30 -0
- xarm/tools/utils.py +36 -0
- xarm/version.py +1 -0
- xarm/wrapper/__init__.py +1 -0
- xarm/wrapper/studio_api.py +34 -0
- xarm/wrapper/xarm_api.py +4416 -0
- xarm/x3/__init__.py +2 -0
- xarm/x3/base.py +2638 -0
- xarm/x3/base_board.py +198 -0
- xarm/x3/code.py +62 -0
- xarm/x3/decorator.py +104 -0
- xarm/x3/events.py +166 -0
- xarm/x3/ft_sensor.py +264 -0
- xarm/x3/gpio.py +457 -0
- xarm/x3/grammar_async.py +21 -0
- xarm/x3/grammar_coroutine.py +24 -0
- xarm/x3/gripper.py +830 -0
- xarm/x3/modbus_tcp.py +84 -0
- xarm/x3/parse.py +110 -0
- xarm/x3/record.py +216 -0
- xarm/x3/report.py +204 -0
- xarm/x3/robotiq.py +220 -0
- xarm/x3/servo.py +485 -0
- xarm/x3/studio.py +138 -0
- xarm/x3/track.py +424 -0
- xarm/x3/utils.py +43 -0
- xarm/x3/xarm.py +1928 -0
- xarm_python_sdk-1.15.2.dist-info/METADATA +103 -0
- xarm_python_sdk-1.15.2.dist-info/RECORD +63 -0
- xarm_python_sdk-1.15.2.dist-info/WHEEL +4 -0
- xarm_python_sdk-1.15.2.dist-info/licenses/LICENSE +27 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Software License Agreement (BSD License)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2018, UFACTORY, Inc.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Author: Jimy Zhang <jimy.zhang@ufactory.cc> <jimy92@163.com>
|
|
8
|
+
# Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
from ..utils import crc16
|
|
13
|
+
from .uxbus_cmd import UxbusCmd
|
|
14
|
+
from ..config.x_config import XCONF
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def debug_log_datas(datas, label=''):
|
|
18
|
+
print('{}:'.format(label), end=' ')
|
|
19
|
+
for i in range(len(datas)):
|
|
20
|
+
print('{:x}'.format(datas[i]).zfill(2), end=' ')
|
|
21
|
+
# print(hex(rx_data[i]), end=',')
|
|
22
|
+
print()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class UxbusCmdSer(UxbusCmd):
|
|
26
|
+
def __init__(self, arm_port, fromid=XCONF.SerialConf.UXBUS_DEF_FROMID, toid=XCONF.SerialConf.UXBUS_DEF_TOID):
|
|
27
|
+
super(UxbusCmdSer, self).__init__()
|
|
28
|
+
self.arm_port = arm_port
|
|
29
|
+
self.fromid = fromid
|
|
30
|
+
self.toid = toid
|
|
31
|
+
arm_port.flush(fromid, toid)
|
|
32
|
+
self._has_err_warn = False
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def has_err_warn(self):
|
|
36
|
+
return self._has_err_warn
|
|
37
|
+
|
|
38
|
+
@has_err_warn.setter
|
|
39
|
+
def has_err_warn(self, value):
|
|
40
|
+
self._has_err_warn = value
|
|
41
|
+
|
|
42
|
+
def set_protocol_identifier(self, protocol_identifier):
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
def get_protocol_identifier(self):
|
|
46
|
+
return 0
|
|
47
|
+
|
|
48
|
+
def check_protocol_header(self, data, t_trans_id, t_prot_id, t_unit_id):
|
|
49
|
+
return 0
|
|
50
|
+
|
|
51
|
+
def check_private_protocol(self, data):
|
|
52
|
+
self._state_is_ready = not (data[3] & 0x10)
|
|
53
|
+
if data[3] & 0x08:
|
|
54
|
+
return XCONF.UxbusState.INVALID
|
|
55
|
+
if data[3] & 0x40:
|
|
56
|
+
self._has_err_warn = True
|
|
57
|
+
return XCONF.UxbusState.ERR_CODE
|
|
58
|
+
elif data[3] & 0x20:
|
|
59
|
+
self._has_err_warn = True
|
|
60
|
+
return XCONF.UxbusState.WAR_CODE
|
|
61
|
+
else:
|
|
62
|
+
self._has_err_warn = False
|
|
63
|
+
return 0
|
|
64
|
+
|
|
65
|
+
def send_modbus_request(self, reg, txdata, num, prot_id=-1, t_id=None):
|
|
66
|
+
send_data = bytes([self.fromid, self.toid, num + 1, reg])
|
|
67
|
+
for i in range(num):
|
|
68
|
+
send_data += bytes([txdata[i]])
|
|
69
|
+
send_data += crc16.crc_modbus(send_data)
|
|
70
|
+
self.arm_port.flush()
|
|
71
|
+
if self._debug:
|
|
72
|
+
debug_log_datas(send_data, label='send')
|
|
73
|
+
return self.arm_port.write(send_data)
|
|
74
|
+
|
|
75
|
+
def recv_modbus_response(self, t_funcode, t_trans_id, num, timeout, t_prot_id=-1, ret_raw=False):
|
|
76
|
+
ret = [0] * 254 if num == -1 else [0] * (num + 1)
|
|
77
|
+
expired = time.monotonic() + timeout
|
|
78
|
+
ret[0] = XCONF.UxbusState.ERR_TOUT
|
|
79
|
+
while time.monotonic() < expired:
|
|
80
|
+
remaining = expired - time.monotonic()
|
|
81
|
+
rx_data = self.arm_port.read(remaining)
|
|
82
|
+
if rx_data != -1 and len(rx_data) > 5:
|
|
83
|
+
if self._debug:
|
|
84
|
+
debug_log_datas(rx_data, label='recv')
|
|
85
|
+
ret[0] = self.check_private_protocol(rx_data)
|
|
86
|
+
num = rx_data[2] if num == -1 else num
|
|
87
|
+
length = len(rx_data) - 4
|
|
88
|
+
for i in range(num):
|
|
89
|
+
if i >= length:
|
|
90
|
+
break
|
|
91
|
+
ret[i + 1] = rx_data[i + 4]
|
|
92
|
+
return ret
|
|
93
|
+
time.sleep(0.001)
|
|
94
|
+
return ret
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Software License Agreement (BSD License)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2018, UFACTORY, Inc.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Author: Jimy Zhang <jimy.zhang@ufactory.cc> <jimy92@163.com>
|
|
8
|
+
# Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
import struct
|
|
13
|
+
from ..utils import convert
|
|
14
|
+
from .uxbus_cmd import UxbusCmd, lock_require
|
|
15
|
+
from ..config.x_config import XCONF
|
|
16
|
+
|
|
17
|
+
STANDARD_MODBUS_TCP_PROTOCOL = 0x00
|
|
18
|
+
PRIVATE_MODBUS_TCP_PROTOCOL = 0x02
|
|
19
|
+
TRANSACTION_ID_MAX = 65535 # cmd序号 最大值
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def debug_log_datas(datas, label=''):
|
|
23
|
+
print('{}:'.format(label), end=' ')
|
|
24
|
+
for i in range(len(datas)):
|
|
25
|
+
print('{:x}'.format(datas[i]).zfill(2), end=' ')
|
|
26
|
+
# print('0x{}'.format('{:x}'.format(datas[i]).zfill(2)), end=' ')
|
|
27
|
+
# print(hex(rx_data[i]), end=',')
|
|
28
|
+
print()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class UxbusCmdTcp(UxbusCmd):
|
|
32
|
+
def __init__(self, arm_port, set_feedback_key_tranid=None):
|
|
33
|
+
super(UxbusCmdTcp, self).__init__(set_feedback_key_tranid=set_feedback_key_tranid)
|
|
34
|
+
self.arm_port = arm_port
|
|
35
|
+
self._has_err_warn = False
|
|
36
|
+
self._last_comm_time = time.monotonic()
|
|
37
|
+
self._transaction_id = 1
|
|
38
|
+
self._protocol_identifier = PRIVATE_MODBUS_TCP_PROTOCOL
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def has_err_warn(self):
|
|
42
|
+
return self._has_err_warn
|
|
43
|
+
|
|
44
|
+
@has_err_warn.setter
|
|
45
|
+
def has_err_warn(self, value):
|
|
46
|
+
self._has_err_warn = value
|
|
47
|
+
|
|
48
|
+
@lock_require
|
|
49
|
+
def set_protocol_identifier(self, protocol_identifier):
|
|
50
|
+
if self._protocol_identifier != protocol_identifier:
|
|
51
|
+
self._protocol_identifier = protocol_identifier
|
|
52
|
+
print('change protocol identifier to {}'.format(self._protocol_identifier))
|
|
53
|
+
return 0
|
|
54
|
+
|
|
55
|
+
def get_protocol_identifier(self):
|
|
56
|
+
return self._protocol_identifier
|
|
57
|
+
|
|
58
|
+
def _get_trans_id(self):
|
|
59
|
+
return self._transaction_id
|
|
60
|
+
|
|
61
|
+
def check_protocol_header(self, data, t_trans_id, t_prot_id, t_unit_id):
|
|
62
|
+
trans_id = convert.bytes_to_u16(data[0:2])
|
|
63
|
+
prot_id = convert.bytes_to_u16(data[2:4])
|
|
64
|
+
# length = convert.bytes_to_u16(data[4:6])
|
|
65
|
+
unit_id = data[6] # standard(unit_id), private(funcode)
|
|
66
|
+
if trans_id != t_trans_id:
|
|
67
|
+
return XCONF.UxbusState.ERR_NUM
|
|
68
|
+
if prot_id != t_prot_id:
|
|
69
|
+
return XCONF.UxbusState.ERR_PROT
|
|
70
|
+
if unit_id != t_unit_id:
|
|
71
|
+
return XCONF.UxbusState.ERR_FUN
|
|
72
|
+
# if len(data) != length + 6:
|
|
73
|
+
# return XCONF.UxbusState.ERR_LENG
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
def check_private_protocol(self, data):
|
|
77
|
+
state = data[7]
|
|
78
|
+
self._state_is_ready = not (state & 0x10)
|
|
79
|
+
if state & 0x08:
|
|
80
|
+
return XCONF.UxbusState.INVALID
|
|
81
|
+
if state & 0x40:
|
|
82
|
+
self._has_err_warn = True
|
|
83
|
+
return XCONF.UxbusState.ERR_CODE
|
|
84
|
+
if state & 0x20:
|
|
85
|
+
self._has_err_warn = True
|
|
86
|
+
return XCONF.UxbusState.WAR_CODE
|
|
87
|
+
self._has_err_warn = False
|
|
88
|
+
return 0
|
|
89
|
+
|
|
90
|
+
def send_modbus_request(self, unit_id, pdu_data, pdu_len, prot_id=-1, t_id=None):
|
|
91
|
+
trans_id = self._transaction_id if t_id is None else t_id
|
|
92
|
+
prot_id = self._protocol_identifier if prot_id < 0 else prot_id
|
|
93
|
+
send_data = convert.u16_to_bytes(trans_id)
|
|
94
|
+
send_data += convert.u16_to_bytes(prot_id)
|
|
95
|
+
send_data += convert.u16_to_bytes(pdu_len + 1)
|
|
96
|
+
send_data += bytes([unit_id])
|
|
97
|
+
for i in range(pdu_len):
|
|
98
|
+
send_data += bytes([pdu_data[i]])
|
|
99
|
+
self.arm_port.flush()
|
|
100
|
+
if self._debug:
|
|
101
|
+
debug_log_datas(send_data, label='send({})'.format(unit_id))
|
|
102
|
+
ret = self.arm_port.write(send_data)
|
|
103
|
+
if ret != 0:
|
|
104
|
+
return -1
|
|
105
|
+
if t_id is None:
|
|
106
|
+
self._transaction_id = self._transaction_id % TRANSACTION_ID_MAX + 1
|
|
107
|
+
return trans_id
|
|
108
|
+
|
|
109
|
+
def recv_modbus_response(self, t_unit_id, t_trans_id, num, timeout, t_prot_id=-1, ret_raw=False):
|
|
110
|
+
prot_id = self._protocol_identifier if t_prot_id < 0 else t_prot_id
|
|
111
|
+
ret = [0] * 320 if num == -1 else [0] * (num + 1)
|
|
112
|
+
ret[0] = XCONF.UxbusState.ERR_TOUT
|
|
113
|
+
expired = time.monotonic() + timeout
|
|
114
|
+
while time.monotonic() < expired:
|
|
115
|
+
remaining = expired - time.monotonic()
|
|
116
|
+
rx_data = self.arm_port.read(remaining)
|
|
117
|
+
if rx_data == -1:
|
|
118
|
+
time.sleep(0.001)
|
|
119
|
+
continue
|
|
120
|
+
self._last_comm_time = time.monotonic()
|
|
121
|
+
if self._debug:
|
|
122
|
+
debug_log_datas(rx_data, label='recv({})'.format(t_unit_id))
|
|
123
|
+
code = self.check_protocol_header(rx_data, t_trans_id, prot_id, t_unit_id)
|
|
124
|
+
if code != 0:
|
|
125
|
+
if code != XCONF.UxbusState.ERR_NUM:
|
|
126
|
+
ret[0] = code
|
|
127
|
+
return ret
|
|
128
|
+
else:
|
|
129
|
+
continue
|
|
130
|
+
if prot_id != STANDARD_MODBUS_TCP_PROTOCOL and not ret_raw:
|
|
131
|
+
# Private Modbus TCP Protocol
|
|
132
|
+
ret[0] = self.check_private_protocol(rx_data)
|
|
133
|
+
num = convert.bytes_to_u16(rx_data[4:6]) - 2
|
|
134
|
+
ret = ret[:num + 1] if len(ret) >= num + 1 else [ret[0]] * (num + 1)
|
|
135
|
+
length = len(rx_data) - 8
|
|
136
|
+
for i in range(num):
|
|
137
|
+
if i >= length:
|
|
138
|
+
break
|
|
139
|
+
ret[i + 1] = rx_data[i + 8]
|
|
140
|
+
else:
|
|
141
|
+
# Standard Modbus TCP Protocol
|
|
142
|
+
ret[0] = 0
|
|
143
|
+
num = convert.bytes_to_u16(rx_data[4:6]) + 6
|
|
144
|
+
ret = ret[:num + 1] if len(ret) >= num + 1 else [ret[0]] * (num + 1)
|
|
145
|
+
length = len(rx_data)
|
|
146
|
+
for i in range(num):
|
|
147
|
+
if i >= length:
|
|
148
|
+
break
|
|
149
|
+
ret[i + 1] = rx_data[i]
|
|
150
|
+
return ret
|
|
151
|
+
return ret
|
|
152
|
+
|
|
153
|
+
# def send_hex_request(self, send_data):
|
|
154
|
+
# trans_id = int('0x' + str(send_data[0]) + str(send_data[1]), 16)
|
|
155
|
+
# data_str = b''
|
|
156
|
+
# for data in send_data:
|
|
157
|
+
# data_str += bytes.fromhex(data)
|
|
158
|
+
# send_data = data_str
|
|
159
|
+
# self.arm_port.flush()
|
|
160
|
+
# if self._debug:
|
|
161
|
+
# debug_log_datas(send_data, label='send')
|
|
162
|
+
# ret = self.arm_port.write(send_data)
|
|
163
|
+
# if ret != 0:
|
|
164
|
+
# return -1
|
|
165
|
+
# return trans_id
|
|
166
|
+
|
|
167
|
+
# def recv_hex_request(self, t_trans_id, timeout, t_prot_id=-1):
|
|
168
|
+
# prot_id = 2
|
|
169
|
+
# expired = time.monotonic() + timeout
|
|
170
|
+
# while time.monotonic() < expired:
|
|
171
|
+
# remaining = expired - time.monotonic()
|
|
172
|
+
# rx_data = self.arm_port.read(remaining)
|
|
173
|
+
# if rx_data == -1:
|
|
174
|
+
# time.sleep(0.001)
|
|
175
|
+
# continue
|
|
176
|
+
# self._last_comm_time = time.monotonic()
|
|
177
|
+
# if self._debug:
|
|
178
|
+
# debug_log_datas(rx_data, label='recv')
|
|
179
|
+
# code = self.check_protocol_header(rx_data, t_trans_id, prot_id, rx_data[6])
|
|
180
|
+
# if code != 0:
|
|
181
|
+
# if code != XCONF.UxbusState.ERR_NUM:
|
|
182
|
+
# return code
|
|
183
|
+
# else:
|
|
184
|
+
# continue
|
|
185
|
+
# break
|
|
186
|
+
# if rx_data != -1 and len(rx_data) > 0:
|
|
187
|
+
# recv_datas = []
|
|
188
|
+
# for i in range(len(rx_data)):
|
|
189
|
+
# recv_datas.append('{:x}'.format(rx_data[i]).zfill(2))
|
|
190
|
+
# return recv_datas
|
|
191
|
+
# else:
|
|
192
|
+
# return rx_data if rx_data else 3
|
|
193
|
+
|
|
194
|
+
####################### Standard Modbus TCP API ########################
|
|
195
|
+
@lock_require
|
|
196
|
+
def __standard_modbus_tcp_request(self, pdu, unit_id=0x01):
|
|
197
|
+
ret = self.send_modbus_request(unit_id, pdu, len(pdu), prot_id=STANDARD_MODBUS_TCP_PROTOCOL)
|
|
198
|
+
if ret == -1:
|
|
199
|
+
return XCONF.UxbusState.ERR_NOTTCP, b''
|
|
200
|
+
ret = self.recv_modbus_response(unit_id, ret, -1, 10000, t_prot_id=STANDARD_MODBUS_TCP_PROTOCOL)
|
|
201
|
+
code, recv_data = ret[0], bytes(ret[1:])
|
|
202
|
+
if code == 0 and recv_data[7] == pdu[0] + 0x80: # len(recv_data) == 9
|
|
203
|
+
# print('request exception, exp={}, res={}'.format(recv_data[8], recv_data))
|
|
204
|
+
return recv_data[8] + 0x80, recv_data
|
|
205
|
+
# elif code != 0:
|
|
206
|
+
# print('recv timeout, len={}, res={}'.format(len(recv_data), recv_data))
|
|
207
|
+
return code, recv_data
|
|
208
|
+
|
|
209
|
+
def __read_bits(self, addr, quantity, func_code=0x01):
|
|
210
|
+
assert func_code == 0x01 or func_code == 0x02
|
|
211
|
+
pdu = struct.pack('>BHH', func_code, addr, quantity)
|
|
212
|
+
code, res_data = self.__standard_modbus_tcp_request(pdu)
|
|
213
|
+
if code == 0 and len(res_data) == 9 + (quantity + 7) // 8:
|
|
214
|
+
return code, [(res_data[9 + i // 8] >> (i % 8) & 0x01) for i in range(quantity)]
|
|
215
|
+
else:
|
|
216
|
+
return code, res_data
|
|
217
|
+
|
|
218
|
+
def __read_registers(self, addr, quantity, func_code=0x03, is_signed=False):
|
|
219
|
+
assert func_code == 0x03 or func_code == 0x04
|
|
220
|
+
pdu = struct.pack('>BHH', func_code, addr, quantity)
|
|
221
|
+
code, res_data = self.__standard_modbus_tcp_request(pdu)
|
|
222
|
+
if code == 0 and len(res_data) == 9 + quantity * 2:
|
|
223
|
+
return 0, list(struct.unpack('>{}{}'.format(quantity, 'h' if is_signed else 'H'), res_data[9:]))
|
|
224
|
+
else:
|
|
225
|
+
return code, res_data
|
|
226
|
+
|
|
227
|
+
def read_coil_bits(self, addr, quantity):
|
|
228
|
+
"""
|
|
229
|
+
func_code: 0x01
|
|
230
|
+
"""
|
|
231
|
+
return self.__read_bits(addr, quantity, func_code=0x01)
|
|
232
|
+
|
|
233
|
+
def read_input_bits(self, addr, quantity):
|
|
234
|
+
"""
|
|
235
|
+
func_code: 0x02
|
|
236
|
+
"""
|
|
237
|
+
return self.__read_bits(addr, quantity, func_code=0x02)
|
|
238
|
+
|
|
239
|
+
def read_holding_registers(self, addr, quantity, is_signed=False):
|
|
240
|
+
"""
|
|
241
|
+
func_code: 0x03
|
|
242
|
+
"""
|
|
243
|
+
return self.__read_registers(addr, quantity, func_code=0x03, is_signed=is_signed)
|
|
244
|
+
|
|
245
|
+
def read_input_registers(self, addr, quantity, is_signed=False):
|
|
246
|
+
"""
|
|
247
|
+
func_code: 0x04
|
|
248
|
+
"""
|
|
249
|
+
return self.__read_registers(addr, quantity, func_code=0x04, is_signed=is_signed)
|
|
250
|
+
|
|
251
|
+
def write_single_coil_bit(self, addr, bit_val):
|
|
252
|
+
"""
|
|
253
|
+
func_code: 0x05
|
|
254
|
+
"""
|
|
255
|
+
pdu = struct.pack('>BHH', 0x05, addr, 0xFF00 if bit_val else 0x0000)
|
|
256
|
+
return self.__standard_modbus_tcp_request(pdu)[0]
|
|
257
|
+
|
|
258
|
+
def write_single_holding_register(self, addr, reg_val):
|
|
259
|
+
"""
|
|
260
|
+
func_code: 0x06
|
|
261
|
+
"""
|
|
262
|
+
# pdu = struct.pack('>BHH', 0x06, addr, reg_val)
|
|
263
|
+
pdu = struct.pack('>BH', 0x06, addr)
|
|
264
|
+
pdu += convert.u16_to_bytes(reg_val)
|
|
265
|
+
return self.__standard_modbus_tcp_request(pdu)[0]
|
|
266
|
+
|
|
267
|
+
def write_multiple_coil_bits(self, addr, bits):
|
|
268
|
+
"""
|
|
269
|
+
func_code: 0x0F
|
|
270
|
+
"""
|
|
271
|
+
datas = [0] * ((len(bits) + 7) // 8)
|
|
272
|
+
for i in range(len(bits)):
|
|
273
|
+
if bits[i]:
|
|
274
|
+
datas[i // 8] |= (1 << (i % 8))
|
|
275
|
+
pdu = struct.pack('>BHHB{}B'.format(len(datas)), 0x0F, addr, len(bits), len(datas), *datas)
|
|
276
|
+
return self.__standard_modbus_tcp_request(pdu)[0]
|
|
277
|
+
|
|
278
|
+
def write_multiple_holding_registers(self, addr, regs):
|
|
279
|
+
"""
|
|
280
|
+
func_code: 0x10
|
|
281
|
+
"""
|
|
282
|
+
# pdu = struct.pack('>BHHB{}H'.format(len(regs)), 0x10, addr, len(regs), len(regs) * 2, *regs)
|
|
283
|
+
pdu = struct.pack('>BHHB', 0x10, addr, len(regs), len(regs) * 2)
|
|
284
|
+
pdu += convert.u16s_to_bytes(regs, len(regs))
|
|
285
|
+
return self.__standard_modbus_tcp_request(pdu)[0]
|
|
286
|
+
|
|
287
|
+
def mask_write_holding_register(self, addr, and_mask, or_mask):
|
|
288
|
+
"""
|
|
289
|
+
func_code: 0x16
|
|
290
|
+
"""
|
|
291
|
+
pdu = struct.pack('>BHHH', 0x16, addr, and_mask, or_mask)
|
|
292
|
+
return self.__standard_modbus_tcp_request(pdu)[0]
|
|
293
|
+
|
|
294
|
+
def write_and_read_holding_registers(self, r_addr, r_quantity, w_addr, w_regs, is_signed=False):
|
|
295
|
+
"""
|
|
296
|
+
func_code: 0x17
|
|
297
|
+
"""
|
|
298
|
+
# pdu = struct.pack('>BHHHHB{}{}'.format(len(w_regs), 'h' if w_signed else 'H'), 0x17, r_addr, r_quantity, w_addr, len(w_regs), len(w_regs) * 2, *w_regs)
|
|
299
|
+
pdu = struct.pack('>BHHHHB', 0x17, r_addr, r_quantity, w_addr, len(w_regs), len(w_regs) * 2)
|
|
300
|
+
pdu += convert.u16s_to_bytes(w_regs, len(w_regs))
|
|
301
|
+
code, res_data = self.__standard_modbus_tcp_request(pdu)
|
|
302
|
+
if code == 0 and len(res_data) == 9 + r_quantity * 2:
|
|
303
|
+
return 0, struct.unpack('>{}{}'.format(r_quantity, 'h' if is_signed else 'H'), res_data[9:])
|
|
304
|
+
else:
|
|
305
|
+
return code, res_data
|
xarm/tools/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from ._blockly_tool import BlocklyTool
|