nest api target temperature for both thermostat modes - target

Is it possible to fetch target temperature for both thermostat mode (cool, heat) in one call ? For now I have a feeling that I can get target temperature for current thermostat mode and then change thermostat mode to second one and get target temperature for second thermostat mode.
Also the same question for changing target temps. Is it possible to change both target temperature for heat and cool mode in one request ?

Assuming your system can cool and heat, the thermostat has 3 modes: heat, cool, heat-cool.
If you are in heat mode or cool mode you can set target_temperature. If you are in heat-cool mode you can set target_temperature_low_c & target_temperature_high_c.
You can retrieve all target temperatures in one thermostat call:
https://developer-api.nest.com/devices/thermostats/$THERMOSTAT_ID?auth=$AUTH
You can set heat-cool temperatures in one call, but you will need to be in heat-cool mode:
{"target_temperature_low_c": 19, "target_temperature_high_c": 21}
You can set heat or cool temperature in one call, but you will need to be in heat or cool mode:
{"target_temperature_c": 20}
You will need to make 2 calls to set the mode and set the temperature(s) if you are not already in an appropriate mode.

It is possible to get all of the thermostat data, even for multiple thermostats in a single API call. I just posted an opensource application written in python that does it on BitBucket at:
https://bitbucket.org/dwalton64_/window-watcher
The application looks at weather data from weather underground, air quality data from airnow and data from Nest to determine if the user should open or close the windows. I make the API call to Nest, getting all of the data in a single call, and then parse the data in a structure. The application then uses the thermostat hvac mode and the target temperature to see if the user should open the windows.
Here is some Python code I pulled out of my application:
nestUserUrl = "https://developer-api.nest.com/?auth=" + auth_token
nest_user_file = urllib2.urlopen(self.nestUserUrl)
nest_user_json = json.loads(nest_user_file.read())
# copy thermostat data out of the json from Nest
thermostat_data = []
for tstat_id in nest_user_json['devices']['thermostats']:
thermostat_data.append(nest_user_json['devices']['thermostats'][tstat_id])
# create thermostat objects containing the thermostat data we want to access
thermostats = []
for tstat in thermostat_data:
thermostats.append(
NestThermostat(tstat['ambient_temperature_f'], tstat['device_id'],
tstat['hvac_mode'],
tstat['is_online'], tstat['last_connection'],
tstat['name'],
tstat['software_version'], tstat['structure_id'],
tstat['target_temperature_f'],
tstat['target_temperature_high_f'],
tstat['target_temperature_low_f']))
class NestThermostat():
def __init__(self, ambient_temperature_f, device_id, hvac_mode, is_online,
last_connection, name, software_version, structure_id,
target_temperature_f, target_temperature_high_f, target_temperature_low_f):
self.ambient_temperature_f = ambient_temperature_f
self.device_id = device_id
self.hvac_mode = hvac_mode
self.is_online = is_online
self.last_connection = last_connection
self.name = name
self.software_version = software_version
self.structure_id = structure_id
self.target_temperature_f = target_temperature_f
self.target_temperature_high_f = target_temperature_high_f
self.target_temperature_low_f = target_temperature_low_f
def print_current_temp_f(self):
print("Thermostat " + self.name + " measures a current temperature of " + str(
self.ambient_temperature_f) + " degrees F")
def print_target_temp_f(self):
print("Thermostat " + self.name + " is set to " + str(self.target_temperature_f) + " degrees F")
Once I have the data in the thermostat objects, I can use both the hvac mode and the target temperatures:
email = ""
for thermostat in thermostats:
email += "For the thermostat " + thermostat.name + ":\n"
if thermostat.hvac_mode == 'cool':
if myWeather.temp_f < thermostat.target_temperature_f:
open_windows = True
email += " - It is cool outside (" + str(myWeather.temp_f) + " Deg F). \n"
else:
email += " - It is too hot outside to have the windows open. \n"
email += " - Thermostat is set at " + str(thermostat.target_temperature_f) + \
" Deg F\n"
if thermostat.hvac_mode == 'heat-cool':
if thermostat.target_temperature_high_f > myWeather.temp_f > thermostat.target_temperature_low_f:
open_windows = True
email += " - Thermostat is set to heat-cool and it's comfortable out (" + \
str(myWeather.temp_f) + " Deg F). \n"
elif myWeather.temp_f >= thermostat.target_temperature_high_f:
email += " - The thermostat is set to heat-cool and it is hot outside (" + \
str(myWeather.temp_f) + " Deg F). \n"
else:
email += " - The thermostat is set to heat-cool & it is cold outside (" + \
str(myWeather.temp_f) + " Deg F). \n"
email += " - The thermostat is set to cool at " + \
str(thermostat.target_temperature_high_f) + " Deg F\n"
email += " - The thermostat is set to heat at " + \
str(thermostat.target_temperature_low_f) + " Deg F\n"
if thermostat.hvac_mode == 'heat':
if myWeather.temp_f > thermostat.target_temperature_f:
open_windows = True
email += " - The thermostat is set to heat and it is warm outside (" + \
str(myWeather.temp_f) + " Deg F). \n"
else:
email += " - The thermostat is set to heat and it is cool outside (" + \
str(myWeather.temp_f) + " Deg F). \n"
email += " - Thermostat is set at " + str(thermostat.target_temperature_f) + \
" Deg F\n"
email += "\n"
Note that the target temperature for heat and cool mode is the same value: target_temperature_f.

Related

print method in lua script/redis is not working

I am trying to execute the following script and getting the below error. Redis is running in docker
Exception in thread "main" org.redisson.client.RedisException: ERR
user_script:1: Script attempted to access nonexistent global variable
'print' script: 6f736423f082e141036b833d1f86b5a36a494611, on
#user_script:1..
I get the same error when I execute using redis CLI
127.0.0.1:6379> eval "print("Comparison is_made b/w minimum_value out of two is: ")" 0 (error) ERR user_script:1: Script attempted to
access nonexistent global variable 'print' script:
8598b7f0db450c711d3a9e73a296e331bd1ef945, on #user_script:1.
127.0.0.1:6379>
Java code. I am using Redison lib to connect to Redis and execute script.
String script = "local rate = redis.call('hget', KEYS[1], 'rate');"
+ "local interval = redis.call('hget', KEYS[1], 'interval');"
+ "local type = redis.call('hget', KEYS[1], 'type');"
+ "assert(rate ~= false and interval ~= false and type ~= false, 'RateLimiter is not initialized')"
+ "local valueName = KEYS[2];"
+ "local permitsName = KEYS[4];"
+ "if type == '1' then "
+ "valueName = KEYS[3];"
+ "permitsName = KEYS[5];"
+ "end;"
+"print(\"rate\"..rate) ;"
+"print(\"interval\"..interval) ;"
+"print(\"type\"..type); "
+ "assert(tonumber(rate) >= tonumber(ARGV[1]), 'Requested permits amount could not exceed defined rate'); "
+ "local currentValue = redis.call('get', valueName); "
+ "local res;"
+ "if currentValue ~= false then "
+ "local expiredValues = redis.call('zrangebyscore', permitsName, 0, tonumber(ARGV[2]) - interval); "
+ "local released = 0; "
+ "for i, v in ipairs(expiredValues) do "
+ "local random, permits = struct.unpack('Bc0I', v);"
+ "released = released + permits;"
+ "end; "
+ "if released > 0 then "
+ "redis.call('zremrangebyscore', permitsName, 0, tonumber(ARGV[2]) - interval); "
+ "if tonumber(currentValue) + released > tonumber(rate) then "
+ "currentValue = tonumber(rate) - redis.call('zcard', permitsName); "
+ "else "
+ "currentValue = tonumber(currentValue) + released; "
+ "end; "
+ "redis.call('set', valueName, currentValue);"
+ "end;"
+ "if tonumber(currentValue) < tonumber(ARGV[1]) then "
+ "local firstValue = redis.call('zrange', permitsName, 0, 0, 'withscores'); "
+ "res = 3 + interval - (tonumber(ARGV[2]) - tonumber(firstValue[2]));"
+ "else "
+ "redis.call('zadd', permitsName, ARGV[2], struct.pack('Bc0I', string.len(ARGV[3]), ARGV[3], ARGV[1])); "
+ "redis.call('decrby', valueName, ARGV[1]); "
+ "res = nil; "
+ "end; "
+ "else "
+ "redis.call('set', valueName, rate); "
+ "redis.call('zadd', permitsName, ARGV[2], struct.pack('Bc0I', string.len(ARGV[3]), ARGV[3], ARGV[1])); "
+ "redis.call('decrby', valueName, ARGV[1]); "
+ "res = nil; "
+ "end;"
+ "local ttl = redis.call('pttl', KEYS[1]); "
+ "if ttl > 0 then "
+ "redis.call('pexpire', valueName, ttl); "
+ "redis.call('pexpire', permitsName, ttl); "
+ "end; "
+ "return res;";
RedissonClient client = null;
try {
client = Redisson.create();
client.getRateLimiter("user1:endpoint1").setRate(
RateType.PER_CLIENT, 5, 1, RateIntervalUnit.SECONDS);
String sha1 = client.getScript().scriptLoad(script);
List<Object> keys =
Arrays.asList("user1:endpoint1", "{user1:endpoint1}:value",
"{user1:endpoint1}:value:febbb04d-6365-4cb8-b32b-8d90800cd4e6",
"{user1:endpoint1}:permits", "{user1:endpoint1}:permits:febbb04d-6365-4cb8-b32b-8d90800cd4e6");
byte[] random = new byte[8];
ThreadLocalRandom.current().nextBytes(random);
Object args[] = {1, System.currentTimeMillis(), random};
boolean res = client.getScript().evalSha(READ_WRITE, sha1, RScript.ReturnType.BOOLEAN, keys, 1,
System.currentTimeMillis(), random);
System.out.println(res);
}finally {
if(client != null && !client.isShutdown()){
client.shutdown();
}
}
checked the Lua print on the same line thread but io.write also is giving same error.
As in the comments wrote return() seems* the only way.
Example for redis-cli (set redis DB and use it in Lua)
(Collect Data and return as one string)
set LuaV 'local txt = "" for k, v in pairs(redis) do txt = txt .. tostring(k) .. " => " .. tostring(v) .. " | " end return(txt)'
Now the eval
eval "local f = redis.call('GET', KEYS[1]) return(loadstring(f))()" 1 LuaV
...shows whats in table: redis
(One long String no \n possible)
Exception: eval 'redis.log(2, _VERSION)' 0 gives out without ending the script but only on the server.
Than \n will work when you do...
set LuaV 'local txt = "" for k, v in pairs(redis) do txt = txt .. tostring(k) .. " => " .. tostring(v) .. "\n" end return(txt)'
...and the eval
eval 'local f = redis.call("GET", KEYS[1]) f = loadstring(f)() redis.log(2, f)' 1 LuaV

Google Ads Scripts AWQL "CONTAINS_ANY" operator doesn't work

I'm trying to extract Search queries by certain rules and I need to get Queries that contain one of the given strings:
" WHERE " +
" Impressions > " + IMPRESSIONS_THRESHOLD +
" AND AverageCpc > " + AVERAGE_CPC_THRESHOLD +
" AND Query CONTAINS_ANY ['for sale in', 'buy'] " +
" DURING YESTERDAY ");
But I'm getting error message (tryed different variations):
One of the conditions in the query is invalid. (file Code.gs, line 19)
Although it seems like I do everything according to Formal Grammar:
String -> StringSingleQ | StringDoubleQ
StringSingleQ -> '(char)'
StringDoubleQ -> "(char)"
StringList -> [ String (, String)* ]
If I do just 1 string it works fine:
" WHERE " +
" Impressions > " + IMPRESSIONS_THRESHOLD +
" AND AverageCpc > " + AVERAGE_CPC_THRESHOLD +
" AND Query CONTAINS 'for sale in' " +
" DURING YESTERDAY ");
IIRC, the CONTAINS_ANY operator only works when you are filtering on labels. I'm not sure if this constraint is actually documented, but this article seems to at least imply it.

How to hdf5 (Hdfsl ) file (One Column Read) read (Big Size file)

I am using the HDF5DotNet with C# and I can read only full data as the attached image in the dataset.
The hdf5 file is too big, up to nearly 1.4GB, and if I load the whole array into the memory then it will be out of memory.
I would like to read all data from One columns
double[] values = new double[203572];
string m_Doc_01 = "data/sample/line";
HDFql.Execute("USE DIRECTORY " + "\"" + File_Directory + "\"");
HDFql.Execute("USE FILE " + "\"" + File_Name + "\"");
HDFql.Execute("CREATE CHUNKED(1, 203572) DATASET my_dataset_BS AS DOUBLE(2050, 203572)");
How to "m_Doc_01 ==> my_dataset_BS" Data
???
???
for (int i = 0; i < 2050; i++)
{
HDFql.Execute("SELECT FROM " + "\"" + m_Doc_01 + "\"" + "(1:::1) INTO MEMORY " + HDFql.VariableRegister(values));
}
To read the column that you have highlighted in the screenshot (i.e. column #0), you have to change the hyperslab to (please note the 0):
HDFql.Execute("SELECT FROM " + "\"" + m_Doc_01 + "\"" + "(, 0:::1) INTO MEMORY " + HDFql.VariableRegister(values));
That said, if you want to loop through the dataset and read one column at the time do the following (also better to register variable values before the loop starts and unregister it after the loop is done - this will increase performance):
number = HDFql.VariableRegister(values);
for(int i = 0; i < 2050; i++)
{
HDFql.Execute("SELECT FROM " + "\"" + m_Doc_01 + "\"" + "(, " + i + ":::1) INTO MEMORY " + number);
// do something with variable "values" (which contains the values of column #i)
}
HDFql.VariableUnregister(values);

Google Adwords Reporting HTTP POST request returns 400 response code

I am trying to use Google Adwords Reporting HTTP POST request to retrieve stats for a list of keywords that could exist under multiple Campaigns/Adgroups. This is the API documentation that I was referring to https://developers.google.com/adwords/api/docs/guides/reporting#prepare-the-http-post-request.
Below is scala code that returns 400 error code. What am I doing wrong ? Or is there another way of retrieving data from KEYWORDS_PERFORMANCE_REPORT report type ?
val httpClient = new DefaultHttpClient()
val postRequest=new HttpPost("https://adwords.google.com/api/adwords/reportdownload/v201605")
postRequest.addHeader("Host","adwords.google.com")
postRequest.addHeader("User-Agent", "curl, gzip")
postRequest.addHeader("Accept","*/*")
postRequest.addHeader("Expect","100-continue")
postRequest.addHeader("Accept-Encoding","gzip")
postRequest.addHeader("Content-Type","multipart/form-data; boundary=------------------------12d01fae60c7b559; charset=utf-8")
postRequest.addHeader("Authorization","Bearer 1/*************************************")
postRequest.addHeader("developerToken","/*************************************")")
postRequest.addHeader("clientCustomerId","/*************************************")")
postRequest.addHeader("Parameters","__rdxml: <?xml version=\"1.0\" " +
"encoding=\"UTF-8\"?>" +
"<reportDefinition>" +
" <selector>" +
" <fields>CampaignId</fields>" +
" <fields>AdGroupId</fields>" +
" <fields>Id</fields>" +
" <fields>Criteria</fields>" +
" <fields>CriteriaType</fields>" +
" <fields>Impressions</fields>" +
" <fields>Clicks</fields>" +
" <fields>Cost</fields>" +
" <predicates>" +
" <field>Status</field>" +
" <operator>NOT_IN</operator>" +
" <values>PAUSED</values>" +
" </predicates>" +
" </selector>" +
" <reportName>Criteria performance report #56bd904878715</reportName>" +
" <reportType>CRITERIA_PERFORMANCE_REPORT</reportType>" +
" <dateRangeType>LAST_7_DAYS</dateRangeType>" +
" <downloadFormat>CSV</downloadFormat>" +
"</reportDefinition>")
val httpResponse=httpClient.execute(postRequest)
println(httpResponse.getStatusLine.toString)
Your report definition should go into the POST request's body encoded either as application/x-www-form-urlencoded or multipart/form-data—in your code you are adding it as a header called Parameters.

Parsing on server versus parsing on localhost

Here is my code:
if (amount != -1)
returnJson.Add("<p style=\"color: black;\">" + double.Parse(res_q.Replace(",", ".")) * amount + " " + res_i + "</p>");
else
returnJson.Add("<p style=\"color: black;\">" + res_q + " " + " ") + res_i + "</p>");
And no matter if the execution of the program goes to if or the else, if res_q="1,5", this returns 15 on server, and 1.5 locally.
Why is this happening?
The problem was in the comma.
I want to apply globalization in my program. Using CultureInfo.InvariantCulture was the answer I needed. Or simple replcing the comma with dot.

Resources