-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwb-mio-change-speed.sh
286 lines (237 loc) · 7.82 KB
/
wb-mio-change-speed.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#!/bin/bash
#
# Script for interactive configuration of WB-MIO (or similar Modbus devices) via TCP and Modbus RTU.
# It performs the following steps:
# 1) Stops the wb-mqtt-serial service.
# 2) Launches socat to create a virtual serial port (PTY).
# 3) Checks the current Modbus address and speed registers.
# 4) Offers an interactive prompt to change the speed, validating user input.
# 5) Writes the new speed value and (optionally) reboots the device.
# 6) Stops socat and restarts wb-mqtt-serial.
#
# Requirements:
# - Utilities: modbus_client, socat
# - Sufficient privileges (root or sudo)
#
# Example usage:
# chmod +x wb-mio-change-speed.sh
# ./wb-mio-change-speed.sh
######################################
# PARAMETERS
######################################
# Parameters of WM-MIO-E device for socat
IP_ADDRESS="10.10.100.7"
TCP_PORT="20108"
CURRENT_ADDR=139 # Current Modbus address of WB-MIO-E device
# Current device settings for connecting to WB-MIO
CURRENT_BAUD=9600 # Current speed (e.g., 9600 or 115200)
CURRENT_PARITY="none" # Parity: none / odd / even
CURRENT_STOPBITS=1 # Number of stop bits: 1 or 2
# Virtual serial port (PTY) that socat will create
DEV_PORT="/dev/ttyRS485-6"
######################################
# WB-MIO Modbus registers
REG_SPEED=110 # Register for speed (baud / 100)
REG_ADDR=128 # Register for the device address
REG_REBOOT=120 # Register for rebooting the device
# An associative array mapping human-readable speeds to codes (baud / 100)
declare -A SPEED_MAP=(
[1200]=12
[2400]=24
[4800]=48
[9600]=96
[19200]=192
[38400]=384
[57600]=576
[115200]=1152
)
######################################
# SERVICE CONTROL FUNCTIONS
######################################
stop_wb_mqtt_serial() {
echo "[INFO] Stopping the wb-mqtt-serial service..."
systemctl stop wb-mqtt-serial
# Status check
if systemctl is-active wb-mqtt-serial --quiet; then
echo "[WARNING] The wb-mqtt-serial service is still active!"
else
echo "[INFO] The wb-mqtt-serial service has been stopped."
fi
}
start_wb_mqtt_serial() {
echo "[INFO] Starting the wb-mqtt-serial service..."
systemctl start wb-mqtt-serial
if systemctl is-active wb-mqtt-serial --quiet; then
echo "[INFO] The wb-mqtt-serial service started successfully."
else
echo "[ERROR] Failed to start the wb-mqtt-serial service!"
fi
}
start_socat() {
echo "[INFO] Launching socat: TCP=$IP_ADDRESS:$TCP_PORT -> $DEV_PORT"
# Start socat with parameters derived from variables
socat -d -d -d -x \
PTY,raw,b${CURRENT_BAUD},parenb=0,cstopb=${CURRENT_STOPBITS},cs8,link="${DEV_PORT}" \
tcp:"${IP_ADDRESS}":"${TCP_PORT}" &
SOCAT_PID=$!
# Give socat time to create the PTY
sleep 2
# Check if the socat process is still running
if ! kill -0 "$SOCAT_PID" 2>/dev/null; then
echo "[ERROR] Socat failed to start or exited immediately!"
return 1
fi
echo "[INFO] Socat started (PID $SOCAT_PID)."
return 0
}
stop_socat() {
echo "[INFO] Stopping socat (PID=$SOCAT_PID)..."
kill "$SOCAT_PID" 2>/dev/null
wait "$SOCAT_PID" 2>/dev/null
echo "[INFO] Socat has been stopped."
}
######################################
# MODBUS REGISTER FUNCTIONS
######################################
read_register() {
local reg=$1
local value
value=$(modbus_client \
-m rtu \
-b "$CURRENT_BAUD" \
-p "$CURRENT_PARITY" \
-s "$CURRENT_STOPBITS" \
"$DEV_PORT" \
-a "$CURRENT_ADDR" \
-t 0x03 \
-r "$reg" 2>/dev/null | \
awk -F'Data:' '/Data:/ {print $2}')
echo "$value"
}
write_register() {
local reg=$1
local val=$2
modbus_client \
-m rtu \
-b "$CURRENT_BAUD" \
-p "$CURRENT_PARITY" \
-s "$CURRENT_STOPBITS" \
"$DEV_PORT" \
-a "$CURRENT_ADDR" \
-t 0x06 \
-r "$reg" "$val"
}
check_device_addr() {
local val_dec
val_dec=$(read_register "$REG_ADDR")
if [[ -z "$val_dec" ]]; then
echo "[ERROR] Failed to read register $REG_ADDR (device address)."
return 1
fi
# Convert to decimal if necessary
val_dec=$(printf "%d\n" "$val_dec")
echo "[INFO] Current device address (from reg.128): $val_dec"
if [[ "$val_dec" -eq "$CURRENT_ADDR" ]]; then
return 0
else
echo "[WARNING] The address in register 128 ($val_dec) does NOT match the expected ($CURRENT_ADDR)!"
return 2
fi
}
get_device_speed() {
local val_dec
val_dec=$(read_register "$REG_SPEED")
if [[ -z "$val_dec" ]]; then
echo "[ERROR] Failed to read the speed register ($REG_SPEED)."
return 1
fi
# The device stores speed as (baud / 100)
val_dec=$(printf "%d\n" "$val_dec")
local baud=$((val_dec * 100))
echo "$baud"
return 0
}
set_device_speed() {
local new_baud_code=$1
echo "[INFO] Setting the new speed (code $new_baud_code) to register $REG_SPEED..."
write_register "$REG_SPEED" "$new_baud_code"
}
reboot_device() {
echo "[INFO] Sending reboot command to register $REG_REBOOT..."
write_register "$REG_REBOOT" "1"
}
######################################
# MAIN SCRIPT LOGIC
######################################
# 1. Stop wb-mqtt-serial
stop_wb_mqtt_serial
echo "==========================================================="
# 2. Start socat
if ! start_socat ; then
echo "[ERROR] Failed to start socat. Exiting."
echo "==========================================================="
start_wb_mqtt_serial
exit 1
fi
echo "==========================================================="
# 3. Check the Modbus address
if ! check_device_addr ; then
echo "[ERROR] The device address does not match or cannot be read. Exiting."
echo "==========================================================="
stop_socat
start_wb_mqtt_serial
exit 1
fi
echo "[INFO] The WB-MIO address is confirmed."
echo "==========================================================="
# 4. Read the current speed
CURRENT_DEVICE_SPEED=$(get_device_speed)
if [[ -z "$CURRENT_DEVICE_SPEED" ]]; then
echo "[ERROR] Failed to read the current speed. Exiting."
echo "==========================================================="
stop_socat
start_wb_mqtt_serial
exit 1
fi
echo "[INFO] The current device speed is: $CURRENT_DEVICE_SPEED baud."
echo "==========================================================="
# 5. Ask if we want to change the speed
read -r -p "Do you want to change the speed? [y/N] " ans
ans="${ans,,}" # Convert to lowercase
if [[ "$ans" =~ ^(y|yes)$ ]]; then
echo "[INFO] Available speeds: ${!SPEED_MAP[@]}"
read -r -p "Enter the desired speed (from the list above): " NEW_SPEED_INPUT
# Validate the chosen speed
if [[ -z "${SPEED_MAP[$NEW_SPEED_INPUT]}" ]]; then
echo "[ERROR] Invalid speed: $NEW_SPEED_INPUT"
echo "==========================================================="
stop_socat
start_wb_mqtt_serial
exit 2
fi
NEW_SPEED_CODE=${SPEED_MAP[$NEW_SPEED_INPUT]}
echo "[INFO] Selected speed: $NEW_SPEED_INPUT baud (code $NEW_SPEED_CODE)."
# Apply the new speed
set_device_speed "$NEW_SPEED_CODE"
# Ask about reboot
read -r -p "Reboot the device (to apply settings)? [y/N] " reboot_ans
reboot_ans="${reboot_ans,,}"
if [[ "$reboot_ans" =~ ^(y|yes)$ ]]; then
reboot_device
echo "[INFO] Reboot command sent. The device will restart and switch to the new speed."
else
echo "[INFO] Reboot not performed. The device may have already applied the new speed."
fi
echo "[INFO] After changing the speed, the old settings may no longer work."
echo "[INFO] To continue at the new speed, restart the script with the updated CURRENT_BAUD."
else
echo "[INFO] Keeping the current device speed: $CURRENT_DEVICE_SPEED baud."
fi
echo "==========================================================="
echo "[INFO] Finishing up: stopping socat and restarting wb-mqtt-serial..."
# 6. Stop socat
stop_socat
# 7. Restart wb-mqtt-serial
start_wb_mqtt_serial
echo "[INFO] Script execution completed."
exit 0