精度到0.1
parent
b4e8bcb9c9
commit
e2eaf3cbe5
|
|
@ -195,3 +195,5 @@ chmod +x start_frontend.sh
|
|||
|
||||
前端默认连接 `http://localhost:5000`,如需修改,编辑 `frontend/wrench_gui.py` 中的 `api_base_url` 变量。
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -109,3 +109,5 @@ simulator = WrenchSimulator(
|
|||
2. **端口被占用**:修改端口号或关闭占用端口的程序
|
||||
3. **无响应**:检查网络连接和防火墙设置
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,250 @@
|
|||
# SSH反向隧道配置指南
|
||||
|
||||
## 问题分析
|
||||
|
||||
错误信息 `sh: ssh -fN -R 2222:localhost:22 root@123.56.98.4: command not found` 表示:
|
||||
1. **SSH客户端未安装** - 系统找不到 `ssh` 命令
|
||||
2. 需要先安装 `openssh-client` 或 `openssh-clients`
|
||||
|
||||
## 快速解决方案
|
||||
|
||||
### 步骤1:安装SSH客户端
|
||||
|
||||
**CentOS/RHEL系统:**
|
||||
```bash
|
||||
sudo yum install -y openssh-clients openssh-server
|
||||
```
|
||||
|
||||
**Debian/Ubuntu系统:**
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y openssh-client openssh-server
|
||||
```
|
||||
|
||||
**Arch Linux:**
|
||||
```bash
|
||||
sudo pacman -S openssh
|
||||
```
|
||||
|
||||
### 步骤2:验证安装
|
||||
|
||||
```bash
|
||||
# 检查SSH是否安装成功
|
||||
ssh -V
|
||||
|
||||
# 应该显示类似:OpenSSH_8.0p1, OpenSSL 1.1.1g
|
||||
```
|
||||
|
||||
### 步骤3:建立SSH反向隧道
|
||||
|
||||
```bash
|
||||
# 基本命令
|
||||
ssh -fN -R 2222:localhost:22 root@123.56.98.4 -p 22
|
||||
|
||||
# 参数说明:
|
||||
# -f: 后台运行
|
||||
# -N: 不执行远程命令
|
||||
# -R: 反向隧道
|
||||
# 2222: 阿里云服务器上的端口
|
||||
# localhost:22: 本地SSH端口
|
||||
# root@123.56.98.4: 阿里云服务器地址
|
||||
# -p 22: SSH端口
|
||||
```
|
||||
|
||||
### 步骤4:测试连接
|
||||
|
||||
在**任何能访问阿里云服务器的机器**上:
|
||||
```bash
|
||||
# 先SSH到阿里云服务器
|
||||
ssh root@123.56.98.4
|
||||
|
||||
# 然后在阿里云服务器上连接内网服务器
|
||||
ssh -p 2222 root@localhost
|
||||
```
|
||||
|
||||
## 使用提供的脚本(推荐)
|
||||
|
||||
### 方法1:使用自动设置脚本
|
||||
|
||||
```bash
|
||||
# 1. 下载并运行设置脚本
|
||||
chmod +x ssh_tunnel_setup.sh
|
||||
./ssh_tunnel_setup.sh
|
||||
|
||||
# 脚本会自动:
|
||||
# - 检测并安装SSH客户端
|
||||
# - 配置SSH服务
|
||||
# - 生成SSH密钥
|
||||
# - 测试连接
|
||||
```
|
||||
|
||||
### 方法2:使用自动重连脚本
|
||||
|
||||
```bash
|
||||
# 1. 编辑 ssh_tunnel_auto.sh,修改配置参数
|
||||
vim ssh_tunnel_auto.sh
|
||||
|
||||
# 2. 运行自动重连脚本(前台运行)
|
||||
chmod +x ssh_tunnel_auto.sh
|
||||
./ssh_tunnel_auto.sh
|
||||
|
||||
# 或者后台运行
|
||||
nohup ./ssh_tunnel_auto.sh > /dev/null 2>&1 &
|
||||
```
|
||||
|
||||
### 方法3:配置为系统服务(开机自启)
|
||||
|
||||
```bash
|
||||
# 1. 使用root权限运行
|
||||
sudo chmod +x ssh_tunnel_service.sh
|
||||
sudo ./ssh_tunnel_service.sh
|
||||
|
||||
# 2. 服务会自动:
|
||||
# - 创建systemd服务
|
||||
# - 设置开机自启
|
||||
# - 自动重连
|
||||
```
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
### 1. SSH命令找不到
|
||||
|
||||
**问题:** `command not found: ssh`
|
||||
|
||||
**解决:**
|
||||
```bash
|
||||
# 检查是否安装
|
||||
which ssh
|
||||
|
||||
# 如果为空,安装SSH客户端
|
||||
# CentOS/RHEL:
|
||||
sudo yum install openssh-clients
|
||||
|
||||
# Ubuntu/Debian:
|
||||
sudo apt-get install openssh-client
|
||||
```
|
||||
|
||||
### 2. 连接被拒绝
|
||||
|
||||
**问题:** `Connection refused`
|
||||
|
||||
**可能原因:**
|
||||
- 阿里云服务器防火墙未开放22端口
|
||||
- SSH服务未启动
|
||||
- 用户名或密码错误
|
||||
|
||||
**解决:**
|
||||
```bash
|
||||
# 检查SSH服务状态
|
||||
sudo systemctl status sshd
|
||||
|
||||
# 启动SSH服务
|
||||
sudo systemctl start sshd
|
||||
sudo systemctl enable sshd
|
||||
|
||||
# 检查防火墙
|
||||
sudo firewall-cmd --list-ports # CentOS
|
||||
sudo ufw status # Ubuntu
|
||||
```
|
||||
|
||||
### 3. 隧道建立后无法连接
|
||||
|
||||
**问题:** 在阿里云服务器上 `ssh -p 2222 root@localhost` 失败
|
||||
|
||||
**检查:**
|
||||
```bash
|
||||
# 1. 检查隧道是否建立
|
||||
ps aux | grep ssh | grep 2222
|
||||
|
||||
# 2. 检查端口是否监听(在阿里云服务器上)
|
||||
netstat -tlnp | grep 2222
|
||||
# 或
|
||||
ss -tlnp | grep 2222
|
||||
|
||||
# 3. 检查阿里云服务器SSH配置
|
||||
sudo vim /etc/ssh/sshd_config
|
||||
# 确保有:GatewayPorts yes
|
||||
sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
### 4. 连接频繁断开
|
||||
|
||||
**解决:** 使用自动重连脚本,或添加保活参数:
|
||||
```bash
|
||||
ssh -fN -R 2222:localhost:22 \
|
||||
-o ServerAliveInterval=30 \
|
||||
-o ServerAliveCountMax=3 \
|
||||
root@123.56.98.4 -p 22
|
||||
```
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **使用SSH密钥认证**(推荐)
|
||||
```bash
|
||||
# 生成密钥对
|
||||
ssh-keygen -t rsa -b 2048
|
||||
|
||||
# 复制公钥到阿里云服务器
|
||||
ssh-copy-id root@123.56.98.4
|
||||
```
|
||||
|
||||
2. **修改SSH端口**(可选)
|
||||
```bash
|
||||
# 编辑 /etc/ssh/sshd_config
|
||||
sudo vim /etc/ssh/sshd_config
|
||||
# 修改:Port 2222
|
||||
|
||||
# 重启服务
|
||||
sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
3. **禁用密码登录**(使用密钥后)
|
||||
```bash
|
||||
# 编辑 /etc/ssh/sshd_config
|
||||
PasswordAuthentication no
|
||||
|
||||
# 重启服务
|
||||
sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
## 验证连接
|
||||
|
||||
### 在阿里云服务器上验证
|
||||
|
||||
```bash
|
||||
# 1. 检查端口监听
|
||||
ss -tlnp | grep 2222
|
||||
|
||||
# 2. 测试连接
|
||||
ssh -p 2222 root@localhost
|
||||
|
||||
# 3. 查看隧道进程
|
||||
ps aux | grep "ssh.*-R.*2222"
|
||||
```
|
||||
|
||||
### 从外部访问
|
||||
|
||||
```bash
|
||||
# 1. SSH到阿里云服务器
|
||||
ssh root@123.56.98.4
|
||||
|
||||
# 2. 通过隧道连接内网服务器
|
||||
ssh -p 2222 root@localhost
|
||||
```
|
||||
|
||||
## 文件说明
|
||||
|
||||
- `ssh_tunnel_setup.sh` - 自动设置脚本(安装SSH、配置密钥等)
|
||||
- `ssh_tunnel_auto.sh` - 自动重连脚本(监控并自动重连)
|
||||
- `ssh_tunnel_service.sh` - 创建systemd服务(开机自启)
|
||||
- `SSH_TUNNEL_README.md` - 本文档
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 运行 `ssh_tunnel_setup.sh` 完成初始设置
|
||||
2. 运行 `ssh_tunnel_auto.sh` 建立隧道
|
||||
3. 或运行 `ssh_tunnel_service.sh` 配置为系统服务
|
||||
|
||||
如有问题,请检查日志或联系技术支持。
|
||||
|
||||
|
||||
|
|
@ -75,3 +75,5 @@ conn.close()
|
|||
|
||||
print("\n" + "="*60)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,3 +26,5 @@ else:
|
|||
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,3 +66,5 @@ print("\n" + "="*60)
|
|||
print("诊断完成")
|
||||
print("="*60)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -111,3 +111,5 @@ def migrate_add_device_info():
|
|||
if __name__ == "__main__":
|
||||
migrate_add_device_info()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -53,3 +53,5 @@ print("2. 后端服务器日志中的调试信息")
|
|||
print("3. 重启后端服务器")
|
||||
print("="*60)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
Flask==2.3.3
|
||||
flask-cors==4.0.0
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,3 +8,5 @@ cd /d %~dp0
|
|||
python app.py
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,3 +6,5 @@ echo ""
|
|||
cd "$(dirname "$0")"
|
||||
python3 app.py
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,3 +40,5 @@ def test_query():
|
|||
if __name__ == "__main__":
|
||||
test_query()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,2 +1,4 @@
|
|||
requests==2.31.0
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,3 +8,5 @@ cd /d %~dp0
|
|||
python wrench_gui.py
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,3 +6,5 @@ echo ""
|
|||
cd "$(dirname "$0")"
|
||||
python3 wrench_gui.py
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
#!/bin/bash
|
||||
# SSH反向隧道自动重连脚本
|
||||
|
||||
# 配置参数
|
||||
REMOTE_HOST="123.56.98.4"
|
||||
REMOTE_USER="root"
|
||||
REMOTE_PORT=22
|
||||
TUNNEL_PORT=2222
|
||||
LOCAL_PORT=22
|
||||
CHECK_INTERVAL=60 # 检查间隔(秒)
|
||||
|
||||
echo "=== SSH反向隧道自动重连脚本 ==="
|
||||
echo "远程服务器: ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PORT}"
|
||||
echo "隧道端口: ${TUNNEL_PORT} -> localhost:${LOCAL_PORT}"
|
||||
echo "检查间隔: ${CHECK_INTERVAL}秒"
|
||||
echo ""
|
||||
|
||||
# 检查SSH是否安装
|
||||
if ! command -v ssh &> /dev/null; then
|
||||
echo "错误: SSH客户端未安装,请先运行 ssh_tunnel_setup.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 函数:建立SSH隧道
|
||||
establish_tunnel() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 建立SSH反向隧道..."
|
||||
|
||||
# 先检查是否已有连接
|
||||
PID=$(pgrep -f "ssh.*-R.*${TUNNEL_PORT}:localhost:${LOCAL_PORT}.*${REMOTE_USER}@${REMOTE_HOST}")
|
||||
if [ ! -z "$PID" ]; then
|
||||
echo "发现已有隧道进程 (PID: $PID),先关闭..."
|
||||
kill $PID 2>/dev/null
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# 建立新连接
|
||||
ssh -fN -R ${TUNNEL_PORT}:localhost:${LOCAL_PORT} \
|
||||
-o ServerAliveInterval=30 \
|
||||
-o ServerAliveCountMax=3 \
|
||||
-o ExitOnForwardFailure=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-p ${REMOTE_PORT} \
|
||||
${REMOTE_USER}@${REMOTE_HOST}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✓ 隧道建立成功"
|
||||
return 0
|
||||
else
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✗ 隧道建立失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:检查隧道是否存活
|
||||
check_tunnel() {
|
||||
PID=$(pgrep -f "ssh.*-R.*${TUNNEL_PORT}:localhost:${LOCAL_PORT}.*${REMOTE_USER}@${REMOTE_HOST}")
|
||||
if [ ! -z "$PID" ]; then
|
||||
# 检查进程是否真的在运行
|
||||
if ps -p $PID > /dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# 主循环
|
||||
echo "开始监控SSH隧道..."
|
||||
establish_tunnel
|
||||
|
||||
while true; do
|
||||
sleep ${CHECK_INTERVAL}
|
||||
|
||||
if ! check_tunnel; then
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ⚠ 检测到隧道断开,重新连接..."
|
||||
establish_tunnel
|
||||
else
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✓ 隧道连接正常"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#!/bin/bash
|
||||
# 创建systemd服务文件,用于开机自启
|
||||
|
||||
REMOTE_HOST="123.56.98.4"
|
||||
REMOTE_USER="root"
|
||||
TUNNEL_PORT=2222
|
||||
|
||||
# 获取脚本所在目录
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
AUTO_SCRIPT="${SCRIPT_DIR}/ssh_tunnel_auto.sh"
|
||||
|
||||
echo "=== 创建SSH隧道systemd服务 ==="
|
||||
|
||||
# 检查是否以root运行
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "请使用sudo运行此脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建服务文件
|
||||
SERVICE_FILE="/etc/systemd/system/ssh-tunnel.service"
|
||||
|
||||
cat > ${SERVICE_FILE} << EOF
|
||||
[Unit]
|
||||
Description=SSH Reverse Tunnel to ${REMOTE_HOST}
|
||||
After=network.target ssh.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=/bin/bash ${AUTO_SCRIPT}
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
echo "✓ 服务文件已创建: ${SERVICE_FILE}"
|
||||
|
||||
# 重新加载systemd
|
||||
systemctl daemon-reload
|
||||
|
||||
echo "✓ systemd配置已重新加载"
|
||||
|
||||
# 启用服务
|
||||
systemctl enable ssh-tunnel.service
|
||||
|
||||
echo "✓ 服务已设置为开机自启"
|
||||
|
||||
# 启动服务
|
||||
read -p "是否立即启动服务?(y/n): " start_now
|
||||
if [ "$start_now" = "y" ] || [ "$start_now" = "Y" ]; then
|
||||
systemctl start ssh-tunnel.service
|
||||
echo "✓ 服务已启动"
|
||||
echo ""
|
||||
echo "查看服务状态: systemctl status ssh-tunnel"
|
||||
echo "查看服务日志: journalctl -u ssh-tunnel -f"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 服务配置完成 ==="
|
||||
echo ""
|
||||
echo "常用命令:"
|
||||
echo " 启动服务: sudo systemctl start ssh-tunnel"
|
||||
echo " 停止服务: sudo systemctl stop ssh-tunnel"
|
||||
echo " 查看状态: sudo systemctl status ssh-tunnel"
|
||||
echo " 查看日志: sudo journalctl -u ssh-tunnel -f"
|
||||
echo " 禁用自启: sudo systemctl disable ssh-tunnel"
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash
|
||||
# SSH反向隧道设置脚本
|
||||
|
||||
echo "=== SSH反向隧道设置脚本 ==="
|
||||
|
||||
# 1. 检查SSH客户端是否安装
|
||||
echo "1. 检查SSH客户端..."
|
||||
if command -v ssh &> /dev/null; then
|
||||
echo "✓ SSH客户端已安装: $(which ssh)"
|
||||
ssh -V
|
||||
else
|
||||
echo "✗ SSH客户端未安装,开始安装..."
|
||||
|
||||
# 检测Linux发行版
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
# CentOS/RHEL
|
||||
echo "检测到 CentOS/RHEL 系统"
|
||||
sudo yum install -y openssh-clients openssh-server
|
||||
elif [ -f /etc/debian_version ]; then
|
||||
# Debian/Ubuntu
|
||||
echo "检测到 Debian/Ubuntu 系统"
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y openssh-client openssh-server
|
||||
elif [ -f /etc/arch-release ]; then
|
||||
# Arch Linux
|
||||
echo "检测到 Arch Linux 系统"
|
||||
sudo pacman -S --noconfirm openssh
|
||||
else
|
||||
echo "无法自动检测系统类型,请手动安装 openssh-client"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 验证安装
|
||||
if command -v ssh &> /dev/null; then
|
||||
echo "✓ SSH客户端安装成功"
|
||||
ssh -V
|
||||
else
|
||||
echo "✗ SSH客户端安装失败,请手动安装"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "2. 检查SSH服务是否运行..."
|
||||
if systemctl is-active --quiet sshd || systemctl is-active --quiet ssh; then
|
||||
echo "✓ SSH服务正在运行"
|
||||
else
|
||||
echo "⚠ SSH服务未运行,启动SSH服务..."
|
||||
sudo systemctl start sshd 2>/dev/null || sudo systemctl start ssh
|
||||
sudo systemctl enable sshd 2>/dev/null || sudo systemctl enable ssh
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "3. 生成SSH密钥(如果不存在)..."
|
||||
if [ ! -f ~/.ssh/id_rsa ]; then
|
||||
echo "生成SSH密钥..."
|
||||
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""
|
||||
echo "✓ SSH密钥已生成"
|
||||
else
|
||||
echo "✓ SSH密钥已存在"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "4. 配置SSH密钥免密登录(可选)..."
|
||||
read -p "是否配置免密登录到阿里云服务器?(y/n): " setup_key
|
||||
if [ "$setup_key" = "y" ] || [ "$setup_key" = "Y" ]; then
|
||||
read -p "请输入阿里云服务器IP: " server_ip
|
||||
read -p "请输入阿里云服务器用户名(默认root): " server_user
|
||||
server_user=${server_user:-root}
|
||||
|
||||
echo "复制SSH公钥到阿里云服务器..."
|
||||
ssh-copy-id -p 22 ${server_user}@${server_ip}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ 免密登录配置成功"
|
||||
else
|
||||
echo "⚠ 免密登录配置失败,请手动配置或使用密码登录"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "5. 测试SSH连接..."
|
||||
read -p "请输入阿里云服务器IP(用于测试连接): " test_ip
|
||||
read -p "请输入用户名(默认root): " test_user
|
||||
test_user=${test_user:-root}
|
||||
|
||||
echo "测试连接到 ${test_user}@${test_ip}..."
|
||||
ssh -o ConnectTimeout=5 -p 22 ${test_user}@${test_ip} "echo '连接成功!'"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ SSH连接测试成功"
|
||||
else
|
||||
echo "✗ SSH连接测试失败,请检查:"
|
||||
echo " - 网络连接是否正常"
|
||||
echo " - 阿里云服务器防火墙是否开放22端口"
|
||||
echo " - 用户名和密码是否正确"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 设置完成 ==="
|
||||
echo ""
|
||||
echo "使用方法:"
|
||||
echo " 手动连接: ssh -fN -R 2222:localhost:22 root@123.56.98.4 -p 22"
|
||||
echo ""
|
||||
echo " 或者使用自动重连脚本(见下方)"
|
||||
|
||||
|
||||
|
|
@ -7,3 +7,5 @@ echo.
|
|||
python wrench_simulator.py
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,5 @@ echo "========================================"
|
|||
echo ""
|
||||
python3 wrench_simulator.py
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,3 +79,5 @@ if __name__ == "__main__":
|
|||
print("4. 设备地址码不匹配")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -70,3 +70,5 @@ def test_simulator():
|
|||
if __name__ == "__main__":
|
||||
test_simulator()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ class WrenchController:
|
|||
return self._send_command(bytes(data))
|
||||
|
||||
def set_torque_parameters(self,
|
||||
target_torque: int,
|
||||
target_torque: float,
|
||||
mode: int = 1,
|
||||
torque_tolerance: float = 0.10,
|
||||
target_angle: int = 0,
|
||||
|
|
@ -329,7 +329,7 @@ class WrenchController:
|
|||
controller_sn: str = None) -> bytes:
|
||||
"""
|
||||
设定扭矩参数(功能码0x10)
|
||||
:param target_torque: 目标扭矩(Nm)
|
||||
:param target_torque: 目标扭矩(Nm,支持一位小数,协议中按Nm×10编码为整数)
|
||||
:param mode: 模式 1=M1模式(扭矩模式), 2=M2模式(角度模式)
|
||||
:param torque_tolerance: 扭矩偏差百分比(仅M1模式),如0.10表示±10%
|
||||
:param target_angle: 目标角度(度),M1模式填0
|
||||
|
|
@ -353,13 +353,18 @@ class WrenchController:
|
|||
# 获取当前时间
|
||||
now = datetime.now()
|
||||
|
||||
# 计算扭矩上下限
|
||||
# 计算扭矩上下限(以物理量 Nm 计算,可带一位小数)
|
||||
if mode == 1: # M1模式
|
||||
torque_min = int(target_torque * (1 - torque_tolerance))
|
||||
torque_max = int(target_torque * (1 + torque_tolerance))
|
||||
torque_min_nm = target_torque * (1 - torque_tolerance)
|
||||
torque_max_nm = target_torque * (1 + torque_tolerance)
|
||||
else: # M2模式
|
||||
torque_min = int(target_torque * 0.8) # 默认下限
|
||||
torque_max = int(target_torque * 1.2) # 默认上限
|
||||
torque_min_nm = target_torque * 0.8 # 默认下限
|
||||
torque_max_nm = target_torque * 1.2 # 默认上限
|
||||
|
||||
# 协议中扭矩以 0.1Nm 精度编码:协议值 = Nm × 10
|
||||
target_torque_val = int(round(target_torque * 10))
|
||||
torque_min_val = int(round(torque_min_nm * 10))
|
||||
torque_max_val = int(round(torque_max_nm * 10))
|
||||
|
||||
# 角度需要乘10
|
||||
angle_value = target_angle * 10
|
||||
|
|
@ -401,14 +406,14 @@ class WrenchController:
|
|||
# 参数模式
|
||||
data.append(mode)
|
||||
|
||||
# 目标扭矩 (2字节)
|
||||
data.extend(struct.pack('>H', target_torque))
|
||||
# 目标扭矩 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', target_torque_val))
|
||||
|
||||
# 扭矩下限 (2字节)
|
||||
data.extend(struct.pack('>H', torque_min))
|
||||
# 扭矩下限 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', torque_min_val))
|
||||
|
||||
# 扭矩上限 (2字节)
|
||||
data.extend(struct.pack('>H', torque_max))
|
||||
# 扭矩上限 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', torque_max_val))
|
||||
|
||||
# 目标角度 (2字节)
|
||||
data.extend(struct.pack('>H', angle_value))
|
||||
|
|
@ -427,8 +432,8 @@ class WrenchController:
|
|||
mode_str = "M1(扭矩模式)" if mode == 1 else "M2(角度模式)"
|
||||
print(f"\n设定扭矩参数:")
|
||||
print(f" 模式: {mode_str}")
|
||||
print(f" 目标扭矩: {target_torque} Nm")
|
||||
print(f" 扭矩范围: {torque_min}-{torque_max} Nm")
|
||||
print(f" 目标扭矩: {target_torque:.1f} Nm")
|
||||
print(f" 扭矩范围: {torque_min_nm:.1f}-{torque_max_nm:.1f} Nm")
|
||||
print(f" 目标角度: {target_angle}°")
|
||||
print(f" 角度范围: {angle_min}-{angle_max}°")
|
||||
print(f" 报文: {data.hex(' ').upper()}")
|
||||
|
|
@ -512,12 +517,17 @@ class WrenchController:
|
|||
|
||||
mode = "M1(扭矩模式)" if response[26] == 0x01 else "M2(角度模式)"
|
||||
|
||||
target_torque = struct.unpack('>H', response[27:29])[0]
|
||||
actual_torque = struct.unpack('>H', response[29:31])[0]
|
||||
# 扭矩以 0.1Nm 精度编码,需要还原为物理量
|
||||
target_torque_raw = struct.unpack('>H', response[27:29])[0]
|
||||
actual_torque_raw = struct.unpack('>H', response[29:31])[0]
|
||||
target_torque = target_torque_raw / 10.0
|
||||
actual_torque = actual_torque_raw / 10.0
|
||||
target_angle = struct.unpack('>H', response[31:33])[0] / 10
|
||||
actual_angle = struct.unpack('>H', response[33:35])[0] / 10
|
||||
torque_max = struct.unpack('>H', response[35:37])[0]
|
||||
torque_min = struct.unpack('>H', response[37:39])[0]
|
||||
torque_max_raw = struct.unpack('>H', response[35:37])[0]
|
||||
torque_min_raw = struct.unpack('>H', response[37:39])[0]
|
||||
torque_max = torque_max_raw / 10.0
|
||||
torque_min = torque_min_raw / 10.0
|
||||
angle_max = struct.unpack('>H', response[39:41])[0] / 10
|
||||
angle_min = struct.unpack('>H', response[41:43])[0] / 10
|
||||
|
||||
|
|
@ -533,7 +543,7 @@ class WrenchController:
|
|||
"actual_torque": actual_torque,
|
||||
"target_angle": target_angle,
|
||||
"actual_angle": actual_angle,
|
||||
"torque_range": f"{torque_min}-{torque_max} Nm",
|
||||
"torque_range": f"{torque_min:.1f}-{torque_max:.1f} Nm",
|
||||
"angle_range": f"{angle_min}-{angle_max}°"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,9 +106,15 @@ class WrenchSimulator:
|
|||
second = data[73]
|
||||
|
||||
mode = data[74]
|
||||
target_torque = struct.unpack('>H', data[75:77])[0]
|
||||
torque_min = struct.unpack('>H', data[77:79])[0]
|
||||
torque_max = struct.unpack('>H', data[79:81])[0]
|
||||
|
||||
# 扭矩以 0.1Nm 精度编码,协议值 = Nm×10
|
||||
target_torque_raw = struct.unpack('>H', data[75:77])[0]
|
||||
torque_min_raw = struct.unpack('>H', data[77:79])[0]
|
||||
torque_max_raw = struct.unpack('>H', data[79:81])[0]
|
||||
target_torque = target_torque_raw / 10.0
|
||||
torque_min = torque_min_raw / 10.0
|
||||
torque_max = torque_max_raw / 10.0
|
||||
|
||||
target_angle = struct.unpack('>H', data[81:83])[0] / 10
|
||||
angle_max = struct.unpack('>H', data[83:85])[0] / 10
|
||||
angle_min = struct.unpack('>H', data[85:87])[0] / 10
|
||||
|
|
@ -121,7 +127,7 @@ class WrenchSimulator:
|
|||
"controller_sn": controller_sn,
|
||||
"timestamp": f"{year}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}",
|
||||
"mode": mode,
|
||||
"target_torque": target_torque,
|
||||
"target_torque": target_torque, # Nm,支持一位小数
|
||||
"torque_min": torque_min,
|
||||
"torque_max": torque_max,
|
||||
"target_angle": target_angle,
|
||||
|
|
@ -138,8 +144,8 @@ class WrenchSimulator:
|
|||
print(f" 控制器SN: {controller_sn}")
|
||||
print(f" 时间: {params['timestamp']}")
|
||||
print(f" 模式: {'M1(扭矩模式)' if mode == 1 else 'M2(角度模式)'}")
|
||||
print(f" 目标扭矩: {target_torque} Nm")
|
||||
print(f" 扭矩范围: {torque_min}-{torque_max} Nm")
|
||||
print(f" 目标扭矩: {target_torque:.1f} Nm")
|
||||
print(f" 扭矩范围: {torque_min:.1f}-{torque_max:.1f} Nm")
|
||||
print(f" 目标角度: {target_angle}°")
|
||||
print(f" 角度范围: {angle_min}-{angle_max}°")
|
||||
|
||||
|
|
@ -174,19 +180,34 @@ class WrenchSimulator:
|
|||
if params is None:
|
||||
params = self.current_parameters
|
||||
|
||||
# 使用当前参数或默认值
|
||||
# 使用当前参数或默认值(以物理量计算)
|
||||
employee_id = params.get("employee_id", "2222222222")
|
||||
mode = params.get("mode", 1)
|
||||
target_torque = params.get("target_torque", 300)
|
||||
torque_min = params.get("torque_min", 270)
|
||||
torque_max = params.get("torque_max", 330)
|
||||
target_angle = int(params.get("target_angle", 0) * 10)
|
||||
angle_min = int(params.get("angle_min", 1) * 10)
|
||||
angle_max = int(params.get("angle_max", 360) * 10)
|
||||
|
||||
|
||||
# 扭矩以 Nm 表示,支持一位小数
|
||||
target_torque_nm = float(params.get("target_torque", 300.0))
|
||||
torque_min_nm = float(params.get("torque_min", 270.0))
|
||||
torque_max_nm = float(params.get("torque_max", 330.0))
|
||||
|
||||
# 角度以度表示,协议中仍按×10存整数
|
||||
target_angle_deg = float(params.get("target_angle", 0.0))
|
||||
angle_min_deg = float(params.get("angle_min", 1.0))
|
||||
angle_max_deg = float(params.get("angle_max", 360.0))
|
||||
|
||||
# 模拟实际值(略高于目标值,表示成功)
|
||||
actual_torque = target_torque + 5 # 实际扭矩略高于目标
|
||||
actual_angle = int(params.get("target_angle", 45) * 10) if mode == 2 else 0
|
||||
actual_torque_nm = target_torque_nm + 0.5 # 实际扭矩略高于目标
|
||||
actual_angle_deg = float(params.get("target_angle", 45.0)) if mode == 2 else 0.0
|
||||
|
||||
# 协议编码:扭矩 Nm×10,角度 deg×10
|
||||
target_torque_val = int(round(target_torque_nm * 10))
|
||||
torque_min_val = int(round(torque_min_nm * 10))
|
||||
torque_max_val = int(round(torque_max_nm * 10))
|
||||
actual_torque_val = int(round(actual_torque_nm * 10))
|
||||
|
||||
target_angle_val = int(round(target_angle_deg * 10))
|
||||
angle_min_val = int(round(angle_min_deg * 10))
|
||||
angle_max_val = int(round(angle_max_deg * 10))
|
||||
actual_angle_val = int(round(actual_angle_deg * 10))
|
||||
|
||||
# 获取当前时间
|
||||
now = datetime.now()
|
||||
|
|
@ -219,29 +240,29 @@ class WrenchSimulator:
|
|||
# 参数模式 (1字节)
|
||||
data.append(mode)
|
||||
|
||||
# 目标扭矩 (2字节)
|
||||
data.extend(struct.pack('>H', target_torque))
|
||||
# 目标扭矩 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', target_torque_val))
|
||||
|
||||
# 实际扭矩 (2字节)
|
||||
data.extend(struct.pack('>H', actual_torque))
|
||||
# 实际扭矩 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', actual_torque_val))
|
||||
|
||||
# 目标角度 (2字节)
|
||||
data.extend(struct.pack('>H', target_angle))
|
||||
# 目标角度 (2字节,deg×10)
|
||||
data.extend(struct.pack('>H', target_angle_val))
|
||||
|
||||
# 实际角度 (2字节)
|
||||
data.extend(struct.pack('>H', actual_angle))
|
||||
# 实际角度 (2字节,deg×10)
|
||||
data.extend(struct.pack('>H', actual_angle_val))
|
||||
|
||||
# 扭矩上限 (2字节)
|
||||
data.extend(struct.pack('>H', torque_max))
|
||||
# 扭矩上限 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', torque_max_val))
|
||||
|
||||
# 扭矩下限 (2字节)
|
||||
data.extend(struct.pack('>H', torque_min))
|
||||
# 扭矩下限 (2字节,Nm×10)
|
||||
data.extend(struct.pack('>H', torque_min_val))
|
||||
|
||||
# 角度上限 (2字节)
|
||||
data.extend(struct.pack('>H', angle_max))
|
||||
# 角度上限 (2字节,deg×10)
|
||||
data.extend(struct.pack('>H', angle_max_val))
|
||||
|
||||
# 角度下限 (2字节)
|
||||
data.extend(struct.pack('>H', angle_min))
|
||||
# 角度下限 (2字节,deg×10)
|
||||
data.extend(struct.pack('>H', angle_min_val))
|
||||
|
||||
# 计算并添加校验码
|
||||
checksum = self._calculate_checksum(data)
|
||||
|
|
|
|||
Loading…
Reference in New Issue