SER Getting Started

博客提供了iptel.org上SER的入门文档链接,即http://www.iptel.org/ser/doc/gettingstarted ,可帮助相关人员获取SER入门知识。
import serial import time import logging class Program: """Aging chamber program step model""" def __init__(self, temperature, humidity, hour, minute): self.temperature = temperature self.humidity = humidity self.hour = hour self.minute = minute class GWSChamberCtrl(object): # Serial command constants COMMAND_GET_TEMP = "1, TEMP?" COMMAND_GET_HUMI = "1, HUMI?" COMMAND_GET_PRGM = "1, PRGM SET?" COMMAND_STOP_DEV = "1, MODE, OFF" COMMAND_EXECUTE_PROGRAM = "1, PRGM, RUN, RAM:1, STEP1" COMMAND_SET_CONSTANT_TEMP = "1, TEMP" COMMAND_SET_MODE_CONSTANT = "1, MODE, CONSTANT" # Special response identifiers NA_PREFIX = "NA:" NOT_READY_CODE = "NA:CONT NOT READY-1" # Success response identifier OK_SIGN = "[b'OK:1" def __init__(self, port, baudrate=19200, bytesize=8, stopbits=1, parity=None): self.logger = logging.getLogger() if not logging.root.handlers: self.logger.setLevel(logging.INFO) self.console_handler = logging.StreamHandler() self.formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s", "%m-%d %H:%M:%S") self.console_handler.setFormatter(self.formatter) self.logger.addHandler(self.console_handler) self.port = port self.baudrate = baudrate self.bytesize = bytesize self.stopbits = stopbits self.parity = parity try: self.ser = self.open_serial(port=self.port, baudrate=self.baudrate, bytesize=self.bytesize, stopbits=self.stopbits, parity=self.parity) self.logger.info("Serial Port Opened") except Exception as e: self.logger.error("Error Opening Serial Port: %s" % e) def SInterval(self): """Command execution interval delay""" time.sleep(0.5) def open_serial(self, port, baudrate, bytesize, stopbits, parity): """Open serial connection""" try: if port is None: port = self.port else: self.port = port if baudrate is None: baudrate = self.baudrate else: self.baudrate = baudrate if bytesize is None: bytesize = self.bytesize else: self.bytesize = bytesize if stopbits is None: stopbits = self.stopbits else: self.stopbits = stopbits if parity is None: parity = self.parity else: self.parity = parity bytesize = serial.EIGHTBITS if bytesize == 8 else serial.SEVENBITS parity = serial.PARITY_NONE if parity is None else parity stopbits = serial.STOPBITS_ONE if stopbits == 1 else serial.STOPBITS_TWO ser = serial.Serial(port=port, baudrate=baudrate, bytesize=bytesize, parity=parity, stopbits=stopbits, timeout=1, xonxoff=False) self.logger.info('%s has opened, baudrate is %s' % (port, baudrate)) return ser except serial.SerialException as e: self.logger.error('Can\'t open %s: %s' % (port, e)) raise def send_command(self, command): """Send command to the serial port""" try: if self.ser is not None and self.ser.isOpen(): # Python 2: Directly send string (no need for encode) self.ser.write(command) self.logger.info('Send command:<%s>' % command) time.sleep(0.5) data = self.receive_data() return data else: self.logger.error('Serial port is closed or does not exist') except Exception as e: self.logger.error('Error sending command <%s>: %s' % (command, e)) raise def receive_data(self): """Get data from the serial port""" try: if self.ser is not None and self.ser.isOpen(): # Python 2: Directly read as string data = [] while True: line = self.ser.readline() if not line: break data.append(line) self.logger.info('Receive data:<%s>' % data) return data else: self.logger.error('Serial port is closed or does not exist') return None except Exception as e: self.logger.error('Error receiving data: %s' % e) raise def close_serial(self): """Close the serial connection""" try: if self.ser is not None and self.ser.isOpen(): self.ser.close() self.logger.info('Serial port has been closed') else: self.logger.error('Serial port is already closed') except Exception as e: self.logger.error('Error closing serial port: %s' % e) raise def get_temperature(self): """ Get the chamber's temperature :return: [monitored temperature, target temperature, highlimit temperature, lowlimit temperature] """ try: # Send temperature query command response = self.send_command(command=self.COMMAND_GET_TEMP) # Validate response format if not response or not isinstance(response, list): raise ValueError("Invalid response format: %s" % response) # Python 2: Directly use string (no need for decode) data_str = response[0] # Split string and convert to float temp_values = data_str.strip().split(',') # Validate split result count if len(temp_values) != 4: raise ValueError("Expected 4 temperature values, got %d" % len(temp_values)) # Convert each value to float temperatures = [float(value.strip()) for value in temp_values] return temperatures except ValueError as ve: self.logger.error("Temperature value error: %s" % ve) raise except Exception as e: self.logger.error("Error getting temperature: %s" % e) raise def get_current_temperature(self, temperature_data): """ Get the first data (current temperature) from the temperature data list Parameters: temperature_data (list): List containing temperature data, format [monitored temperature, target temperature, high limit, low limit] Returns: float: Current temperature value """ try: # Validate input type if not isinstance(temperature_data, list): raise TypeError("Parameter must be a list type") # Validate list is not empty if len(temperature_data) < 1: raise IndexError("Temperature data list cannot be empty") # Get the first element and assign to current_temp current_temp = temperature_data[0] # Validate data type is numeric if not isinstance(current_temp, (int, float)): raise TypeError("First temperature data must be a numeric type") return current_temp except Exception as e: self.logger.error("Error getting current temperature: %s" % e) raise def get_humidity(self): """ Get the chamber's humidity :return: [monitored humidity, target humidity, highlimit humidity, lowlimit humidity] """ try: # Send humidity query command response = self.send_command(command=self.COMMAND_GET_HUMI) # Python 2: Directly use string response_str = response[0] if response else "" if response_str == self.NOT_READY_CODE: self.logger.error("Unable to query humidity: Device does not support or humidity control is not enabled") response = [0, 0, 0, 0] return response # Validate response format if not response or not isinstance(response, list): raise ValueError("Invalid response format: %s" % response) # Get the first element (string) from the list data_str = response[0] # Split string and convert to float humi_values = data_str.strip().split(',') # Validate split result count if len(humi_values) != 4: raise ValueError("Expected 4 humidity values, got %d" % len(humi_values)) # Convert each value to float humiditys = [float(value.strip()) for value in humi_values] return humiditys except ValueError as ve: self.logger.error("Humidity value error: %s" % ve) raise except Exception as e: self.logger.error("Error getting humidity: %s" % e) raise def get_current_humidity(self, humidity_data): """ Get the first data (current humidity) from the humidity data list Parameters: humidity_data (list): List containing humidity data, format [monitored humidity, target humidity, high limit, low limit] Returns: float: Current humidity value """ try: # Validate input type if not isinstance(humidity_data, list): raise TypeError("Parameter must be a list type") # Validate list is not empty if len(humidity_data) < 1: raise IndexError("Humidity data list cannot be empty") # Get the first element and assign to current_humi current_humi = humidity_data[0] # Validate data type is numeric if not isinstance(current_humi, (int, float)): raise TypeError("First humidity data must be a numeric type") return current_humi except Exception as e: self.logger.error("Error getting current humidity: %s" % e) raise def constant_mode_set(self, constant_target_temp, constant_target_humi): """ Set the target temperature and humidity in constant mode Parameters: constant_target_temp (float): Target temperature value to set constant_target_humi (float): Target humidity value to set Returns: str: Complete instruction string sent to the aging chamber Functionality: Constructs "1, TEMP, SX.X" format instruction based on the input target temperature value Constructs "1, HUMI, SX.X" format instruction based on the input target humidity value """ try: # Temperature setting # Validate input is numeric type if not isinstance(constant_target_temp, (int, float)): raise TypeError("Target temperature must be a numeric type") # Format temperature value to a string with one decimal place formatted_temp = "%.1f" % constant_target_temp # Construct complete instruction string constant_temp_command = "1, TEMP, S%s" % formatted_temp # Humidity setting # Validate input is numeric type if not isinstance(constant_target_humi, (int, float)): raise TypeError("Target humidity must be a numeric type") # Format humidity value to a string with one decimal place formatted_humi = "%.1f" % constant_target_humi # Construct complete instruction string constant_humi_command = "1, HUMI, S%s" % formatted_humi # Send commands to the device self.send_command(command=constant_temp_command) time.sleep(1) self.send_command(command=constant_humi_command) time.sleep(1) self.send_command(command=self.COMMAND_SET_MODE_CONSTANT) time.sleep(1) time.sleep(1) # Check if settings are successful temp_result_data = self.get_temperature() time.sleep(1) current_temp_set = temp_result_data[1] self.logger.info("Current temp set: %s" % current_temp_set) # Check if current set temperature matches expectations if current_temp_set != constant_target_temp: raise ValueError("Expected set temp to %s, current %s" % ( constant_target_temp, current_temp_set)) humi_result_data = self.get_humidity() time.sleep(1) current_humi_set = humi_result_data[1] self.logger.info("Current humi set: %s" % current_humi_set) # Check if current set humidity matches expectations if current_humi_set != constant_target_humi: raise ValueError("Expected set humi to %s, current %s" % ( constant_target_humi, current_humi_set)) except Exception as e: self.logger.error("Setting failed: %s" % e) raise def WriteProgram(self, program_list): """Write the program to the device""" # Send start editing command try: self.send_command("1, PRGM DATA WRITE, PGM1, EDIT START") step = 1 for program in program_list: commands = self.ConvertProgramToCommands(program, step) for cmd in commands: # Check command length limit if len(cmd) > 50: self.logger.info("Command too long, may be truncated: %s" % cmd) if not self.send_command(cmd): self.logger.info("Program write failed") return False step += 1 self.SInterval() # Step interval # Send end editing command self.send_command("1, PRGM DATA WRITE, PGM1, END, OFF") self.send_command("1, PRGM DATA WRITE, PGM1, EDIT END") self.logger.info("Program write successful") return True except Exception as e: self.logger.error("Setting failed: %s" % e) raise def ConvertProgramToCommands(self, program, step): """ Convert program steps to commands :param program: Program step :param step: Step number :return: Command list """ try: commands = [] step_cmd = "STEP%d" % step if program.temperature != 0: temp_cmd = ( "1, PRGM DATA WRITE, PGM1, %s, " % step_cmd + "TEMP%s, " % program.temperature + "TIME%02d:%02d" % (program.hour, program.minute) ) commands.append(temp_cmd) if program.humidity != 0: humi_cmd = ( "1, PRGM DATA WRITE, PGM1, %s, " % step_cmd + "HUMI%s, " % program.humidity + "TIME%02d:%02d" % (program.hour, program.minute) ) commands.append(humi_cmd) return commands except Exception as e: self.logger.error("Setting failed: %s" % e) raise def SetProgram(self, program_list): """Set the aging chamber program (with retry mechanism)""" try: # Three retry attempts for tryout in range(1, 4): if self.WriteProgram(program_list): return True self.logger.info("Attempt %d to write program failed, retrying in 1 second" % tryout) time.sleep(1.0) self.logger.error("Program write failed: Maximum retry attempts reached") return False except Exception as e: self.logger.error("Setting failed: %s" % e) raise def RunProgram(self): """Execute the program (with retry mechanism)""" try: # Three retry attempts for tryout in range(1, 4): response = self.send_command(self.COMMAND_EXECUTE_PROGRAM) # Check if response matches expectations if response and any(self.OK_SIGN in r for r in response): self.logger.info("Program started successfully") return True self.logger.info("Attempt %d to start program failed, response: %s" % (tryout, response)) time.sleep(1.0) return False except Exception as e: self.logger.error("Setting failed: %s" % e) raise def StopDevice(self): """Stop the program (with retry mechanism)""" try: # Three retry attempts for tryout in range(1, 4): response = self.send_command(self.COMMAND_STOP_DEV) if response and not any(self.NA_PREFIX in r for r in response): self.logger.info("Device stopped") self.close_serial() return True self.logger.info("Attempt %d to stop device failed" % tryout) time.sleep(1.0) self.logger.error("Device stop failed") return False except Exception as e: self.logger.error("Setting failed: %s" % e) raise 全部代码,保留每个函数的功能,但是整理
06-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值