Does anyone know if there is a built-in way within Hubitat APIs to determine if a provided lat/log is within the radius of the home? Or is that something that I would have to code using the haversine formula myself?
Don't think it's built in.
I have a Groovy version of Haversine in my Purple Air driver if you want to use it:
3 Likes
Just curious if I could benefit from this too: where is the lat/lon coming from?
The lat/log is coming from a car. Here is the code that I wrote to solve it:
/**
* Check if the coordinates are within the home radius.
*
* @param latitude The latitude of the current object.
* @param longitude The longitude of the current object.
* @param radius The radius the object should be within in meters or miles if.
* @param radiusInMiles Use miles instead of meters for the radius.
*
* @return
*/
private Boolean isCoordinatesInHomeRadius(
Number latitude,
Number longitude,
Number radius,
Boolean radiusInMiles = false
) {
if (radiusInMiles) {
radius *= 1609.34
}
Double distance = calculateDistance(
latitude.doubleValue(),
longitude.doubleValue(),
location.getLatitude().doubleValue(),
location.getLongitude().doubleValue(),
)
return distance <= radius
}
/**
* Calculate the distance between two points using the Haversine formula.
*
* @param lat1 The latitude of the first point, in degrees.
* @param lon1 The longitude of the first point, in degrees.
* @param lat2 The latitude of the second point, in degrees.
* @param lon2 The longitude of the second point, in degrees.
*
* @return The distance between the two points, in meters.
*/
private Double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
final int earthRadius = 6371 * 1000;
def dLat = Math.toRadians(lat2 - lat1);
def dLon = Math.toRadians(lon2 - lon1);
def a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
def c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return earthRadius * c;
}
2 Likes