diff --git a/README.md b/README.md
index 0cecdab..72a76c5 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,14 @@
# Find My Device
-Home Assistant에 기록된 Fold7 위치, 배터리, 활동 상태, 이동 경로를 지도에 표시하는 개인용 나의 찾기 페이지입니다.
+Home Assistant에 기록된 Galaxy 기기의 위치, 배터리, 활동 상태, 이동 경로를 지도에 표시하는 개인용 나의 찾기 페이지입니다.
## 기능
- 현재 위치 지도 표시
- GPS 정확도 원 표시
- 최근 24시간 및 사용자 지정 기간 이동 경로 표시
-- 배터리, 워치 배터리, 활동 상태, 걸음 수, 이동 거리 표시
+- 배터리, 충전 상태, 배터리 건강, 온도, 전력, 활동 상태, 걸음 수, 이동 거리 표시
+- Wi-Fi, 모바일 데이터, 전화 상태, 화면 활성, Doze, 절전, 잠금 상태 표시
- 자동 위치 갱신 웹훅 제어
- 강제 업데이트 요청
- 한국어/영어 전환
@@ -15,7 +16,6 @@ Home Assistant에 기록된 Fold7 위치, 배터리, 활동 상태, 이동 경
## 구조
-- `debug.html`: 페이지 삽입용 HTML 조각
- `php/api.php`: Home Assistant 상태/히스토리 조회 API
- `js/main.js`: 지도 렌더링, 상태 갱신, 히스토리 표시
- `css/style.css`: iOS 설정 화면 스타일
diff --git a/debug.html b/debug.html
deleted file mode 100644
index 51124b5..0000000
--- a/debug.html
+++ /dev/null
@@ -1,175 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/js/main.js b/js/main.js
index 23076a5..1621fde 100644
--- a/js/main.js
+++ b/js/main.js
@@ -15,21 +15,39 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
autoCurrentUpdate: "현재 위치 자동 이동",
autoUpdate: "자동 업데이트",
forceUpdate: "업데이트 하기",
- battery: "배터리",
- batteryState: "배터리 상태",
- batteryLevel: "배터리 잔량",
- watchbatteryState: "워치 배터리 상태",
- watchbatteryLevel: "워치 배터리 잔량",
- activity: "활동",
- currentActivity: "현재 활동",
- activityAccuracy: "활동 정확도",
+ battery: "배터리",
+ batteryState: "배터리 상태",
+ batteryLevel: "배터리 잔량",
+ watchbatteryState: "워치 배터리 상태",
+ watchbatteryLevel: "워치 배터리 잔량",
+ isCharging: "충전 여부",
+ chargerType: "충전 방식",
+ batteryHealth: "배터리 건강",
+ batteryTemperature: "배터리 온도",
+ batteryPower: "배터리 전력",
+ remainingChargeTime: "충전 남은 시간",
+ batteryCycleCount: "배터리 사이클",
+ activity: "활동",
+ currentActivity: "현재 활동",
+ activityAccuracy: "활동 정확도",
distance: "도보로 움직인 거리",
steps: "걸음 수",
ascended: "오른 계단",
descended: "내려간 계단",
- etc: "기타",
- connection: "연결 방법",
- editPage: "페이지 수정",
+ etc: "기타",
+ connection: "연결 방법",
+ wifiConnection: "Wi-Fi",
+ wifiIp: "Wi-Fi IP",
+ wifiLinkSpeed: "Wi-Fi 속도",
+ wifiFrequency: "Wi-Fi 주파수",
+ wifiSignalStrength: "Wi-Fi 신호",
+ mobileData: "모바일 데이터",
+ phoneState: "전화 상태",
+ interactive: "화면 활성",
+ dozeMode: "Doze 모드",
+ powerSave: "절전 모드",
+ deviceLocked: "잠금 상태",
+ editPage: "페이지 수정",
pwa: "눌러 홈 화면에 추가해 바로 보기",
history: "기록",
startTime: "시작",
@@ -50,21 +68,39 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
autoCurrentUpdate: "Current Location Auto Update",
autoUpdate: "Auto Update",
forceUpdate: "Force Update",
- battery: "Battery",
- batteryState: "Battery State",
- batteryLevel: "Battery Level",
- watchbatteryState: "Watch Battery State",
- watchbatteryLevel: "Watch Battery Level",
- activity: "Activity",
+ battery: "Battery",
+ batteryState: "Battery State",
+ batteryLevel: "Battery Level",
+ watchbatteryState: "Watch Battery State",
+ watchbatteryLevel: "Watch Battery Level",
+ isCharging: "Charging",
+ chargerType: "Charger Type",
+ batteryHealth: "Battery Health",
+ batteryTemperature: "Battery Temp",
+ batteryPower: "Battery Power",
+ remainingChargeTime: "Remaining Charge",
+ batteryCycleCount: "Battery Cycles",
+ activity: "Activity",
currentActivity: "Current Activity",
activityAccuracy: "Activity Confidence",
distance: "Distance walked",
steps: "Steps",
ascended: "Floors Ascended",
descended: "Floors Descended",
- etc: "Others",
- connection: "Network Type",
- editPage: "Edit Page",
+ etc: "Others",
+ connection: "Network Type",
+ wifiConnection: "Wi-Fi",
+ wifiIp: "Wi-Fi IP",
+ wifiLinkSpeed: "Wi-Fi Speed",
+ wifiFrequency: "Wi-Fi Frequency",
+ wifiSignalStrength: "Wi-Fi Signal",
+ mobileData: "Mobile Data",
+ phoneState: "Phone State",
+ interactive: "Interactive",
+ dozeMode: "Doze Mode",
+ powerSave: "Power Save",
+ deviceLocked: "Device Locked",
+ editPage: "Edit Page",
pwa: "Add to Home Screen for quick access!",
history: "History",
startTime: "Start",
@@ -538,29 +574,133 @@ function setCookieHours(name, value, hours) {
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; expires=${d.toUTCString()}; path=/; SameSite=Lax`;
}
-function updateDOM(data) {
- const textMap = {
- currentPosition: data.address,
+function updateDOM(data) {
+ const textMap = {
+ currentPosition: data.address,
lastUpdateTime: data.updated ? getRelativeTime(data.updated) : "-",
nowActivity: data.activity,
connectionType: data.connection,
updateTrigger: data.trigger,
- batteryStatus: data.state,
- Battery: data.level > 0 ? `${data.level}%` : "-",
- WbatteryStatus: data.wstate,
- WBattery: data.wlevel > 0 ? `${data.wlevel}%` : "-",
- todaySteps: data.steps > 0 ? `${formatNumber(data.steps)}${langCode === "ko" ? "걸음" : "steps"}` : "-",
+ batteryStatus: data.state,
+ Battery: data.level > 0 ? `${data.level}%` : "-",
+ WbatteryStatus: data.wstate,
+ WBattery: data.wlevel > 0 ? `${data.wlevel}%` : "-",
+ todaySteps: data.steps > 0 ? `${formatNumber(data.steps)}${langCode === "ko" ? "걸음" : "steps"}` : "-",
todayAscended: data.ascended > 0 ? `${formatNumber(data.ascended)}${langCode === "ko" ? "층" : "floors"}` : "-",
todayDescended: data.descended > 0 ? `${formatNumber(data.descended)}${langCode === "ko" ? "층" : "floors"}` : "-",
todayDistance: data.distance > 0 ? `${formatNumber(data.distance)}m` : "-",
accuracyValue: data.accuracy > 0 ? `${formatNumber(data.accuracy)}m` : "-"
};
- for (const [id, value] of Object.entries(textMap)) {
- const el = document.getElementById(id);
- if (el) el.textContent = value || "-";
- }
-}
+ for (const [id, value] of Object.entries(textMap)) {
+ const el = document.getElementById(id);
+ if (el) el.textContent = value || "-";
+ }
+
+ toggleOptionalRow('WbatteryStatus', data.wstate);
+ toggleOptionalRow('WBattery', data.wlevel);
+ updateGalaxyRows(data.galaxy || {});
+}
+
+function updateGalaxyRows(galaxy) {
+ const t = translations[langCode] || translations.ko;
+ const rows = [
+ ['isCharging', t.isCharging, galaxy.isCharging],
+ ['chargerType', t.chargerType, galaxy.chargerType],
+ ['batteryHealth', t.batteryHealth, galaxy.batteryHealth],
+ ['batteryTemperature', t.batteryTemperature, formatWithUnit(galaxy.batteryTemperature, '°C')],
+ ['batteryPower', t.batteryPower, formatWithUnit(galaxy.batteryPower, 'W')],
+ ['remainingChargeTime', t.remainingChargeTime, formatDuration(galaxy.remainingChargeTime)],
+ ['batteryCycleCount', t.batteryCycleCount, galaxy.batteryCycleCount],
+ ['wifiConnection', t.wifiConnection, galaxy.wifiConnection],
+ ['wifiIp', t.wifiIp, galaxy.wifiIp],
+ ['wifiLinkSpeed', t.wifiLinkSpeed, formatWithUnit(galaxy.wifiLinkSpeed, 'Mbps')],
+ ['wifiFrequency', t.wifiFrequency, formatWithUnit(galaxy.wifiFrequency, 'MHz')],
+ ['wifiSignalStrength', t.wifiSignalStrength, formatWithUnit(galaxy.wifiSignalStrength, 'dBm')],
+ ['mobileData', t.mobileData, galaxy.mobileData],
+ ['phoneState', t.phoneState, galaxy.phoneState],
+ ['interactive', t.interactive, galaxy.interactive],
+ ['dozeMode', t.dozeMode, galaxy.dozeMode],
+ ['powerSave', t.powerSave, galaxy.powerSave],
+ ['deviceLocked', t.deviceLocked, galaxy.deviceLocked],
+ ];
+
+ rows.forEach(([key, label, value]) => {
+ const targetSection = ['isCharging', 'chargerType', 'batteryHealth', 'batteryTemperature', 'batteryPower', 'remainingChargeTime', 'batteryCycleCount'].includes(key)
+ ? findSectionByTitle(langCode === 'ko' ? '배터리' : 'Battery')
+ : findSectionByTitle(langCode === 'ko' ? '기타' : 'Others');
+ upsertOptionalRow(targetSection, `galaxy_${key}`, label, value);
+ });
+}
+
+function findSectionByTitle(titleText) {
+ const titles = document.querySelectorAll('.settingTitle');
+ for (const title of titles) {
+ if (title.textContent.trim() === titleText) {
+ const section = title.nextElementSibling;
+ if (section && section.classList.contains('settingSection')) return section;
+ }
+ }
+ return null;
+}
+
+function upsertOptionalRow(section, id, label, value) {
+ if (!section) return;
+ const displayValue = normalizeDisplayValue(value);
+ let row = document.getElementById(id);
+
+ if (!displayValue) {
+ if (row) row.remove();
+ return;
+ }
+
+ if (!row) {
+ row = document.createElement('div');
+ row.className = 'settingRow';
+ row.id = id;
+ row.innerHTML = ` `;
+ section.appendChild(row);
+ }
+
+ row.children[0].textContent = label;
+ row.children[1].textContent = displayValue;
+}
+
+function toggleOptionalRow(valueId, value) {
+ const el = document.getElementById(valueId);
+ const row = el?.closest('.settingRow');
+ if (!row) return;
+ row.style.display = normalizeDisplayValue(value) ? '' : 'none';
+}
+
+function normalizeDisplayValue(value) {
+ if (value === null || typeof value === 'undefined' || value === '' || value === '-' || value === 'unknown' || value === 'unavailable') {
+ return '';
+ }
+ return String(value);
+}
+
+function formatWithUnit(value, unit) {
+ const normalized = normalizeDisplayValue(value);
+ if (!normalized) return '';
+ return /[a-zA-Z%°]/.test(normalized) ? normalized : `${normalized}${unit}`;
+}
+
+function formatDuration(value) {
+ const normalized = normalizeDisplayValue(value);
+ if (!normalized) return '';
+ const seconds = Number(normalized);
+ if (!Number.isFinite(seconds)) return normalized;
+ if (seconds <= 0) return '0s';
+ const h = Math.floor(seconds / 3600);
+ const m = Math.floor((seconds % 3600) / 60);
+ const s = Math.floor(seconds % 60);
+ return [
+ h ? `${h}h` : '',
+ m ? `${m}m` : '',
+ s && !h ? `${s}s` : '',
+ ].filter(Boolean).join(' ');
+}
function updateActivitySection(data) {
const validActivities = ["Stationary", "Walking", "Running", "In Vehicle", "Cycling", "가만히 있음", "걷는 중", "달리는 중", "차량 이동 중", "자전거 이동 중"];
@@ -1006,18 +1146,19 @@ function debounce(fn, delay = 400) {
};
}
-function resetDisplayValues() {
- const ids = [
- 'currentPosition', 'accuracyValue', 'lastUpdateTime', 'updateTrigger',
- 'batteryStatus', 'Battery', 'WbatteryStatus', 'WBattery',
- 'nowActivity', 'nowactivityAccuracy', 'todayDistance',
- 'todaySteps', 'todayAscended', 'todayDescended', 'connectionType'
- ];
- ids.forEach(id => {
- const el = document.getElementById(id);
- if (el) el.textContent = '-';
- });
-}
+function resetDisplayValues() {
+ const ids = [
+ 'currentPosition', 'accuracyValue', 'lastUpdateTime', 'updateTrigger',
+ 'batteryStatus', 'Battery', 'WbatteryStatus', 'WBattery',
+ 'nowActivity', 'nowactivityAccuracy', 'todayDistance',
+ 'todaySteps', 'todayAscended', 'todayDescended', 'connectionType'
+ ];
+ ids.forEach(id => {
+ const el = document.getElementById(id);
+ if (el) el.textContent = '-';
+ });
+ document.querySelectorAll('[id^="galaxy_"]').forEach(row => row.remove());
+}
function triggerForceUpdate() {
callDeviceWebhook('force_update');
diff --git a/php/api.php b/php/api.php
index 51a9842..3ffe0c5 100644
--- a/php/api.php
+++ b/php/api.php
@@ -42,8 +42,6 @@ $deviceUrl = $entities['device'];
$geoUrl = $entities['geo'];
$batteryStateUrl = $entities['battery_state'];
$batteryLevelUrl = $entities['battery_level'];
-$watchBatteryStateUrl = $entities['watch_battery_state'];
-$watchBatteryLevelUrl = $entities['watch_battery_level'];
$activityUrl = $entities['activity'];
$connectionUrl = $entities['connection'];
$fascendedUrl = $entities['daily_floors'];
@@ -77,13 +75,39 @@ function getData($entityId) {
return custom_ha_state('seoul', $entityId) ?? [];
}
+function getEntityData($entities, $key) {
+ if (empty($entities[$key])) {
+ return [];
+ }
+ return getData($entities[$key]);
+}
+
+function stateValue($data) {
+ $state = $data['state'] ?? null;
+ if ($state === null || $state === 'unknown' || $state === 'unavailable' || $state === '' || $state === '') {
+ return null;
+ }
+ return $state;
+}
+
+function boolText($state, $lang) {
+ if ($state === null) return null;
+ if ($lang === 'ko') {
+ return $state === 'on' ? '켜짐' : ($state === 'off' ? '꺼짐' : $state);
+ }
+ return $state === 'on' ? 'On' : ($state === 'off' ? 'Off' : $state);
+}
+
+function mappedText($state, $lang, $map) {
+ if ($state === null) return null;
+ return $map[$lang][$state] ?? $map[$lang][strtolower((string)$state)] ?? $state;
+}
+
// 데이터 불러오기
$deviceData = getData($deviceUrl);
$geoData = getData($geoUrl);
$batteryStateData = getData($batteryStateUrl);
$batteryLevelData = getData($batteryLevelUrl);
-$watchBatteryStateData = getData($watchBatteryStateUrl);
-$watchBatteryLevelData = getData($watchBatteryLevelUrl);
$activityData = getData($activityUrl);
$connectionData = getData($connectionUrl);
$ascendedData = getData($fascendedUrl);
@@ -92,6 +116,27 @@ $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 = [];
@@ -160,18 +205,43 @@ $connectionMap = [
$batteryStateMap = [
'ko' => [
'Charging' => '충전 중',
+ 'Discharging' => '방전 중',
'Not Charging' => '충전중이 아님',
'Full' => '가득참',
+ 'charging' => '충전 중',
+ 'discharging' => '방전 중',
+ 'not_charging' => '충전중이 아님',
+ 'full' => '가득참',
'Unknown' => '-',
],
'en' => [
'Charging' => 'Charging',
+ 'Discharging' => 'Discharging',
'Not Charging' => 'Not Charging',
'Full' => 'Full',
+ 'charging' => 'Charging',
+ 'discharging' => 'Discharging',
+ 'not_charging' => 'Not Charging',
+ 'full' => 'Full',
'Unknown' => '-',
]
];
+$androidValueMap = [
+ 'chargerType' => [
+ 'ko' => ['none' => '없음', 'wireless' => '무선', 'ac' => '유선', 'usb' => 'USB'],
+ 'en' => ['none' => 'None', 'wireless' => 'Wireless', 'ac' => 'AC', 'usb' => 'USB'],
+ ],
+ 'batteryHealth' => [
+ 'ko' => ['good' => '양호', 'overheat' => '과열', 'dead' => '불량', 'over_voltage' => '과전압', 'cold' => '저온'],
+ 'en' => ['good' => 'Good', 'overheat' => 'Overheat', 'dead' => 'Dead', 'over_voltage' => 'Over voltage', 'cold' => 'Cold'],
+ ],
+ 'phoneState' => [
+ 'ko' => ['idle' => '대기', 'ringing' => '수신 중', 'offhook' => '통화 중'],
+ 'en' => ['idle' => 'Idle', 'ringing' => 'Ringing', 'offhook' => 'Off hook'],
+ ],
+];
+
$triggerMap = [
'ko' => [
"Launch" => "앱 실행",
@@ -202,10 +272,9 @@ $triggerMap = [
];
$activityState = $activityData['state'] ?? null;
-$aaccuracyState = $activityData['attributes']['Confidence'] ?? null;
+$aaccuracyState = $activityData['attributes']['Confidence'] ?? $activityData['attributes']['confidence'] ?? null;
$connectionState = $connectionData['state'] ?? null;
$batteryState = $batteryStateData['state'] ?? null;
-$watchBatteryState = $watchBatteryStateData['state'] ?? null;
$address = null;
@@ -224,6 +293,34 @@ 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;
+ }
+}
+
// 해시 요청만 들어온 경우
if (isset($_GET['hashonly']) && $_GET['hashonly'] == '1') {
$raw = json_encode([
@@ -235,8 +332,6 @@ if (isset($_GET['hashonly']) && $_GET['hashonly'] == '1') {
'address' => $address,
'state' => $batteryStateMap[$lang][$batteryState] ?? $batteryState ?? null,
'level' => $batteryLevelData['state'] ?? null,
- 'wstate' => $batteryStateMap[$lang][$watchBatteryState] ?? $watchBatteryState ?? null,
- 'wlevel' => $watchBatteryLevelData['state'] ?? null,
'ascended' => $ascendedData['state'] ?? null,
'descended' => $descendedData['state'] ?? null,
'steps' => $stepsData['state'] ?? null,
@@ -244,6 +339,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,
]);
echo json_encode(['hash' => hash('sha256', $raw)]);
@@ -259,8 +355,6 @@ echo json_encode([
'address' => $address,
'state' => $batteryStateMap[$lang][$batteryState] ?? $batteryState ?? null,
'level' => $batteryLevelData['state'] ?? null,
- 'wstate' => $batteryStateMap[$lang][$watchBatteryState] ?? $watchBatteryState ?? null,
- 'wlevel' => $watchBatteryLevelData['state'] ?? null,
'ascended' => $ascendedData['state'] ?? null,
'descended' => $descendedData['state'] ?? null,
'steps' => $stepsData['state'] ?? null,
@@ -268,6 +362,7 @@ echo json_encode([
'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null,
'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null,
'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null,
+ 'galaxy' => $galaxy,
'history' => $path ?? null,
], JSON_UNESCAPED_UNICODE);
?>