Created
October 12, 2022 14:36
-
-
Save djhunter67/d7721f51ddddac74654be0a9ff25f989 to your computer and use it in GitHub Desktop.
Interfacing with the Quectel EG25 Cellular Modem. Commands seem to work better with the EC25-AFX Quectel modem.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MODEM: dict[str, str] = { | |
"POWER_DOWN": "AT+QPOWD", | |
"DATA_CARRIER_DETECTION_MODE": "AT&C0", # Always on | |
"REQUEST_MODEL_IDENTIFICATION": "AT+GMM", | |
"UE_CONFIG": "AT+QCFG", | |
"ENGINEERING_MODE": "AT+QENG", | |
"BAND_SCAN": "AT+QCOPS", | |
"SIGNAL_QUALITY": "AT+CSQ", | |
"QUERY_NETWORK": "AT+QNWINFO", | |
} | |
class EG25G: | |
"""Control of the Quectel EG25 Celluar modem""" | |
def __init__(self, port): | |
self.port = port | |
self.ser = sr.Serial(port, 115_200, timeout=2) | |
def power_down(self) -> sr.Serial: | |
key_word = f"{MODEM.get('POWER_DOWN')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
print(self.ser.readlines()) | |
self.ser.close() | |
def data_carrier_detection_mode(self) -> None: | |
key_word = f"{MODEM.get('DATA_CARRIER_DETECTION_MODE')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
def check_connection(self) -> str: | |
key_word = f"{MODEM.get('REQUEST_MODEL_IDENTIFICATION')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
return str(self.ser.readlines()[1:][0].decode().strip('\n').strip('\r\n')) | |
def get_signal_strength(self) -> int | str: | |
key_word = f"{MODEM.get('SIGNAL_QUALITY')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
rssi = int(self.ser.readlines()[1].decode().strip( | |
'\n').strip('\r\n').split(":")[1].split(",")[0]) | |
match rssi: | |
case 0: | |
return -113 | |
case 1: | |
return -111 | |
case val if 2 <= val < 31: | |
return int(translate(value=val, leftMin=2, leftMax=31, rightMin=-109, rightMax=-52)) | |
case 31: | |
return -51 | |
case 99: | |
return "Undetectable" | |
case 100: | |
return -116 | |
case 101: | |
return -115 | |
case val if 102 <= val < 190: | |
return int(translate(value=val, leftMin=102, leftMax=191, rightMin=-114, rightMax=-25)) | |
case 199: | |
return "Undetectable" | |
case _: | |
return "Undetectable" | |
def get_neighborcell(self) -> str: | |
key_word = f"{MODEM.get('BAND_SCAN')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
return self.ser.readlines()[1:][0].decode().strip('\n').strip('\r\n') | |
def ue_config(self) -> str: | |
key_word = f"{MODEM.get('UE_CONFIG')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
return self.ser.readlines()[1:][0].decode().strip('\n').strip('\r\n') | |
def engineering_mode(self) -> str: | |
key_word = f"{MODEM.get('ENGINEERING_MODE')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
return self.ser.readlines()[1:][0].decode().strip('\n').strip('\r\n') | |
def set_band(self, bands_in_int: list) -> bool: | |
"""Set the bands to scan""" | |
key_word = f'{MODEM.get("UE_CONFIG")}="band",0,{E_UTRA.quectel_band(bands=bands_in_int)},0\r\n' | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
return True | |
def check_current_band(self) -> str: | |
"""Check the band that is presently set""" | |
key_word = f'{MODEM.get("UE_CONFIG")}="band"\r\n' | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
band = self.ser.readlines()[1].decode().strip( | |
'\n').strip('\r\n').split(',')[2] | |
band = int(band, base=16) | |
return band | |
def is_ser_open(self) -> bool: | |
return self.ser.isOpen() | |
def get_neighborcell_list(self) -> list[int]: | |
key_word = f'{MODEM.get("ENGINEERING_MODE")}="neighbourcell"\r\n' | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
neighborcell = [line.decode().strip('\n').strip('\r\n').split("',") | |
for line in self.ser.readlines()][1: -2] | |
earfcns = [neighborcell[i][0][35:].split( | |
",")[0] for i in range(len(neighborcell))] # Get the earfcn | |
return [int(earfcn) for earfcn in earfcns] | |
def get_band_scan(self) -> list[str]: | |
start = time.time() | |
# 4: 4G only, 1: Most information, 0: show PSID, 1: seconds per scan | |
key_word = f'{MODEM.get("BAND_SCAN")}=4,1,0,1\r\n' | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
band_scan = self.ser.readlines() | |
end = time.time() | |
# show time taken in colorama red | |
print( | |
f"{c.blue('Time taken to scan bands: ')} {c.red(str(round(end - start, 3)))} secs") | |
return band_scan | |
def query_network(self) -> None: | |
key_word = f"{MODEM.get('QUERY_NETWORK')}\r\n" | |
self.ser.write(key_word.encode()) | |
self.ser.flush() | |
print(self.ser.readlines()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment