findmydevice 얼굴 재생 마커와 자동 추적 차단
This commit is contained in:
+187
-2
@@ -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([
|
||||
|
||||
Reference in New Issue
Block a user