example 'meshtastic': review WiFi mode

This commit is contained in:
pls.153 2024-05-03 10:46:58 +02:00
parent f56a468983
commit 5d19145186
13 changed files with 119 additions and 23 deletions

View file

@ -23,7 +23,9 @@ WiFi_ME::WiFi_ME(Connection* _con) : emitter(_con), con(_con) {
}
void WiFi_ME::connectToRadio(const QString& ip) {
connectToHost(ip, 4403);
if (state() != ConnectedState) {
connectToHost(ip, 4403);
}
}
void WiFi_ME::stateChanged(SocketState state) {
@ -34,7 +36,9 @@ void WiFi_ME::stateChanged(SocketState state) {
}
void WiFi_ME::disconnect() {
disconnectFromHost();
if (state() == ConnectedState) {
disconnectFromHost();
}
}
void WiFi_ME::write2(const QByteArray& data) {

View file

@ -152,6 +152,17 @@ QVariant QT::write2(const QVariant& vBytes) {
return QVariant();
}
QVariant QT::wifiConnectable(const QVariant& vIP) {
if (tcp.state() == QTcpSocket::ConnectedState) {
return true;
}
tcp.connectToHost(vIP.toString(), 4403);
if (tcp.waitForConnected(1000)) {
return true;
}
return QVariant();
}
// GPS
#ifdef Q_OS_ANDROID

View file

@ -2,6 +2,7 @@
#include <QtCore>
#include <QSqlDatabase>
#include <QTcpSocket>
#ifdef Q_CC_MSVC
#define LIB_EXPORT __declspec(dllexport)
@ -31,6 +32,7 @@ public:
Q_INVOKABLE QVariant setDeviceFilter(const QVariant&);
Q_INVOKABLE QVariant read2();
Q_INVOKABLE QVariant write2(const QVariant&);
Q_INVOKABLE QVariant wifiConnectable(const QVariant&);
// GPS
Q_INVOKABLE QVariant iniPositioning();
@ -50,6 +52,7 @@ public:
QT();
QSqlDatabase db;
QTcpSocket tcp;
#ifdef Q_OS_ANDROID
QtAndroidServiceReplica* con = nullptr;
#else

View file

@ -47,17 +47,19 @@
:initial-contents list))
(defun start-device-discovery (&optional (name (or (app:setting :device) "")))
(when *allow-discovery*
(setf *ready* nil
*ble-names* nil
*schedule-clear* t)
(unless radios:*found*
(radios:clear))
(qrun* (qt:start-device-discovery qt:*cpp*
(if (eql :wifi radios:*connection*)
(app:setting :wifi-ip)
name)))
(q> |playing| ui:*busy* t)))
(let ((wifi (eql :wifi radios:*connection*)))
(when wifi
(unless (radios:ensure-wifi-connection t)
(return-from start-device-discovery)))
(when *allow-discovery*
(setf *ready* nil
*ble-names* nil
*schedule-clear* t)
(unless radios:*found*
(radios:clear))
(qrun* (qt:start-device-discovery qt:*cpp*
(if wifi (radios:wifi-ip) name)))
(q> |playing| ui:*busy* t))))
(defun get-node-config ()
;; see also Timer in 'qml/ext/group/Group.qml'

View file

@ -140,12 +140,12 @@
text (x:callback-name callback)))
(defun input-dialog (label callback &key (title "")
(text "") (max-length #.(float 32767))
(text "") (max-length #.(float 32767)) (input-mask "")
from to value)
(qjs |input| ui:*dialogs*
title label (x:callback-name callback)
text max-length ; string (line edit)
from to value)) ; integer (spin box)
text max-length input-mask ; string (line edit)
from to value)) ; integer (spin box)
;;; backup/restore all app data

View file

@ -126,10 +126,13 @@
#:choose-region
#:clear
#:device-discovered
#:ensure-wifi-connection
#:ini
#:reset
#:saved-region
#:set-region))
#:set-region
#:wifi-connectable
#:wifi-ip))
(defpackage :location
(:nicknames :loc)

View file

@ -17,6 +17,7 @@
#:set-connection-type
#:set-device-filter
#:sql-query
#:wifi-connectable
#:write*))
(in-package :qt)

View file

@ -26,6 +26,36 @@
(defun set-connection-type ()
(qt:set-connection-type qt:*cpp* (symbol-name *connection*)))
(defun wifi-ip ()
(or (app:setting :wifi-ip) ""))
(defun wifi-connectable ()
(qrun* (qt:wifi-connectable qt:*cpp* (wifi-ip))))
(let (start-discovery)
(defun ensure-wifi-connection (&optional start)
(setf start-discovery start)
(or (wifi-connectable)
(progn
(app:input-dialog
(tr "Radio WiFi IP:") 'wifi-ip-changed
:title (tr "IP")
:text (wifi-ip)
:input-mask "000.000.000.000")
nil)))
(defun wifi-ip-changed* (ok)
(when ok
(app:change-setting :wifi-ip (q< |text| ui:*dialog-line-edit*))
(if (and (wifi-connectable)
start-discovery)
(progn
(setf start-discovery nil)
(qlater 'lora:start-device-discovery))
(qlater (lambda () (ensure-wifi-connection start-discovery)))))))
(defun wifi-ip-changed (ok)
(qlater (lambda () (wifi-ip-changed* ok))))
(defun saved-region ()
(let ((region (app:setting :region)))
(unless (find region '(nil :unset))

View file

@ -41,6 +41,7 @@ Rectangle {
<img src='../../img/radio.png' width=60 height=60>
<br>Radios
</h3>
<h4>BLE</h4>
<p>
If you use more than 1 radio, switch here to the radio you want to use.
</p>
@ -51,6 +52,21 @@ To manually restart device discovery, press-and-hold on the radio icon.
If your radio is not found, it may help to turn it off/on again.
</p>
%1
<h4>USB</h4>
Desktop only. You may need to install serial drivers first, and you need to use a data USB cable.
<h4>WiFi</h4>
<p>
Use the Python CLI to setup your connection like this:
</p>
<pre>
meshtastic &#92;
--set network.wifi_enabled true &#92;
--set network.wifi_ssid \"&lt;name&gt;\" &#92;
--set network.wifi_psk \"&lt;password&gt;\"
</pre>
<p>
The app will ask for your radio IP, which can be found on its screen as soon as it is connected to WiFi.
</p>
<h3>
<img src='../../img/group.png' width=60 height=60>
<br>Group

View file

@ -37,7 +37,7 @@ Item {
loader.item.open()
}
function input(title, label, callback, text, maxLength, from, to, value) {
function input(title, label, callback, text, maxLength, inputMask, from, to, value) {
loader.active = false // force reload
if (rootItem.mobile) {
loader.source = "InputMobile.qml"
@ -50,6 +50,7 @@ Item {
loader.item.callback = callback
loader.item.text = text
loader.item.maxLength = maxLength
loader.item.inputMask = inputMask
loader.item.from = from
loader.item.to = to
loader.item.value = value

View file

@ -7,6 +7,7 @@ Dialog {
property alias label: label.text
property alias text: edit.text
property alias inputMask: edit.inputMask
property alias maxLength: edit.maximumLength
property alias from: spinBox.from
property alias to: spinBox.to

View file

@ -9,6 +9,7 @@ Dialog {
property alias label: label.text
property alias text: edit.text
property alias inputMask: edit.inputMask
property alias maxLength: edit.maximumLength
property alias from: spinBox.from
property alias to: spinBox.to

View file

@ -66,12 +66,10 @@ they are 64 bit and run at least iOS 12.
How to use cl-meshtastic
------------------------
If you have your radio connected to your PC via USB, you can choose 'USB' as
connection type from the main menu (see 'Radios' icon). This only works on
Linux and macOS (Windows not tested), and only with RAK devices (which don't
need any driver, just permission to e.g. `/dev/ttyACM0` on Linux).
## Bluetooth
For mobile there is BLE (Bluetooth Low Energy).
The most universal connection type is BLE (Bluetooth Low Energy), which should
work everywhere.
Your radio needs to be turned on and bluetooth needs to be enabled before you
start the app.
@ -94,6 +92,31 @@ It may occur that your radio device is sometimes not found; some suggestions:
A generic bluetooth app like **nRF Connect** may help in order to see if the
devices themselves work and are able to connect.
## USB
If you have your radio connected to your PC via USB, you can also choose 'USB'
as connection type from the main menu (see 'Radios' icon). This only works on
Linux and macOS (Windows not tested). RAK devices won't need any additional
driver, just permission to e.g. `/dev/ttyACM0` (Linux). Other radios (ESP32
based) require addtional serial drivers to be installed, see official
Meshtastic website.
## WiFi
If you have a radio with intgrated WiFi (like LILYGO T-BEAM, HELTEC V3), you
can setup your WiFi connection using the Python CLI:
```
meshtastic \
--set network.wifi_enabled true \
--set network.wifi_ssid "<name>" \
--set network.wifi_psk "<password>"
```
You should now be able to see the IP of your WiFi connected radio on it's
small display (use the user button to switch to the WiFi page). After entering
the IP in the appropriate setting of this app, you should be able to choose
'WiFi' as connection type after switching to 'Radios'.
See also [readme-usage](readme-usage.md).