def iot_device_his_data(key, sn, vsn=None, fields="*", condition=None): vsn = vsn or sn doc = frappe.get_doc('IOT Device', sn) if not doc.has_permission("read"): raise frappe.PermissionError if vsn != sn: if vsn not in iot_device_tree(sn): return 401 inf_server = IOTHDBSettings.get_influxdb_server() if not inf_server: frappe.logger(__name__).error( "InfluxDB Configuration missing in IOTHDBSettings") return 500 query = 'SELECT ' + fields + ' FROM "' + key + '" WHERE device=\'' + vsn + '\'' if condition: query = query + condition else: query = query + " ORDER BY time DESC LIMIT 1000" domain = frappe.get_value("Cloud Company", doc.company, "domain") r = requests.session().get(inf_server + "/query", params={ "q": query, "db": domain }, timeout=10) if r.status_code == 200: return r.json()["results"] or r.json() return r.text
def device_event_count_statistics(): valid_auth_code() companies = list_user_companies(frappe.session.user) if len(companies) == 0: return company = companies[0] client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/15", decode_responses=True) from iot.hdb_api import list_iot_devices as _list_iot_devices devices = _list_iot_devices(frappe.session.user) company_devices = devices.get('company_devices') try: result = [] if company_devices: for group in company_devices: devices = group["devices"] for dev in devices: devdoc = IOTDevice.get_device_doc(dev) if devdoc: vals = client.hgetall('event_count.' + dev) vals['sn'] = dev vals['name'] = devdoc.dev_name vals['last_updated'] = str(devdoc.last_updated)[:-7] vals['position'] = 'N/A' vals['device_status'] = devdoc.device_status result.append(vals) return result except Exception as ex: return []
def device_info(sn): valid_auth_code() device = frappe.get_doc('IOT Device', sn) if not device.has_permission("read"): raise frappe.PermissionError device = { 'sn': device.sn, 'name': device.dev_name, 'desc': device.description, 'company': device.company, 'location': 'UNKNOWN', # TODO: Get device location 'beta': device.use_beta, 'is_beta': device_is_beta(sn), 'status': device.device_status, } client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/12", decode_responses=True) if client.exists(sn): info = client.hgetall(sn) if info: device['version'] = info.get("version/value") device['skynet_version'] = info.get("skynet_version/value") _starttime = info.get("starttime/value") device['start_time'] = str( convert_utc_to_user_timezone(datetime.datetime.utcfromtimestamp(int(_starttime))).replace( tzinfo=None)) device['uptime'] = int(info.get("uptime/value") / 1000) # convert to seconds device['platform'] = info.get("platform/value") return device
def valid_auth_code(): if frappe.session.user != "Guest": return auth_code = frappe.get_request_header("HDB-AuthorizationCode") user = None if auth_code: frappe.logger(__name__).debug( _("HDB-AuthorizationCode as {0}").format(auth_code)) user = IOTHDBSettings.get_on_behalf(auth_code) else: auth_code = frappe.get_request_header("AuthorizationCode") if auth_code: user = frappe.get_value("IOT User Api", {"authorization_code": auth_code}, "user") else: throw(_("Authorization Code/Login is required!")) if not user: throw(_("Authorization Code is incorrect!")) # form dict keeping form_dict = frappe.local.form_dict frappe.set_user(user) frappe.local.form_dict = form_dict
def iot_device_tree(sn=None): sn = sn or frappe.form_dict.get('sn') doc = frappe.get_doc('IOT Device', sn) doc.has_permission("read") client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/11", decode_responses=True) return client.lrange(sn, 0, -1)
def iot_device_data(sn=None, vsn=None): sn = sn or frappe.form_dict.get('sn') vsn = vsn or sn doc = frappe.get_doc('IOT Device', sn) if not doc.has_permission("read"): raise frappe.PermissionError if vsn != sn: if vsn not in iot_device_tree(sn): return "" cfg = iot_device_cfg(sn, vsn) if not cfg: return "" client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/12", decode_responses=True) hs = client.hgetall(vsn) data = {} if "inputs" in cfg: inputs = cfg.get("inputs") for input in inputs: input_name = input.get('name') s = hs.get(input_name + "/value") if s: val = json.loads(s) data[input_name] = {"PV": val[1], "TM": val[0], "Q": val[2]} return data
def list_install_apps(device): server = IOTHDBSettings.get_redis_server() print(server) if not server: throw(_("Redis Server is empty in IOT HDB Settings")) client = redis.Redis.from_url(server + "/6") return json.loads(client.get(device) or "")
def data(gateway, name=None): try: valid_auth_code() doc = frappe.get_doc('IOT Device', gateway) if not doc.has_permission("read"): throw("has_no_permission") if not name: name = gateway if name and name != gateway: if name not in gateway_device_list(gateway): throw("no_such_device_in_gateway") cfg = gateway_device_info(gateway, name) if not cfg: throw("device_info_empty") client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/12", decode_responses=True) hs = client.hgetall(name) device_data = [] if "inputs" in cfg: inputs = cfg.get("inputs") for input in inputs: input_name = input.get('name') s = hs.get(input_name + "/value") if not s: device_data.append({ "name": input_name, "pv": None, "tm": '', "q": -1, "vt": input.get('vt'), "desc": input.get("desc"), "unit": input.get('unit'), }) else: val = json.loads(hs.get(input_name + "/value")) ts = datetime.datetime.utcfromtimestamp(int(val[0])) time_str = str( convert_utc_to_user_timezone(ts).replace(tzinfo=None)) device_data.append({ "name": input_name, "pv": val[1], "tm": time_str, "q": val[2], "vt": input.get('vt'), "desc": input.get("desc"), "unit": input.get('unit'), }) frappe.response.update({"ok": True, "data": device_data}) except Exception as ex: frappe.response.update({"ok": False, "error": str(ex)})
def single_device_event_type_statistics(device): valid_auth_code() companies = list_user_companies(frappe.session.user) if len(companies) == 0: return company = companies[0] inf_server = IOTHDBSettings.get_influxdb_server() if not inf_server: frappe.logger(__name__).error("InfluxDB Configuration missing in IOTHDBSettings") return query = 'SELECT sum("SYS"), sum("DEV"), sum("COMM"), sum("DATA"), sum("APP")' query = query + ' FROM "single_device_event_type_statistics" WHERE time > now() - 7d' query = query + ' AND "owner"=\'' + company + '\'' + ' AND "iot"=\'' + device + '\' GROUP BY time(1d) FILL(0)' domain = frappe.get_value("Cloud Company", company, "domain") r = requests.session().get(inf_server + "/query", params={"q": query, "db": domain + '.statistics'}, timeout=10) if r.status_code == 200: ret = r.json() if not ret: return frappe.logger(__name__).error("Got Single Device Event Type Count {0}".format(json.dumps(ret))) results = ret['results'] if not results or len(results) < 1: return series = results[0].get('series') if not series or len(series) < 1: return res = series[0].get('values') if not res: return taghis = [] for i in range(0, len(res)): hisvalue = {} # print('*********', res[i][0]) try: utc_time = datetime.datetime.strptime(res[i][0], UTC_FORMAT1) except Exception as err: pass try: utc_time = datetime.datetime.strptime(res[i][0], UTC_FORMAT2) except Exception as err: pass local_time = str(convert_utc_to_user_timezone(utc_time).replace(tzinfo=None)) hisvalue = {'name': 'single_device_event_type_statistics', 'time': local_time, 'owner': company, 'device': device} hisvalue['系统'] = res[i][1] or 0 hisvalue['设备'] = res[i][2] or 0 hisvalue['通讯'] = res[i][3] or 0 hisvalue['数据'] = res[i][4] or 0 hisvalue['应用'] = res[i][5] or 0 taghis.append(hisvalue) return taghis else: return r.txt
def gateway_device_info(gateway=None, device=None): doc = frappe.get_doc('IOT Device', gateway) if not doc.has_permission("read"): throw("has_no_permission") client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/10", decode_responses=True) return json.loads(client.get(device or gateway) or "{}")
def gateway_device_list(gateway=None): doc = frappe.get_doc('IOT Device', gateway) if not doc.has_permission("read"): throw("has_no_permission") client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/11", decode_responses=True) return client.lrange(gateway, 0, -1)
def iot_device_cfg(sn=None, vsn=None): sn = sn or frappe.form_dict.get('sn') doc = frappe.get_doc('IOT Device', sn) if not doc.has_permission("read"): raise frappe.PermissionError client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/10", decode_responses=True) return json.loads(client.get(vsn or sn) or "{}")
def iot_device_cfg(sn=None, vsn=None): sn = sn or frappe.form_dict.get('sn') doc = frappe.get_doc('IOT Device', sn) doc.has_permission("read") client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/0") if client.get(vsn or sn): return json.loads(client.get(vsn or sn)) else: return None
def device_app_list(sn): from app_center.app_center.doctype.iot_application_version.iot_application_version import IOTApplicationVersion valid_auth_code() device = frappe.get_doc('IOT Device', sn) if not device.has_permission("read"): raise frappe.PermissionError client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/6", decode_responses=True) applist = json.loads(client.get(sn) or "[]") iot_applist = [] for app in applist: app_obj = _dict(applist[app]) try: applist[app]['inst'] = app if not frappe.get_value("IOT Application", app_obj.name, "name"): iot_applist.append({ "cloud": None, "info": applist[app], "inst": app, }) continue else: doc = frappe.get_doc("IOT Application", app_obj.name) if app_obj.auto is None: applist[app]['auto'] = "1" iot_applist.append({ "cloud": { "name": doc.name, "app_name": doc.app_name, "code_name": doc.code_name, "app_path": doc.app_path, "developer": doc.developer, "developer_fullname": get_fullname(doc.developer), "version": get_latest_version(doc.name, device.use_beta), "fork_from": doc.fork_from, "fork_version": doc.fork_version, "icon_image": doc.icon_image, }, "info": applist[app], "inst": app, }) except Exception as ex: frappe.logger(__name__).error(ex) iot_applist.append({ "cloud": None, "info": applist[app], "inst": app, }) return iot_applist
def firmware_last_version(sn, beta=0): valid_auth_code() client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/12", decode_responses=True) if client.exists(sn): info = client.hgetall(sn) if info: platform = info.get("platform/value") if platform: return firmware_last_version_by_platform(platform, beta) return None
def device_is_beta(sn): valid_auth_code() iot_beta_flag = 0 client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/12", decode_responses=True) try: betainfo = client.hget(sn, 'enable_beta/value') except Exception as ex: return None if betainfo: iot_beta_flag = eval(betainfo)[1] return iot_beta_flag
def device_type_statistics(): valid_auth_code() companies = list_user_companies(frappe.session.user) if len(companies) == 0: return company = companies[0] client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/15", decode_responses=True) try: return client.hgetall('device_type.' + company) except Exception as ex: return []
def iot_devices_array(sn=None): sn = sn or frappe.form_dict.get('sn') client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/1") devices = [] for d in client.lrange(sn, 0, -1): dev = { 'sn': d } if d[0:len(sn)] == sn: dev['name']= d[len(sn):] devices.append(dev) return devices
def device_status_statistics(): valid_auth_code() companies = list_user_companies(frappe.session.user) if len(companies) == 0: return company = companies[0] inf_server = IOTHDBSettings.get_influxdb_server() if not inf_server: frappe.logger(__name__).error("InfluxDB Configuration missing in IOTHDBSettings") return query = 'SELECT "online", "offline" FROM "device_status_statistics" WHERE time > now() - 12h AND "owner"=\'' + company + '\'' domain = frappe.get_value("Cloud Company", company, "domain") r = requests.session().get(inf_server + "/query", params={"q": query, "db": domain + '.statistics'}, timeout=10) if r.status_code == 200: ret = r.json() if not ret: return results = ret['results'] if not results or len(results) < 1: return series = results[0].get('series') if not series or len(series) < 1: return res = series[0].get('values') if not res: return taghis = [] for i in range(0, len(res)): hisvalue = {} # print('*********', res[i][0]) try: utc_time = datetime.datetime.strptime(res[i][0], UTC_FORMAT1) except Exception as err: pass try: utc_time = datetime.datetime.strptime(res[i][0], UTC_FORMAT2) except Exception as err: pass local_time = str(convert_utc_to_user_timezone(utc_time).replace(tzinfo=None)) hisvalue = {'name': 'device_status_statistics', 'online': res[i][1], 'time': local_time, 'offline': res[i][2], 'owner': company} taghis.append(hisvalue) return taghis else: return r.txt
def access_device(sn, op="read"): """ Check access permission for device :param sn: Device Serial Number :return: Device information """ valid_auth_code() client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/11", decode_responses=True) dev_sn = client.get("PARENT_" + sn) if dev_sn and frappe.has_permission( doctype="IOT Device", doc=dev_sn, ptype=op): return True return False
def get_context(context): name = frappe.form_dict.device or frappe.form_dict.name if not name: frappe.local.flags.redirect_location = "/" raise frappe.Redirect user_roles = frappe.get_roles(frappe.session.user) context.language = frappe.db.get_value("User", frappe.session.user, ["language"]) if 'IOT User' not in user_roles or frappe.session.user == 'Guest': raise frappe.PermissionError context.no_cache = 1 context.show_sidebar = True if 'Company Admin' in frappe.get_roles(frappe.session.user): context.isCompanyAdmin = True menulist = frappe.get_all("Iot Menu") n_list = [] for m in menulist: dd = {} dd['url'] = frappe.get_value("Iot Menu", m['name'], "menuurl") dd['name'] = frappe.get_value("Iot Menu", m['name'], "menuname") dd['ico'] = frappe.get_value("Iot Menu", m['name'], "menuico") dd['id'] = frappe.get_value("Iot Menu", m['name'], "ordernum") n_list.append(dd) n_list.sort(key=lambda k: (k.get('id', 0))) context.leftnavlist = n_list context.title = _('Devices_List') context.csrf_token = frappe.local.session.data.csrf_token device = frappe.get_doc('IOT Device', name) device.has_permission('read') context.doc = device client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/1") context.devices = [] for d in client.lrange(name, 0, -1): dev = {'sn': d} if d[0:len(name)] == name: dev['name'] = d[len(name):] context.devices.append(dev) print(device) print(context.devices) if device.sn: context.vsn = iot_device_tree(device.sn) else: context.vsn = []
def valid_auth_code(auth_code=None): if 'Guest' != frappe.session.user: return auth_code = auth_code or frappe.get_request_header("HDB-AuthorizationCode") if not auth_code: throw(_("HDB-AuthorizationCode is required in HTTP Header!")) frappe.logger(__name__).debug( _("HDB-AuthorizationCode as {0}").format(auth_code)) user = IOTHDBSettings.get_on_behalf(auth_code) if not user: throw(_("Authorization Code is incorrect!")) # form dict keeping form_dict = frappe.local.form_dict frappe.set_user(user) frappe.local.form_dict = form_dict
def iot_device_data_weui(sn=None, vsn=None): sn = sn or frappe.form_dict.get('sn') vsn = vsn or sn doc = frappe.get_doc('IOT Device', sn) doc.has_permission("read") if vsn != sn: if vsn not in iot_device_tree(sn): return "" cfg = iot_device_cfg(sn, vsn) if not cfg: return "" client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/2") hs = client.hgetall(vsn) data = [] if cfg.has_key("nodes"): nodes = cfg.get("nodes") for node in nodes: tags = node.get("tags") for tag in tags: name = tag.get('name') tt = hs.get(name + ".TM") timestr = '' if tt: timestr = str( convert_utc_to_user_timezone(datetime.datetime.utcfromtimestamp(int(int(tt) / 1000))).replace( tzinfo=None))[5:] data.append({"NAME": name, "PV": hs.get(name + ".PV"), # "TM": hs.get(name + ".TM"), "TM": timestr, "Q": hs.get(name + ".Q"), "DESC": tag.get("desc").strip(), }) if cfg.has_key("tags"): tags = cfg.get("tags") for tag in tags: name = tag.get('name') tt = hs.get(name + ".TM") timestr = '' if tt: timestr = str( convert_utc_to_user_timezone(datetime.datetime.utcfromtimestamp(int(int(tt) / 1000))).replace( tzinfo=None))[5:] data.append({"NAME": name, "PV": hs.get(name + ".PV"), # "TM": hs.get(name + ".TM"), "TM": timestr, "Q": hs.get(name + ".Q"), "DESC": tag.get("desc").strip(), }) return data
def taghisdata(sn=None, vsn=None, fields=None, condition=None): vsn = vsn or sn fields = fields or "*" doc = frappe.get_doc('IOT Device', sn) doc.has_permission("read") inf_server = IOTHDBSettings.get_influxdb_server() if not inf_server: frappe.logger(__name__).error( "InfluxDB Configuration missing in IOTHDBSettings") return 500 query = 'SELECT ' + fields + ' FROM "' + vsn + '"' if condition: query = query + " WHERE " + condition else: query = query + " LIMIT 1000" domain = frappe.get_value("Cloud Company", doc.company, "domain") r = requests.session().get(inf_server + "/query", params={ "q": query, "db": domain }, timeout=10) if r.status_code == 200: res = r.json()["results"][0]['series'][0]['values'] taghis = [] for i in range(0, len(res)): hisvalue = {} if len(res[i]) == 5: hisvalue = { 'name': res[i][1], 'value': res[i][3], 'time': res[i][0], 'quality': 0 } taghis.append(hisvalue) elif len(res[i]) == 6: hisvalue = { 'name': res[i][1], 'value': res[i][4], 'time': res[i][0], 'quality': 0 } taghis.append(hisvalue) #print(taghis) return taghis or r.json()
def send_action(channel, action=None, id=None, device=None, data=None): valid_auth_code() if data is None: data = get_post_json_data() if id is None: id = str(uuid.uuid1()).upper() if not device: throw(_("Device SN does not exits!")) doc = frappe.get_doc("IOT Device", device) if not doc.has_permission("write"): add_device_action_log(doc, channel, action, id, data, "Failed", "Permission error") frappe.db.commit() throw(_("Not permitted"), frappe.PermissionError) valids = action_validation.get(channel) if valids: valid_func = valids.get(action) if valid_func: valid_func(doc, data) client = redis.Redis.from_url(IOTHDBSettings.get_redis_server(), decode_responses=True) args = { "id": id, "device": device, "data": data, } if action: args.update({ "action": action, }) r = client.publish("device_" + channel, json.dumps(args)) if r <= 0: add_device_action_log(doc, channel, action, id, data, "Failed", "Redis error") frappe.db.commit() throw(_("Redis message published, but no listener!")) add_device_action_log(doc, channel, action, id, data) return id
def get_action_result(id): ''' Get action result, result example: { "message": "Done", "timestamp_str": "Wed Aug 29 09:39:08 2018", "result": true, "timestamp": 1535535548.28, "device": "000C296CBED3", "id": "605063B4-AB6F-11E8-8C76-00163E06DD4A" } :return: ''' valid_auth_code() client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/7", decode_responses=True) str = client.get(id) if str: return json.loads(str)
def iot_device_data_array(sn=None, vsn=None): sn = sn or frappe.form_dict.get('sn') vsn = vsn or sn doc = frappe.get_doc('IOT Device', sn) if not doc.has_permission("read"): raise frappe.PermissionError if vsn != sn: if vsn not in iot_device_tree(sn): return "" cfg = iot_device_cfg(sn, vsn) if not cfg: return "" client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/12", decode_responses=True) hs = client.hgetall(vsn) data = [] if "inputs" in cfg: inputs = cfg.get("inputs") for input in inputs: input_name = input.get('name') s = hs.get(input_name + "/value") if not s: continue val = json.loads(hs.get(input_name + "/value")) ts = datetime.datetime.utcfromtimestamp(int(val[0])) timestr = str( convert_utc_to_user_timezone(ts).replace(tzinfo=None)) data.append({ "name": input_name, "pv": val[1], "tm": timestr, "q": val[2], "vt": input.get('vt'), "desc": input.get("desc") }) return data
def get_context(context): name = frappe.form_dict.device or frappe.form_dict.name if not name: frappe.local.flags.redirect_location = "/me" raise frappe.Redirect user_roles = frappe.get_roles(frappe.session.user) if 'IOT User' not in user_roles or frappe.session.user == 'Guest': raise frappe.PermissionError context.no_cache = 1 context.show_sidebar = False device = frappe.get_doc('IOT Device', name) device.has_permission('read') context.parents = [{"title": _("IOT Devices"), "route": "/iot_devices"}] context.doc = device context.parents = [ {"title": _("Back"), "route": frappe.get_request_header("referer")}, {"title": _("IOT Devices"), "route": "/iot_devices"} ] client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/1") context.devices = [] for d in client.lrange(name, 0, -1): dev = { 'sn': d } if d[0:len(name)] == name: dev['name']= d[len(name):] context.devices.append(dev) if device.sn: context.vsn = iot_device_tree(device.sn) else: context.vsn = []
def list(gateway): try: valid_auth_code() device = frappe.get_doc('IOT Device', gateway) if not device.has_permission("read"): throw("has_no_permission") client = redis.Redis.from_url(IOTHDBSettings.get_redis_server() + "/6", decode_responses=True) app_list = [] app_list_json_str = client.get(gateway) if app_list_json_str: try: app_list = json.loads(app_list_json_str) except Exception as ex: throw("json_decode_failure") else: throw("data_not_found") frappe.response.update({"ok": True, "data": app_list}) except Exception as ex: frappe.response.update({"ok": False, "error": str(ex)})
def create_influxdb(db_name, max_retry=10, sleep=None): if sleep: time.sleep(sleep) max_retry = max_retry - 1 inf_server = IOTHDBSettings.get_influxdb_server() if not inf_server: frappe.logger(__name__).error( "InfluxDB Configuration missing in IOTHDBSettings") return try: r = requests.session().get( inf_server + "/query", params={"q": ('''CREATE DATABASE "{0}"''').format(db_name)}, timeout=1) if r.status_code != 200: frappe.logger(__name__).error(r.text) if max_retry > 0: frappe.enqueue( 'iot.controllers.cloud_company_hooks.create_influxdb', db_name=db_name, max_retry=max_retry, sleep=60) throw(r.text) else: frappe.logger(__name__).debug(r.text) except Exception as ex: frappe.logger(__name__).error(ex.message) if max_retry > 0: frappe.enqueue( 'iot.controllers.cloud_company_hooks.create_influxdb', db_name=db_name, max_retry=max_retry, sleep=60) throw(ex.message)