Ap settngs post working, error msg on response

This commit is contained in:
Niklas Jensen
2026-01-24 11:24:09 +01:00
committed by nikguin04
parent ae4a2fe115
commit d5af8d0294
6 changed files with 39 additions and 33 deletions
+12 -3
View File
@@ -2,7 +2,8 @@ import { get } from 'svelte/store'
import { Err, Ok, type Result } from './utilities' import { Err, Ok, type Result } from './utilities'
import { apiLocation } from './stores/location-store' import { apiLocation } from './stores/location-store'
import type { MessageFns } from './platform_shared/filesystem' import type { MessageFns } from './platform_shared/filesystem'
import { Response } from './platform_shared/api' import { Request, Response } from './platform_shared/api'
import { BinaryWriter } from '@bufbuild/protobuf/wire'
export const api = { export const api = {
get<TResponse>(endpoint: string, params?: RequestInit) { get<TResponse>(endpoint: string, params?: RequestInit) {
@@ -13,6 +14,10 @@ export const api = {
return sendRequest<TResponse>(endpoint, 'POST', data) return sendRequest<TResponse>(endpoint, 'POST', data)
}, },
post_proto<TResponse>(endpoint: string, data: Request) {
return sendRequest<TResponse>(endpoint, 'POST', Request.encode(data))
},
put<TResponse>(endpoint: string, data?: unknown) { put<TResponse>(endpoint: string, data?: unknown) {
return sendRequest<TResponse>(endpoint, 'PUT', data) return sendRequest<TResponse>(endpoint, 'PUT', data)
}, },
@@ -29,7 +34,11 @@ async function sendRequest<TResponse>(
params?: RequestInit params?: RequestInit
): Promise<Result<TResponse, Error>> { ): Promise<Result<TResponse, Error>> {
endpoint = resolveUrl(endpoint) endpoint = resolveUrl(endpoint)
const body = data !== null && typeof data !== 'undefined' ? JSON.stringify(data) : undefined
const isProtobuf = data instanceof BinaryWriter
const body = data !== null && typeof data !== 'undefined'
? (isProtobuf ? data.finish() : JSON.stringify(data))
: undefined
const request = { const request = {
...params, ...params,
@@ -38,7 +47,7 @@ async function sendRequest<TResponse>(
headers: { headers: {
...params?.headers, ...params?.headers,
Authorization: 'Basic', Authorization: 'Basic',
'Content-Type': 'application/json' 'Content-Type': isProtobuf ? 'application/x-protobuf' : 'application/json'
} }
} }
-12
View File
@@ -71,18 +71,6 @@ export type NetworkItem = {
encryption_type: number encryption_type: number
} }
export type ApSettings = {
provision_mode: number
ssid: string
password: string
channel: number
ssid_hidden: boolean
max_clients: number
local_ip: number
gateway_ip: number
subnet_mask: number
}
export type Rssi = { export type Rssi = {
rssi: number rssi: number
ssid: string ssid: string
+23 -18
View File
@@ -6,15 +6,14 @@
import SettingsCard from '$lib/components/SettingsCard.svelte' import SettingsCard from '$lib/components/SettingsCard.svelte'
import { notifications } from '$lib/components/toasts/notifications' import { notifications } from '$lib/components/toasts/notifications'
import Spinner from '$lib/components/Spinner.svelte' import Spinner from '$lib/components/Spinner.svelte'
import { type ApSettings } from '$lib/types/models'
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 { AP, Devices, Home, MAC } from '$lib/components/icons' import { AP, Devices, Home, MAC } from '$lib/components/icons'
import StatusItem from '$lib/components/StatusItem.svelte' import StatusItem from '$lib/components/StatusItem.svelte'
import { APStatus, Response } from '$lib/platform_shared/api' import { APSettings, APStatus, Request, Response } from '$lib/platform_shared/api'
import { input } from '$lib/stores' import { input } from '$lib/stores'
let apSettings: ApSettings | null = $state(null) let apSettings: APSettings | null = $state(null)
let apStatus: APStatus | null = $state(null) let apStatus: APStatus | null = $state(null)
let ipDisplay = $state({ let ipDisplay = $state({
@@ -36,16 +35,16 @@
} }
async function getAPSettings() { async function getAPSettings() {
const result = await api.get<ApSettings>('/api/ap/settings') const result = await api.get<Response>('/api/ap/settings')
if (result.isErr()) { if (result.isErr()) {
console.error('Error:', result.inner) console.error('Error:', result.inner)
return return
} }
apSettings = result.inner apSettings = result.inner.apSettings!
ipDisplay = { ipDisplay = {
local_ip: uint32ToIp(apSettings.local_ip), local_ip: uint32ToIp(apSettings.localIp),
gateway_ip: uint32ToIp(apSettings.gateway_ip), gateway_ip: uint32ToIp(apSettings.gatewayIp),
subnet_mask: uint32ToIp(apSettings.subnet_mask) subnet_mask: uint32ToIp(apSettings.subnetMask)
} }
return apSettings return apSettings
} }
@@ -88,15 +87,21 @@
subnet_mask: false subnet_mask: false
}) })
async function postAPSettings(data: ApSettings) { async function postAPSettings(data: APSettings) {
const result = await api.post<ApSettings>('/api/ap/settings', data) const result = await api.post_proto<Response>('/api/ap/settings', Request.create({ apSettings: data }))
if (result.isErr()) { if (result.isErr()) {
notifications.error('User not authorized.', 3000) notifications.error('User not authorized.', 3000)
console.error('Error:', result.inner) console.error('Error:', result.inner)
return return
} }
if (result.inner.statusCode !== 200) {
notifications.error(result.inner.errorMessage || 'Failed to update settings', 3000)
return
}
if (result.inner.apSettings) {
apSettings = result.inner.apSettings
}
notifications.success('Access Point settings updated.', 3000) notifications.success('Access Point settings updated.', 3000)
apSettings = result.inner
} }
function handleSubmitAP(e: Event) { function handleSubmitAP(e: Event) {
@@ -119,7 +124,7 @@
formErrors.channel = false formErrors.channel = false
} }
let maxClients = Number(apSettings.max_clients) let maxClients = Number(apSettings.maxClients)
if (1 > maxClients || maxClients > 8) { if (1 > maxClients || maxClients > 8) {
valid = false valid = false
formErrors.max_clients = true formErrors.max_clients = true
@@ -149,9 +154,9 @@
} }
if (valid) { if (valid) {
apSettings.local_ip = ipToUint32(ipDisplay.local_ip) apSettings.localIp = ipToUint32(ipDisplay.local_ip)
apSettings.gateway_ip = ipToUint32(ipDisplay.gateway_ip) apSettings.gatewayIp = ipToUint32(ipDisplay.gateway_ip)
apSettings.subnet_mask = ipToUint32(ipDisplay.subnet_mask) apSettings.subnetMask = ipToUint32(ipDisplay.subnet_mask)
postAPSettings(apSettings) postAPSettings(apSettings)
} }
} }
@@ -225,7 +230,7 @@
<select <select
class="select select-bordered w-full" class="select select-bordered w-full"
id="apmode" id="apmode"
bind:value={apSettings.provision_mode} bind:value={apSettings.provisionMode}
> >
{#each provisionMode as mode (mode.id)} {#each provisionMode as mode (mode.id)}
<option value={mode.id}> <option value={mode.id}>
@@ -305,7 +310,7 @@
) ? ) ?
'border-error border-2' 'border-error border-2'
: ''}" : ''}"
bind:value={apSettings.max_clients} bind:value={apSettings.maxClients}
id="clients" id="clients"
required required
/> />
@@ -393,7 +398,7 @@
<label class="label my-auto cursor-pointer justify-start gap-4"> <label class="label my-auto cursor-pointer justify-start gap-4">
<input <input
type="checkbox" type="checkbox"
bind:checked={apSettings.ssid_hidden} bind:checked={apSettings.ssidHidden}
class="checkbox checkbox-primary" class="checkbox checkbox-primary"
/> />
<span class="">Hide SSID</span> <span class="">Hide SSID</span>
@@ -105,6 +105,7 @@ class StatefulProtoEndpoint {
esp_err_t sendErrorResponse(httpd_req_t* request, uint32_t statusCode, const char* message) { esp_err_t sendErrorResponse(httpd_req_t* request, uint32_t statusCode, const char* message) {
api_Response res = api_Response_init_zero; api_Response res = api_Response_init_zero;
res.status_code = statusCode; res.status_code = statusCode;
res.error_message = (char*)message;
return NativeServer::sendProto(request, statusCode == 200 ? 200 : 400, res, api_Response_fields); return NativeServer::sendProto(request, statusCode == 200 ? 200 : 400, res, api_Response_fields);
} }
}; };
+2
View File
@@ -2,3 +2,5 @@ api.APSettings.ssid max_size:33
api.APSettings.password max_size:64 api.APSettings.password max_size:64
api.APStatus.mac_address max_size:18 api.APStatus.mac_address max_size:18
api.Response.error_message type:FT_POINTER
+1
View File
@@ -59,6 +59,7 @@ message Request {
// Response wrapper for REST endpoints // Response wrapper for REST endpoints
message Response { message Response {
uint32 status_code = 1; uint32 status_code = 1;
string error_message = 2;
oneof payload { oneof payload {
APSettings ap_settings = 10; APSettings ap_settings = 10;