mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Merge pull request #2254 from cesanta/2249-implement-connected-devices-page-for-wifi-router-dashboard
implemented connected devices page
This commit is contained in:
commit
d013e0fc78
@ -20,6 +20,46 @@ struct event {
|
||||
const char *text;
|
||||
};
|
||||
|
||||
// Connected Devices
|
||||
struct device {
|
||||
char *dev_name;
|
||||
char *mac;
|
||||
char *ip_addr;
|
||||
int speed;
|
||||
char *connected_to;
|
||||
int lease_time_left;
|
||||
char *last_seen;
|
||||
};
|
||||
|
||||
static struct device s_devices[] = {
|
||||
{ .dev_name = "espressif",
|
||||
.mac = "02:11:22:33:44:55",
|
||||
.ip_addr = "192.168.1.1/24",
|
||||
.speed = 1000,
|
||||
.connected_to = "Ethernet",
|
||||
.lease_time_left = 1000,
|
||||
.last_seen = "13h20m ago"
|
||||
},
|
||||
|
||||
{ .dev_name = "windows11",
|
||||
.mac = "01:22:11:44:33:55",
|
||||
.ip_addr = "192.168.1.2/24",
|
||||
.speed = 200,
|
||||
.connected_to = "Wifi 2.4 GHz",
|
||||
.lease_time_left = 4141,
|
||||
.last_seen = "23s ago"
|
||||
},
|
||||
|
||||
{ .dev_name = "iRobot-2",
|
||||
.mac = "01:22:11:44:33:42",
|
||||
.ip_addr = "192.168.1.3/24",
|
||||
.speed = 600,
|
||||
.connected_to = "Wifi 5GHz",
|
||||
.lease_time_left = 1141,
|
||||
.last_seen = "20m ago"
|
||||
}
|
||||
};
|
||||
|
||||
// DHCP configuration
|
||||
struct dhcp {
|
||||
bool enabled;
|
||||
@ -184,6 +224,33 @@ static void handle_events_get(struct mg_connection *c) {
|
||||
mg_http_reply(c, 200, s_json_header, "[%M]", print_events);
|
||||
}
|
||||
|
||||
static void handle_devices_get(struct mg_connection *c) {
|
||||
char test_json[1024];
|
||||
int nr_devs = sizeof(s_devices) / sizeof(struct device);
|
||||
memset(test_json, 0, sizeof(test_json));
|
||||
test_json[0] = '[';
|
||||
for (int i = 0; i < nr_devs; i++) {
|
||||
size_t current_length = strlen(test_json);
|
||||
|
||||
mg_snprintf(test_json + current_length, sizeof(test_json) - current_length,
|
||||
"{%m:\"%s\",%m:\"%s\", %m:\"%s\", %m:%d,%m:\"%s\",%m:%d,%m:\"%s\"}", //
|
||||
MG_ESC("dev_name"), s_devices[i].dev_name, //
|
||||
MG_ESC("mac"), s_devices[i].mac, //
|
||||
MG_ESC("ip"), s_devices[i].ip_addr, //
|
||||
MG_ESC("speed"), s_devices[i].speed, //
|
||||
MG_ESC("connected_to"), s_devices[i].connected_to, //
|
||||
MG_ESC("lease_time_left"), s_devices[i].lease_time_left, //
|
||||
MG_ESC("last_seen"), s_devices[i].last_seen);
|
||||
|
||||
if (i < nr_devs - 1) {
|
||||
strncat(test_json, ",", sizeof(test_json) - strlen(test_json) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
strncat(test_json, "]", sizeof(test_json) - strlen(test_json) - 1);
|
||||
mg_http_reply(c, 200, s_json_header, "%s", test_json);
|
||||
}
|
||||
|
||||
static void handle_dhcp_set(struct mg_connection *c, struct mg_str body) {
|
||||
struct dhcp dhcp;
|
||||
memset(&dhcp, 0, sizeof(dhcp));
|
||||
@ -228,6 +295,8 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
handle_stats_get(c);
|
||||
} else if (mg_http_match_uri(hm, "/api/events/get")) {
|
||||
handle_events_get(c);
|
||||
} else if (mg_http_match_uri(hm, "/api/devices/get")) {
|
||||
handle_devices_get(c);
|
||||
} else if (mg_http_match_uri(hm, "/api/dhcp/get")) {
|
||||
handle_dhcp_get(c);
|
||||
} else if (mg_http_match_uri(hm, "/api/dhcp/set")) {
|
||||
|
File diff suppressed because one or more lines are too long
@ -179,6 +179,60 @@ function Main({}) {
|
||||
<//>`;
|
||||
};
|
||||
|
||||
function Devices({}) {
|
||||
const [devices, setDevices] = useState(null);
|
||||
const refresh = () => fetch('api/devices/get')
|
||||
.then(r => r.json())
|
||||
.then(r => setDevices(r));
|
||||
useEffect(refresh, []);
|
||||
|
||||
const th = props => html`<th scope="col" class="sticky top-0 z-10 border-b border-slate-300 bg-white bg-opacity-75 py-1.5 px-4 text-left text-sm font-semibold text-slate-900 backdrop-blur backdrop-filter">${props.title}</th>`;
|
||||
const td = props => html`<td class="whitespace-nowrap border-b border-slate-200 py-2 px-4 pr-3 text-sm text-slate-900">${props.text}</td>`;
|
||||
|
||||
const Device = ({d}) => html`
|
||||
<tr>
|
||||
<${td} text=${d.dev_name} />
|
||||
<${td} text=${d.mac} />
|
||||
<${td} text=${d.ip} />
|
||||
<${td} text=${d.speed} />
|
||||
<${td} text=${d.connected_to} />
|
||||
<${td} text=${d.lease_time_left} />
|
||||
<${td} text=${d.last_seen} />
|
||||
<//>`;
|
||||
|
||||
if (!devices) return '';
|
||||
return html`
|
||||
<div class="flex flex-col p-6 bg-gray-50 dark:bg-gray-900">
|
||||
<div class="overflow-x-auto shadow-xl rounded-xl bg-white dark:bg-gray-800 p-6">
|
||||
|
||||
<div class="flex justify-end mb-4">
|
||||
<${Button} title="Refresh" icon=${Icons.refresh} onclick=${refresh} />
|
||||
</div>
|
||||
|
||||
<div class="align-middle inline-block w-full">
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700 text-sm md:text-base lg:text-lg">
|
||||
<thead class="bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300">
|
||||
<tr>
|
||||
<${th} title="Device Name" />
|
||||
<${th} title="MAC address" />
|
||||
<${th} title="IP address" />
|
||||
<${th} title="Speed (Mbps)" />
|
||||
<${th} title="Connected to" />
|
||||
<${th} title="Lease time left" />
|
||||
<${th} title="Last seen" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200">
|
||||
${devices.map(d => h(Device, {d}))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
};
|
||||
|
||||
function DHCP({}) {
|
||||
const [dhcp, setDhcp] = useState(null);
|
||||
const [saveResult, setSaveResult] = useState(null);
|
||||
@ -240,6 +294,7 @@ const App = function({}) {
|
||||
<${Router} onChange=${ev => setUrl(ev.url)} history=${History.createHashHistory()} >
|
||||
<${Main} default=${true} />
|
||||
<${DHCP} path="dhcp" />
|
||||
<${Devices} path="devices" />
|
||||
<//>
|
||||
<//>
|
||||
<//>`;
|
||||
|
Loading…
Reference in New Issue
Block a user