You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Merge pull request #80 from pavelmachek/m_12_cellular
cellular: simple cellular-network example
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Cellular",
|
||||
"publisher": "Pavel Machek",
|
||||
"short_description": "Application for placing phone calls",
|
||||
"long_description": "Simple application for monitoring network state and placing phone calls.",
|
||||
"icon_url": "https://apps.micropythonos.com/apps/cz.ucw.pavel.cellular/icons/cz.ucw.pavel.cellular_0.0.1_64x64.png",
|
||||
"download_url": "https://apps.micropythonos.com/apps/cz.ucw.pavel.cellular/mpks/cz.ucw.pavel.cellular_0.0.1.mpk",
|
||||
"fullname": "cz.ucw.pavel.cellular",
|
||||
"version": "0.0.1",
|
||||
"category": "utilities",
|
||||
"activities": [
|
||||
{
|
||||
"entrypoint": "assets/main.py",
|
||||
"classname": "Main",
|
||||
"intent_filters": [
|
||||
{
|
||||
"action": "main",
|
||||
"category": "launcher"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
from mpos import Activity
|
||||
|
||||
"""
|
||||
Simple cellular-network example
|
||||
"""
|
||||
|
||||
import time
|
||||
import os
|
||||
import json
|
||||
|
||||
try:
|
||||
import lvgl as lv
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from mpos import Activity, MposKeyboard
|
||||
|
||||
TMP = "/tmp/cmd.json"
|
||||
|
||||
|
||||
def run_cmd_json(cmd):
|
||||
rc = os.system(cmd + " > " + TMP)
|
||||
if rc != 0:
|
||||
raise RuntimeError("command failed")
|
||||
|
||||
with open(TMP, "r") as f:
|
||||
data = f.read().strip()
|
||||
|
||||
return json.loads(data)
|
||||
|
||||
def dbus_json(cmd):
|
||||
return run_cmd_json("sudo /home/mobian/g/MicroPythonOS/internal_filesystem/apps/cz.ucw.pavel.cellular/assets/phone.py " + cmd)
|
||||
|
||||
class CellularManager:
|
||||
def init(self):
|
||||
v = dbus_json("loc_on")
|
||||
|
||||
def poll(self):
|
||||
v = dbus_json("signal")
|
||||
print(v)
|
||||
self.signal = v
|
||||
|
||||
def call(self, num):
|
||||
v = dbus_json("call '%s'" % num)
|
||||
|
||||
def sms(self, num, text):
|
||||
v = dbus_json("call '%s' '%s'" % (num, text))
|
||||
|
||||
cm = CellularManager()
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# User interface
|
||||
# ------------------------------------------------------------
|
||||
|
||||
class Main(Activity):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# --------------------
|
||||
|
||||
def onCreate(self):
|
||||
self.screen = lv.obj()
|
||||
#self.screen.remove_flag(lv.obj.FLAG.SCROLLABLE)
|
||||
|
||||
# Top labels
|
||||
self.lbl_time = lv.label(self.screen)
|
||||
self.lbl_time.set_style_text_font(lv.font_montserrat_34, 0)
|
||||
self.lbl_time.set_text("Startup...")
|
||||
self.lbl_time.align(lv.ALIGN.TOP_LEFT, 6, 22)
|
||||
|
||||
self.lbl_date = lv.label(self.screen)
|
||||
self.lbl_date.set_style_text_font(lv.font_montserrat_20, 0)
|
||||
self.lbl_date.align_to(self.lbl_time, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 5)
|
||||
self.lbl_date.set_text("(details here?")
|
||||
|
||||
self.lbl_month = lv.label(self.screen)
|
||||
self.lbl_month.set_style_text_font(lv.font_montserrat_20, 0)
|
||||
self.lbl_month.align(lv.ALIGN.TOP_RIGHT, -6, 22)
|
||||
|
||||
self.number = lv.textarea(self.screen)
|
||||
#self.number.set_accepted_chars("0123456789")
|
||||
self.number.set_one_line(True)
|
||||
self.number.set_style_text_font(lv.font_montserrat_34, 0)
|
||||
self.number.align_to(self.lbl_date, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 12)
|
||||
|
||||
self.call = lv.button(self.screen)
|
||||
self.call.align_to(self.number, lv.ALIGN.OUT_RIGHT_MID, 2, 0)
|
||||
self.call.add_event_cb(lambda e: self.on_call(), lv.EVENT.CLICKED, None)
|
||||
|
||||
# Two text areas on single screen don't work well.
|
||||
# Perhaps make it dialog?
|
||||
#self.sms = lv.textarea(self.screen)
|
||||
#self.sms.set_style_text_font(lv.font_montserrat_24, 0)
|
||||
#self.sms.align_to(self.number, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 10)
|
||||
|
||||
l = lv.label(self.call)
|
||||
l.set_text("Call")
|
||||
l.center()
|
||||
|
||||
kb = lv.keyboard(self.screen)
|
||||
kb.set_textarea(self.number)
|
||||
kb.set_size(lv.pct(100), lv.pct(33))
|
||||
|
||||
self.setContentView(self.screen)
|
||||
cm.init()
|
||||
|
||||
def onResume(self, screen):
|
||||
self.timer = lv.timer_create(self.tick, 60000, None)
|
||||
self.tick(0)
|
||||
|
||||
def onPause(self, screen):
|
||||
if self.timer:
|
||||
self.timer.delete()
|
||||
self.timer = None
|
||||
|
||||
# --------------------
|
||||
|
||||
def on_call(self):
|
||||
num = self.number.get_text()
|
||||
cm.call(num)
|
||||
|
||||
def on_sms(self):
|
||||
num = self.number.get_text()
|
||||
text = self.sms.get_text()
|
||||
cm.sms(num, text)
|
||||
|
||||
def tick(self, t):
|
||||
now = time.localtime()
|
||||
y, m, d = now[0], now[1], now[2]
|
||||
hh, mm, ss = now[3], now[4], now[5]
|
||||
|
||||
self.lbl_month.set_text("busy")
|
||||
|
||||
cm.poll()
|
||||
s = ""
|
||||
s += cm.signal["OperatorName"] + "\n"
|
||||
s += "RegistrationState %d\n" % cm.signal["RegistrationState"]
|
||||
s += "State %d " % cm.signal["State"]
|
||||
sq, re = cm.signal["SignalQuality"]
|
||||
s += "Signal %d\n" % sq
|
||||
|
||||
self.lbl_month.set_text(s)
|
||||
self.lbl_time.set_text("%02d:%02d" % (hh, mm))
|
||||
s = ""
|
||||
self.lbl_date.set_text("%04d-%02d-%02d %s" % (y, m, d, s))
|
||||
|
||||
|
||||
# --------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python3
|
||||
from pydbus import SystemBus, Variant
|
||||
import pydbus
|
||||
import time
|
||||
import sys
|
||||
import json
|
||||
|
||||
"""
|
||||
Lets make it class Phone, one method would be reading battery information, one would be reading operator name / signal strength, one would be getting wifi enabled/disabled / AP name.
|
||||
|
||||
sudo apt install python3-pydbus
|
||||
|
||||
sudo mmcli --list-modems
|
||||
sudo mmcli -m 6 --location-enable-gps-nmea --location-enable-gps-raw
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class Phone:
|
||||
verbose = False
|
||||
|
||||
def __init__(self):
|
||||
self.bus = pydbus.SystemBus()
|
||||
|
||||
def init_sess(self):
|
||||
self.sess = pydbus.SessionBus()
|
||||
|
||||
def get_mobile_loc(self):
|
||||
loc = None
|
||||
mm = self.bus.get("org.freedesktop.ModemManager1")
|
||||
for modem_path in mm.GetManagedObjects():
|
||||
modem = self.bus.get(".ModemManager1", modem_path)
|
||||
loc = modem.GetLocation()
|
||||
return loc
|
||||
|
||||
def get_cell_signal(self):
|
||||
loc = None
|
||||
mm = self.bus.get("org.freedesktop.ModemManager1")
|
||||
for modem_path in mm.GetManagedObjects():
|
||||
modem = self.bus.get(".ModemManager1", modem_path)
|
||||
|
||||
loc = {}
|
||||
|
||||
def attr(v):
|
||||
loc[v] = getattr(modem, v, None)
|
||||
|
||||
attr("OperatorName")
|
||||
attr("OperatorCode") # 0..11 according to MMState
|
||||
attr("State") # 0..11 according to MMState
|
||||
attr("AccessTechnologies")
|
||||
attr("Model")
|
||||
attr("Manufacturer")
|
||||
attr("Revision")
|
||||
attr("EquipmentIdentifier")
|
||||
|
||||
attr("Gsm")
|
||||
attr("Umts")
|
||||
attr("Lte")
|
||||
|
||||
attr("SignalQuality")
|
||||
attr("RegistrationState")
|
||||
|
||||
return loc
|
||||
|
||||
def start_call(self, num):
|
||||
mm = self.bus.get("org.freedesktop.ModemManager1")
|
||||
|
||||
for modem_path in mm.GetManagedObjects():
|
||||
modem = self.bus.get("org.freedesktop.ModemManager1", modem_path)
|
||||
voice = modem["org.freedesktop.ModemManager1.Modem.Voice"]
|
||||
|
||||
call_properties = {
|
||||
"number": Variant('s', num)
|
||||
}
|
||||
|
||||
call_path = voice.CreateCall(call_properties)
|
||||
#call = self.bus.get("org.freedesktop.ModemManager1", call_path)
|
||||
#call_iface = call["org.freedesktop.ModemManager1.Call"]
|
||||
#call_iface.Start()
|
||||
|
||||
return { "call": call_path }
|
||||
|
||||
def send_sms(self, num, text):
|
||||
mm = self.bus.get("org.freedesktop.ModemManager1")
|
||||
|
||||
for modem_path in mm.GetManagedObjects():
|
||||
modem = self.bus.get("org.freedesktop.ModemManager1", modem_path)
|
||||
messaging = modem["org.freedesktop.ModemManager1.Modem.Messaging"]
|
||||
|
||||
sms_properties = {
|
||||
"number": Variant('s', num),
|
||||
"text": Variant('s', text)
|
||||
}
|
||||
|
||||
sms_path = messaging.Create(sms_properties)
|
||||
sms = self.bus.get("org.freedesktop.ModemManager1", sms_path)
|
||||
sms_iface = sms["org.freedesktop.ModemManager1.Sms"]
|
||||
sms_iface.Send()
|
||||
|
||||
return { "sms": sms_path }
|
||||
|
||||
# 0x01 = 3GPP LAC/CI
|
||||
# 0x02 = GPS NMEA
|
||||
# 0x04 = GPS RAW
|
||||
# 0x08 = CDMA BS
|
||||
# 0x10 = GPS Unmanaged
|
||||
CELL_ID = 0x01
|
||||
GPS_NMEA = 0x02
|
||||
GPS_RAW = 0x04
|
||||
|
||||
def enable_mobile_loc(self, gps_on, cell_on):
|
||||
"""
|
||||
Enable GPS RAW + NMEA.
|
||||
"""
|
||||
mm = self.bus.get("org.freedesktop.ModemManager1")
|
||||
for modem_path in mm.GetManagedObjects():
|
||||
modem = self.bus.get(".ModemManager1", modem_path)
|
||||
|
||||
# Setup(uint32 sources, boolean signal_location)
|
||||
# signal_location=True makes ModemManager emit LocationUpdated signals
|
||||
if gps_on:
|
||||
sources = self.GPS_NMEA | self.GPS_RAW
|
||||
else:
|
||||
sources = 0
|
||||
if cell_on:
|
||||
sources |= self.CELL_ID;
|
||||
modem.Setup(sources, True)
|
||||
|
||||
continue
|
||||
# Optional: explicitly enable (some modems require it)
|
||||
try:
|
||||
modem.SetEnable(True)
|
||||
except Exception:
|
||||
print("Cant setenable")
|
||||
return { 'result' : 'setenable failed' }
|
||||
return { 'result': 'ok' }
|
||||
|
||||
phone = Phone()
|
||||
|
||||
def handle_cmd(v, a):
|
||||
if v == "bat":
|
||||
print(json.dumps(phone.get_battery_info()))
|
||||
sys.exit(0)
|
||||
if v == "loc":
|
||||
print(json.dumps(phone.get_mobile_loc()))
|
||||
sys.exit(0)
|
||||
if v == "loc_on":
|
||||
print(json.dumps(phone.enable_mobile_loc(True, True)))
|
||||
sys.exit(0)
|
||||
if v == "loc_off":
|
||||
print(json.dumps(phone.enable_mobile_loc(False, False)))
|
||||
sys.exit(0)
|
||||
if v == "signal":
|
||||
print(json.dumps(phone.get_cell_signal()))
|
||||
sys.exit(0)
|
||||
if v == "call":
|
||||
print(json.dumps(phone.start_call(a[2])))
|
||||
sys.exit(0)
|
||||
if v == "sms":
|
||||
print(json.dumps(phone.send_sms(a[2], a[3])))
|
||||
sys.exit(0)
|
||||
print("Unknown command "+v)
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
handle_cmd(sys.argv[1], sys.argv)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
Reference in New Issue
Block a user