I'm trying to use update_network_device to update the lat and lng of devices, and I just can't seem to get the API call to work.
I'm using something like:
from dotenv import load_dotenv
load_dotenv()
load_dotenv(dotenv_path=os.path.join(os.path.expanduser("~"),".meraki.env"))
from meraki_sdk.meraki_sdk_client import MerakiSdkClient
from meraki_sdk.exceptions.api_exception import APIException
from meraki_sdk.models.update_network_device_model import UpdateNetworkDeviceModel
meraki = MerakiSdkClient(os.getenv("x_cisco_meraki_api_key"))
meraki.config.base_uri='https://api-mp.meraki.com/api/v0'
...
device=UpdateNetworkDeviceModel()
device.lat=lat;
device.lng=long;
try:
meraki.devices.update_network_device({'network_id':netId,'serial':serial,'update_network_device':device})
except APIException as e:
print(e)
I just get back a "HTTP response not OK.". All other API calls work up to this point. So I'm confident the API key is correct. The API key belongs to an account that has sufficient rights to make the change.
Solved! Go to solution.
Thanks @chengineer . I had been delaying using that library in production thinking it was more still in beta.
However that library ("pip3 install meraki") works perfectly. Sample working code:
import gpsd,os,argparse,meraki
from dotenv import load_dotenv
load_dotenv()
load_dotenv(dotenv_path=os.path.join(os.path.expanduser("~"),".meraki.env"))
dashboard = meraki.DashboardAPI(
api_key=os.getenv("x_cisco_meraki_api_key"),
base_url='https://api-mp.meraki.com/api/v0/',
print_console=False
)
...
dashboard.devices.updateNetworkDevice(netId,serial,lat=lat,lng=long)
Yea this isn't working for me either. Same result. Oddly, Postman receives a 200 but does not change anything. Tried changing device name, no change either.
Postman raw body:
{
"lat": XX.XXXXXX,
"lng": -YY.YYYYY,
}
Think I figured it out, UpdateNetworkDeviceModel does not behave properly.
name = dictionary.get('name')
tags = dictionary.get('tags')
lat = dictionary.get('lat')
lng = dictionary.get('lng')
address = dictionary.get('address')
notes = dictionary.get('notes')
move_map_marker = dictionary.get('moveMapMarker')
switch_profile_id = dictionary.get('switchProfileId')
floor_plan_id = dictionary.get('floorPlanId')
All possible fields are always returned and sent in the PUT. For values you did not pass, like switch_profile_id, null is returned. The API rejects a null value for this key.
Passing the parameters composed by the Python API to curl results in various errors:
{"errors":["Device's network must be bound to a configuration template (that supports switches) to allow for switch profile binding"]}
{"errors":["'moveMapMarker' must be a boolean"]}
So TL;DR the underlying UpdateNetworkDeviceModel has to be updated with additional logic to not send invalid values when they're not set.
For me it works fine in Postman when just specifying a lng and a lat. But as for you @PhilipDAth it fails with the SDK.
After some debuging I found that there are multiple issues.
At this point I stopped debugging as there is no sensible value I can put in in the switch_profile_id... None gets translated to null as well so that won't help.
This smells like SDK bug.
Lol, I should've refreshed before putting the effort for the debugging in. At least we came to the same conclusion @boomi .
Haha, every time!
We're going to deprecate and remove that SDK entirely, so please transition to using this library instead.
Thanks @chengineer . I had been delaying using that library in production thinking it was more still in beta.
However that library ("pip3 install meraki") works perfectly. Sample working code:
import gpsd,os,argparse,meraki
from dotenv import load_dotenv
load_dotenv()
load_dotenv(dotenv_path=os.path.join(os.path.expanduser("~"),".meraki.env"))
dashboard = meraki.DashboardAPI(
api_key=os.getenv("x_cisco_meraki_api_key"),
base_url='https://api-mp.meraki.com/api/v0/',
print_console=False
)
...
dashboard.devices.updateNetworkDevice(netId,serial,lat=lat,lng=long)