findmydevice 얼굴 재생 마커와 자동 추적 차단

This commit is contained in:
seo
2026-07-10 20:13:13 +09:00
parent 6652280915
commit debb6ead7a
3 changed files with 216 additions and 29 deletions
+187 -2
View File
@@ -87,6 +87,161 @@ function findmydevice_mobile_command(string $message, array $data = []): bool
return $ok;
}
function findmydevice_ha_profiles(): array
{
$config = custom_config();
$refresh = $config['findmydevice_location_refresh'] ?? [];
return array_values(array_unique(array_filter(array_map('strval', (array)($refresh['profiles'] ?? [$refresh['profile'] ?? 'seoul'])))));
}
function findmydevice_state_timestamp(?array $state): int
{
if (!$state) {
return 0;
}
$time = $state['last_updated'] ?? $state['last_changed'] ?? null;
return $time ? (strtotime((string)$time) ?: 0) : 0;
}
function findmydevice_latest_state(string $entityId): ?array
{
$latest = null;
foreach (findmydevice_ha_profiles() as $profile) {
$state = custom_ha_state($profile, $entityId);
if (!$state) {
continue;
}
$state['_source_profile'] = $profile;
if (!$latest || findmydevice_state_timestamp($state) > findmydevice_state_timestamp($latest)) {
$latest = $state;
}
}
return $latest;
}
function findmydevice_distance_meters(float $lat1, float $lng1, float $lat2, float $lng2): float
{
$earth = 6371000;
$dLat = deg2rad($lat2 - $lat1);
$dLng = deg2rad($lng2 - $lng1);
$a = sin($dLat / 2) ** 2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLng / 2) ** 2;
return $earth * 2 * atan2(sqrt($a), sqrt(1 - $a));
}
function findmydevice_current_position(): ?array
{
$config = custom_config();
$device = (string)($config['entities']['device'] ?? '');
if ($device === '') {
return null;
}
$state = findmydevice_latest_state($device);
$attrs = is_array($state['attributes'] ?? null) ? $state['attributes'] : [];
if (!isset($attrs['latitude'], $attrs['longitude']) || !is_numeric($attrs['latitude']) || !is_numeric($attrs['longitude'])) {
return null;
}
return [
'latitude' => (float)$attrs['latitude'],
'longitude' => (float)$attrs['longitude'],
'state' => $state['state'] ?? null,
'source' => $state['_source_profile'] ?? null,
];
}
function findmydevice_quiet_zone(?array $position): ?array
{
if (!$position) {
return null;
}
$config = custom_config();
foreach ((array)($config['findmydevice_quiet_zones'] ?? []) as $zone) {
if (!is_array($zone) || !isset($zone['latitude'], $zone['longitude'])) {
continue;
}
$radius = max(1, (int)($zone['radius_m'] ?? 150));
$distance = findmydevice_distance_meters(
(float)$position['latitude'],
(float)$position['longitude'],
(float)$zone['latitude'],
(float)$zone['longitude']
);
if ($distance <= $radius) {
return [
'name' => (string)($zone['name'] ?? ''),
'label' => (string)($zone['label'] ?? $zone['name'] ?? 'quiet_zone'),
'distance_m' => round($distance, 1),
'radius_m' => $radius,
];
}
}
return null;
}
function findmydevice_required_bluetooth_connected(): bool
{
$config = custom_config();
$refresh = $config['findmydevice_location_refresh'] ?? [];
$targets = array_map('strtolower', array_map('strval', (array)($refresh['required_bluetooth_names'] ?? ['Niro'])));
$targets = array_values(array_filter($targets));
if (!$targets) {
return true;
}
$entity = (string)($config['findmydevice_sensor_sections']['environment']['bluetoothConnection']['entity'] ?? 'sensor.seocaegeonyi_z_fold7_bluetooth_connection');
$state = findmydevice_latest_state($entity);
$attrs = is_array($state['attributes'] ?? null) ? $state['attributes'] : [];
$values = [];
if (isset($state['state'])) {
$values[] = (string)$state['state'];
}
foreach ((array)($attrs['connected_paired_devices'] ?? []) as $device) {
$values[] = (string)$device;
if (str_contains((string)$device, ' (')) {
$values[] = rtrim(substr((string)$device, strrpos((string)$device, ' (') + 2), ')');
}
}
foreach ($values as $value) {
$lower = strtolower($value);
foreach ($targets as $target) {
if ($target !== '' && str_contains($lower, $target)) {
return true;
}
}
}
return false;
}
function findmydevice_auto_tracking_policy(): array
{
$position = findmydevice_current_position();
$zone = findmydevice_quiet_zone($position);
$bluetooth = findmydevice_required_bluetooth_connected();
return [
'allowed' => !$zone && $bluetooth,
'position' => $position,
'quiet_zone' => $zone,
'required_bluetooth_connected' => $bluetooth,
];
}
function findmydevice_bool_result_exists(array $results): bool
{
foreach ($results as $value) {
if ($value === true) {
return true;
}
}
return false;
}
function findmydevice_location_refresh(string $name): array
{
$config = custom_config();
@@ -95,6 +250,21 @@ function findmydevice_location_refresh(string $name): array
$results = [];
if ($name === 'auto_on') {
$policy = findmydevice_auto_tracking_policy();
if (!$policy['allowed']) {
$results['policy'] = 'blocked';
$results['quietZone'] = $policy['quiet_zone'];
$results['requiredBluetoothConnected'] = $policy['required_bluetooth_connected'];
$results['allowWebhook'] = false;
$results['high_accuracy_off'] = findmydevice_mobile_command('command_high_accuracy_mode', [
'command' => 'force_off',
]);
return $results;
}
$results['policy'] = 'allowed';
$results['quietZone'] = null;
$results['requiredBluetoothConnected'] = true;
$results['high_accuracy_interval'] = findmydevice_mobile_command('command_high_accuracy_mode', [
'command' => 'high_accuracy_set_update_interval',
'high_accuracy_update_interval' => $interval,
@@ -105,6 +275,21 @@ function findmydevice_location_refresh(string $name): array
$results['request_location'] = findmydevice_mobile_command('request_location_update');
$results['update_sensors'] = findmydevice_mobile_command('command_update_sensors');
} elseif ($name === 'auto_tick') {
$policy = findmydevice_auto_tracking_policy();
if (!$policy['allowed']) {
$results['policy'] = 'blocked';
$results['quietZone'] = $policy['quiet_zone'];
$results['requiredBluetoothConnected'] = $policy['required_bluetooth_connected'];
$results['allowWebhook'] = false;
$results['high_accuracy_off'] = findmydevice_mobile_command('command_high_accuracy_mode', [
'command' => 'force_off',
]);
return $results;
}
$results['policy'] = 'allowed';
$results['quietZone'] = null;
$results['requiredBluetoothConnected'] = true;
$results['request_location'] = findmydevice_mobile_command('request_location_update');
$results['update_sensors'] = findmydevice_mobile_command('command_update_sensors');
} elseif ($name === 'force_update') {
@@ -133,8 +318,8 @@ if (isset($_GET['action']) && $_GET['action'] === 'webhook') {
}
$mobileResults = findmydevice_location_refresh($name);
$webhookOk = custom_ha_webhook($allowed[$name]);
$mobileOk = !$mobileResults || in_array(true, $mobileResults, true);
$webhookOk = ($mobileResults['allowWebhook'] ?? true) === false ? false : custom_ha_webhook($allowed[$name]);
$mobileOk = !$mobileResults || findmydevice_bool_result_exists($mobileResults);
$ok = $webhookOk || $mobileOk;
custom_json([