geofence
Advanced tools
Comparing version 1.0.7 to 1.0.8
require("ansicolor").nice; | ||
const log = require("ololog").configure({ | ||
time: { yes: true, print: x => x.toLocaleString().bright.cyan + " " }, | ||
// time: { yes: true, print: x => x.toLocaleString().bright.cyan + " " }, | ||
time: {yes: false}, | ||
locate: false, | ||
@@ -22,2 +23,3 @@ tag: true | ||
locationCacheTimeoutInMinutes: 10, | ||
useBirdFlyDistanceOptimization: true, | ||
// control | ||
@@ -40,2 +42,5 @@ enable: true // Used for start/stop | ||
apiCalls: 0 | ||
}, | ||
internal:{ | ||
detinationGeocode: {} | ||
} | ||
@@ -42,0 +47,0 @@ }; |
@@ -11,2 +11,3 @@ /** | ||
const api = require("termux"); | ||
var utility_functions = require("../utility"); | ||
@@ -18,2 +19,3 @@ var log = defines.log; | ||
} | ||
var g_notification_id = 1; | ||
@@ -44,3 +46,3 @@ //----------------------------------------------------------------------------- | ||
.content("We are inside the geofence!") | ||
.id(1) | ||
.id(g_notification_id + 1) | ||
.title("Geofencing done") | ||
@@ -52,7 +54,5 @@ // .url('...') | ||
/** | ||
* Callback function to be called whenever the current location and distance | ||
* is updated | ||
* @param {Objecgt} updateDistanceResults | ||
* @returns {object} | ||
*/ | ||
async function updateDistanceCallBack(updateDistanceResults) { | ||
function buildNotification(updateDistanceResults) { | ||
let notificationTitle = ` | ||
@@ -68,8 +68,21 @@ curDist: ${updateDistanceResults.curDistance.text}, | ||
`; | ||
return { | ||
title: notificationTitle, | ||
text: notificationText | ||
}; | ||
} | ||
//----------------------------------------------------------------------------- | ||
/** | ||
* Callback function to be called whenever the current location and distance | ||
* is updated | ||
* @param {Object} updateDistanceResults | ||
*/ | ||
async function updateDistanceCallBack(updateDistanceResults) { | ||
let notification = buildNotification(updateDistanceResults); | ||
api | ||
.notification() | ||
.content(notificationText) | ||
.id(1) | ||
.title(notificationTitle) | ||
.content(notification.text) | ||
.id(g_notification_id) | ||
.title(notification.title) | ||
// .url('...') | ||
@@ -96,7 +109,5 @@ .run(); | ||
//----------------------------------------------------------------------------- | ||
const argv = process.argv.slice(2); | ||
let cliArgs = mri(argv); | ||
[ | ||
let optionKeys = [ | ||
`apiKey`, | ||
@@ -107,3 +118,6 @@ `updateInterval`, | ||
`fenceDistanceValue` | ||
].forEach(e => { | ||
]; | ||
let locationSepcKeys = [`destination`, `mode`, `origin`]; | ||
optionKeys.forEach(e => { | ||
if (cliArgs[e]) { | ||
@@ -115,3 +129,3 @@ options[e] = cliArgs[e]; | ||
[`destination`, `mode`, `origin`].forEach(e => { | ||
locationSepcKeys.forEach(e => { | ||
if (cliArgs[e]) { | ||
@@ -123,4 +137,5 @@ locationSepc[e] = cliArgs[e]; | ||
g_notification_id = utility_functions.hashCode(locationSepc.destination); | ||
var geofence = require("../index.js")(options, locationSepc); | ||
geofence.start(options); |
102
index.js
@@ -1,2 +0,1 @@ | ||
var utility_functions = require("./utility"); | ||
var defines = require("./defines"); | ||
@@ -6,2 +5,4 @@ const moment = require("moment"); | ||
var googleMapsClient; | ||
const geolib = require("geolib"); | ||
var utility_functions = require("./utility"); | ||
@@ -62,2 +63,5 @@ //----------------------------------------------------------------------------- | ||
} else { | ||
// First calculate the bird-fly-distance without Google API | ||
// let shouldCallAPI = shouldCallAPIBasedOnDirectFlyDistance(curLocation); | ||
// Call google API | ||
@@ -70,3 +74,3 @@ result = await getDistance( | ||
// Update cashe | ||
// Update cache | ||
defines.cache.distance[curLocation] = { | ||
@@ -79,7 +83,5 @@ value: result, | ||
log.error("Error: ", error); | ||
} | ||
} | ||
if(!result.distance.distance){ | ||
if (!result.distance.distance) { | ||
log.error("Distance was not found: ", `curLocation: ${curLocation}`); | ||
@@ -93,8 +95,11 @@ } else { | ||
log.info("apiCalls: ", defines.Globals.counters.apiCalls); | ||
let insideFence = false; | ||
if ( | ||
result.distance.duration && | ||
["duration", "both", "either"].includes(defines.Globals.options.activateFenceOn) && | ||
result.distance.duration.value <= defines.Globals.options.fenceDurationValue | ||
["duration", "both", "either"].includes( | ||
defines.Globals.options.activateFenceOn | ||
) && | ||
result.distance.duration.value <= | ||
defines.Globals.options.fenceDurationValue | ||
) { | ||
@@ -109,7 +114,10 @@ log.info( | ||
} | ||
if ( | ||
result.distance.distance && | ||
["distance", "both", "either"].includes(defines.Globals.options.activateFenceOn) && | ||
result.distance.distance.value <= defines.Globals.options.fenceDistanceValue | ||
["distance", "both", "either"].includes( | ||
defines.Globals.options.activateFenceOn | ||
) && | ||
result.distance.distance.value <= | ||
defines.Globals.options.fenceDistanceValue | ||
) { | ||
@@ -124,7 +132,6 @@ log.info( | ||
} | ||
// Call updateDistanceResults | ||
if (defines.Globals.options.updateDistanceCallBack) { | ||
let updateDistanceResults={ | ||
let updateDistanceResults = { | ||
curAddress: result.origin_address, | ||
@@ -135,11 +142,11 @@ destAddress: result.destination_address, | ||
curDuration: result.distance.duration, | ||
activateFenceOn:defines.Globals.options.activateFenceOn, | ||
fenceDurationValue:defines.Globals.options.fenceDurationValue, | ||
fenceDistanceValue:defines.Globals.options.fenceDistanceValue, | ||
activateFenceOn: defines.Globals.options.activateFenceOn, | ||
fenceDurationValue: defines.Globals.options.fenceDurationValue, | ||
fenceDistanceValue: defines.Globals.options.fenceDistanceValue, | ||
apiCalls: defines.Globals.counters.apiCalls, | ||
insideFence: insideFence | ||
} | ||
}; | ||
defines.Globals.options.updateDistanceCallBack(updateDistanceResults); | ||
} | ||
if (insideFence) { | ||
@@ -157,3 +164,3 @@ log.info("We are inside the fence!".green); | ||
} | ||
log.info( | ||
@@ -164,3 +171,56 @@ "-----------------------------------------------------------------------------" | ||
//----------------------------------------------------------------------------- | ||
/** | ||
* Using the bird-fly-distance, decides if we should call distance API. | ||
* This is based on the fact that if the bird-fly-distance is much higher than | ||
* the fence range, We already know that we are outside the fence, and | ||
* there is no point in calling the API. | ||
* Similarly, if the bird-fly-distance is much lower than the fence range, | ||
* we already know that we are inside the fence. | ||
* THIS FUNCTION IS NOT COMPLETE YET! | ||
* @param {String} curLocation | ||
* @returns {boolean} | ||
*/ | ||
function shouldCallAPIBasedOnDirectFlyDistance(curLocation) { | ||
let result = true; | ||
if (defines.Globals.options.useBirdFlyDistanceOptimization) { | ||
let latLong = utility_functions.getLatLong(curLocation); | ||
if (latLong) { | ||
let birdDistance = geolib.getDistance( | ||
latLong, | ||
defines.Globals.options.destLatLong, | ||
(accuracy = 1) | ||
); | ||
console.log("birdDistance: ", JSON.stringify(birdDistance)); | ||
} | ||
} | ||
return result; | ||
} | ||
//----------------------------------------------------------------------------- | ||
async function main() { | ||
if (defines.Globals.options.useBirdFlyDistanceOptimization) { | ||
log.info("Geocoding the destination..."); | ||
let geocode = await googleMapsClient | ||
.geocode({ | ||
address: defines.Globals.locationSpecs.destination | ||
}) | ||
.asPromise(); | ||
defines.Globals.counters.apiCalls++; | ||
defines.Globals.internal.detinationGeocode = geocode; | ||
if ( | ||
utility_functions.validChain(geocode, "json", "results") && | ||
geocode.json.results[0].geometry | ||
) { | ||
defines.Globals.options.destLatLong = | ||
geocode.json.results[0].geometry.location; | ||
log.info( | ||
"Destination Geocode: ", | ||
JSON.stringify(geocode.json.results[0].geometry.location) | ||
); | ||
} | ||
} | ||
defines.Globals.intervals.aggregatePriceInterval = setInterval(() => { | ||
@@ -167,0 +227,0 @@ if (defines.Globals.options.enable) { |
{ | ||
"name": "geofence", | ||
"version": "1.0.7", | ||
"version": "1.0.8", | ||
"description": "Geofencing for npm", | ||
"main": "index.js", | ||
"main": "test_api.js", | ||
"scripts": { | ||
@@ -31,7 +31,9 @@ "test": "echo \"Error: no test specified\" && exit 1" | ||
"ansicolor": "^1.1.92", | ||
"geolib": "^3.0.4", | ||
"moment": "^2.24.0", | ||
"mri": "^1.1.4", | ||
"ololog": "^1.1.144", | ||
"prompt": "^1.0.0", | ||
"termux": "^1.1.0" | ||
} | ||
} |
@@ -6,2 +6,3 @@ # Geofence | ||
[![NPM](https://badge.fury.io/js/geofence.svg)](https://www.npmjs.com/package/geofence) | ||
[![NPM Downloads][downloadst-image]][downloads-url] | ||
@@ -76,2 +77,9 @@ - [x] Check the current location's distance/duration againts the destination | ||
- [examples/termux.js](examples/termux.js): demonstrates running inside [Termux](https://termux.com/) and [Termux-API](https://play.google.com/store/apps/details?id=com.termux.api) on Android using device GPS and system notifications. Run with: | ||
- `node termux.js --apiKey=YOUR_API_KEY --destination="320 Main St, Venice, CA" --fenceDurationValue=5 --updateInterval=10` | ||
- `node termux.js --apiKey=YOUR_API_KEY --destination="320 Main St, Venice, CA" --fenceDurationValue=300 --updateInterval=10` | ||
- [examples/termux_prompt.js](examples/termux_prompt.js): demonstrates running inside [Termux](https://termux.com/) and [Termux-API](https://play.google.com/store/apps/details?id=com.termux.api) on Android using device GPS and system notifications. It receives the inputs from command prompt: | ||
- `node termux_prompt.js` | ||
[downloads-image]: https://img.shields.io/npm/dm/geofence.svg | ||
[downloadst-image]: https://img.shields.io/npm/dt/geofence.svg | ||
[downloads-url]: https://npmjs.org/package/geofence |
@@ -9,6 +9,6 @@ var defines = require("./defines"); | ||
let items = [ | ||
"Hayward, CA", | ||
"San Jose, CA", | ||
// "Hayward, CA", | ||
// "San Jose, CA", | ||
"41.43206,-81.38992", | ||
"San Francisco, CA" | ||
// "San Francisco, CA" | ||
]; | ||
@@ -33,3 +33,3 @@ | ||
let locationSepc = { | ||
destination: "Oakland, CA" | ||
destination: "Los Angeles, CA" | ||
}; | ||
@@ -36,0 +36,0 @@ //----------------------------------------------------------------------------- |
@@ -85,2 +85,35 @@ var defines = require("./defines"); | ||
//----------------------------------------------------------------------------- | ||
/** | ||
* Hashes a string to a number | ||
* https://stackoverflow.com/a/7616484/1383356 | ||
* @param {String} stringValue | ||
* @returns {number} | ||
*/ | ||
function hashCode(stringValue) { | ||
var hash = 0; | ||
stringValue = stringValue || "Utility"; | ||
if (stringValue.length == 0) return hash; | ||
for (let i = 0; i < stringValue.length; i++) { | ||
let c = stringValue.charCodeAt(i); | ||
hash = (hash << 5) - hash + c; | ||
hash = hash & hash; // Convert to 32bit integer | ||
} | ||
return hash; | ||
} | ||
//----------------------------------------------------------------------------- | ||
/** | ||
* | ||
* @param {String} locationString | ||
* @returns {object} | ||
*/ | ||
function getLatLong(locationString) { | ||
let valueArr = locationString.split(","); | ||
let result={}; | ||
if (valueArr && valueArr.length == 2) { | ||
result["lat"] = Number(valueArr[0]); | ||
result["lng"] = Number(valueArr[1]); | ||
} | ||
return result; | ||
} | ||
//----------------------------------------------------------------------------- | ||
@@ -94,2 +127,4 @@ var exports = (module.exports = { | ||
formatNumber: formatNumber, | ||
hashCode: hashCode, | ||
getLatLong: getLatLong | ||
}); |
829878
13
887
84
8
+ Addedgeolib@^3.0.4
+ Addedprompt@^1.0.0
+ Added@colors/colors@1.5.0(transitive)
+ Addedasync@2.6.43.2.3(transitive)
+ Addedcolors@1.0.3(transitive)
+ Addedcycle@1.0.3(transitive)
+ Addedeyes@0.1.8(transitive)
+ Addedgeolib@3.3.4(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedmute-stream@0.0.8(transitive)
+ Addedprompt@1.3.0(transitive)
+ Addedread@1.0.7(transitive)
+ Addedrevalidator@0.1.8(transitive)
+ Addedstack-trace@0.0.10(transitive)
+ Addedwinston@2.4.7(transitive)