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
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):
import hashlib
import datetime
sensors = []
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 + 'uvh2r1qmbqk8dcgv0hc31a6l8s5cnb0ii7oglpfj' # SALT for the MD5
requestMD5 = requestMD5.replace('-','')
requestMD5 = requestMD5.replace(',','')
requestMD5 = requestMD5.replace('.','')
requestMD5 = requestMD5.lower()
m = hashlib.md5()
m.update(requestMD5.encode("utf-8"))
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.