Geofence Tracking with Meshtastic
This Node-RED flow listens for GPS data from a Meshtastic device, calculates the distance to a predefined geofence center using the Haversine formula, and outputs whether the device is inside or outside the geofence.
[{"id":"1","type":"mqtt in","z":"flow1","name":"","topic":"meshtastic/+/gps","qos":"2","datatype":"auto","broker":"mqtt_broker","x":100,"y":100,"wires":[["2"]]},{"id":"2","type":"function","z":"flow1","name":"Geofence","func":"const geoLat = 40.748817;\nconst geoLng = -73.985428;\nconst radius = 1000; // 1 km in meters\n\nfunction haversine(lat1, lon1, lat2, lon2) {\n const R = 6371000; // Radius of the Earth in meters\n const dLat = (lat2 - lat1) * (Math.PI / 180);\n const dLon = (lon2 - lon1) * (Math.PI / 180);\n const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) *\n Math.sin(dLon / 2) * Math.sin(dLon / 2);\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n return R * c;\n}\n\nconst latitude = msg.payload.latitude;\nconst longitude = msg.payload.longitude;\nconst distance = haversine(latitude, longitude, geoLat, geoLng);\n\nif (distance <= radius) {\n node.status({fill: \"green\", shape: \"dot\", text: \"Inside geofence\"});\n msg.payload = \"Inside geofence\";\n} else {\n node.status({fill: \"red\", shape: \"dot\", text: \"Outside geofence\"});\n msg.payload = \"Outside geofence\";\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":100,"wires":[["3"]]},{"id":"3","type":"debug","z":"flow1","name":"Output","active":true,"console":"false","complete":"true","x":500,"y":100,"wires":[]}]