Render grouped mobile sensor sections

This commit is contained in:
seo
2026-06-12 15:30:53 +09:00
parent 4559301fa6
commit b8778427f7
4 changed files with 378 additions and 358 deletions
+70 -50
View File
@@ -36,6 +36,13 @@ if (isset($_GET['action']) && $_GET['action'] === 'webhook') {
$config = custom_config();
$entities = $config['entities'];
$allStates = custom_ha_request('seoul', 'GET', '/states') ?? [];
$stateMap = [];
foreach ($allStates as $stateRow) {
if (isset($stateRow['entity_id'])) {
$stateMap[$stateRow['entity_id']] = $stateRow;
}
}
// 엔드포인트 URL
$deviceUrl = $entities['device'];
@@ -72,7 +79,8 @@ $historyEndpoint = "/history/period/{$startTime}?filter_entity_id=" . rawurlenco
// 공통 요청 함수
function getData($entityId) {
return custom_ha_state('seoul', $entityId) ?? [];
global $stateMap;
return $stateMap[$entityId] ?? [];
}
function getEntityData($entities, $key) {
@@ -84,7 +92,7 @@ function getEntityData($entities, $key) {
function stateValue($data) {
$state = $data['state'] ?? null;
if ($state === null || $state === 'unknown' || $state === 'unavailable' || $state === '<not connected>' || $state === '<not available>') {
if ($state === null || $state === 'unknown' || $state === 'unavailable' || $state === '<not connected>' || $state === '<not available>' || $state === 'none') {
return null;
}
return $state;
@@ -103,6 +111,46 @@ function mappedText($state, $lang, $map) {
return $map[$lang][$state] ?? $map[$lang][strtolower((string)$state)] ?? $state;
}
function formatSensorValue($value, $definition, $lang, $maps) {
if ($value === null) return null;
if (($definition['format'] ?? '') === 'bool') {
return boolText($value, $lang);
}
if (($definition['format'] ?? '') === 'duration') {
if (!is_numeric($value)) return $value;
$seconds = (int)$value;
if ($seconds <= 0) return null;
$days = intdiv($seconds, 86400);
$seconds %= 86400;
$hours = intdiv($seconds, 3600);
$seconds %= 3600;
$minutes = intdiv($seconds, 60);
$seconds %= 60;
$parts = [];
if ($days) $parts[] = $days . 'd';
if ($hours) $parts[] = $hours . 'h';
if ($minutes) $parts[] = $minutes . 'm';
if ($seconds && !$days && !$hours) $parts[] = $seconds . 's';
return implode(' ', $parts) ?: null;
}
if (($definition['format'] ?? '') === 'datetime') {
return $value;
}
if (isset($definition['map'], $maps[$definition['map']])) {
$value = mappedText($value, $lang, $maps[$definition['map']]);
}
if (isset($definition['unit']) && is_numeric($value)) {
return $value . $definition['unit'];
}
return $value;
}
// 데이터 불러오기
$deviceData = getData($deviceUrl);
$geoData = getData($geoUrl);
@@ -116,27 +164,6 @@ $stepsData = getData($stepsUrl);
$distanceData = getData($distanceUrl);
$historyData = custom_ha_request('seoul', 'GET', $historyEndpoint) ?? [];
$triggerData = getData($triggerUrl);
$galaxyData = [
'isCharging' => getEntityData($entities, 'is_charging'),
'chargerType' => getEntityData($entities, 'charger_type'),
'batteryHealth' => getEntityData($entities, 'battery_health'),
'batteryTemperature' => getEntityData($entities, 'battery_temperature'),
'batteryPower' => getEntityData($entities, 'battery_power'),
'remainingChargeTime' => getEntityData($entities, 'remaining_charge_time'),
'batteryCycleCount' => getEntityData($entities, 'battery_cycle_count'),
'wifiConnection' => getEntityData($entities, 'wifi_connection'),
'wifiBssid' => getEntityData($entities, 'wifi_bssid'),
'wifiIp' => getEntityData($entities, 'wifi_ip'),
'wifiLinkSpeed' => getEntityData($entities, 'wifi_link_speed'),
'wifiFrequency' => getEntityData($entities, 'wifi_frequency'),
'wifiSignalStrength' => getEntityData($entities, 'wifi_signal_strength'),
'mobileData' => getEntityData($entities, 'mobile_data'),
'phoneState' => getEntityData($entities, 'phone_state'),
'interactive' => getEntityData($entities, 'interactive'),
'dozeMode' => getEntityData($entities, 'doze_mode'),
'powerSave' => getEntityData($entities, 'power_save'),
'deviceLocked' => getEntityData($entities, 'device_locked'),
];
// 경로 기록
$path = [];
@@ -293,31 +320,24 @@ if (($deviceData['state'] ?? null) !== 'not_home') {
$address = trim($locality . ' ' . ($geoData['attributes']['Name'] ?? ''));
}
$galaxy = [
'isCharging' => boolText(stateValue($galaxyData['isCharging']), $lang),
'chargerType' => mappedText(stateValue($galaxyData['chargerType']), $lang, $androidValueMap['chargerType']),
'batteryHealth' => mappedText(stateValue($galaxyData['batteryHealth']), $lang, $androidValueMap['batteryHealth']),
'batteryTemperature' => stateValue($galaxyData['batteryTemperature']),
'batteryPower' => stateValue($galaxyData['batteryPower']),
'remainingChargeTime' => stateValue($galaxyData['remainingChargeTime']),
'batteryCycleCount' => stateValue($galaxyData['batteryCycleCount']),
'wifiConnection' => stateValue($galaxyData['wifiConnection']),
'wifiBssid' => stateValue($galaxyData['wifiBssid']),
'wifiIp' => stateValue($galaxyData['wifiIp']),
'wifiLinkSpeed' => stateValue($galaxyData['wifiLinkSpeed']),
'wifiFrequency' => stateValue($galaxyData['wifiFrequency']),
'wifiSignalStrength' => stateValue($galaxyData['wifiSignalStrength']),
'mobileData' => boolText(stateValue($galaxyData['mobileData']), $lang),
'phoneState' => mappedText(stateValue($galaxyData['phoneState']), $lang, $androidValueMap['phoneState']),
'interactive' => boolText(stateValue($galaxyData['interactive']), $lang),
'dozeMode' => boolText(stateValue($galaxyData['dozeMode']), $lang),
'powerSave' => boolText(stateValue($galaxyData['powerSave']), $lang),
'deviceLocked' => boolText(stateValue($galaxyData['deviceLocked']), $lang),
];
if (!$galaxy['wifiConnection']) {
foreach (['wifiBssid', 'wifiIp', 'wifiLinkSpeed', 'wifiFrequency', 'wifiSignalStrength'] as $wifiKey) {
$galaxy[$wifiKey] = null;
$sensorSections = [];
$flatSensors = [];
foreach (($config['findmydevice_sensor_sections'] ?? []) as $sectionKey => $definitions) {
$sensorSections[$sectionKey] = [];
foreach ($definitions as $sensorKey => $definition) {
if (!empty($definition['requires']) && empty($flatSensors[$definition['requires']])) {
continue;
}
$raw = stateValue(getData($definition['entity']));
$value = formatSensorValue($raw, $definition, $lang, $androidValueMap);
if ($value === null || $value === '') {
continue;
}
$sensorSections[$sectionKey][$sensorKey] = $value;
$flatSensors[$sensorKey] = $value;
}
if (!$sensorSections[$sectionKey]) {
unset($sensorSections[$sectionKey]);
}
}
@@ -339,7 +359,7 @@ if (isset($_GET['hashonly']) && $_GET['hashonly'] == '1') {
'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null,
'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null,
'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null,
'galaxy' => $galaxy,
'sensors' => $sensorSections,
]);
echo json_encode(['hash' => hash('sha256', $raw)]);
@@ -362,7 +382,7 @@ echo json_encode([
'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null,
'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null,
'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null,
'galaxy' => $galaxy,
'sensors' => $sensorSections,
'history' => $path ?? null,
], JSON_UNESCAPED_UNICODE);
?>