How to access IoT core devices from Google Apps Script?

114 Views Asked by At

I use a script that runs a Nest thermostat. It works well for me, but when I share it with another person with multiple thermostats, it does not work even though I set up the script to run only on one of his thermostats.

This is the script I am talking about:

function changetemp() {
  // enter the thermostat ID manually after running makerequesttest function
  const THERMOSTAT = '';
const smartService = getSmartService();
const access_token = smartService.getAccessToken();
const url = 'https://smartdevicemanagement.googleapis.com/v1';
const endpoint = '/enterprises/' + PROJECT_ID + '/devices';
const headers = {
    'Authorization': 'Bearer ' + access_token,
    'Content-Type': 'application/json'
}
const params = {
  'headers': headers,
  'method': 'get',
  'muteHttpExceptions': true
}

try {
    const response = UrlFetchApp.fetch(url + endpoint, params);
    const responseCode = response.getResponseCode();
    const responseBody = JSON.parse(response.getContentText());
    
    console.log("Response code: " + responseCode);
    console.log(responseBody);

    const devices = responseBody['devices'];
  
    const device = devices.find(d => d.name === 'enterprises/' + PROJECT_ID + '/devices/' + THERMOSTAT)
    if (!device) {
      console.log("Thermostat with ID " + THERMOSTAT + " not found.")
    return
    }
}

The person with multiple thermostats gets the "not found" message, while it works for me.

The THERMOSTAT const is gotten from that function that we execute first:

function makeRequesttest() {

  // get the smart service
  const smartService = getSmartService();
   
  // get the access token
  const access_token = smartService.getAccessToken();
  //console.log(access_token);
 
  // setup the SMD API url
  const url = 'https://smartdevicemanagement.googleapis.com/v1';
  const endpoint = '/enterprises/' + PROJECT_ID + '/devices';
 
  // setup the headers for the call
  const headers = {
    'Authorization': 'Bearer ' + access_token,
    'Content-Type': 'application/json'
  }
   
  // set up params
  const params = {
    'headers': headers,
    'method': 'get',
    'muteHttpExceptions': true
  }
   
  // try calling API
  try {
    const response = UrlFetchApp.fetch(url + endpoint, params);
    const responseBody = JSON.parse(response.getContentText());
    Logger.log('response: ' + response);
    return responseBody;
  }
  catch(e) {
    console.log('Error: ' + e);
    //throw e;
  }
}

The makeRequesttest() function gives me that result:

response: {
  "devices": [
    {
      "name": "enterprises/AAA/devices/BBB",
      "type": "sdm.devices.types.THERMOSTAT",
      "assignee": "enterprises/AAA/structures/CCC/rooms/DDD",
      "traits": {
        "sdm.devices.traits.Info": {
          "customName": ""
        },
        "sdm.devices.traits.Humidity": {
          "ambientHumidityPercent": 58
        },
        "sdm.devices.traits.Connectivity": {
          "status": "ONLINE"
        },
        "sdm.devices.traits.Fan": {},
        "sdm.devices.traits.ThermostatMode": {
          "mode": "OFF",
          "availableModes": [
            "HEAT",
            "OFF"
          ]
        },
        "sdm.devices.traits.ThermostatEco": {
          "availableModes": [
            "OFF",
            "MANUAL_ECO"
          ],
          "mode": "OFF",
          "heatCelsius": 13.04544,
          "coolCelsius": 24.44443
        },
        "sdm.devices.traits.ThermostatHvac": {
          "status": "OFF"
        },
        "sdm.devices.traits.Settings": {
          "temperatureScale": "CELSIUS"
        },
        "sdm.devices.traits.ThermostatTemperatureSetpoint": {},
        "sdm.devices.traits.Temperature": {
          "ambientTemperatureCelsius": 9.20999
        }
      },
      "parentRelations": [
        {
          "parent": "enterprises/AAA/structures/EEE/rooms/FFF",
          "displayName": "Office"
        }
      ]
    }
  ]
}

With that log, I manually update the THERMOSTAT const value.

The person with multiple thermostats gets that result with makeRequestest():

Logging output too large. Truncating output. response: {
  "devices": [
    {
      "name": "enterprises/XXX/devices/AVPHwGGG",
      "type": "sdm.devices.types.THERMOSTAT",
      "assignee": "enterprises/XXX/structures/YYY/rooms/ZZZ",
      "traits": {
        "sdm.devices.traits.Info": {
          "customName": ""
        },
        "sdm.devices.traits.Humidity": {
          "ambientHumidityPercent": 28
        },
        "sdm.devices.traits.Connectivity": {
          "status": "ONLINE"
        },
        "sdm.devices.traits.Fan": {},
        "sdm.devices.traits.ThermostatMode": {
          "mode": "HEAT",
          "availableModes": [
            "HEAT",
            "OFF"
          ]
        },
        "sdm.devices.traits.ThermostatEco": {
          "availableModes": [
            "OFF",
            "MANUAL_ECO"
          ],
          "mode": "OFF",
          "heatCelsius": 16.52971,
          "coolCelsius": 24.44444
        },
        "sdm.devices.traits.ThermostatHvac": {
          "status": "OFF"
        },
        "sdm.devices.traits.Settings": {
          "temperatureScale": "FAHRENHEIT"
        },
        "sdm.devices.traits.ThermostatTemperatureSetpoint": {
          "heatCelsius": 17.777779
        },
        "sdm.devices.traits.Temperature": {
          "ambientTemperatureCelsius": 19.17
        }
      },
      "parentRelations": [
        {
          "parent": "enterprises/XXX/structures/YYY/rooms/ZZZ",
          "displayName": "Notinteresting1"
        }
      ]
    },
    {
      "name": "enterprises/XXX/devices/AVPHAAA",
      "type": "sdm.devices.types.THERMOSTAT",
      "assignee": "enterprises/XXX/structures/YYY/rooms/BBB",
      "traits": {
        "sdm.devices.traits.Info": {
          "customName": ""
        },
        "sdm.devices.traits.Humidity": {
          "ambientHumidityPercent": 27
        },
        "sdm.devices.traits.Connectivity": {
          "status": "ONLINE"
        },
        "sdm.devices.traits.Fan": {},
        "sdm.devices.traits.ThermostatMode": {
          "mode": "HEAT",
          "availableModes": [
            "HEAT",
            "OFF"
          ]
        },
        "sdm.devices.traits.ThermostatEco": {
          "availableModes": [
            "OFF",
            "MANUAL_ECO"
          ],
          "mode": "OFF",
          "heatCelsius": 12.77776,
          "coolCelsius": 24.44444
        },
        "sdm.devices.traits.ThermostatHvac": {
          "status": "HEATING"
        },
        "sdm.devices.traits.Settings": {
          "temperatureScale": "FAHRENHEIT"
        },
        "sdm.devices.traits.ThermostatTemperatureSetpoint": {
          "heatCelsius": 18.98769
        },
        "sdm.devices.traits.Temperature": {
          "ambientTemperatureCelsius": 19.03
        }
      },
      "parentRelations": [
        {
          "parent": "enterprises/XXX/structures/YYY/rooms/BBB",
          "displayName": "Notinteresting2"
        }
      ]
    },
    {
      "name": "enterprises/XXX/devices/CCC",
      "type": "sdm.devices.types.THERMOSTAT",
      "assignee": "enterprises/XXX/structures/YYY/rooms/DDD",
      "traits": {
        "sdm.devices.traits.Info": {
          "customName": ""
        },
        "sdm.devices.traits.Humidity": {
          "ambientHumidityPercent": 29
        },
        "sdm.devices.traits.Connectivity": {
          "status": "ONLINE"
        },
        "sdm.devices.traits.Fan": {},
        "sdm.devices.traits.ThermostatMode": {
          "mode": "HEAT",
          "availableModes": [
            "HEAT",
            "OFF"
          ]
        },
        "sdm.devices.traits.ThermostatEco": {
          "availableModes": [
            "OFF",
            "MANUAL_ECO"
          ],
          "mode": "OFF",
          "heatCelsius": 17.062832,
          "coolCelsius": 24.44444
        },
        "sdm.devices.traits.ThermostatHvac": {
          "status": "OFF"
        },
        "sdm.devices.traits.Settings": {
          "temperatureScale": "FAHRENHEIT"
        },
        "sdm.devices.traits.ThermostatTemperatureSetpoint": {
          "heatCelsius": 16.71161
        },
        "sdm.devices.traits.Temperature": {
          "ambientTemperatureCelsius": 19.67999
        }
      },
      "parentRelations": [
        {
          "parent": "enterprises/XXX/structures/YYY/rooms/DDD",
          "displayName": "Theone"
        }
      ]
    },
    {
      "name": "enterprises/XXX/devices/EEE",
      "type": "sdm.devices.types.THERMOSTAT",
      "assignee": "enterprises/XXX/structures/YYY/rooms/FFF",
      "traits": {
        "sdm.devices.traits.Info": {
          "customName": ""
        },
        "sdm.devices.traits.Humidity": {
          "ambientHumidityPercent": 26
        },
        "sdm.devices.traits.Connectivity": {
          "status": "ONLINE"
        },
        "sdm.devices.traits.Fan": {},
        "sdm.devices.traits.ThermostatMode": {
          "mode": "HEAT",
          "availableModes": [
            "HEAT",
            "OFF"
          ]
        },
        "sdm.devices.traits.ThermostatEco": {
          "availableModes": [
            "OFF",
            "MANUAL_ECO"
          ],
          "mode": "OFF",
          "heatCelsius": 15.586624,
          "coolCelsius": 24.444443
        },
        "sdm.devices.traits.ThermostatHvac": {
          "status": "OFF"
        },
        "sdm.devices.traits.Settings": {
          "temperatureScale": "FAHRENHEIT"
        },
        "sdm.devices.traits.ThermostatTemperatureSetpoint": {
          "heatCelsius": 18.360092
        },
        "sdm.devices.traits.Temperature": {
          "ambientTemperatureCelsius": 19.259995
        }
      },
      "parentRelations": [
        {
          "parent": "enterprises/XXX/structures/YYY/rooms/AVPHw

The thermostat with display name "Theone" is the one that we are interested in.

We updated the THERMOSTAT const manually with "CCC" in the changetemp function. And we tried with other values he got like "GGG" or "DDD" but still got the log "device not found".

For that reason, I decided to create a "dummy" device in Google Cloud Console in order to simulate the fact that I have many thermostats running.

What is the way to acces this thermostat from Google Apps Script? How to make my script run like this fake device exists in my installation?

This is what I have at the moment in my registry:

dummydevice-details

dummydevice-configstate

dummydevice-authentication

Edit: public key added to the device: dummydevice-authenticationpublickey

0

There are 0 best solutions below