Merge pull request #2254 from cesanta/2249-implement-connected-devices-page-for-wifi-router-dashboard

implemented connected devices page
This commit is contained in:
Sergey Lyubka 2023-06-14 11:17:06 +01:00 committed by GitHub
commit d013e0fc78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 125 additions and 1 deletions

View File

@ -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

View File

@ -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" />
<//>
<//>
<//>`;