Support Galaxy sensor fields and remove debug file

This commit is contained in:
seo
2026-06-12 15:18:13 +09:00
parent 72aedf47e5
commit 4559301fa6
4 changed files with 294 additions and 233 deletions
+3 -3
View File
@@ -1,13 +1,14 @@
# Find My Device # Find My Device
Home Assistant에 기록된 Fold7 위치, 배터리, 활동 상태, 이동 경로를 지도에 표시하는 개인용 나의 찾기 페이지입니다. Home Assistant에 기록된 Galaxy 기기의 위치, 배터리, 활동 상태, 이동 경로를 지도에 표시하는 개인용 나의 찾기 페이지입니다.
## 기능 ## 기능
- 현재 위치 지도 표시 - 현재 위치 지도 표시
- GPS 정확도 원 표시 - GPS 정확도 원 표시
- 최근 24시간 및 사용자 지정 기간 이동 경로 표시 - 최근 24시간 및 사용자 지정 기간 이동 경로 표시
- 배터리, 워치 배터리, 활동 상태, 걸음 수, 이동 거리 표시 - 배터리, 충전 상태, 배터리 건강, 온도, 전력, 활동 상태, 걸음 수, 이동 거리 표시
- Wi-Fi, 모바일 데이터, 전화 상태, 화면 활성, Doze, 절전, 잠금 상태 표시
- 자동 위치 갱신 웹훅 제어 - 자동 위치 갱신 웹훅 제어
- 강제 업데이트 요청 - 강제 업데이트 요청
- 한국어/영어 전환 - 한국어/영어 전환
@@ -15,7 +16,6 @@ Home Assistant에 기록된 Fold7 위치, 배터리, 활동 상태, 이동 경
## 구조 ## 구조
- `debug.html`: 페이지 삽입용 HTML 조각
- `php/api.php`: Home Assistant 상태/히스토리 조회 API - `php/api.php`: Home Assistant 상태/히스토리 조회 API
- `js/main.js`: 지도 렌더링, 상태 갱신, 히스토리 표시 - `js/main.js`: 지도 렌더링, 상태 갱신, 히스토리 표시
- `css/style.css`: iOS 설정 화면 스타일 - `css/style.css`: iOS 설정 화면 스타일
-175
View File
@@ -1,175 +0,0 @@
<meta charset="UTF-8">
<link href="/custom/findmydevice/css/style.css" rel="stylesheet" />
<div id="mySettingContainer" style="user-select: none;">
<div id="settingsHeader">
<a id="blogBackLink"></a>
<span class="headerTitle"></span>
<div id="langToggle">
<img src="/custom/findmydevice/img/language-empty.svg" alt="Language Toggle">
</div>
</div>
<div id="toggleContent" style="padding-bottom:80px;">
<div id="mapContainer">
<div id="map" style="width:100%; height:100%;"></div>
</div>
<div class="settingTitle">
<span id="titleSettings"></span>
</div>
<div class="settingSection">
<div class="settingRow" id="wakeLockRow">
<span id="labelKeepScreenOn"></span>
<label class="iosSwitch">
<input type="checkbox" id="wakeLockSwitch">
<span class="slider"></span>
</label>
</div>
</div>
<div class="settingTitle">
<span id="titleHistory"></span>
</div>
<div class="settingSection">
<div class="settingRow">
<span id="labelStartTime"></span>
<input type="datetime-local" id="rangeStart" class="dth">
</div>
<div class="settingRow">
<span id="labelEndTime"></span>
<input type="datetime-local" id="rangeEnd" class="dth">
</div>
<div class="settingRow locateRow" id="HistoryResetBtn">
<span style="color:#007AFF; cursor:default;" id="labelHistoryReset"></span>
</div>
</div>
<div class="settingTitle">
<span id="titleLocation"></span>
</div>
<div class="settingSection">
<div class="settingRow">
<span id="labelCurrentPosition"></span>
<span id="currentPosition"></span>
</div>
<div class="settingRow">
<span id="labelGpsAccuracy"></span>
<span id="accuracyValue"></span>
</div>
<div class="settingRow" id="autoLocateBtn">
<span id="labelCurrentAutoPosition"></span>
<label class="iosSwitch">
<input type="checkbox" id="autoPositionSwitch">
<span class="slider"></span>
</label>
</div>
<div class="settingRow locateRow" id="locateBtn">
<span style="color:#007AFF; cursor:default;" id="labelMoveToCurrent"></span>
</div>
</div>
<div class="settingTitle">
<span id="titleUpdate"></span>
</div>
<div class="settingSection">
<div class="settingRow">
<span id="labelLastUpdate"></span>
<span id="lastUpdateTime"></span>
</div>
<div class="settingRow">
<span id="labelUpdateTrigger"></span>
<span id="updateTrigger"></span>
</div>
<div class="settingRow" id="autoUpdateBtn">
<span id="labelAutoUpdate"></span>
<label class="iosSwitch">
<input type="checkbox" id="autoUpdateSwitch">
<span class="slider"></span>
</label>
</div>
<div class="settingRow locateRow" id="updateBtn">
<span style="color:#007AFF; cursor:default;" id="labelForceUpdate"></span>
</div>
</div>
<div class="settingTitle">
<span id="titleBattery"></span>
</div>
<div class="settingSection">
<div class="settingRow">
<span id="labelBatteryState"></span>
<span id="batteryStatus"></span>
</div>
<div class="settingRow">
<span id="labelBatteryLevel"></span>
<span id="Battery"></span>
</div>
<div class="settingRow">
<span id="labelWatchBatteryState"></span>
<span id="WbatteryStatus"></span>
</div>
<div class="settingRow">
<span id="labelWatchBatteryLevel"></span>
<span id="WBattery"></span>
</div>
</div>
<div class="settingTitle">
<span id="titleActivity"></span>
</div>
<div class="settingSection">
<div class="settingRow">
<span id="labelCurrentActivity"></span>
<span id="nowActivity"></span>
</div>
<div class="settingRow" id="existnowActivity">
<span id="labelActivityAccuracy"></span>
<span id="nowactivityAccuracy"></span>
</div>
<div class="settingRow">
<span id="labelDistance"></span>
<span id="todayDistance"></span>
</div>
<div class="settingRow">
<span id="labelSteps"></span>
<span id="todaySteps"></span>
</div>
<div class="settingRow">
<span id="labelAscended"></span>
<span id="todayAscended"></span>
</div>
<div class="settingRow">
<span id="labelDescended"></span>
<span id="todayDescended"></span>
</div>
</div>
<div class="settingTitle">
<span id="titleEtc"></span>
</div>
<div class="settingSection">
<div class="settingRow">
<span id="labelConnection"></span>
<span id="connectionType"></span>
</div>
</div>
</div>
</div>
<div id="ios-pwa-tooltip">
<span class="close-btn" id="close-tooltip"></span>
<span
style="width:18px;height:18px;display:inline-block;vertical-align:middle;margin-right:5px;transform:translateZ(0);will-change:transform;">
<svg height="18" viewbox="0 0 50 50" width="18" xmlns="http://www.w3.org/2000/svg">
<path d="M30.3 13.7L25 8.4l-5.3 5.3-1.4-1.4L25 5.6l6.7 6.7z"></path>
<path d="M24 7h2v21h-2z"></path>
<path
d="M35 40H15c-1.7 0-3-1.3-3-3V19c0-1.7 1.3-3 3-3h7v2h-7c-.6 0-1 .4-1 1v18c0 .6.4 1 1 1h20c.6 0 1-.4 1-1V19c0-.6-.4-1-1-1h-7v-2h7c1.7 0 3 1.3 3 3v18c0 1.7-1.3 3-3 3z">
</path>
</svg>
</span>
</div>
<script src="https://oapi.map.naver.com/openapi/v3/maps.js?ncpKeyId=g3btu2qfeb"></script>
<script src="/custom/findmydevice/js/main.js"></script>
+141
View File
@@ -20,6 +20,13 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
batteryLevel: "배터리 잔량", batteryLevel: "배터리 잔량",
watchbatteryState: "워치 배터리 상태", watchbatteryState: "워치 배터리 상태",
watchbatteryLevel: "워치 배터리 잔량", watchbatteryLevel: "워치 배터리 잔량",
isCharging: "충전 여부",
chargerType: "충전 방식",
batteryHealth: "배터리 건강",
batteryTemperature: "배터리 온도",
batteryPower: "배터리 전력",
remainingChargeTime: "충전 남은 시간",
batteryCycleCount: "배터리 사이클",
activity: "활동", activity: "활동",
currentActivity: "현재 활동", currentActivity: "현재 활동",
activityAccuracy: "활동 정확도", activityAccuracy: "활동 정확도",
@@ -29,6 +36,17 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
descended: "내려간 계단", descended: "내려간 계단",
etc: "기타", etc: "기타",
connection: "연결 방법", 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: "페이지 수정", editPage: "페이지 수정",
pwa: "눌러 홈 화면에 추가해 바로 보기", pwa: "눌러 홈 화면에 추가해 바로 보기",
history: "기록", history: "기록",
@@ -55,6 +73,13 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
batteryLevel: "Battery Level", batteryLevel: "Battery Level",
watchbatteryState: "Watch Battery State", watchbatteryState: "Watch Battery State",
watchbatteryLevel: "Watch Battery Level", 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", activity: "Activity",
currentActivity: "Current Activity", currentActivity: "Current Activity",
activityAccuracy: "Activity Confidence", activityAccuracy: "Activity Confidence",
@@ -64,6 +89,17 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
descended: "Floors Descended", descended: "Floors Descended",
etc: "Others", etc: "Others",
connection: "Network Type", 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", editPage: "Edit Page",
pwa: "Add to Home Screen for quick access!", pwa: "Add to Home Screen for quick access!",
history: "History", history: "History",
@@ -560,6 +596,110 @@ function updateDOM(data) {
const el = document.getElementById(id); const el = document.getElementById(id);
if (el) el.textContent = value || "-"; 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 = `<span></span><span></span>`;
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) { function updateActivitySection(data) {
@@ -1017,6 +1157,7 @@ function resetDisplayValues() {
const el = document.getElementById(id); const el = document.getElementById(id);
if (el) el.textContent = '-'; if (el) el.textContent = '-';
}); });
document.querySelectorAll('[id^="galaxy_"]').forEach(row => row.remove());
} }
function triggerForceUpdate() { function triggerForceUpdate() {
+105 -10
View File
@@ -42,8 +42,6 @@ $deviceUrl = $entities['device'];
$geoUrl = $entities['geo']; $geoUrl = $entities['geo'];
$batteryStateUrl = $entities['battery_state']; $batteryStateUrl = $entities['battery_state'];
$batteryLevelUrl = $entities['battery_level']; $batteryLevelUrl = $entities['battery_level'];
$watchBatteryStateUrl = $entities['watch_battery_state'];
$watchBatteryLevelUrl = $entities['watch_battery_level'];
$activityUrl = $entities['activity']; $activityUrl = $entities['activity'];
$connectionUrl = $entities['connection']; $connectionUrl = $entities['connection'];
$fascendedUrl = $entities['daily_floors']; $fascendedUrl = $entities['daily_floors'];
@@ -77,13 +75,39 @@ function getData($entityId) {
return custom_ha_state('seoul', $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 === '<not connected>' || $state === '<not available>') {
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); $deviceData = getData($deviceUrl);
$geoData = getData($geoUrl); $geoData = getData($geoUrl);
$batteryStateData = getData($batteryStateUrl); $batteryStateData = getData($batteryStateUrl);
$batteryLevelData = getData($batteryLevelUrl); $batteryLevelData = getData($batteryLevelUrl);
$watchBatteryStateData = getData($watchBatteryStateUrl);
$watchBatteryLevelData = getData($watchBatteryLevelUrl);
$activityData = getData($activityUrl); $activityData = getData($activityUrl);
$connectionData = getData($connectionUrl); $connectionData = getData($connectionUrl);
$ascendedData = getData($fascendedUrl); $ascendedData = getData($fascendedUrl);
@@ -92,6 +116,27 @@ $stepsData = getData($stepsUrl);
$distanceData = getData($distanceUrl); $distanceData = getData($distanceUrl);
$historyData = custom_ha_request('seoul', 'GET', $historyEndpoint) ?? []; $historyData = custom_ha_request('seoul', 'GET', $historyEndpoint) ?? [];
$triggerData = getData($triggerUrl); $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 = []; $path = [];
@@ -160,18 +205,43 @@ $connectionMap = [
$batteryStateMap = [ $batteryStateMap = [
'ko' => [ 'ko' => [
'Charging' => '충전 중', 'Charging' => '충전 중',
'Discharging' => '방전 중',
'Not Charging' => '충전중이 아님', 'Not Charging' => '충전중이 아님',
'Full' => '가득참', 'Full' => '가득참',
'charging' => '충전 중',
'discharging' => '방전 중',
'not_charging' => '충전중이 아님',
'full' => '가득참',
'Unknown' => '-', 'Unknown' => '-',
], ],
'en' => [ 'en' => [
'Charging' => 'Charging', 'Charging' => 'Charging',
'Discharging' => 'Discharging',
'Not Charging' => 'Not Charging', 'Not Charging' => 'Not Charging',
'Full' => 'Full', 'Full' => 'Full',
'charging' => 'Charging',
'discharging' => 'Discharging',
'not_charging' => 'Not Charging',
'full' => 'Full',
'Unknown' => '-', '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 = [ $triggerMap = [
'ko' => [ 'ko' => [
"Launch" => "앱 실행", "Launch" => "앱 실행",
@@ -202,10 +272,9 @@ $triggerMap = [
]; ];
$activityState = $activityData['state'] ?? null; $activityState = $activityData['state'] ?? null;
$aaccuracyState = $activityData['attributes']['Confidence'] ?? null; $aaccuracyState = $activityData['attributes']['Confidence'] ?? $activityData['attributes']['confidence'] ?? null;
$connectionState = $connectionData['state'] ?? null; $connectionState = $connectionData['state'] ?? null;
$batteryState = $batteryStateData['state'] ?? null; $batteryState = $batteryStateData['state'] ?? null;
$watchBatteryState = $watchBatteryStateData['state'] ?? null;
$address = null; $address = null;
@@ -224,6 +293,34 @@ if (($deviceData['state'] ?? null) !== 'not_home') {
$address = trim($locality . ' ' . ($geoData['attributes']['Name'] ?? '')); $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') { if (isset($_GET['hashonly']) && $_GET['hashonly'] == '1') {
$raw = json_encode([ $raw = json_encode([
@@ -235,8 +332,6 @@ if (isset($_GET['hashonly']) && $_GET['hashonly'] == '1') {
'address' => $address, 'address' => $address,
'state' => $batteryStateMap[$lang][$batteryState] ?? $batteryState ?? null, 'state' => $batteryStateMap[$lang][$batteryState] ?? $batteryState ?? null,
'level' => $batteryLevelData['state'] ?? null, 'level' => $batteryLevelData['state'] ?? null,
'wstate' => $batteryStateMap[$lang][$watchBatteryState] ?? $watchBatteryState ?? null,
'wlevel' => $watchBatteryLevelData['state'] ?? null,
'ascended' => $ascendedData['state'] ?? null, 'ascended' => $ascendedData['state'] ?? null,
'descended' => $descendedData['state'] ?? null, 'descended' => $descendedData['state'] ?? null,
'steps' => $stepsData['state'] ?? null, 'steps' => $stepsData['state'] ?? null,
@@ -244,6 +339,7 @@ if (isset($_GET['hashonly']) && $_GET['hashonly'] == '1') {
'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null, 'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null,
'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null, 'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null,
'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null, 'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null,
'galaxy' => $galaxy,
]); ]);
echo json_encode(['hash' => hash('sha256', $raw)]); echo json_encode(['hash' => hash('sha256', $raw)]);
@@ -259,8 +355,6 @@ echo json_encode([
'address' => $address, 'address' => $address,
'state' => $batteryStateMap[$lang][$batteryState] ?? $batteryState ?? null, 'state' => $batteryStateMap[$lang][$batteryState] ?? $batteryState ?? null,
'level' => $batteryLevelData['state'] ?? null, 'level' => $batteryLevelData['state'] ?? null,
'wstate' => $batteryStateMap[$lang][$watchBatteryState] ?? $watchBatteryState ?? null,
'wlevel' => $watchBatteryLevelData['state'] ?? null,
'ascended' => $ascendedData['state'] ?? null, 'ascended' => $ascendedData['state'] ?? null,
'descended' => $descendedData['state'] ?? null, 'descended' => $descendedData['state'] ?? null,
'steps' => $stepsData['state'] ?? null, 'steps' => $stepsData['state'] ?? null,
@@ -268,6 +362,7 @@ echo json_encode([
'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null, 'activity' => $activityMap[$lang][$activityState] ?? $activityState ?? null,
'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null, 'aaccuracy' => $aaccuracyMap[$lang][$aaccuracyState] ?? $aaccuracyState ?? null,
'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null, 'connection' => $connectionMap[$lang][$connectionState] ?? $connectionState ?? null,
'galaxy' => $galaxy,
'history' => $path ?? null, 'history' => $path ?? null,
], JSON_UNESCAPED_UNICODE); ], JSON_UNESCAPED_UNICODE);
?> ?>