69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Helper for parsing AT command responses.
|
|
"""
|
|
|
|
import logging
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from m2m.serial.serial_port import SerialPort
|
|
|
|
logger = logging.getLogger('atparser')
|
|
|
|
|
|
class AtParser:
|
|
"""
|
|
Parses responses from the serial port to determine command success/failure.
|
|
"""
|
|
|
|
def __init__(self, serial_port: 'SerialPort'):
|
|
self._port = serial_port
|
|
self._last_response = b''
|
|
|
|
@property
|
|
def last_response(self) -> bytes:
|
|
return self._last_response
|
|
|
|
def read_ok(self, timeout: float = 1.0) -> bool:
|
|
"""
|
|
Reads until a terminator is found and checks if it was 'OK'.
|
|
"""
|
|
self._last_response = self._port.read_until(terminator=b'OK', timeout=timeout)
|
|
# Check if the buffer *ends* with OK, or contains it on a line.
|
|
# Strict check:
|
|
lines = self._last_response.splitlines()
|
|
for line in reversed(lines):
|
|
line = line.strip()
|
|
if line == b'OK':
|
|
return True
|
|
if line == b'ERROR' or b'CME ERROR' in line:
|
|
return False
|
|
return False
|
|
|
|
def is_on(self, query_cmd: bytes, response_prefix: bytes, timeout: float = 1.0) -> bool:
|
|
"""
|
|
Sends a query and checks if the value is '1'.
|
|
Example: is_on(b'AT+CFUN?', b'+CFUN:')
|
|
"""
|
|
self._port.send_cmd(query_cmd)
|
|
response = self._port.read_until(timeout=timeout)
|
|
self._last_response = response
|
|
|
|
# Parse for prefix
|
|
for line in response.splitlines():
|
|
line = line.strip()
|
|
if line.startswith(response_prefix):
|
|
# +CFUN: 1
|
|
try:
|
|
# Remove prefix, then split by comma if multiple params
|
|
# We assume the first param is the status
|
|
payload = line[len(response_prefix):].strip()
|
|
# Handle cases like "1" or "1,0"
|
|
val_str = payload.split(b',')[0]
|
|
return int(val_str) == 1
|
|
except ValueError:
|
|
pass
|
|
return False
|