4 Translates Netatmo Weather Station data to ROS. 5 The time between updates is one minute. 6 Value -1 in CO2, noise, pressure or battery_percent means no value. 7 This node expect the configuration path to be specified via private parameter configpath. If the path a file called 8 config.ini, it will be used. If this file is not found, the configuration values will be read from the following 9 files: username, password, client_id, client_secret and device_id. 10 Author: José Jaime Ariza (jariza@ieee.org). 19 from netatmo2ros.msg
import WeatherdataArray, Weatherdata
24 Get the Netatmo access token 25 :param username: Netamo username 26 :param password: Netamo password 27 :param client_id: Netamo Client ID 28 :param client_secret: Netamo Client Secret 32 payload = {
'grant_type':
'password',
35 'client_id': client_id,
36 'client_secret': client_secret,
37 'scope':
'read_station'}
40 response = requests.post(
"https://api.netatmo.com/oauth2/token", data=payload)
41 response.raise_for_status()
42 if response.json()[
"scope"][0] !=
'read_station':
43 raise ValueError(
"Unexpected scope: " +
' '.join(response.json()[
"scope"]))
46 return response.json()[
"access_token"]
51 Get values from a station and it's modules 52 :param access_token: Netatmo access token 53 :param device_id: Netatmo device ID 54 :return: station weather data 59 'access_token': access_token,
60 'device_id': device_id
64 response = requests.post(
"https://api.netatmo.com/api/getstationsdata", params=params)
65 response.raise_for_status()
66 device_data = response.json()[
"body"][
"devices"][0]
67 if device_data[
"_id"] != device_id:
68 raise Exception(
"Unexpected device: " + device_data[
"_id"])
71 output = WeatherdataArray()
73 wd.name = str(device_data[
"module_name"])
74 wd.battery_percent = -1
75 wd.co2 = int(device_data[
"dashboard_data"][
"CO2"])
76 wd.humidity = int(device_data[
"dashboard_data"][
"Humidity"])
77 wd.noise = int(device_data[
"dashboard_data"][
"Noise"])
78 wd.pressure = float(device_data[
"dashboard_data"][
"Pressure"])
79 wd.temperature = float(device_data[
"dashboard_data"][
"Temperature"])
80 wd.link_status = int(device_data[
"wifi_status"])
82 wd.time_utc = long(device_data[
"dashboard_data"][
"time_utc"])
86 for module_data
in device_data[
"modules"]:
88 wd.name = str(module_data[
"module_name"])
89 wd.battery_percent = int(module_data[
"battery_percent"])
91 wd.humidity = int(module_data[
"dashboard_data"][
"Humidity"])
94 wd.temperature = float(module_data[
"dashboard_data"][
"Temperature"])
95 wd.link_status = int(module_data[
"rf_status"])
96 wd.last_seen = long(module_data[
"last_seen"])
106 Loop for publishing data in ROS 107 :param access_token: Netatmo access token 108 :param device_id: Netatmo Weather Station device ID 111 while not rospy.is_shutdown():
113 pub.publish(station_data)
117 if __name__ ==
'__main__':
119 pub = rospy.Publisher(
"weather", WeatherdataArray, queue_size=1)
120 rospy.init_node(
"netatmo2ros", anonymous=
False)
123 config_path = rospy.get_param(
"~configpath")
125 if os.path.isfile(os.path.join(config_path,
"config.ini")):
127 config = ConfigParser.ConfigParser()
128 config.read(os.path.join(config_path,
"config.ini"))
129 uname = config.get(
"user",
"username")
130 passw = config.get(
"user",
"password")
131 clientid = config.get(
"user",
"client_id")
132 clientsecret = config.get(
"user",
"client_secret")
133 deviceid = config.get(
"device",
"device_id")
134 elif os.path.isdir(config_path):
136 with open(os.path.join(config_path,
"username"),
"r") as f: 137 uname = f.readline().rstrip() 138 with open(os.path.join(config_path, "password"),
"r") as f: 139 passw = f.readline().rstrip() 140 with open(os.path.join(config_path, "client_id"),
"r") as f: 141 clientid = f.readline().rstrip() 142 with open(os.path.join(config_path, "client_secret"),
"r") as f: 143 clientsecret = f.readline().rstrip() 144 with open(os.path.join(config_path, "device_id"),
"r") as f: 145 deviceid = f.readline().rstrip() 147 sys.exit(
"Couldn't find configuration in path {0}.".format(config_path))
def get_access_token(username, password, client_id, client_secret)
def publisher_loop(access_token, device_id)
def get_station_values(access_token, device_id)