Geofency Modul

…ich denke, dass die Berechnung von Abstand und Winkel im Modul sehr sinnvoll wären (=Richtung des Ein-/Austritts und ungefähre Vorlaufzeit). Da ich meistens den selben Weg fahre, erhoffe ich mir einfach mehr Optionen bei der Haussteuerung (z.B. Bad vorwärmen, wenn wir anreisen, aber keine Aktion, wenn ich nur kurz zum Bäcker bin). Da muss natürlich jeder selbst seine Szenarien testen. Die Einschränkung, dass die Aktualisierung nur an der Grenze erfolgt, ist für meine Zwecke akzeptabel.

Eine ganz andere Sache macht mir gelegentlich noch Probleme: Es ist schon einige Male passiert, dass der Webhook z.B. beim Verlassen einer Zone nicht angekommen ist (Internetprobleme?). Das führt dann zu komischen Effekten, z.B. bin ich dann an zwei Orten gleichzeitig - meint zumindest IPS :D. Mir fällt leider keine richtige Lösung ein, wie man das im Modul abfangen könnte, denn ein stures Setzen der anderen Zonen auf Abwesenheit bei Eintritt ist z.B. bei überlagernden Zonen nicht sinnvoll. Ich denke, ich werde die Anwesenheits-Bool-Vars noch einmal getrennt auswerten müssen nach meiner Logik der Zonen ("wenn ich nach B komme, kann ich nicht in A sein). Oder hat hier jemand das Problem intelligenter gelöst?

Schöne Grüße! Carsten

Kannst Du mal schauen ob bei Dir da ein sinnvoller Wert rauskommt (ObjektIDs anpassen)?


$center_longitude = GetValue(32967 /*[Geofency\iPhone\Longitude]*/);
$center_latitude = GetValue(32691 /*[Geofency\iPhone\Latitude]*/);
$current_longitude = GetValue(34829 /*[Geofency\iPhone\current Longitude]*/);
$current_latitude = GetValue(12839 /*[Geofency\iPhone\current Latitude]*/);

$distance = GetDistanceToCenter($center_latitude, $center_longitude, $current_latitude, $current_longitude, "m");
var_dump($distance);


 function GetDistanceToCenter($center_latitude, $center_longitude, $current_latitude, $current_longitude, $unit)
 {
  $theta = $center_longitude - $current_longitude;
  $distance = sin(deg2rad($center_latitude)) * sin(deg2rad($current_latitude)) +  cos(deg2rad($center_latitude)) * cos(deg2rad($current_latitude)) * cos(deg2rad($theta));
  $distance = acos($distance);
  $distance = rad2deg($distance); 
  $miles = $distance * 60 * 1.1515;
  $unit = strtoupper($unit);

  if ($unit == "KM") // Kilometer
  {
    $distance = round(($miles * 1.609344), 2);
  }
  else if ($unit == "NM") // Nautic Mile NM
  {
      $distance = round(($miles * 0.8684), 2);
  }
  else if ($unit == "M") // Meter m
  {
      $distance = round(($miles * 1.609344 * 1000), 2);
  }
  else
  {
        $distance = round($miles, 2);
  }

	return $distance;
 }

…das sieht super aus! Danke! Sobald das Update für das Modul und damit die Variablen verfügbar sind, werde ich es testen und Feedback geben. Bin aber eh erst mal ein paar Tage auf Dienstreise…

Danke für den PR. Habe mal Kommentiert. Ein paar Wünsche aber dann merge ich das gerne :slight_smile:

paresy

Hoffe es passt jetzt so, was dann noch fehlt wären zwei weitere Variablen. Distanz zum Zentrum und Eintrittswinkel.
Die Distanz hoffe ich kann man so wie oben angegeben berechnen. Beim Winkel bzw. der Himmelsrichtung habe ich mir noch keine Gedanken gemacht. Fürs erste reicht es ja denke ich mal wenn die beiden Variablen überhaupt vorhanden sind.

Ist gemerged und online :slight_smile:

paresy

Winkel


$center_longitude = GetValue(32967 /*[Geofency\iPhone\Longitude]*/);
$center_latitude = GetValue(32691 /*[Geofency\iPhone\Latitude]*/);
$current_longitude = GetValue(34829 /*[Geofency\iPhone\current Longitude]*/);
$current_latitude = GetValue(12839 /*[Geofency\iPhone\current Latitude]*/);

$angle = GetDirectionToCenter($center_latitude, $center_longitude, $current_latitude, $current_longitude);
var_dump($angle);
SetValue(40604 /*[Info\Geofency\Richtung Grad]*/, $angle);
$direction = getCompassDirection($angle);
var_dump($direction);
SetValue(27705 /*[Info\Geofency\Himmelsrichtung]*/, $direction);

function GetDirectionToCenter($lat1, $lon1, $lat2, $lon2)
 {
 	//difference in longitudinal coordinates
   $dLon = deg2rad($lon2) - deg2rad($lon1); // Δlon = abs( lonA - lonB ) 
 
   //difference in the phi of latitudinal coordinates
   $dPhi = log(tan(deg2rad($lat2) / 2 + pi() / 4) / tan(deg2rad($lat1) / 2 + pi() / 4)); // Δφ = ln( tan( latB / 2 + π / 4 ) / tan( latA / 2 + π / 4) ) 
	
	//Note: 1) ln = natural log      2) if Δlon > 180°  then   Δlon = Δlon (mod 180).  3) operation a mod n     4) function atan2(y, x)      5) the angles are in radians 
		   
	//we need to recalculate $dLon if it is greater than pi
   if(abs($dLon) > pi()) {
      if($dLon > 0) {
         $dLon = (2 * pi() - $dLon) * -1;
      }
      else {
         $dLon = 2 * pi() + $dLon;
      }
   }
   //return the angle, normalized
   $angle = (rad2deg(atan2($dLon, $dPhi)) + 360) % 360; // tragen :  θ = atan2( Δlon ,  Δφ ) 
   return $angle;
 }

function getCompassDirection($angle) {
   $tmp = round($angle / 22.5);
   switch($tmp) {
      case 1:
         $direction = "NNE";
         break;
      case 2:
         $direction = "NE";
         break;
      case 3:
         $direction = "ENE";
         break;
      case 4:
         $direction = "E";
         break;
      case 5:
         $direction = "ESE";
         break;
      case 6:
         $direction = "SE";
         break;
      case 7:
         $direction = "SSE";
         break;
      case 8:
         $direction = "S";
         break;
      case 9:
         $direction = "SSW";
         break;
      case 10:
         $direction = "SW";
         break;
      case 11:
         $direction = "WSW";
         break;
      case 12:
         $direction = "W";
         break;
      case 13:
         $direction = "WNW";
         break;
      case 14:
         $direction = "NW";
         break;
      case 15:
         $direction = "NNW";
         break;
      default:
         $direction = "N";
   }
   return $direction;
}


Super. Ich habe es gleich ausprobiert. Die Variablen current Latitude und currrent Longitude werden angelegt und auch beim Eintreten und Verlassen gefüllt.

Sie werden bei mir aber nur mit Ganzzahlen gefüllt:eek:

Auch die Variablen Latitude und Longitude werden nur mit Ganzzahlen gefüllt. Ist mir aber bislang nicht aufgefallen, da ich sie nicht benutzt habe.

Hat da jemand eine Idee, woran das liegt?

Debuginformationen im Instanzenfenster gibt es keine, oder?

Gruß

Burkhard

Doch einfach das Debug Fenster der Geofency Instanz öffnen. Ist aber komisch mit den Ganzen Zahlen, bei mir wird Float übergeben.

Es liegt wohl an der ParseFloat Funktion. Sie macht bei mir aus ‚51.7244352328008‘ bei LocaleInfo[„decimal_point“] == ‚,‘ eine 51.

Das Debugfenster funktioniert doch und zeigt auch Float Werte an.:banghead:

/EDIT:

Genauer gesagt liegt die Ursache wohl in


    $floatString = str_replace(".", $LocaleInfo["decimal_point"], $floatString);

Denn danach ist $floatString == ‚51,7244352328008‘ und daraus macht das anschließende floatval eine 51.

Wenn ich die Zeile auskommentiere dann geht’s.

Komisch, dann kann das ja aber an sich bei Dir ja noch nie funktioniert haben. Ich weis auch nicht warum Paresy da localeconv() benutzt. Ansich muss da ja einfach immer ein „.“ eingesetzt werden.
Was gibt denn bei Dir


$LocaleInfo = localeconv(); 
var_dump($LocaleInfo);

aus?
Bei mir kommt da ein . als Trennzeichen dann funktioniert das auch. Ich würde da einfach localeconv() raus nehmen und grundsätzlich einen Punkt setzten, vielleicht habe ich da aber auch einen Denkfehler.

Die Funktion ist meiner Meinung nach verdreht, da floatval() die lokalen Einstellungen nicht berücksichtigt.

Richtig wäre:


function ParseFloat($floatString){ 
    $LocaleInfo = localeconv(); 
    $floatString = str_replace($LocaleInfo['thousands_sep'] , '', $floatString); 
    $floatString = str_replace($LocaleInfo['decimal_point'] , '.', $floatString); 
    return floatval($floatString); 
} 

So ist es auch hier bei den Beispielen zu finden.

Ich bin übrigens unter Windows mit deutschen Einstellungen unterwegs…

//EDIT:

der Fehler ist auch in SymconMisc\EgiGeoZone\module.php enthalten

//EDIT (2):
Noch ein anderer Punkt:

Wenn ‚Proximity‘ bei einem Ort ausgeschaltet ist, dann sollten die Variablen current Latitude und current Longitude geleert werden. Sonst ist nur aufwändig anhand der Timestamps erkennbar, ob die ‚currents‘ auch zum aktuellen Ereignis gehören.

Ja so macht das auch Sinn, die andere Funktion habe ich wie gesagt nicht verstanden weil die haut einem am Schluss noch ein Komma rein wenn die Lokalen Einstellungen so sind. Auch wenn es für den konkreten Fall etwas zu viel des Guten ist, denn die Zahlen werden ja sauber mit . geliefert, aber so würde man dann zumindest auch alle Zahlen im US Stil wie 1.950,50 sauber in ein Float überführen.

Ich habe nun auch die Funktionen GetDirectionToCenter, GetDistanceToCenter und getCompassDirection ausprobiert. Sie funktionieren tadellos.

Können sie vielleicht noch mit in das Modul übernommen werden? Halte ich zumindest für die ersten beiden für sinnvoll. Die Funktion getCompassDirection ist schon eher speziell, zumal sie die englischen Bezeichnungen zurückgibt.

Ich fände es gut, wenn gleich die Variablen ‚current Direction to Center‘ (als Integer) und ‚current Distance to Center‘ (als Integer in Meter) zur Verfügung gestellt würden.

@Fonzo: könntest du einen neuen PR schreiben?

Gruß

Burkhard

Habe ich ergänzt.

Ist jetzt deutsch und ein Variablenprofil, das kann dann also derjenige anpassen, der das in einer anderen Sprache haben will.

Habe ich gemacht.

Perfekt. Besten Dank!

Hast du meine Anmerkung unter ‚EDIT 2‘ gesehen? Da hat sich meine Bearbeitung wahrscheinlich mit deiner Antwort überschnitten.

Vielleicht kannst du das noch aufnehmen.

Gruß

Burkhard

Ja hab ich gemacht wird auf 0 gesetzt wenn die Variable existent ist aber kein Wert gesendet wird. Himmelrichtung ist dann eben bei 0 bzw. Nord was nicht stimmt, aber das kann man glaube ich verschmerzen, man sieht ja das der Wert auf 0 steht von der aktuellen Position.

[emoji106] [emoji106] [emoji106]

…auch von mir herzliches Danke!

Hallo IPS Team,

es wäre super, wenn Ihr die beiden Pull Requests für die oben beschriebene Erweiterung des Moduls bearbeiten könntet. Damit wäre a) die gewünschte Funktion vollständig verfügbar und b) das Thema abgehakt. Ich glaube, hier würden einige gern weiter arbeiten/experimentieren…

Danke auf jeden Fall schon einmal.