Mobile Alerts Cloud Server
The sensor data is send to the cloud server with the name www.data199.com, registered by DATA INFORMATION SERVICES GmbH in Wildau, Germany. It is actually a Microsoft Azure Website running on a Microsoft system in the US with the domain of sensorcloud.cloudapp.net
Reading from the Cloud
The Sensor Cloud is accessed from phones to display the data of the sensors. The only protection against others reading the data is the secrecy of the device IDs.
To receive the data, send a POST request to http://www.data199.com:8080/api/v1/dashboard with the following HTTP headers:
"User-Agent" : "remotemonitor/248 CFNetwork/758.2.8 Darwin/15.0.0", "Accept-Language" : "en-us", "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "Host" : "www.data199.com:8080",
and the following data in the body of the request (as a Python sample code):
devicetoken = 'empty' # defaults to "empty" vendorid = 'BE60BB85-EAC9-4C5B-8885-1A54A9D51E29' # iOS vendor UUID (returned by iOS, any UUID will do). Launch uuidgen from the terminal to generate a fresh one. phoneid = 'Unknown' # Phone ID - probably generated by the server based on the vendorid (this string can be "Unknown" and it still works) version = '1.21' # Info.plist CFBundleShortVersionString build = '248' # Info.plist CFBundleVersion executable = 'Mobile Alerts' # Info.plist CFBundleExecutable bundle = 'de.synertronixx.remotemonitor' # [[NSBundle mainBundle] bundleIdentifier] lang = 'en' # preferred language request = "devicetoken=%s&vendorid=%s&phoneid=%s&version=%s&build=%s&executable=%s&bundle=%s&lang=%s" % (devicetoken,vendorid,phoneid,version,build,executable,bundle,lang) request += '&timezoneoffset=%d' % 60 # local offset to UTC time request += '&timeampm=%s' % ('true') # 12h vs 24h clock request += '&usecelsius=%s' % ('true') # Celcius vs Fahrenheit request += '&usemm=%s' % ('true') # mm va in request += '&speedunit=%d' % 0 # wind speed (0: m/s, 1: km/h, 2: mph, 3: kn) request += '×tamp=%s' % datetime.datetime.utcnow().strftime("%s") # current UTC timestamp requestMD5 = request + 'asdfaldfjadflxgeteeiorut0ß8vfdft34503580' # SALT for the MD5 requestMD5 = requestMD5.replace('-','') requestMD5 = requestMD5.replace(',','') requestMD5 = requestMD5.replace('.','') requestMD5 = requestMD5.lower() m = hashlib.md5() m.update(requestMD5) hexdig = m.hexdigest() request += '&requesttoken=%s' % hexdig request += '&deviceids=%s' % ','.join(sensors) #request += '&measurementfroms=%s' % ('0,' * len(sensors)) #request += '&measurementcounts=%s' % ('50,' * len(sensors))
As you can see: the first part of the request (before the sensor IDs) is "signed" with an MD5 salted hash to avoid people modifying it. I am not sure why the device IDs are not included in it. This request will send all data for all sensors back. You can reduce the amount by limit the number of data points with the measurementcounts parameter (one per sensor) or by measurementfroms, which is a UNIX UTC timestamp for each sensor.
The returned data is a JSON block with timestamps again being UNIX UTC based ones.