Missing where_id in structures/<structure-id>/wheres - nest-api

For one of the homes my app is connecting to using the Nest REST API, the where location assigned to one of the cameras is not listed in the wheres list. I’m not 100% sure but I believe the where location in question, ‘Front Yard’, is a built-in one that was recently added to accommodate outdoor cams. The where_id for ‘Front Yard' is L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnCbIQ0AQRHSg and for reference the complete wheres list is cut/paste below.
All of this works fine using the web app from a browser and the iOS app on on iPad/iPhone but clearly something is out of sync when using the REST API. My app only has write permission for home/away so I’m pretty I didn’t introduce the inconsistency.
Thanks,
Kevin
{'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnHRs9CoUFwCQ': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnHRs9CoUFwCQ', 'name': 'Bedroom'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrk6bmlW6JPIKw': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrk6bmlW6JPIKw', 'name': 'Den'}, 'xqmEMyhCen8FHEmFxOo5jX3RWobmscu6zBBr8pdu-veIYbhrFjxNNw': {'where_id': 'xqmEMyhCen8FHEmFxOo5jX3RWobmscu6zBBr8pdu-veIYbhrFjxNNw', 'name': 'Garage'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrlcNa-V3WRJAA': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrlcNa-V3WRJAA', 'name': 'Basement'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnH3br5CDnsKA': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnH3br5CDnsKA', 'name': 'Family Room'}, 'kJ71hVxi0hJ7zUo4TzUu3jfQLd6yPtBMx696H_tumzUUcK_3VLe0Ew': {'where_id': 'kJ71hVxi0hJ7zUo4TzUu3jfQLd6yPtBMx696H_tumzUUcK_3VLe0Ew', 'name': 'Back Yard'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmJPnCH5smMUg': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmJPnCH5smMUg', 'name': 'Hallway'}, 'd44aSYTfLVEYmcfI0Jwcz9G2uazXEmUfl_YzwLu1l37V6xivkkk1KA': {'where_id': 'd44aSYTfLVEYmcfI0Jwcz9G2uazXEmUfl_YzwLu1l37V6xivkkk1KA', 'name': 'West Yard'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrlQnDUuljAWbw': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrlQnDUuljAWbw', 'name': 'Downstairs'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrkuLsLZUeH-3A': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrkuLsLZUeH-3A', 'name': 'Master Bedroom'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrkn2yuSZHKulg': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrkn2yuSZHKulg', 'name': 'Living Room'}, '6M1qTQskUQFmQUL_QoHu-JGKdJwkoG6MZ4Bu7OsKYL-JOUQSRhhcRA': {'where_id': '6M1qTQskUQFmQUL_QoHu-JGKdJwkoG6MZ4Bu7OsKYL-JOUQSRhhcRA', 'name': 'Upstairs Hallway'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmFL6Eiqigsmw': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmFL6Eiqigsmw', 'name': 'Kids Room'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmltcwKgm79iQ': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmltcwKgm79iQ', 'name': 'Upstairs'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrn_59qioWdi-Q': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrn_59qioWdi-Q', 'name': 'Entryway'}, '3BBZNJp4tlkXpM3anwwpcnSl9t3Lqljagf0znxFq96PYyUG5_-HNGg': {'where_id': '3BBZNJp4tlkXpM3anwwpcnSl9t3Lqljagf0znxFq96PYyUG5_-HNGg', 'name': 'Guest Bedroom'}, 'fOdDlUl68hSiHsjDuNisUtq1Dq8p_SYabum4CUGUlkzJAFzMIMrgTA': {'where_id': 'fOdDlUl68hSiHsjDuNisUtq1Dq8p_SYabum4CUGUlkzJAFzMIMrgTA', 'name': 'Mud Room'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnACVy3F3e5BA': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnACVy3F3e5BA', 'name': 'Kitchen'}, '2ZK4PvWgSljwwW947D9XkLej0b7wtvDJvGG4sM_3dvEub7BoZW2Y1Q': {'where_id': '2ZK4PvWgSljwwW947D9XkLej0b7wtvDJvGG4sM_3dvEub7BoZW2Y1Q', 'name': 'East Yard'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmGc1UwaBS6nQ': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrmGc1UwaBS6nQ', 'name': 'Office'}, 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrlrBwYMB0Ma5Q': {'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrlrBwYMB0Ma5Q', 'name': 'Dining Room'}}

Looks like Nest has populated the new built-in where items - the "Front Yard" entry is now in the wheres list:
'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnCbIQ0AQRHSg': {'name': 'Front Yard', 'where_id': 'L5K8ePT_SA_xeABp03h9LOH2J3gR2sjE58zxotSsFrnCbIQ0AQRHSg'},

Related

Forming a list of dicts in a loop according to if conditions

I need your help.
I have this code:
import ipaddress
from ipaddress import IPv4Network
prefixes = []
ip_addresses_all = [{'address': '10.0.0.1/24', 'vrf': {'id': 31,'name': 'god_inet'},
{'address': '10.0.0.10/24', 'vrf': {'id': 33, 'name': 'for_test'},
{'address': '10.1.1.1/30', 'vrf': {'id': 8, 'name': 'ott_private_net'},
{'address': '10.1.1.2/30', 'vrf': {'id': 11,'name': 'ott_public_net'},
{'address': '10.10.0.129/30', 'vrf': None,},
{'address': '10.10.0.130/30', 'vrf': None,},
{'address': '10.10.0.137/30', 'vrf': None,},
{'address': '10.10.0.138/30', 'vrf': None,}]
for ip in ip_addresses_all:
prefix = str(ipaddress.ip_network(ip.address, False))
mask_length = int(IPv4Network(prefix).prefixlen)
description_interface = ip.address
if ip.vrf:
ip_vrf_name = ip.vrf.name
ip_vrf_id = ip.vrf.id
ip_vrf = ip.vrf
else:
ip_vrf_name = 'null'
ip_vrf_id = 'null'
ip_vrf = 'null'
prefix_dict = {'prefix': prefix,
'vrf': {'name': ip_vrf_name,
'id': ip_vrf_id},
'prefix_description': [description_interface]}
if prefixes:
for i in prefixes:
if prefix != i['prefix']:
prefixes.append(prefix_dict)
elif i['prefix'] == prefix and i['vrf']['name'] == ip_vrf_name and description_interface not in i['prefix_description']:
i['prefix_description'].append(description_interface)
else:
prefixes.append(prefix_dict)
pprint(prefixes)
So, I wanna append the 'prefixes' list with dicts according to this logic : if prefix not in prefixes = [] - create new dict , if prefix with the same vrf already exists, then append a description string to a description key and update existing dict.
I struggle with this for 8 hours and it doesnt work, Ive got infinite loops=)
Intended output, something like that:
{'10.0.0.0/24': {'prefix_description': ['10.0.0.10/24'],'vrf': {'id': 31, 'name': 'god_inet'}},
'10.0.0.0/24': {'prefix_description': ['10.0.0.10/24'],'vrf': {'id': 33, 'name': 'for_test'}},
'10.1.1.0/30': {'prefix_description': ['10.1.1.2/30'],'vrf': {'id': 8, 'name': 'ott_private_net'}},
'10.1.1.0/30': {'prefix_description': ['10.1.1.2/30'],'vrf': {'id': 11, 'name': 'ott_public_net'}},
'10.10.0.128/30': {'prefix_description': ['10.10.0.129/30',
'10.10.0.130/30'],'vrf': {'id': 'null', 'name': 'null'}},
'10.10.0.136/30': {'prefix_description': ['10.10.0.137/30',
'10.10.0.138/30'],'vrf': {'id': 'null', 'name': 'null'}}}
Or better in a list like that:
[{'prefix': '10.0.0.0/24',
'prefix_description': ['77-GOD-VPN-2 ---- Vlan40'],
'vrf': {'id': 31, 'name': 'god_inet'}},
{'prefix': '10.0.0.0/24',
'prefix_description': ['78-ELS-CORE ---- Vlan142'],
'vrf': {'id': 33, 'name': 'for_test'}}]
make prefixes a dict and handle that code in the for loop
import ipaddress
from ipaddress import IPv4Network
prefixes = {}
ip_addresses_all = [{'address': '10.0.0.1/24', 'vrf': {'id': 31,'name': 'god_inet'}},
{'address': '10.0.0.10/24', 'vrf': {'id': 33, 'name': 'for_test'}},
{'address': '10.1.1.1/30', 'vrf': {'id': 8, 'name': 'ott_private_net'}},
{'address': '10.1.1.2/30', 'vrf': {'id': 11,'name': 'ott_public_net'}},
{'address': '10.10.0.129/30', 'vrf': None,},
{'address': '10.10.0.130/30', 'vrf': None,},
{'address': '10.10.0.137/30', 'vrf': None,},
{'address': '10.10.0.138/30', 'vrf': None,}]
for ip in ip_addresses_all:
prefix = str(ipaddress.ip_network(ip['address'], False))
mask_length = int(IPv4Network(prefix).prefixlen)
description_interface = ip['address']
if ip['vrf']:
ip_vrf_name = ip['vrf']['name']
ip_vrf_id = ip['vrf']['id']
ip_vrf = ip['vrf']
else:
ip_vrf_name = 'null'
ip_vrf_id = 'null'
ip_vrf = 'null'
prefix_dict = {
'vrf': {'name': ip_vrf_name,
'id': ip_vrf_id},
'prefix_description': [description_interface]}
if prefix in prefixes and \
prefixes[prefix]['vrf']['name'] == ip_vrf_name and \
description_interface not in prefixes[prefix]['prefix_description']:
prefixes[prefix]['prefix_description'].append(description_interface)
else:
prefixes[prefix] = prefix_dict
from pprint import pprint
pprint(prefixes)
output
{'10.0.0.0/24': {'prefix_description': ['10.0.0.10/24'],
'vrf': {'id': 33, 'name': 'for_test'}},
'10.1.1.0/30': {'prefix_description': ['10.1.1.2/30'],
'vrf': {'id': 11, 'name': 'ott_public_net'}},
'10.10.0.128/30': {'prefix_description': ['10.10.0.129/30', '10.10.0.130/30'],
'vrf': {'id': 'null', 'name': 'null'}},
'10.10.0.136/30': {'prefix_description': ['10.10.0.137/30', '10.10.0.138/30'],
'vrf': {'id': 'null', 'name': 'null'}}}

Create cloudwatch alarm with multiple metrics and math expression (python3)

Here is an example of how to create cloudwatch alarm using too many metrics and Math expression using boto3.
asg_name : autoscaling group name
import boto3
cloudwatch = boto3.client('cloudwatch', region_name="eu-west-1")
def create_cloudwatch_alarm(asg_name):
cloudwatch.put_metric_alarm(
ActionsEnabled=True,
AlarmName=asg_name,
ComparisonOperator='GreaterThanThreshold',
DatapointsToAlarm=3,
EvaluationPeriods=3,
Metrics=[{'Expression': 'IF(m1 > m2, 1, 0)',
'Id': 'e2',
'Label': 'Compare Running vs desired capacity',
'ReturnData': True},
{'Id': 'm1',
'MetricStat': {'Metric': {'Dimensions': [{'Name': 'AutoScalingGroupName',
'Value': asg_name}],
'MetricName': 'GroupDesiredCapacity',
'Namespace': 'AWS/AutoScaling'},
'Period': 300,
'Stat': 'Average'},
'ReturnData': False},
{'Id': 'm2',
'MetricStat': {'Metric': {'Dimensions': [{'Name': 'AutoScalingGroupName',
'Value': asg_name}],
'MetricName': 'GroupInServiceInstances',
'Namespace': 'AWS/AutoScaling'},
'Period': 300,
'Stat': 'Average'},
'ReturnData': False}],
Threshold=0.1,
TreatMissingData='missing'
)
According AWS's documentation, you can only create alarm on up to 10 metrics with metrics math : https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Create-alarm-on-metric-math-expression.html

Extraxt a specific field from a list in python

I am having a list in python. I would like to extract the field countryRegion only. How am I supposed to do that. The code lst['countryRegion'] procduces the error : TypeError: list indices must be integers or slices, not str.
Help me please
[{'__type': 'Location:http://schemas.microsoft.com/search/local/ws/rest/v1',
'address': {'adminDistrict': 'Tamil Nadu',
'adminDistrict2': 'Chennai',
'countryRegion': 'India',
'formattedAddress': 'Chennai, Tamil Nadu',
'locality': 'Chennai'},
'bbox': [12.85071, 79.97689, 13.23403, 80.33292],
'confidence': 'High',
'entityType': 'PopulatedPlace',
'geocodePoints': [{'calculationMethod': 'None',
'coordinates': [13.07209, 80.20186],
'type': 'Point',
'usageTypes': ['Display']}],
'matchCodes': ['Good'],
'name': 'Chennai, Tamil Nadu',
'point': {'coordinates': [13.07209, 80.20186], 'type': 'Point'}}]
Given your input
lst = [{'__type': 'Location:http://schemas.microsoft.com/search/local/ws/rest/v1',
'address': {'adminDistrict': 'Tamil Nadu',
'adminDistrict2': 'Chennai',
'countryRegion': 'India',
'formattedAddress': 'Chennai, Tamil Nadu',
'locality': 'Chennai'},
'bbox': [12.85071, 79.97689, 13.23403, 80.33292],
'confidence': 'High',
'entityType': 'PopulatedPlace',
'geocodePoints': [{'calculationMethod': 'None',
'coordinates': [13.07209, 80.20186],
'type': 'Point',
'usageTypes': ['Display']}],
'matchCodes': ['Good'],
'name': 'Chennai, Tamil Nadu',
'point': {'coordinates': [13.07209, 80.20186], 'type': 'Point'}}]
you get your data from
lst[0]['address']['countryRegion']
First, TypeError is due to lst being a list type and not Dictionary type
Second, countryRegion is not a key of your dictionary, but inside the dictionary value from key address
It is producing that error because of the list containing a single element that is of type dictionary.
so to access the desired value you can just use the command
list_dic = [{'__type': 'Location:http://schemas.microsoft.com/search/local/ws/rest/v1',
'address': {'adminDistrict': 'Tamil Nadu',
'adminDistrict2': 'Chennai',
'countryRegion': 'India',
'formattedAddress': 'Chennai, Tamil Nadu',
'locality': 'Chennai'},
'bbox': [12.85071, 79.97689, 13.23403, 80.33292],
'confidence': 'High',
'entityType': 'PopulatedPlace',
'geocodePoints': [{'calculationMethod': 'None',
'coordinates': [13.07209, 80.20186],
'type': 'Point',
'usageTypes': ['Display']}],
'matchCodes': ['Good'],
'name': 'Chennai, Tamil Nadu',
'point': {'coordinates': [13.07209, 80.20186], 'type': 'Point'}}]
lst_dic[0]['address']['countryRegion']
That's because it is a list of dictionary.
I dont know how you obtain the json but here's what i was able to get:
js=[{'__type': 'Location:http://schemas.microsoft.com/search/local/ws/rest/v1',
'address': {'adminDistrict': 'Tamil Nadu',
'adminDistrict2': 'Chennai',
'countryRegion': 'India',
'formattedAddress': 'Chennai, Tamil Nadu',
'locality': 'Chennai'},
'bbox': [12.85071, 79.97689, 13.23403, 80.33292],
'confidence': 'High',
'entityType': 'PopulatedPlace',
'geocodePoints': [{'calculationMethod': 'None',
'coordinates': [13.07209, 80.20186],
'type': 'Point',
'usageTypes': ['Display']}],
'matchCodes': ['Good'],
'name': 'Chennai, Tamil Nadu',
'point': {'coordinates': [13.07209, 80.20186], 'type': 'Point'}}]
for i in range(len(js)):
print(js[i]["address"]["countryRegion"])

How do I remove an item in my dictionary?

I am trying to remove an item ("logs") from my dictionary using the del method.
this is my code:
del response.json() ["logs"]
print(response.json())
this is my JSON dictionary:
{'count': 19804,
'next': {'limit': 1, 'offset': 1},
'previous': None,
'results':
[{'id': '334455',
'custom_id': '112',
'company': 28,
'company_name': 'Sunshine and Flowers',
'delivery_address': '34 olive beach house, #01-22, 612345',
'delivery_timeslot': {'lower': '2019-12-06T10:00:00Z', 'upper': '2019-12-06T13:00:00Z', 'bounds': '[)'},
'sender_name': 'Edward Shine',
'sender_email': '',
'sender_contact': '91234567',
'removed': None,
'recipient_name': 'Mint Shine',
'recipient_contact': '91234567',
'notes': '',
'items': [{'id': 21668, 'name': 'Loose hair flowers', 'quantity': 1, 'metadata': {}, 'removed': None}, {'id': 21667, 'name': "Groom's Boutonniere", 'quantity': 1, 'metadata': {}, 'removed': None}, {'id': 21666, 'name': 'Bridal Bouquet', 'quantity': 1, 'metadata': {}, 'removed': None}],
'latitude': '1.28283838383642000000',
'longitude': '103.2828037266201000000',
'created': '2019-08-15T05:40:30.385467Z',
'updated': '2019-08-15T05:41:27.930110Z',
'status': 'pending',
'verbose_status': 'Pending',
'**logs**': [{'id': 334455, 'order': '50c402d8-7c76-45b5-b883-e2fb887a507e', 'order_custom_id': '112', 'order_delivery_address': '34 olive beach house, #01-22, 6123458', 'order_delivery_timeslot': {'lower': '2019-12-06T10:00:00Z', 'upper': '2019-12-06T13:00:00Z', 'bounds': '[)'}, 'message': 'Order was created.', 'failure_reason': None, 'success_code': None, 'success_description': None, 'created': '2019-08-15T05:40:30.431790Z', 'removed': None}, {'id': 334455, 'order': '50c402d8-7c76-45b5-b883-e2fb887a507e', 'order_custom_id': '112', 'order_delivery_address': '34 olive beach house, #01-22, 612345', 'order_delivery_timeslot': {'lower': '2019-12-06T10:00:00Z', 'upper': '2019-12-06T13:00:00Z', 'bounds': '[)'}, 'message': 'Order is pending.', 'failure_reason': None, 'success_code': None, 'success_description': None, 'created': '2019-08-15T05:40:30.433139Z', 'removed': None}],
'reschedule_requests': [],
'signature': None}]
but it is saying this error
KeyError: 'logs'
what am i doing wrong? please assist
Every time you call response.json(), it returns a new dict, so the key you delete from response.json() won't be reflected in the next call to response.json().
You should instead save the returning value of response.json() to a variable before deleting the desired key:
data = response.json()
del data['results'][0]['logs']
print(data)

how to attach AWS scp-organization unit's (OUs) policies to particular organization unit(OU) using python script?

YAML file:
Organization-unit:
xyz
Organization-unit:
xyz2
Policies:
- name: scp-xyz
description:
- name: scp-xyz2
description:
using python how to attach xyz organization unit to scp-xyz only under aws organization.
output: list of policies and organization unit info
{'Policies': [{'Id': 'p-xw7j86as', 'Arn': '', 'Name': 'scp-xyz', 'Description': 'Allows access to every operation', 'Type': 'SERVICE_CONTROL_POLICY', 'AwsManaged': True}
{'Policies': [{'Id': 'p-xw7j006as', 'Arn': '', 'Name': 'scp-xyz2', 'Description': 'Allows access to every operation', 'Type': 'SERVICE_CONTROL_POLICY', 'AwsManaged': True}
{'OrganizationalUnit': {'Id': 'ou-uwjh-87', 'Arn': 'a', 'Name': 'xyz'}
{'OrganizationalUnit': {'Id': 'ou-uw-87', 'Arn': 'a', 'Name': 'xyz2'}
I have below sample to attach policy to OU:
response = client.attach_policy(
PolicyId='string', #policy ID string requires "p-" followed by from 8 to
128 lower-case letters or digits.
TargetId='string' # ID of OU
)
Can anyone please guide me how can I do this task ?
REsult should be like below :
[![SCP-xyz policy should attach with xyz organization unit][1]][1]

Resources