0

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

Permafrost
  • 27
  • 4
  • Whenever is possible avoid the use of images, instead use text to describe the steps you did. Also add a [mcve] showing how do you use Google Apps Script to run a Nest thermostats how do you share it with other person and the error messages / execution logs that lead you to decide to create a "dummy" device in Google Cloud. – Rubén Jan 24 '23 at 19:32
  • Ok thanks, I will do it. I guess that will not fit into comments, so I will edit my original post if possible. – Permafrost Jan 24 '23 at 19:38
  • All the relevant details *always* should be added into the question body :) – Rubén Jan 24 '23 at 19:40
  • Related: https://stackoverflow.com/q/75049406/1595451 – Rubén Jan 24 '23 at 19:46
  • Post edited. :) Actually I now replaced the makeRequest(endpoint) with a makerequesttest() function that works well. I will update the related post too. – Permafrost Jan 24 '23 at 20:13
  • I'm sorry, I find hard to understand `The thermostat with display name "Theone" is the one that we are interested in. We actually gave the THERMOSTAT the "DDD" value for him. And we tried with other values he got like "GGG" but still found the error "device not found" when running the changetemp function.` and how that lead you to create the "dummy" device. As "Theone" appears in the logs perhaps you should change the way that the script is parsing the API response. – Rubén Jan 24 '23 at 20:24
  • Actually "Theone" appears in the logs when running the makerequest function, just so that we can find its device ID instead of its name. Its device ID is actually "CCC" (I edited the post to replace "DDD" with "CCC"), but when storing the value "CCC" in the THERMOSTAT const, the changtemp function gives him that message `Thermostat with ID CCC not found.`. Since I have a hard time understanding why this changetemp function works for me but not for him, I was trying to recreate his multiple devices setup. But maybe the issue can be solved without doing this? – Permafrost Jan 24 '23 at 20:31
  • The code in the questin is uncomplete as it doesn't include the declaration of `THERMOSTAT`. The question mentions `The THERMOSTAT const is gotten from that function that we execute first:` but it's unclear how the value is assigend to this variable. – Rubén Jan 24 '23 at 20:41
  • We change the value manually in `const THERMOSTAT = 'CCC';` – Permafrost Jan 24 '23 at 20:46
  • I don't see that in the question. The question should include a [mcve]. – Rubén Jan 24 '23 at 20:47
  • @Rubén would you have any hint on what is going wrong? I am quite desperate about this since weeks now, and you are my last hope if I may say! :) – Permafrost Jan 25 '23 at 19:41
  • I'm sorry, I find the question hard to understand. I suggest to write a [mcve] (try reduce the code, sample input data and the corresponding expect output) and improve the wording. If there are parts of your script that you don't understand you might have to take some steps back and focus on understand them. – Rubén Jan 25 '23 at 20:02
  • Ok I will reformulate all of this tomorrow, in a more "chronological" way. Would you recommend me to open a new post for this, as I will not focus anymore on the dummy device? – Permafrost Jan 25 '23 at 20:06
  • Hi @Rubén, I posted a more ordered question with a real minimal reproducible example here: https://stackoverflow.com/questions/75260886/why-is-my-nest-device-not-found-when-working-in-a-multiple-devices-environment I hope it is explanatory enough, at least I made my best to do it so. :) – Permafrost Jan 27 '23 at 16:36

0 Answers0