Updated WIFI on esp and svelte side to use proto
This commit is contained in:
@@ -10,7 +10,8 @@
|
|||||||
import ScanNetworks from './Scan.svelte'
|
import ScanNetworks from './Scan.svelte'
|
||||||
import Spinner from '$lib/components/Spinner.svelte'
|
import Spinner from '$lib/components/Spinner.svelte'
|
||||||
import InfoDialog from '$lib/components/InfoDialog.svelte'
|
import InfoDialog from '$lib/components/InfoDialog.svelte'
|
||||||
import { type KnownNetworkItem, type WifiSettings, type WifiStatus } from '$lib/types/models'
|
import { type WifiStatus } from '$lib/types/models'
|
||||||
|
import { WifiSettings, WifiNetwork, Response, Request } from '$lib/platform_shared/api'
|
||||||
import { api } from '$lib/api'
|
import { api } from '$lib/api'
|
||||||
import { ipToUint32, uint32ToIp, isValidIpString } from '$lib/utilities'
|
import { ipToUint32, uint32ToIp, isValidIpString } from '$lib/utilities'
|
||||||
import {
|
import {
|
||||||
@@ -34,26 +35,26 @@
|
|||||||
} from '$lib/components/icons'
|
} from '$lib/components/icons'
|
||||||
import StatusItem from '$lib/components/StatusItem.svelte'
|
import StatusItem from '$lib/components/StatusItem.svelte'
|
||||||
|
|
||||||
let networkEditable: KnownNetworkItem = $state({
|
let networkEditable: WifiNetwork = $state({
|
||||||
ssid: '',
|
ssid: '',
|
||||||
password: '',
|
password: '',
|
||||||
static_ip_config: false,
|
staticIpConfig: false,
|
||||||
local_ip: 0,
|
localIp: 0,
|
||||||
subnet_mask: 0,
|
subnetMask: 0,
|
||||||
gateway_ip: 0,
|
gatewayIp: 0,
|
||||||
dns_ip_1: 0,
|
dnsIp1: 0,
|
||||||
dns_ip_2: 0
|
dnsIp2: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
let ipDisplay = $state({
|
let ipDisplay = $state({
|
||||||
local_ip: '',
|
localIp: '',
|
||||||
subnet_mask: '',
|
subnetMask: '',
|
||||||
gateway_ip: '',
|
gatewayIp: '',
|
||||||
dns_ip_1: '',
|
dnsIp1: '',
|
||||||
dns_ip_2: ''
|
dnsIp2: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
let static_ip_config = $state(false)
|
let staticIpConfig = $state(false)
|
||||||
|
|
||||||
let newNetwork: boolean = $state(true)
|
let newNetwork: boolean = $state(true)
|
||||||
let showNetworkEditor: boolean = $state(false)
|
let showNetworkEditor: boolean = $state(false)
|
||||||
@@ -61,7 +62,7 @@
|
|||||||
let wifiStatus: WifiStatus | null = $state(null)
|
let wifiStatus: WifiStatus | null = $state(null)
|
||||||
let wifiSettings: WifiSettings | null = $state(null)
|
let wifiSettings: WifiSettings | null = $state(null)
|
||||||
|
|
||||||
let dndNetworkList: KnownNetworkItem[] = $state([])
|
let dndNetworkList: WifiNetwork[] = $state([])
|
||||||
|
|
||||||
let showWifiDetails = $state(false)
|
let showWifiDetails = $state(false)
|
||||||
|
|
||||||
@@ -69,11 +70,11 @@
|
|||||||
|
|
||||||
let formErrors = $state({
|
let formErrors = $state({
|
||||||
ssid: false,
|
ssid: false,
|
||||||
local_ip: false,
|
localIp: false,
|
||||||
gateway_ip: false,
|
gatewayIp: false,
|
||||||
subnet_mask: false,
|
subnetMask: false,
|
||||||
dns_1: false,
|
dnsIp1: false,
|
||||||
dns_2: false
|
dnsIp2: false
|
||||||
})
|
})
|
||||||
|
|
||||||
let formErrorhostname = $state(false)
|
let formErrorhostname = $state(false)
|
||||||
@@ -89,24 +90,30 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getWifiSettings() {
|
async function getWifiSettings() {
|
||||||
const result = await api.get<WifiSettings>('/api/wifi/sta/settings')
|
const result = await api.get<Response>('/api/wifi/sta/settings')
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
console.error(`Error occurred while fetching: `, result.inner)
|
console.error(`Error occurred while fetching: `, result.inner)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wifiSettings = result.inner
|
wifiSettings = result.inner.wifiSettings!
|
||||||
dndNetworkList = wifiSettings.wifi_networks
|
dndNetworkList = wifiSettings.wifiNetworks
|
||||||
return wifiSettings
|
return wifiSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
async function postWiFiSettings(data: WifiSettings) {
|
async function postWiFiSettings(data: WifiSettings) {
|
||||||
const result = await api.post<WifiSettings>('/api/wifi/sta/settings', data)
|
const result = await api.post_proto<Response>('/api/wifi/sta/settings', Request.create({ wifiSettings: data }))
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
console.error(`Error occurred while fetching: `, result.inner)
|
console.error(`Error occurred while fetching: `, result.inner)
|
||||||
notifications.error('User not authorized.', 3000)
|
notifications.error('User not authorized.', 3000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wifiSettings = result.inner
|
if (result.inner.statusCode !== 200) {
|
||||||
|
notifications.error(result.inner.errorMessage || 'Failed to update settings', 3000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (result.inner.wifiSettings) {
|
||||||
|
wifiSettings = result.inner.wifiSettings
|
||||||
|
}
|
||||||
notifications.success('Wi-Fi settings updated.', 3000)
|
notifications.success('Wi-Fi settings updated.', 3000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +124,7 @@
|
|||||||
} else {
|
} else {
|
||||||
formErrorhostname = false
|
formErrorhostname = false
|
||||||
// Update global wifiSettings object
|
// Update global wifiSettings object
|
||||||
wifiSettings.wifi_networks = dndNetworkList
|
wifiSettings.wifiNetworks = dndNetworkList
|
||||||
// Post to REST API
|
// Post to REST API
|
||||||
postWiFiSettings(wifiSettings)
|
postWiFiSettings(wifiSettings)
|
||||||
console.log(wifiSettings)
|
console.log(wifiSettings)
|
||||||
@@ -135,55 +142,55 @@
|
|||||||
formErrors.ssid = false
|
formErrors.ssid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
networkEditable.static_ip_config = static_ip_config
|
networkEditable.staticIpConfig = staticIpConfig
|
||||||
|
|
||||||
if (networkEditable.static_ip_config) {
|
if (networkEditable.staticIpConfig) {
|
||||||
if (!isValidIpString(ipDisplay.gateway_ip)) {
|
if (!isValidIpString(ipDisplay.gatewayIp)) {
|
||||||
valid = false
|
valid = false
|
||||||
formErrors.gateway_ip = true
|
formErrors.gatewayIp = true
|
||||||
} else {
|
} else {
|
||||||
formErrors.gateway_ip = false
|
formErrors.gatewayIp = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIpString(ipDisplay.subnet_mask)) {
|
if (!isValidIpString(ipDisplay.subnetMask)) {
|
||||||
valid = false
|
valid = false
|
||||||
formErrors.subnet_mask = true
|
formErrors.subnetMask = true
|
||||||
} else {
|
} else {
|
||||||
formErrors.subnet_mask = false
|
formErrors.subnetMask = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIpString(ipDisplay.local_ip)) {
|
if (!isValidIpString(ipDisplay.localIp)) {
|
||||||
valid = false
|
valid = false
|
||||||
formErrors.local_ip = true
|
formErrors.localIp = true
|
||||||
} else {
|
} else {
|
||||||
formErrors.local_ip = false
|
formErrors.localIp = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIpString(ipDisplay.dns_ip_1)) {
|
if (!isValidIpString(ipDisplay.dnsIp1)) {
|
||||||
valid = false
|
valid = false
|
||||||
formErrors.dns_1 = true
|
formErrors.dnsIp1 = true
|
||||||
} else {
|
} else {
|
||||||
formErrors.dns_1 = false
|
formErrors.dnsIp1 = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIpString(ipDisplay.dns_ip_2)) {
|
if (!isValidIpString(ipDisplay.dnsIp2)) {
|
||||||
valid = false
|
valid = false
|
||||||
formErrors.dns_2 = true
|
formErrors.dnsIp2 = true
|
||||||
} else {
|
} else {
|
||||||
formErrors.dns_2 = false
|
formErrors.dnsIp2 = false
|
||||||
}
|
}
|
||||||
|
|
||||||
networkEditable.local_ip = ipToUint32(ipDisplay.local_ip)
|
networkEditable.localIp = ipToUint32(ipDisplay.localIp)
|
||||||
networkEditable.subnet_mask = ipToUint32(ipDisplay.subnet_mask)
|
networkEditable.subnetMask = ipToUint32(ipDisplay.subnetMask)
|
||||||
networkEditable.gateway_ip = ipToUint32(ipDisplay.gateway_ip)
|
networkEditable.gatewayIp = ipToUint32(ipDisplay.gatewayIp)
|
||||||
networkEditable.dns_ip_1 = ipToUint32(ipDisplay.dns_ip_1)
|
networkEditable.dnsIp1 = ipToUint32(ipDisplay.dnsIp1)
|
||||||
networkEditable.dns_ip_2 = ipToUint32(ipDisplay.dns_ip_2)
|
networkEditable.dnsIp2 = ipToUint32(ipDisplay.dnsIp2)
|
||||||
} else {
|
} else {
|
||||||
formErrors.local_ip = false
|
formErrors.localIp = false
|
||||||
formErrors.subnet_mask = false
|
formErrors.subnetMask = false
|
||||||
formErrors.gateway_ip = false
|
formErrors.gatewayIp = false
|
||||||
formErrors.dns_1 = false
|
formErrors.dnsIp1 = false
|
||||||
formErrors.dns_2 = false
|
formErrors.dnsIp2 = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@@ -195,6 +202,10 @@
|
|||||||
addNetwork()
|
addNetwork()
|
||||||
dndNetworkList = [...dndNetworkList]
|
dndNetworkList = [...dndNetworkList]
|
||||||
showNetworkEditor = false
|
showNetworkEditor = false
|
||||||
|
if (wifiSettings) {
|
||||||
|
wifiSettings.wifiNetworks = dndNetworkList
|
||||||
|
postWiFiSettings(wifiSettings)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,19 +225,19 @@
|
|||||||
networkEditable = {
|
networkEditable = {
|
||||||
ssid: '',
|
ssid: '',
|
||||||
password: '',
|
password: '',
|
||||||
static_ip_config: false,
|
staticIpConfig: false,
|
||||||
local_ip: 0,
|
localIp: 0,
|
||||||
subnet_mask: 0,
|
subnetMask: 0,
|
||||||
gateway_ip: 0,
|
gatewayIp: 0,
|
||||||
dns_ip_1: 0,
|
dnsIp1: 0,
|
||||||
dns_ip_2: 0
|
dnsIp2: 0
|
||||||
}
|
}
|
||||||
ipDisplay = {
|
ipDisplay = {
|
||||||
local_ip: '',
|
localIp: '',
|
||||||
subnet_mask: '',
|
subnetMask: '',
|
||||||
gateway_ip: '',
|
gatewayIp: '',
|
||||||
dns_ip_1: '',
|
dnsIp1: '',
|
||||||
dns_ip_2: ''
|
dnsIp2: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,11 +246,11 @@
|
|||||||
showNetworkEditor = true
|
showNetworkEditor = true
|
||||||
networkEditable = dndNetworkList[index]
|
networkEditable = dndNetworkList[index]
|
||||||
ipDisplay = {
|
ipDisplay = {
|
||||||
local_ip: networkEditable.local_ip ? uint32ToIp(networkEditable.local_ip) : '',
|
localIp: networkEditable.localIp ? uint32ToIp(networkEditable.localIp) : '',
|
||||||
subnet_mask: networkEditable.subnet_mask ? uint32ToIp(networkEditable.subnet_mask) : '',
|
subnetMask: networkEditable.subnetMask ? uint32ToIp(networkEditable.subnetMask) : '',
|
||||||
gateway_ip: networkEditable.gateway_ip ? uint32ToIp(networkEditable.gateway_ip) : '',
|
gatewayIp: networkEditable.gatewayIp ? uint32ToIp(networkEditable.gatewayIp) : '',
|
||||||
dns_ip_1: networkEditable.dns_ip_1 ? uint32ToIp(networkEditable.dns_ip_1) : '',
|
dnsIp1: networkEditable.dnsIp1 ? uint32ToIp(networkEditable.dnsIp1) : '',
|
||||||
dns_ip_2: networkEditable.dns_ip_2 ? uint32ToIp(networkEditable.dns_ip_2) : ''
|
dnsIp2: networkEditable.dnsIp2 ? uint32ToIp(networkEditable.dnsIp2) : ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +503,7 @@
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
bind:checked={wifiSettings.priority_RSSI}
|
bind:checked={wifiSettings.priorityRssi}
|
||||||
class="checkbox checkbox-primary sm:-mb-5"
|
class="checkbox checkbox-primary sm:-mb-5"
|
||||||
/>
|
/>
|
||||||
<span class="sm:-mb-5">Connect to strongest WiFi</span>
|
<span class="sm:-mb-5">Connect to strongest WiFi</span>
|
||||||
@@ -541,13 +552,13 @@
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
bind:checked={static_ip_config}
|
bind:checked={staticIpConfig}
|
||||||
class="checkbox checkbox-primary sm:-mb-5"
|
class="checkbox checkbox-primary sm:-mb-5"
|
||||||
/>
|
/>
|
||||||
<span class="sm:-mb-5">Static IP Config?</span>
|
<span class="sm:-mb-5">Static IP Config?</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{#if static_ip_config}
|
{#if staticIpConfig}
|
||||||
<div
|
<div
|
||||||
class="grid w-full grid-cols-1 content-center gap-x-4 px-4 sm:grid-cols-2"
|
class="grid w-full grid-cols-1 content-center gap-x-4 px-4 sm:grid-cols-2"
|
||||||
transition:slide|local={{ duration: 300, easing: cubicOut }}
|
transition:slide|local={{ duration: 300, easing: cubicOut }}
|
||||||
@@ -559,21 +570,21 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered w-full {(
|
class="input input-bordered w-full {(
|
||||||
formErrors.local_ip
|
formErrors.localIp
|
||||||
) ?
|
) ?
|
||||||
'border-error border-2'
|
'border-error border-2'
|
||||||
: ''}"
|
: ''}"
|
||||||
minlength="7"
|
minlength="7"
|
||||||
maxlength="15"
|
maxlength="15"
|
||||||
size="15"
|
size="15"
|
||||||
bind:value={ipDisplay.local_ip}
|
bind:value={ipDisplay.localIp}
|
||||||
id="localIP"
|
id="localIP"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<label class="label" for="localIP">
|
<label class="label" for="localIP">
|
||||||
<span
|
<span
|
||||||
class="label-text-alt text-error {(
|
class="label-text-alt text-error {(
|
||||||
formErrors.local_ip
|
formErrors.localIp
|
||||||
) ?
|
) ?
|
||||||
''
|
''
|
||||||
: 'hidden'}">Must be a valid IPv4 address</span
|
: 'hidden'}">Must be a valid IPv4 address</span
|
||||||
@@ -588,20 +599,20 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered w-full {(
|
class="input input-bordered w-full {(
|
||||||
formErrors.gateway_ip
|
formErrors.gatewayIp
|
||||||
) ?
|
) ?
|
||||||
'border-error border-2'
|
'border-error border-2'
|
||||||
: ''}"
|
: ''}"
|
||||||
minlength="7"
|
minlength="7"
|
||||||
maxlength="15"
|
maxlength="15"
|
||||||
size="15"
|
size="15"
|
||||||
bind:value={ipDisplay.gateway_ip}
|
bind:value={ipDisplay.gatewayIp}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<label class="label" for="gateway">
|
<label class="label" for="gateway">
|
||||||
<span
|
<span
|
||||||
class="label-text-alt text-error {(
|
class="label-text-alt text-error {(
|
||||||
formErrors.gateway_ip
|
formErrors.gatewayIp
|
||||||
) ?
|
) ?
|
||||||
''
|
''
|
||||||
: 'hidden'}">Must be a valid IPv4 address</span
|
: 'hidden'}">Must be a valid IPv4 address</span
|
||||||
@@ -615,20 +626,20 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered w-full {(
|
class="input input-bordered w-full {(
|
||||||
formErrors.subnet_mask
|
formErrors.subnetMask
|
||||||
) ?
|
) ?
|
||||||
'border-error border-2'
|
'border-error border-2'
|
||||||
: ''}"
|
: ''}"
|
||||||
minlength="7"
|
minlength="7"
|
||||||
maxlength="15"
|
maxlength="15"
|
||||||
size="15"
|
size="15"
|
||||||
bind:value={ipDisplay.subnet_mask}
|
bind:value={ipDisplay.subnetMask}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<label class="label" for="subnet">
|
<label class="label" for="subnet">
|
||||||
<span
|
<span
|
||||||
class="label-text-alt text-error {(
|
class="label-text-alt text-error {(
|
||||||
formErrors.subnet_mask
|
formErrors.subnetMask
|
||||||
) ?
|
) ?
|
||||||
''
|
''
|
||||||
: 'hidden'}"
|
: 'hidden'}"
|
||||||
@@ -643,18 +654,18 @@
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered w-full {formErrors.dns_1 ?
|
class="input input-bordered w-full {formErrors.dnsIp1 ?
|
||||||
'border-error border-2'
|
'border-error border-2'
|
||||||
: ''}"
|
: ''}"
|
||||||
minlength="7"
|
minlength="7"
|
||||||
maxlength="15"
|
maxlength="15"
|
||||||
size="15"
|
size="15"
|
||||||
bind:value={ipDisplay.dns_ip_1}
|
bind:value={ipDisplay.dnsIp1}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<label class="label" for="gateway">
|
<label class="label" for="gateway">
|
||||||
<span
|
<span
|
||||||
class="label-text-alt text-error {formErrors.dns_1 ?
|
class="label-text-alt text-error {formErrors.dnsIp1 ?
|
||||||
''
|
''
|
||||||
: 'hidden'}"
|
: 'hidden'}"
|
||||||
>
|
>
|
||||||
@@ -668,18 +679,18 @@
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered w-full {formErrors.dns_2 ?
|
class="input input-bordered w-full {formErrors.dnsIp2 ?
|
||||||
'border-error border-2'
|
'border-error border-2'
|
||||||
: ''}"
|
: ''}"
|
||||||
minlength="7"
|
minlength="7"
|
||||||
maxlength="15"
|
maxlength="15"
|
||||||
size="15"
|
size="15"
|
||||||
bind:value={ipDisplay.dns_ip_2}
|
bind:value={ipDisplay.dnsIp2}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<label class="label" for="subnet">
|
<label class="label" for="subnet">
|
||||||
<span
|
<span
|
||||||
class="label-text-alt text-error {formErrors.dns_2 ?
|
class="label-text-alt text-error {formErrors.dnsIp2 ?
|
||||||
''
|
''
|
||||||
: 'hidden'}"
|
: 'hidden'}"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <ArduinoJson.h>
|
|
||||||
#include <template/state_result.h>
|
#include <template/state_result.h>
|
||||||
#include <string>
|
#include <platform_shared/api.pb.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#ifndef FACTORY_WIFI_SSID
|
#ifndef FACTORY_WIFI_SSID
|
||||||
#define FACTORY_WIFI_SSID ""
|
#define FACTORY_WIFI_SSID ""
|
||||||
@@ -21,118 +21,39 @@
|
|||||||
#define FACTORY_WIFI_RSSI_THRESHOLD -80
|
#define FACTORY_WIFI_RSSI_THRESHOLD -80
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
using WiFiNetwork = api_WifiNetwork;
|
||||||
std::string ssid;
|
using WiFiSettings = api_WifiSettings;
|
||||||
uint8_t bssid[6];
|
|
||||||
int32_t channel;
|
|
||||||
std::string password;
|
|
||||||
bool staticIPConfig;
|
|
||||||
IPAddress localIP;
|
|
||||||
IPAddress gatewayIP;
|
|
||||||
IPAddress subnetMask;
|
|
||||||
IPAddress dnsIP1;
|
|
||||||
IPAddress dnsIP2;
|
|
||||||
bool available;
|
|
||||||
|
|
||||||
void serialize(JsonVariant &json) const {
|
inline WiFiNetwork WiFiNetwork_defaults() {
|
||||||
json["ssid"] = ssid.c_str();
|
WiFiNetwork network = api_WifiNetwork_init_zero;
|
||||||
json["password"] = password.c_str();
|
strncpy(network.ssid, FACTORY_WIFI_SSID, sizeof(network.ssid) - 1);
|
||||||
json["static_ip_config"] = staticIPConfig;
|
strncpy(network.password, FACTORY_WIFI_PASSWORD, sizeof(network.password) - 1);
|
||||||
if (staticIPConfig) {
|
network.static_ip_config = false;
|
||||||
json["local_ip"] = (uint32_t)(localIP);
|
network.local_ip = 0;
|
||||||
json["gateway_ip"] = (uint32_t)(gatewayIP);
|
network.gateway_ip = 0;
|
||||||
json["subnet_mask"] = (uint32_t)(subnetMask);
|
network.subnet_mask = 0;
|
||||||
json["dns_ip_1"] = (uint32_t)(dnsIP1);
|
network.dns_ip_1 = 0;
|
||||||
json["dns_ip_2"] = (uint32_t)(dnsIP2);
|
network.dns_ip_2 = 0;
|
||||||
}
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deserialize(const JsonVariant &json) {
|
inline WiFiSettings WiFiSettings_defaults() {
|
||||||
std::string newSsid = json["ssid"].as<std::string>();
|
WiFiSettings settings = api_WifiSettings_init_zero;
|
||||||
std::string newPassword = json["password"].as<std::string>();
|
strncpy(settings.hostname, FACTORY_WIFI_HOSTNAME, sizeof(settings.hostname) - 1);
|
||||||
if (newSsid.length() < 1 || newSsid.length() > 31 || newPassword.length() > 64) {
|
settings.priority_rssi = true;
|
||||||
ESP_LOGE("WiFiSettings", "SSID or password length is invalid");
|
settings.wifi_networks_count = 0;
|
||||||
return false;
|
if (strlen(FACTORY_WIFI_SSID) > 0) {
|
||||||
|
settings.wifi_networks[0] = WiFiNetwork_defaults();
|
||||||
|
settings.wifi_networks_count = 1;
|
||||||
}
|
}
|
||||||
ssid = newSsid;
|
return settings;
|
||||||
password = newPassword;
|
|
||||||
staticIPConfig = json["static_ip_config"] | false;
|
|
||||||
if (staticIPConfig) {
|
|
||||||
localIP = IPAddress(json["local_ip"] | 0u);
|
|
||||||
gatewayIP = IPAddress(json["gateway_ip"] | 0u);
|
|
||||||
subnetMask = IPAddress(json["subnet_mask"] | 0u);
|
|
||||||
dnsIP1 = IPAddress(json["dns_ip_1"] | 0u);
|
|
||||||
dnsIP2 = IPAddress(json["dns_ip_2"] | 0u);
|
|
||||||
if (dnsIP1 == IPAddress(0, 0, 0, 0) && dnsIP2 != IPAddress(0, 0, 0, 0)) {
|
|
||||||
dnsIP1 = dnsIP2;
|
|
||||||
dnsIP2 = IPAddress(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
if (localIP == IPAddress(0, 0, 0, 0) || gatewayIP == IPAddress(0, 0, 0, 0) ||
|
|
||||||
subnetMask == IPAddress(0, 0, 0, 0)) {
|
|
||||||
staticIPConfig = false;
|
|
||||||
ESP_LOGW("WiFiSettings", "Invalid static IP configuration - falling back to DHCP");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
available = false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} wifi_settings_t;
|
inline void WiFiSettings_read(const WiFiSettings &settings, WiFiSettings &proto) {
|
||||||
|
proto = settings;
|
||||||
inline wifi_settings_t createDefaultWiFiSettings() {
|
|
||||||
return wifi_settings_t {
|
|
||||||
.ssid = FACTORY_WIFI_SSID,
|
|
||||||
.bssid = {0},
|
|
||||||
.channel = -1,
|
|
||||||
.password = FACTORY_WIFI_PASSWORD,
|
|
||||||
.staticIPConfig = false,
|
|
||||||
.localIP = IPAddress(0, 0, 0, 0),
|
|
||||||
.gatewayIP = IPAddress(0, 0, 0, 0),
|
|
||||||
.subnetMask = IPAddress(0, 0, 0, 0),
|
|
||||||
.dnsIP1 = IPAddress(0, 0, 0, 0),
|
|
||||||
.dnsIP2 = IPAddress(0, 0, 0, 0),
|
|
||||||
.available = false,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WiFiSettings {
|
inline StateUpdateResult WiFiSettings_update(const WiFiSettings &proto, WiFiSettings &settings) {
|
||||||
public:
|
settings = proto;
|
||||||
std::string hostname;
|
|
||||||
bool priorityBySignalStrength;
|
|
||||||
std::vector<wifi_settings_t> wifiSettings;
|
|
||||||
static void read(WiFiSettings &settings, JsonVariant &root) {
|
|
||||||
root["hostname"] = settings.hostname.c_str();
|
|
||||||
root["priority_RSSI"] = settings.priorityBySignalStrength;
|
|
||||||
JsonArray wifiNetworks = root["wifi_networks"].to<JsonArray>();
|
|
||||||
for (const auto &wifi : settings.wifiSettings) {
|
|
||||||
JsonVariant wifiNetwork = wifiNetworks.add<JsonVariant>();
|
|
||||||
wifi.serialize(wifiNetwork);
|
|
||||||
}
|
|
||||||
ESP_LOGV("WiFiSettings", "WiFi Settings read");
|
|
||||||
}
|
|
||||||
static StateUpdateResult update(JsonVariant &root, WiFiSettings &settings) {
|
|
||||||
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
|
|
||||||
settings.priorityBySignalStrength = root["priority_RSSI"] | true;
|
|
||||||
settings.wifiSettings.clear();
|
|
||||||
if (root["wifi_networks"].is<JsonArray>()) {
|
|
||||||
JsonArray wifiNetworks = root["wifi_networks"];
|
|
||||||
int networkCount = 0;
|
|
||||||
for (JsonVariant wifiNetwork : wifiNetworks) {
|
|
||||||
if (networkCount >= 5) {
|
|
||||||
ESP_LOGE("WiFiSettings", "Too many wifi networks");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wifi_settings_t newSettings;
|
|
||||||
if (newSettings.deserialize(wifiNetwork)) {
|
|
||||||
settings.wifiSettings.push_back(newSettings);
|
|
||||||
networkCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (std::string(FACTORY_WIFI_SSID).length() > 0) {
|
|
||||||
ESP_LOGI("WiFiSettings", "No WiFi config found - using factory settings");
|
|
||||||
settings.wifiSettings.push_back(createDefaultWiFiSettings());
|
|
||||||
}
|
|
||||||
ESP_LOGV("WiFiSettings", "WiFi Settings updated");
|
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
@@ -3,15 +3,18 @@
|
|||||||
#include <esp_http_server.h>
|
#include <esp_http_server.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <filesystem.h>
|
#include <filesystem.h>
|
||||||
#include <utils/timing.h>
|
#include <utils/timing.h>
|
||||||
#include <template/stateful_service.h>
|
#include <template/stateful_service.h>
|
||||||
#include <template/stateful_persistence.h>
|
#include <template/stateful_persistence_pb.h>
|
||||||
#include <template/stateful_endpoint.h>
|
#include <template/stateful_proto_endpoint.h>
|
||||||
#include <settings/wifi_settings.h>
|
#include <settings/wifi_settings.h>
|
||||||
|
|
||||||
|
#define WIFI_SETTINGS_FILE "/config/wifiSettings.pb"
|
||||||
|
|
||||||
class WiFiService : public StatefulService<WiFiSettings> {
|
class WiFiService : public StatefulService<WiFiSettings> {
|
||||||
private:
|
private:
|
||||||
static void getNetworks(JsonObject &root);
|
static void getNetworks(JsonObject &root);
|
||||||
@@ -20,12 +23,12 @@ class WiFiService : public StatefulService<WiFiSettings> {
|
|||||||
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
|
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
|
|
||||||
FSPersistence<WiFiSettings> _persistence;
|
FSPersistencePB<WiFiSettings> _persistence;
|
||||||
|
|
||||||
void reconfigureWiFiConnection();
|
void reconfigureWiFiConnection();
|
||||||
void manageSTA();
|
void manageSTA();
|
||||||
void connectToWiFi();
|
void connectToWiFi();
|
||||||
void configureNetwork(wifi_settings_t &network);
|
void configureNetwork(WiFiNetwork &network);
|
||||||
|
|
||||||
unsigned long _lastConnectionAttempt;
|
unsigned long _lastConnectionAttempt;
|
||||||
bool _stopping;
|
bool _stopping;
|
||||||
@@ -41,11 +44,11 @@ class WiFiService : public StatefulService<WiFiSettings> {
|
|||||||
|
|
||||||
void setupMDNS(const char *hostname);
|
void setupMDNS(const char *hostname);
|
||||||
|
|
||||||
const char *getHostname() { return state().hostname.c_str(); }
|
const char *getHostname() { return state().hostname; }
|
||||||
|
|
||||||
static esp_err_t handleScan(httpd_req_t *request);
|
static esp_err_t handleScan(httpd_req_t *request);
|
||||||
static esp_err_t getNetworks(httpd_req_t *request);
|
static esp_err_t getNetworks(httpd_req_t *request);
|
||||||
static esp_err_t getNetworkStatus(httpd_req_t *request);
|
static esp_err_t getNetworkStatus(httpd_req_t *request);
|
||||||
|
|
||||||
StatefulHttpEndpoint<WiFiSettings> endpoint;
|
StatefulProtoEndpoint<WiFiSettings, api_WifiSettings> protoEndpoint;
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-5
@@ -65,11 +65,10 @@ void setupServer() {
|
|||||||
return servoController.protoEndpoint.handleStateUpdate(request, protoReq);
|
return servoController.protoEndpoint.handleStateUpdate(request, protoReq);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: REMAKE TO PROTO
|
|
||||||
server.on("/api/wifi/sta/settings", HTTP_GET,
|
server.on("/api/wifi/sta/settings", HTTP_GET,
|
||||||
[&](httpd_req_t *request) { return wifiService.endpoint.getState(request); });
|
[&](httpd_req_t *request) { return wifiService.protoEndpoint.getState(request); });
|
||||||
server.on("/api/wifi/sta/settings", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
server.onProto("/api/wifi/sta/settings", HTTP_POST, [&](httpd_req_t *request, api_Request *protoReq) {
|
||||||
return wifiService.endpoint.handleStateUpdate(request, json);
|
return wifiService.protoEndpoint.handleStateUpdate(request, protoReq);
|
||||||
});
|
});
|
||||||
server.on("/api/wifi/scan", HTTP_GET, [&](httpd_req_t *request) { return wifiService.handleScan(request); });
|
server.on("/api/wifi/scan", HTTP_GET, [&](httpd_req_t *request) { return wifiService.handleScan(request); });
|
||||||
server.on("/api/wifi/networks", HTTP_GET, [&](httpd_req_t *request) { return wifiService.getNetworks(request); });
|
server.on("/api/wifi/networks", HTTP_GET, [&](httpd_req_t *request) { return wifiService.getNetworks(request); });
|
||||||
@@ -102,7 +101,6 @@ void setupServer() {
|
|||||||
[&](httpd_req_t *request, JsonVariant &json) { return mdnsService.queryServices(request, json); });
|
[&](httpd_req_t *request, JsonVariant &json) { return mdnsService.queryServices(request, json); });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: REMAKE TO PROTO
|
|
||||||
server.on("/api/config/*", HTTP_GET, [](httpd_req_t *request) { return FileSystem::getConfigFile(request); });
|
server.on("/api/config/*", HTTP_GET, [](httpd_req_t *request) { return FileSystem::getConfigFile(request); });
|
||||||
server.on("/api/files", HTTP_GET, [&](httpd_req_t *request) { return FileSystem::getFilesProto(request); });
|
server.on("/api/files", HTTP_GET, [&](httpd_req_t *request) { return FileSystem::getFilesProto(request); });
|
||||||
PROTO_ENDPOINT(server, "/api/files/delete", file_delete_request, FileSystem::handleDelete);
|
PROTO_ENDPOINT(server, "/api/files/delete", file_delete_request, FileSystem::handleDelete);
|
||||||
|
|||||||
+32
-27
@@ -2,8 +2,11 @@
|
|||||||
#include <communication/webserver.h>
|
#include <communication/webserver.h>
|
||||||
|
|
||||||
WiFiService::WiFiService()
|
WiFiService::WiFiService()
|
||||||
: _persistence(WiFiSettings::read, WiFiSettings::update, this, WIFI_SETTINGS_FILE),
|
: _persistence(WiFiSettings_read, WiFiSettings_update, this, WIFI_SETTINGS_FILE,
|
||||||
endpoint(WiFiSettings::read, WiFiSettings::update, this) {
|
api_WifiSettings_fields, api_WifiSettings_size, WiFiSettings_defaults()),
|
||||||
|
protoEndpoint(WiFiSettings_read, WiFiSettings_update, this,
|
||||||
|
API_REQUEST_EXTRACTOR(wifi_settings, api_WifiSettings),
|
||||||
|
API_RESPONSE_ASSIGNER(wifi_settings, api_WifiSettings)) {
|
||||||
addUpdateHandler([&](const std::string &originId) { reconfigureWiFiConnection(); }, false);
|
addUpdateHandler([&](const std::string &originId) { reconfigureWiFiConnection(); }, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,8 +28,8 @@ void WiFiService::begin() {
|
|||||||
_persistence.readFromFS();
|
_persistence.readFromFS();
|
||||||
reconfigureWiFiConnection();
|
reconfigureWiFiConnection();
|
||||||
|
|
||||||
if (state().wifiSettings.size() == 1) {
|
if (state().wifi_networks_count == 1) {
|
||||||
configureNetwork(state().wifiSettings[0]);
|
configureNetwork(state().wifi_networks[0]);
|
||||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +67,7 @@ esp_err_t WiFiService::getNetworks(httpd_req_t *request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::setupMDNS(const char *hostname) {
|
void WiFiService::setupMDNS(const char *hostname) {
|
||||||
MDNS.begin(state().hostname.c_str());
|
MDNS.begin(state().hostname);
|
||||||
MDNS.setInstanceName(hostname);
|
MDNS.setInstanceName(hostname);
|
||||||
MDNS.addService("http", "tcp", 80);
|
MDNS.addService("http", "tcp", 80);
|
||||||
MDNS.addService("ws", "tcp", 80);
|
MDNS.addService("ws", "tcp", 80);
|
||||||
@@ -115,15 +118,11 @@ void WiFiService::getNetworkStatus(JsonObject &root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::manageSTA() {
|
void WiFiService::manageSTA() {
|
||||||
if (WiFi.isConnected() || state().wifiSettings.empty()) return;
|
if (WiFi.isConnected() || state().wifi_networks_count == 0) return;
|
||||||
if ((WiFi.getMode() & WIFI_STA) == 0) connectToWiFi();
|
if ((WiFi.getMode() & WIFI_STA) == 0) connectToWiFi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::connectToWiFi() {
|
void WiFiService::connectToWiFi() {
|
||||||
for (auto &network : state().wifiSettings) {
|
|
||||||
network.available = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int scanResult = WiFi.scanNetworks();
|
int scanResult = WiFi.scanNetworks();
|
||||||
if (scanResult == WIFI_SCAN_FAILED) {
|
if (scanResult == WIFI_SCAN_FAILED) {
|
||||||
ESP_LOGE("WiFiSettingsService", "WiFi scan failed.");
|
ESP_LOGE("WiFiSettingsService", "WiFi scan failed.");
|
||||||
@@ -132,7 +131,7 @@ void WiFiService::connectToWiFi() {
|
|||||||
} else {
|
} else {
|
||||||
ESP_LOGI("WiFiSettingsService", "%d networks found.", scanResult);
|
ESP_LOGI("WiFiSettingsService", "%d networks found.", scanResult);
|
||||||
|
|
||||||
wifi_settings_t *bestNetwork = nullptr;
|
WiFiNetwork *bestNetwork = nullptr;
|
||||||
int32_t bestNetworkDb = FACTORY_WIFI_RSSI_THRESHOLD;
|
int32_t bestNetworkDb = FACTORY_WIFI_RSSI_THRESHOLD;
|
||||||
|
|
||||||
for (int i = 0; i < scanResult; ++i) {
|
for (int i = 0; i < scanResult; ++i) {
|
||||||
@@ -144,10 +143,11 @@ void WiFiService::connectToWiFi() {
|
|||||||
|
|
||||||
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
|
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
|
||||||
|
|
||||||
for (auto &network : state().wifiSettings) {
|
for (pb_size_t j = 0; j < state().wifi_networks_count; j++) {
|
||||||
if (ssid_scan == network.ssid.c_str()) {
|
WiFiNetwork &network = state().wifi_networks[j];
|
||||||
|
if (ssid_scan == network.ssid) {
|
||||||
if (rssi_scan >= FACTORY_WIFI_RSSI_THRESHOLD) {
|
if (rssi_scan >= FACTORY_WIFI_RSSI_THRESHOLD) {
|
||||||
network.available = true;
|
// Network is available
|
||||||
}
|
}
|
||||||
if (rssi_scan > bestNetworkDb) {
|
if (rssi_scan > bestNetworkDb) {
|
||||||
bestNetworkDb = rssi_scan;
|
bestNetworkDb = rssi_scan;
|
||||||
@@ -157,18 +157,22 @@ void WiFiService::connectToWiFi() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state().priorityBySignalStrength) {
|
if (!state().priority_rssi) {
|
||||||
for (auto &network : state().wifiSettings) {
|
for (pb_size_t j = 0; j < state().wifi_networks_count; j++) {
|
||||||
if (network.available == true) {
|
WiFiNetwork &network = state().wifi_networks[j];
|
||||||
ESP_LOGI("WiFiSettingsService", "Connecting to first available network: %s", network.ssid.c_str());
|
// Check if this network was found in scan
|
||||||
|
for (int i = 0; i < scanResult; ++i) {
|
||||||
|
if (WiFi.SSID(i) == network.ssid) {
|
||||||
|
ESP_LOGI("WiFiSettingsService", "Connecting to first available network: %s", network.ssid);
|
||||||
configureNetwork(network);
|
configureNetwork(network);
|
||||||
break;
|
WiFi.scanDelete();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (state().priorityBySignalStrength && bestNetwork) {
|
}
|
||||||
ESP_LOGI("WiFiSettingsService", "Connecting to strongest network: %s", bestNetwork->ssid.c_str());
|
} else if (bestNetwork) {
|
||||||
|
ESP_LOGI("WiFiSettingsService", "Connecting to strongest network: %s", bestNetwork->ssid);
|
||||||
configureNetwork(*bestNetwork);
|
configureNetwork(*bestNetwork);
|
||||||
WiFi.begin(bestNetwork->ssid.c_str(), bestNetwork->password.c_str());
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI("WiFiSettingsService", "No known networks found.");
|
ESP_LOGI("WiFiSettingsService", "No known networks found.");
|
||||||
}
|
}
|
||||||
@@ -177,15 +181,16 @@ void WiFiService::connectToWiFi() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::configureNetwork(wifi_settings_t &network) {
|
void WiFiService::configureNetwork(WiFiNetwork &network) {
|
||||||
if (network.staticIPConfig) {
|
if (network.static_ip_config) {
|
||||||
WiFi.config(network.localIP, network.gatewayIP, network.subnetMask, network.dnsIP1, network.dnsIP2);
|
WiFi.config(IPAddress(network.local_ip), IPAddress(network.gateway_ip),
|
||||||
|
IPAddress(network.subnet_mask), IPAddress(network.dns_ip_1), IPAddress(network.dns_ip_2));
|
||||||
} else {
|
} else {
|
||||||
WiFi.config(IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0));
|
WiFi.config(IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
WiFi.setHostname(state().hostname.c_str());
|
WiFi.setHostname(state().hostname);
|
||||||
|
|
||||||
WiFi.begin(network.ssid.c_str(), network.password.c_str());
|
WiFi.begin(network.ssid, network.password);
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||||
|
|||||||
@@ -18,3 +18,8 @@ api.FileEditRequest.path max_size:128
|
|||||||
api.FileEditRequest.content type:FT_POINTER
|
api.FileEditRequest.content type:FT_POINTER
|
||||||
|
|
||||||
api.FileMkdirRequest.path max_size:128
|
api.FileMkdirRequest.path max_size:128
|
||||||
|
|
||||||
|
api.WifiNetwork.ssid max_size:33
|
||||||
|
api.WifiNetwork.password max_size:65
|
||||||
|
api.WifiSettings.hostname max_size:33
|
||||||
|
api.WifiSettings.wifi_networks max_count:5
|
||||||
|
|||||||
@@ -63,6 +63,29 @@ message ServoSettings {
|
|||||||
|
|
||||||
message ServoSettingsRequest {}
|
message ServoSettingsRequest {}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// WiFi STA Settings - shared data types
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
message WifiNetwork {
|
||||||
|
string ssid = 1;
|
||||||
|
string password = 2;
|
||||||
|
bool static_ip_config = 3;
|
||||||
|
uint32 local_ip = 4;
|
||||||
|
uint32 gateway_ip = 5;
|
||||||
|
uint32 subnet_mask = 6;
|
||||||
|
uint32 dns_ip_1 = 7;
|
||||||
|
uint32 dns_ip_2 = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WifiSettings {
|
||||||
|
string hostname = 1;
|
||||||
|
bool priority_rssi = 2;
|
||||||
|
repeated WifiNetwork wifi_networks = 3; // max 5 networks
|
||||||
|
}
|
||||||
|
|
||||||
|
message WifiSettingsRequest {}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// File System - shared data types
|
// File System - shared data types
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -109,6 +132,8 @@ message Request {
|
|||||||
FileDeleteRequest file_delete_request = 31;
|
FileDeleteRequest file_delete_request = 31;
|
||||||
FileEditRequest file_edit_request = 32;
|
FileEditRequest file_edit_request = 32;
|
||||||
FileMkdirRequest file_mkdir_request = 33;
|
FileMkdirRequest file_mkdir_request = 33;
|
||||||
|
WifiSettings wifi_settings = 40;
|
||||||
|
WifiSettingsRequest wifi_settings_request = 41;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,5 +148,6 @@ message Response {
|
|||||||
APStatus ap_status = 11;
|
APStatus ap_status = 11;
|
||||||
ServoSettings servo_settings = 20;
|
ServoSettings servo_settings = 20;
|
||||||
FileList file_list = 30;
|
FileList file_list = 30;
|
||||||
|
WifiSettings wifi_settings = 40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user