자동 위치 갱신 명령 반복 제한
This commit is contained in:
@@ -50,7 +50,7 @@ PWA standalone으로 진입한 경우에는 설치형 앱 사용성을 우선해
|
|||||||
|
|
||||||
페이지 본문에는 `<div id="findmydevice"></div>`만 두면 됩니다. `main.js`는 이 컨테이너 안에 지도, 헤더, 설정/기록/위치/업데이트/배터리/활동 섹션과 iOS PWA 안내 영역을 항상 자동 생성합니다. 상단 복귀 링크는 `chaegeon.com`이면 채건닷컴, `/blog`이면 블로그처럼 알려진 경로명을 우선 표시하고, 같은 출처의 다른 이전 페이지는 문서 제목을 읽어 표시합니다. 같은 경로에서 쿼리만 바뀐 화면은 같은 페이지로 보고 세션 방문 기록에서 다른 이전 페이지를 찾습니다. 직접 접속처럼 이전 페이지 확인이 어려우면 채건닷컴으로 표시하고 `https://chaegeon.com/`로 이동합니다.
|
페이지 본문에는 `<div id="findmydevice"></div>`만 두면 됩니다. `main.js`는 이 컨테이너 안에 지도, 헤더, 설정/기록/위치/업데이트/배터리/활동 섹션과 iOS PWA 안내 영역을 항상 자동 생성합니다. 상단 복귀 링크는 `chaegeon.com`이면 채건닷컴, `/blog`이면 블로그처럼 알려진 경로명을 우선 표시하고, 같은 출처의 다른 이전 페이지는 문서 제목을 읽어 표시합니다. 같은 경로에서 쿼리만 바뀐 화면은 같은 페이지로 보고 세션 방문 기록에서 다른 이전 페이지를 찾습니다. 직접 접속처럼 이전 페이지 확인이 어려우면 채건닷컴으로 표시하고 `https://chaegeon.com/`로 이동합니다.
|
||||||
|
|
||||||
위치 갱신 명령은 `/custom/common/config.php`의 `findmydevice_location_refresh` 설정을 사용합니다. `seoul`, `main` Home Assistant 프로필의 `notify.mobile_app_seocaegeonyi_z_fold7` 서비스로 Companion App notification command를 보냅니다. 자동 업데이트는 서울 집과 목포 집 150m 반경 밖이고 충전 중이거나 `Niro` 블루투스가 연결되어 있을 때만 Android high accuracy mode를 5초 간격으로 설정하고 `force_on`, `request_location_update`, `command_update_sensors`를 호출합니다. 화면이 열려 있으면 5초마다 위치/센서 갱신 명령을 반복하고, HA 자동화도 30초마다 같은 조건을 확인합니다. 집 안이거나 충전 중도 아니고 `Niro`도 연결되어 있지 않으면 자동 명령은 `force_off`로 고정밀 위치 갱신을 끕니다.
|
위치 갱신 명령은 `/custom/common/config.php`의 `findmydevice_location_refresh` 설정을 사용합니다. `seoul`, `main` Home Assistant 프로필의 `notify.mobile_app_seocaegeonyi_z_fold7` 서비스로 Companion App notification command를 보냅니다. 자동 업데이트는 서울 집과 목포 집 150m 반경 밖이고 충전 중이거나 `Niro` 블루투스가 연결되어 있을 때만 Android high accuracy mode를 5초 간격으로 설정하고 `force_on`, `request_location_update`, `command_update_sensors`를 호출합니다. 화면 자동 갱신 tick은 5초마다 돌지만, 휴대폰 위치/센서 명령은 서버에서 30초 이상 간격으로 제한합니다. 고정밀 모드가 이미 켜져 스위치가 잠긴 상태에서는 웹 화면이 추가 자동 명령을 보내지 않고 상태 표시만 유지합니다. HA 자동화도 30초마다 같은 조건을 확인합니다. 집 안이거나 충전 중도 아니고 `Niro`도 연결되어 있지 않으면 자동 명령은 `force_off`로 고정밀 위치 갱신을 끕니다.
|
||||||
|
|
||||||
집 판정 중심은 `/custom/common/config.php`의 `findmydevice_quiet_zones` 설정을 사용합니다. 현재 서울 집 좌표는 `37.558924572072, 127.20413804054`, 목포 집 좌표는 `34.80634217996409, 126.38442277908327`이며 둘 다 반경은 `150m`입니다. API 응답의 `homes` 값을 브라우저가 사용하므로 서울 집과 목포 집 모두 집 원, 체류/외출 판정, GPS 튐 흡수 기준에 포함됩니다.
|
집 판정 중심은 `/custom/common/config.php`의 `findmydevice_quiet_zones` 설정을 사용합니다. 현재 서울 집 좌표는 `37.558924572072, 127.20413804054`, 목포 집 좌표는 `34.80634217996409, 126.38442277908327`이며 둘 다 반경은 `150m`입니다. API 응답의 `homes` 값을 브라우저가 사용하므로 서울 집과 목포 집 모두 집 원, 체류/외출 판정, GPS 튐 흡수 기준에 포함됩니다.
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1101,7 +1101,8 @@ document.getElementById('autoUpdateSwitch').addEventListener('change', () => {
|
|||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (!findmydeviceAuthenticated) return;
|
if (!findmydeviceAuthenticated) return;
|
||||||
if (document.getElementById('autoUpdateSwitch')?.checked || highAccuracyModeActive) {
|
const switchEl = document.getElementById('autoUpdateSwitch');
|
||||||
|
if (switchEl?.checked && !switchEl.disabled) {
|
||||||
callDeviceWebhook('auto_tick');
|
callDeviceWebhook('auto_tick');
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|||||||
+64
-2
@@ -87,6 +87,60 @@ function findmydevice_mobile_command(string $message, array $data = []): bool
|
|||||||
return $ok;
|
return $ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findmydevice_command_state_file(): string
|
||||||
|
{
|
||||||
|
return rtrim(sys_get_temp_dir(), '/\\') . '/findmydevice_location_refresh_state.json';
|
||||||
|
}
|
||||||
|
|
||||||
|
function findmydevice_throttled_mobile_command(string $key, int $seconds, string $message, array $data = []): ?bool
|
||||||
|
{
|
||||||
|
if ($seconds <= 0) {
|
||||||
|
return findmydevice_mobile_command($message, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = findmydevice_command_state_file();
|
||||||
|
$now = time();
|
||||||
|
$handle = fopen($file, 'c+');
|
||||||
|
if (!$handle) {
|
||||||
|
return findmydevice_mobile_command($message, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!flock($handle, LOCK_EX)) {
|
||||||
|
fclose($handle);
|
||||||
|
return findmydevice_mobile_command($message, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw = stream_get_contents($handle);
|
||||||
|
$state = json_decode($raw ?: '{}', true);
|
||||||
|
if (!is_array($state)) {
|
||||||
|
$state = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$last = (int)($state[$key] ?? 0);
|
||||||
|
if ($last > 0 && ($now - $last) < $seconds) {
|
||||||
|
flock($handle, LOCK_UN);
|
||||||
|
fclose($handle);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$state[$key] = $now;
|
||||||
|
ftruncate($handle, 0);
|
||||||
|
rewind($handle);
|
||||||
|
fwrite($handle, json_encode($state, JSON_UNESCAPED_UNICODE));
|
||||||
|
fflush($handle);
|
||||||
|
flock($handle, LOCK_UN);
|
||||||
|
fclose($handle);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
if (is_resource($handle)) {
|
||||||
|
flock($handle, LOCK_UN);
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return findmydevice_mobile_command($message, $data);
|
||||||
|
}
|
||||||
|
|
||||||
function findmydevice_ha_profiles(): array
|
function findmydevice_ha_profiles(): array
|
||||||
{
|
{
|
||||||
$config = custom_config();
|
$config = custom_config();
|
||||||
@@ -252,6 +306,9 @@ function findmydevice_bool_result_exists(array $results): bool
|
|||||||
if ($value === true) {
|
if ($value === true) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if ($value === 'throttled') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -261,6 +318,7 @@ function findmydevice_location_refresh(string $name): array
|
|||||||
$config = custom_config();
|
$config = custom_config();
|
||||||
$refresh = $config['findmydevice_location_refresh'] ?? [];
|
$refresh = $config['findmydevice_location_refresh'] ?? [];
|
||||||
$interval = max(1, (int)($refresh['high_accuracy_interval'] ?? 1));
|
$interval = max(1, (int)($refresh['high_accuracy_interval'] ?? 1));
|
||||||
|
$autoTickInterval = max(5, (int)($refresh['auto_tick_command_interval'] ?? 30));
|
||||||
$results = [];
|
$results = [];
|
||||||
|
|
||||||
if ($name === 'auto_on') {
|
if ($name === 'auto_on') {
|
||||||
@@ -278,6 +336,7 @@ function findmydevice_location_refresh(string $name): array
|
|||||||
}
|
}
|
||||||
|
|
||||||
$results['policy'] = 'allowed';
|
$results['policy'] = 'allowed';
|
||||||
|
$results['allowWebhook'] = false;
|
||||||
$results['quietZone'] = null;
|
$results['quietZone'] = null;
|
||||||
$results['charging'] = $policy['charging'];
|
$results['charging'] = $policy['charging'];
|
||||||
$results['requiredBluetoothConnected'] = $policy['required_bluetooth_connected'];
|
$results['requiredBluetoothConnected'] = $policy['required_bluetooth_connected'];
|
||||||
@@ -308,8 +367,11 @@ function findmydevice_location_refresh(string $name): array
|
|||||||
$results['quietZone'] = null;
|
$results['quietZone'] = null;
|
||||||
$results['charging'] = $policy['charging'];
|
$results['charging'] = $policy['charging'];
|
||||||
$results['requiredBluetoothConnected'] = $policy['required_bluetooth_connected'];
|
$results['requiredBluetoothConnected'] = $policy['required_bluetooth_connected'];
|
||||||
$results['request_location'] = findmydevice_mobile_command('request_location_update');
|
$requestLocation = findmydevice_throttled_mobile_command('auto_tick_request_location', $autoTickInterval, 'request_location_update');
|
||||||
$results['update_sensors'] = findmydevice_mobile_command('command_update_sensors');
|
$updateSensors = findmydevice_throttled_mobile_command('auto_tick_update_sensors', $autoTickInterval, 'command_update_sensors');
|
||||||
|
$results['throttleSeconds'] = $autoTickInterval;
|
||||||
|
$results['request_location'] = $requestLocation ?? 'throttled';
|
||||||
|
$results['update_sensors'] = $updateSensors ?? 'throttled';
|
||||||
} elseif ($name === 'force_update') {
|
} elseif ($name === 'force_update') {
|
||||||
$results['request_location'] = findmydevice_mobile_command('request_location_update');
|
$results['request_location'] = findmydevice_mobile_command('request_location_update');
|
||||||
$results['update_sensors'] = findmydevice_mobile_command('command_update_sensors');
|
$results['update_sensors'] = findmydevice_mobile_command('command_update_sensors');
|
||||||
|
|||||||
Reference in New Issue
Block a user