On double-click, locate via GPS and cell-tower triangulation

Hi everyone,

I could probably work this out with a LOT of work, but I’m wondering if there’s someone who can help me with the following code?

So I want my LTE beacon to do the following on double-click (or single-click, if that’s not possible):

  • Establish location via both GPS and/ or cell-tower triangulation
  • Send a text message via Twilio to a specific mobile number with the location information

This process needs to occur as quickly as possible.

If anyone could help me with the code or at least give me some guidance, that would be great!

Thanks.

It does not require a lot of work. LTE Beacon was designed to make such use cases easy to implement. Here you have a draft of such an app. You can start from it. It needs proper error handling and notification, setting network tech etc. It is basically Alert Button + GPS Locator + Cellular Locator combined and simplified (Google Maps used for resolving cell towers).
Micro-app code:

function locate() {
  io.led(true)
  print("Start location")
    var gnss = location.startUpdates(()=>{ location.stop() }, {timeout: "1m" /* 1 minute might be not long enough to get fix all the time */ }); 
  var cell = modem.getStatus(); // you may use modem.getCells() but it takes longer to execute, but you have more cells

  Promise.all([gnss, cell]).then( data => { 
    print("Location data acquired. Sending.")
    io.led(false)
    print(`Data preview: ${JSON.stringify(data)}`)
    cloud.enqueue("loc_data", {gnss: data[0], cell: data[1]});
    sync.now();
  })
}

io.press(locate, io.PressType.LONG);

Cloud code:

const superagent = require('superagent');
const accountSid = 'PASTE_YOUR_TWILIO_ACCOUNT_SID_HERE';
const authToken = 'PASTE_YOUR_TWILIO_AUTH_TOKEN_HERE';
const googleMapsApiKey = "PASTE_YOUR_GOOGLE_MAPS_KEY_HERE";

const resolveCellData = async (cellData) => {
  const { body } = await superagent.post(`https://www.googleapis.com/geolocation/v1/geolocate?key=${googleMapsApiKey}`).send({
      cellTowers: [
        {
          cellId: cellData.cell,
          locationAreaCode: cellData.lac,
          mobileCountryCode: cellData.mcc,
          mobileNetworkCode: cellData.mnc,
        },
      ],
    })
    .ok(({ status }) => status === 200)
    .retry(2);
  if (body.location) {
    return { lat: body.location.lat, long: body.location.lng };
  }
  throw new Error('No location data');
};

module.exports = async function (event) {
  if (event.type === 'loc_data') {
    let position = event.payload.gnss;
    if(!position && event.payload.cell) {
      console.log("No GNSS position. Using cell towers.")
      position = await resolveCellData(event.payload.cell);
    }
    if(position) {
      const text = `Position: ${position.lat} ${position.long}`;
      console.log("Text to send: "+ text)
      if (accountSid === 'PASTE_YOUR_TWILIO_ACCOUNT_SID_HERE') {
        console.log('Twilio is not set up, not sending an SMS');
      } else {
        const twilio = require('twilio')(accountSid, authToken);
        await twilio.messages.create({
          body: text,
          to: 'PASTE_YOUR_PHONE_NUMBER_HERE',
          from: 'PASTE_YOUR_TWILIO_VERIFIED_NUMBER_HERE',
        });
      }
    }
  }
};

Thank you very much for that code, pober.

I only have very basic programming skills, so writing this code would require a lot of work. I only bought the Estimote buttons because they’re the only IOT button has exactly everything I need.

For the cellular locator, is it absolutely necessary to have a Google Maps API key? That means joining the Google Cloud Platform, which would eventually have fees associated with it.

Thank you,

H

Google Maps API is only one of the services that offers resolving cell data into geographical position. You may check Cellular Locator template that uses different provider that may better suit your needs.