Python Demo: Retrieve OP-BT/BTS Battery Voltage

1. Environment

  • Install Python Compiler
  • Install serial port communication library(e.g. PySerial)
pip install pyserial

2. How to run

  • Run with default (COM3 at 9600bps):
python opbt_battery_voltage.py
  • Run with specific port and speed:
python opbt_battery_voltage.py --port COM4 --baud 57600

– 程序将可能返回以下内容

Using COM port: COM25, Baud rate: 9600
Entering command mode...
Response: {"OK":true}
Querying battery voltage...
Response: {"BatteryVoltage":4020}

Battery voltage: 4020 mV (4.02 V)
Exiting command mode...
Response: {"OK":false}

3. Understand the code

Features

  • Connect OP-BT/BTS by using serial port
  • Send command to enter command mode
  • Query battery voltage
  • Parse and display voltage
  • Exit command mode
  • Shutdown serial port connection

Steps

  • Using serial port for communication
  • Send command in JSON to enter command mode: {“AtCommandMode”:true}
  • Send command to query device information: {“BatteryVoltage”:"?"}
  • Parse and data in JSON to retrieve battery voltage
  • Send {“AtCommandMode”:false} to exit command mode

4. Code

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# opbt_battery_voltage.py

import serial
import time
import json
import re
import sys
import argparse

DEFAULT_COM = "COM3"  # Default COM port, can be modified as needed
DEFAULT_BAUDRATE = 9600  # Default baud rate, can be modified as needed
BUFFER_SIZE = 1024

def send_command(ser, command):
    """Send command and receive response"""
    # Clear buffers
    ser.reset_input_buffer()
    ser.reset_output_buffer()
    
    # Send command
    ser.write(command.encode())
    
    # Wait for device response
    time.sleep(0.5)  # Wait 500ms, can be adjusted based on device response time
    
    # Read response
    response = ser.read(BUFFER_SIZE).decode('utf-8', errors='ignore')
    return response

def parse_battery_voltage(json_response):
    """Parse battery voltage from JSON response"""
    try:
        # Try to parse as JSON
        data = json.loads(json_response)
        if "BatteryVoltage" in data:
            return data["BatteryVoltage"]
    except json.JSONDecodeError:
        # If not valid JSON, try regex
        match = re.search(r'"BatteryVoltage"\s*:\s*(\d+)', json_response)
        if match:
            return int(match.group(1))
    
    return -1  # Battery voltage not found

def main():
    # Parse command line arguments
    parser = argparse.ArgumentParser(description='Query OPBT device battery voltage')
    parser.add_argument('--port', default=DEFAULT_COM, help='COM port (default: COM3)')
    parser.add_argument('--baud', type=int, default=DEFAULT_BAUDRATE, help='Baud rate (default: 9600)')
    args = parser.parse_args()
    
    com_port = args.port
    baud_rate = args.baud
    
    print(f"Using COM port: {com_port}, Baud rate: {baud_rate}")
    
    try:
        # Open serial port
        ser = serial.Serial(
            port=com_port,
            baudrate=baud_rate,
            bytesize=serial.EIGHTBITS,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            timeout=1
        )
        
        # 1. Enter command mode
        print("Entering command mode...")
        response = send_command(ser, "{\"AtCommandMode\":true}\r\n")
        print(f"Response: {response}")
        
        if "\"OK\":true" not in response:
            print("Failed to enter command mode")
            ser.close()
            return 1
        
        # 2. Query battery voltage directly
        print("Querying battery voltage...")
        response = send_command(ser, "{\"BatteryVoltage\":\"?\"}\r\n")
        print(f"Response: {response}")
        
        # Parse battery voltage
        battery_voltage = parse_battery_voltage(response)
        if battery_voltage > 0:
            print(f"\nBattery voltage: {battery_voltage} mV ({battery_voltage/1000:.2f} V)")
        else:
            print("Unable to parse battery voltage")
        
        # 3. Exit command mode
        print("Exiting command mode...")
        response = send_command(ser, "{\"AtCommandMode\":false}\r\n")
        print(f"Response: {response}")
        
        # Close serial port
        ser.close()
        
    except serial.SerialException as e:
        print(f"Serial port error: {e}")
        return 1
    
    return 0

if __name__ == "__main__":
    sys.exit(main())