device matching via mac instead of ip address

This commit is contained in:
Luca Haid
2026-01-26 12:20:52 +01:00
parent 4b206f0696
commit 5ca7fa29c6
4 changed files with 113 additions and 13 deletions

View File

@@ -218,6 +218,69 @@ class RadiusController extends mfBaseController {
}
}
protected function genieacsGetDeviceByMacAction() {
try {
$mac = $_GET['mac'] ?? null;
$this->log->debug("genieacsGetDeviceByMacAction", ['mac' => $mac]);
if (!$mac) self::sendError("MAC address is required");
$acs = $this->getGenieACS();
$matchedDevice = $acs->getDeviceByMac($mac);
if (!$matchedDevice) {
self::returnJson(['success' => false, 'message' => 'No device found with this MAC address']);
return;
}
self::returnJson([
'success' => true,
'deviceId' => GenieACS::getDeviceId($matchedDevice),
'deviceInfo' => GenieACS::getDeviceInfo($matchedDevice),
'mac' => $mac,
'externalIp' => GenieACS::getExternalIP($matchedDevice),
'managementIp' => GenieACS::getManagementIP($matchedDevice)
]);
} catch (Exception $e) {
$this->log->debug("GetDeviceByMac Error", ['error' => $e->getMessage()]);
self::sendError("Error fetching device: " . $e->getMessage());
}
}
protected function genieacsRefreshDeviceAction() {
try {
$input = json_decode(file_get_contents('php://input'), true);
$deviceId = $input['deviceId'] ?? null;
$this->log->debug("genieacsRefreshDeviceAction", ['deviceId' => $deviceId]);
if (!$deviceId) self::sendError("Device ID is required");
$acs = $this->getGenieACS();
$acs->getParameterValues($deviceId, [
'InternetGatewayDevice.DeviceInfo.HardwareVersion',
'InternetGatewayDevice.DeviceInfo.SoftwareVersion',
'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.*.MACAddress',
'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.*.ExternalIPAddress',
'InternetGatewayDevice.LANDevice.*.WLANConfiguration.*.SSID',
'InternetGatewayDevice.LANDevice.*.WLANConfiguration.*.KeyPassphrase',
'InternetGatewayDevice.LANDevice.*.Hosts.Host.*.HostName',
'InternetGatewayDevice.LANDevice.*.Hosts.Host.*.IPAddress',
'InternetGatewayDevice.LANDevice.*.Hosts.Host.*.MACAddress'
]);
$device = $acs->getDevice($deviceId);
self::returnJson([
'success' => true,
'deviceInfo' => GenieACS::getDeviceInfo($device),
'externalIp' => GenieACS::getExternalIP($device),
'managementIp' => GenieACS::getManagementIP($device)
]);
} catch (Exception $e) {
$this->log->debug("RefreshDevice Error", ['error' => $e->getMessage()]);
self::sendError("Error refreshing device: " . $e->getMessage());
}
}
protected function genieacsRebootDeviceAction() {
try {
$input = json_decode(file_get_contents('php://input'), true);

View File

@@ -106,6 +106,24 @@ class GenieACS {
return $this->_request('GET', '/api/devices');
}
public function getDeviceByMac($mac) {
$mac = strtolower(preg_replace('/[^A-Fa-f0-9]/', '', $mac));
$mac = implode(':', str_split($mac, 2));
$paths = [
'InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress',
'InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.2.MACAddress',
];
foreach ($paths as $path) {
$filter = urlencode($path . ' = "' . $mac . '"');
$result = $this->_request('GET', '/api/devices/?filter=' . $filter . '&limit=1');
if ($result && is_array($result) && count($result) > 0) return $result[0];
}
return null;
}
public function getDevice($deviceId) {
return $this->_request('GET', '/api/devices/' . rawurlencode($deviceId));
}

View File

@@ -228,8 +228,10 @@
/* Router Management Modal */
.tt-scope .router-info-header { display: flex; align-items: center; gap: 12px; padding: 20px 24px; margin: -14px -24px 12px -16px; background: linear-gradient(135deg, #e3f0f8 0%, #cce4f5 100%); border-bottom: 2px solid #b8d9f0; }
.tt-scope .router-info-header i { font-size: 28px; color: var(--accent); flex-shrink: 0; }
.tt-scope .router-info-header > i { font-size: 28px; color: var(--accent); flex-shrink: 0; }
.tt-scope .router-header-text { flex-grow: 1; min-height: 39px; }
.tt-scope .refresh-btn { padding: 8px; border-radius: 6px; flex-shrink: 0; }
.tt-scope .refresh-btn i { font-size: 16px; margin: 0; }
.tt-scope .router-title { font-size: 16px; font-weight: 800; color: var(--text); letter-spacing: 0.3px; line-height: 1.375; }
.tt-scope .router-subtitle { font-size: 12px; color: var(--muted); font-family: var(--mono); margin-top: 2px; line-height: 1.25; }
.tt-scope .router-info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 16px; margin-right: -8px; }

View File

@@ -32,6 +32,9 @@ const RadiusRouterManager = {
<span v-else>{{ routerDevice.username || userItem.username }}</span>
</div>
</div>
<button class="ghost-btn refresh-btn" @click="refreshDevice" :disabled="routerLoading || refreshLoading" title="Daten aktualisieren">
<i class="fa-duotone fa-arrows-rotate" :class="{ 'fa-spin': refreshLoading }"></i>
</button>
</div>
<!-- Router Information Grid -->
@@ -40,7 +43,7 @@ const RadiusRouterManager = {
<tt-info-card icon="fa-code-branch" label="Software Version" :value="routerDevice?.deviceInfo?.softwareVersion" :loading="routerLoading" />
<tt-info-card icon="fa-barcode" label="CWMP Account" :value="routerDevice?.deviceInfo?.serialNumber" :loading="routerLoading" />
<tt-info-card icon="fa-fingerprint" label="ACS ID" :value="routerDevice?.deviceId" :loading="routerLoading" />
<tt-info-card icon="fa-globe" label="Externe IP" :value="routerDevice?.ip" :loading="routerLoading" />
<tt-info-card icon="fa-globe" label="Externe IP" :value="routerDevice?.externalIp" :loading="routerLoading" />
<tt-info-card icon="fa-network-wired" label="Management IP" :value="routerDevice?.managementIp" :loading="routerLoading" />
</div>
@@ -239,7 +242,8 @@ const RadiusRouterManager = {
showEventLogModal: false,
eventLogLoading: false,
eventLogData: null
eventLogData: null,
refreshLoading: false
}),
watch: {
show: {
@@ -265,18 +269,12 @@ const RadiusRouterManager = {
this.speedtestLoading = false;
try {
const { data: radacct } = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Radius/proxyUnsecureHTTPRequestToRadius`, {
params: { action2: 'fetchRadacct', username: this.userItem.username }
const { data: deviceData } = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Radius/genieacsGetDeviceByMac`, {
params: { mac: this.userItem.username }
});
if (radacct?.ip) {
const { data: deviceData } = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Radius/genieacsGetDeviceByIp`, {
params: { ip: radacct.ip }
});
if (deviceData?.success) {
this.routerDevice = deviceData;
}
if (deviceData?.success) {
this.routerDevice = deviceData;
}
} catch (error) {
console.error('Error fetching router:', error);
@@ -284,6 +282,25 @@ const RadiusRouterManager = {
}
this.routerLoading = false;
},
async refreshDevice() {
if (!this.routerDevice?.deviceId) return;
this.refreshLoading = true;
try {
const { data } = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Radius/genieacsRefreshDevice`, {
deviceId: this.routerDevice.deviceId
});
if (data?.success) {
this.routerDevice.deviceInfo = data.deviceInfo;
this.routerDevice.externalIp = data.externalIp;
this.routerDevice.managementIp = data.managementIp;
window.notify('success', 'Daten aktualisiert');
}
} catch (error) {
console.error('Error refreshing device:', error);
window.notify('error', 'Fehler beim Aktualisieren');
}
this.refreshLoading = false;
},
async rebootRouter() {
if (!this.routerDevice || !this.routerDevice.deviceId) return;
if (!confirm('Möchten Sie den Router wirklich neu starten?')) return;