class GeneralInfo(Common): """Class for GeneralInfo""" # INITIALIZE def __init__(self): """The Constructor for GeneralInfo class""" self._couch_db = CouchDatabase() self.couch_query = Queries() self.epoch_default = 26763 super(GeneralInfo, self).__init__() def general_info(self): """ This API is for getting general info of device --- tags: - Devices produces: - application/json parameters: - name: token in: header description: Token required: true type: string - name: userid in: header description: User ID required: true type: string - name: vessel_id in: query description: Vessel ID required: true type: string responses: 500: description: Error 200: description: Vessel Device List """ # INIT DATA data = {} # VESSEL ID vessel_id = request.args.get('vessel_id') # GET DATA token = request.headers.get('token') userid = request.headers.get('userid') # CHECK TOKEN token_validation = self.validate_token(token, userid) if not token_validation: data["alert"] = "Invalid Token" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) if not vessel_id: data["alert"] = "No Vessel ID" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) rows = [] heading = self.get_heading(vessel_id) if heading: row = {} row['option_name'] = 'Heading' row['value'] = "{0}°".format(float(heading['heading'])) row['data_provider'] = heading['heading_source'] rows.append(row) speed = self.get_speed(vessel_id) if speed: row = {} row['option_name'] = 'Speed' row['value'] = speed['speed'] row['data_provider'] = speed['speed_source'] rows.append(row) failover = self.couch_query.get_complete_values(vessel_id, "FAILOVER") if failover: row = {} row['option_name'] = 'Internet provider' row['value'] = failover['FAILOVER']['General']['Description'] row['data_provider'] = 'Failover' rows.append(row) parameters = self.couch_query.get_complete_values( vessel_id, "PARAMETERS") info = parameters['PARAMETERS']['INFO'] if info: row = {} row['option_name'] = 'IMO' row['value'] = info['IMO'] row['data_provider'] = 'PARAMETERS' rows.append(row) if info: row = {} row['option_name'] = 'MMSI' row['value'] = info['MMSI'] row['data_provider'] = 'PARAMETERS' rows.append(row) data['status'] = 'ok' data['rows'] = rows return self.return_data(data) def get_heading(self, vessel_id): """Return Heading""" all_devices = self.couch_query.get_all_devices(vessel_id) source = 'VSAT' devices = self.get_device(all_devices, source) data = {} for device in devices: values = self.couch_query.get_complete_values( vessel_id, device['device']) if values: # GET DEVICE NUMBER number = device['device'].split(source)[1] # GET DEVICE COMPLETE NAME heading_source = self.device_complete_name(source, number) # SET RETURN data['heading'] = values[ device['device']]['General']['Heading'] data['heading_source'] = heading_source # # RETURN # return data source = 'NMEA' devices = self.get_device(all_devices, source) for device in devices: values = self.couch_query.get_complete_values( vessel_id, device['device']) if values: # GET DEVICE NUMBER number = device['device'].split(source)[1] # GET DEVICE COMPLETE NAME heading_source = self.device_complete_name(source, number) gen = values[device['device']].keys() if 'GP0001' in gen: gp0001 = values[device['device']]['GP0001'] # SET RETURN if not data: data['heading'] = gp0001['VTG'][ 'courseOverGroundTrueDegrees'] data['heading_source'] = heading_source # RETURN return data def get_device(self, devices, pattern): """Return Device""" data = [] for device in devices: if re.findall(r'' + pattern + r'\d', device['doc']['device']): data.append(device['doc']) data = sorted(data, key=lambda i: i['device']) return data def get_speed(self, vessel_id): """Return Speed""" all_devices = self.couch_query.get_all_devices(vessel_id) source = 'NMEA' devices = self.get_device(all_devices, source) data = {} speed = None speed_source = "" for device in devices: values = self.couch_query.get_complete_values( vessel_id, device['device']) if values: # GET DEVICE NUMBER number = device['device'].split(source)[1] # GET DEVICE COMPLETE NAME heading_source = self.device_complete_name(source, number) gen = values[device['device']].keys() if 'GP0001' in gen: gp0001 = values[device['device']]['GP0001'] # SET RETURN if not data: data['heading'] = gp0001['VTG'][ 'courseOverGroundTrueDegrees'] data['heading_source'] = heading_source speed = float(gp0001['VTG']['speedOverGroundKnots']) speed_source = device['device'] data['speed'] = str(speed) + " knot(s)" data['speed_source'] = speed_source return data return 0
class RemoteCommand(Common): """Class for RemoteCommand""" # INITIALIZE def __init__(self): """The Constructor for RemoteCommand class""" # INIT CONFIG self.config = ConfigParser() # CONFIG FILE self.config.read("config/config.cfg") self._couch_db = CouchDatabase() self.couch_query = Queries() self.postgres = PostgreSQL() self.epoch_default = 26763 super(RemoteCommand, self).__init__() # GET VESSEL FUNCTION def remote_command(self): """ This API is for Remote Command --- tags: - Remote Command produces: - application/json parameters: - name: token in: header description: Token required: true type: string - name: userid in: header description: User ID required: true type: string - name: vessel_id in: query description: Vessel ID required: true type: string - name: device_id in: query description: Device ID required: false type: string responses: 500: description: Error 200: description: Remote Command """ # GET DATA token = request.headers.get('token') userid = request.headers.get('userid') # CHECK TOKEN token_validation = self.validate_token(token, userid) if not token_validation: data = {} data["alert"] = "Invalid Token" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) vessel_id = request.args.get('vessel_id') device_id = request.args.get('device_id') device_info = {} all_devices = self.couch_query.get_all_devices(vessel_id) if device_id: for dev in all_devices: if dev['id'] == device_id: device_info = dev break parameters = self.couch_query.get_complete_values(vessel_id, "PARAMETERS", flag='one_doc') ntwconf = self.couch_query.get_complete_values(vessel_id, "NTWCONF", flag='one_doc') # COREVALUES, FAILOVER, NTWCONF final_data = [] if device_id and not device_info: pass elif device_id and device_info: if device_info['doc']['device'] == "COREVALUES": system = self.get_system() final_data.append(system) if device_info['doc']['device'] == "FAILOVER": failover = self.get_failover(parameters) final_data.append(failover) if device_info['doc']['device'] == "NTWCONF": netconf = self.get_nc(parameters, ntwconf) final_data.append(netconf) devices = self.get_item([device_info], 'MODEM') for device in devices: modem = self.get_modem(vessel_id, device) final_data.append(modem) devices = self.get_item([device_info], 'POWERSWITCH') for device in devices: power = self.get_power_switch(vessel_id, device) final_data.append(power) else: system = self.get_system() final_data.append(system) failover = self.get_failover(parameters) final_data.append(failover) netconf = self.get_nc(parameters, ntwconf) final_data.append(netconf) devices = self.get_item(all_devices, 'MODEM') for device in devices: modem = self.get_modem(vessel_id, device) final_data.append(modem) devices = self.get_item(all_devices, 'POWERSWITCH') for device in devices: power = self.get_power_switch(vessel_id, device) final_data.append(power) if not device_id: tun1 = '' if 'tun1' in ntwconf['value']['NTWCONF'].keys(): tun1 = ntwconf['value']['NTWCONF']['tun1']['IP'] ssh_opt = [] opt = {} opt['description'] = "SSH to Vessel" opt['option'] = "ssh://" + tun1 ssh_opt.append(opt) ssh = {} ssh['icon'] = "CodeIcon" ssh['label'] = "SSH" ssh['options'] = ssh_opt final_data.append(ssh) ret = {} ret['data'] = final_data ret['status'] = "ok" return self.return_data(ret) def get_system(self): """ SYSTEM / CORE VALUES """ system = {} system["label"] = "System" system["icon"] = "Apps" system["options"] = [] option = {} option["option"] = "Load-average" option[ "description"] = 'Gets the number of processor cores and load-average.' system["options"].append(option) option = {} option["option"] = "Uptime" option[ "description"] = 'Get the uptime of the system, aswell as the start-up timestamp.' system["options"].append(option) option = {} option["option"] = "Free RAM and Swap" option["description"] = 'Show the available/used RAM and swap size' system["options"].append(option) option = {} option["option"] = "Hardware info" option[ "description"] = 'Show hardware info (like serial-number, product name, ...)' system["options"].append(option) option = {} option["option"] = "Memory info" option["description"] = 'Show memory info' system["options"].append(option) option = {} option["option"] = "Disk space" option["description"] = 'Check used/available disk space' system["options"].append(option) option = {} option["option"] = "Debian version" option["description"] = 'Get debian and kernel version' system["options"].append(option) option = {} option["option"] = "PWD" option["description"] = 'Get working directory' system["options"].append(option) option = {} option["option"] = "Initiate program cycle" option["description"] = 'Initiate a new program cycle now.' system["options"].append(option) option = {} option["option"] = "Date/Time" option["description"] = 'Show Date & Time' system["options"].append(option) option = {} option["option"] = "Temporary file server" option["others"] = [] # OTHERS other = {} other["name"] = "File-server shuts down after..." other["selected"] = 60 other["type"] = "dropdown" other["values"] = [] value = {} value["1 Minute"] = 60 other["values"].append(value) value = {} value["2 Minute"] = 120 other["values"].append(value) value = {} value["5 Minute"] = 300 other["values"].append(value) option["others"].append(other) # OTHERS other = {} other["name"] = "Directory" other["selected"] = "/home/rh/backendv1/log" other["type"] = "dropdown" other["values"] = [] value = {} value["Log Files"] = "/home/rh/backendv1/log" other["values"].append(value) value = {} value["Ini File"] = "/home/rh/backendv1/ini" other["values"].append(value) option["others"].append(other) option["description"] = 'Opens a temporary file-server' system["options"].append(option) return system def get_failover(self, parameters): """ FAILOVER """ failover = {} failover["label"] = "Failover" failover["icon"] = "ErrorIcon" failover["options"] = [] option = {} option["option"] = "Reset all gateways" option["description"] = 'Reset all gateways' failover["options"].append(option) option = {} option["option"] = "Failover rule" option["description"] = 'Change failover rule.' option["others"] = [] # OTHERS other = {} other["name"] = "Rule" other["type"] = "dropdown" other["selected"] = "allow" other["values"] = [] value = {} value["Allow: Can be used as gateway/internet provider"] = "allow" other["values"].append(value) value = {} value[ "Force: Will be set as highest priority above anything else."] = "force" other["values"].append(value) value = {} value["Forbid: Will be ignored as internet provider"] = "forbid" other["values"].append(value) value = {} value[ "Reset: Reset to default (allow) or configured setting in the ini-files."] = "reset" other["values"].append(value) option["others"].append(other) # OTHERS other = {} other["name"] = "Failover" other["hint"] = "If current rule is not shown for the list items, " other[ "hint"] += "the interface should be currently be defaulted to allowed." other[ "hint"] += "<br><small>Keep in mind that the current rule state only gets " other["hint"] += "updated every 10 minutes (default value).</small>" other["type"] = "dropdown" other["values"] = [] parameter_rows = parameters['value']['PARAMETERS'].copy() failover_array = self.get_parameters_value(parameter_rows, r'FAILOVER\d') failover_array = sorted(failover_array, key=lambda i: i[0]) for f_arr in failover_array: value = {} value["{0} - {1} - {2}".format(f_arr[1]['INTERFACE'], f_arr[1]['DESCRIPTION'], f_arr[1]['GATEWAY'])] = f_arr[0] other["values"].append(value) if failover_array: f_arr = failover_array[0] other["selected"] = "{0}".format(f_arr[0]) option["others"].append(other) failover["options"].append(option) return failover def get_nc(self, parameters, ntwconf): """ NETWORK CONFIGURATION """ parameter_rows = parameters['value']['PARAMETERS'].copy() netconf = {} netconf["label"] = "Network Configuration" netconf["icon"] = "NetworkCheck" netconf["options"] = [] option = {} option["option"] = "Ping" option["description"] = "Ping an IP" option["others"] = [] # OTHERS other = {} other["name"] = "Number of pings" other["type"] = "dropdown" other["selected"] = 1 other["values"] = [] value = {} value['1'] = 1 other["values"].append(value) value = {} value['2'] = 2 other["values"].append(value) value = {} value['3'] = 3 other["values"].append(value) value = {} value['5'] = 5 other["values"].append(value) value = {} value['10'] = 10 other["values"].append(value) option["others"].append(other) # OTHERS other = {} other["name"] = "Destination IP" other["type"] = "input" option["others"].append(other) # OTHERS other = {} other["name"] = "Interface" other["type"] = "groupdropdown" other["selected"] = "" other["values"] = [] value = {} value['Not defined'] = [\ {"value": "", "label": "No specific interface (default)"} ] other["values"].append(value) ntwconf_rows = ntwconf['value']['NTWCONF'].copy() ntwconf_array = self.get_parameters_value(ntwconf_rows, r'enp\w*') ntwconf_array = sorted(ntwconf_array, key=lambda i: i[0]) value = {} value["Untagged"] = [] for ntconf in ntwconf_array: value["Untagged"].append({ "value": '-I ' + ntconf[0], "label": "{0}, {1}, {2}".format(ntconf[0], ntconf[1]['IP'], ntconf[1]['Netmask']) }) other["values"].append(value) ntwconf_array = self.get_parameters_value(ntwconf_rows, r'tun\d') ntwconf_array = sorted(ntwconf_array, key=lambda i: i[0]) value = {} value["Tunnels (VPN)"] = [] for ntconf in ntwconf_array: value["Tunnels (VPN)"].append({ "value": '-I ' + ntconf[0], "label": "{0}, {1}, {2}".format(ntconf[0], ntconf[1]['IP'], ntconf[1]['Netmask']) }) other["values"].append(value) ntwconf_array = self.get_parameters_value(parameter_rows, r'VLAN\d') ntwconf_array = sorted(ntwconf_array, key=lambda i: i[0]) value = {} value["VLAN's"] = [] for ntconf in ntwconf_array: description = "" if 'DESCRIPTION' in ntconf[1].keys(): description = ntconf[1]['DESCRIPTION'] value["VLAN's"].append({ "value": '-I' + ntconf[0], "label": "{0}, {1}, {2}".format(ntconf[0], description, ntconf[1]['IP']) }) other["values"].append(value) option["others"].append(other) netconf["options"].append(option) option = {} option["option"] = "Interfaces" option[ "description"] = "Check network-interfaces of OBU, including IP-addresses." option["others"] = [] # OTHERS other = {} other["name"] = "Method" other["type"] = "dropdown" other["selected"] = 'nmap --iflist' other["values"] = [] value = {} value["Nmap: Including routes"] = 'nmap --iflist' other["values"].append(value) value = {} value["Ip: New debian method"] = 'ip a' other["values"].append(value) value = {} value["Ifconfig: Old debian method"] = '/sbin/ifconfig' other["values"].append(value) option["others"].append(other) netconf["options"].append(option) option = {} option["option"] = "Routes" option["description"] = "Show routes, including gateways and metrics" option["others"] = [] # OTHERS other = {} other["name"] = "Method" other["type"] = "dropdown" other["selected"] = 'ip route' other["values"] = [] value = {} value["IP Route"] = 'ip route' other["values"].append(value) value = {} value["Route"] = '/sbin/route' other["values"].append(value) value = {} value["Nmap: Including interfaces"] = 'nmap --iflist' other["values"].append(value) value = {} value["Netstat: Kernel IP Routing table"] = 'netstat -r' other["values"].append(value) option["others"].append(other) netconf["options"].append(option) option = {} option["option"] = "Connections" option["description"] = "Show internet connections" option["others"] = [] # OTHERS other = {} other["name"] = "Method" other["type"] = "dropdown" other["selected"] = 'netstat -tp' other["values"] = [] value = {} value["Active internet connections"] = 'netstat -tp' other["values"].append(value) option["others"].append(other) netconf["options"].append(option) option = {} option["option"] = "Network statistics" option["description"] = "Show network statistics" option["others"] = [] # OTHERS other = {} other["name"] = "Method" other["type"] = "dropdown" other["selected"] = 'netstat -i' other["values"] = [] value = {} value["Netstat: Network statistics"] = 'netstat -i' other["values"].append(value) option["others"].append(other) netconf["options"].append(option) option = {} option["option"] = "Scan host" option["description"] = "Scan a host." option["others"] = [] # OTHERS other = {} other["name"] = "Host to scan" other["type"] = "input" other[ "hint"] = "Type IP-address (e.g. 192.168.0.1), can also have a subnet to" other["hint"] = " scan whole subnet (e.g. 192.168.0.1/24)" option["others"].append(other) # OTHERS other = {} other["name"] = "Please select an option:" other["type"] = "dropdown" other["selected"] = '-F' other["values"] = [] value = {} value["Fast scan"] = '-F' other["values"].append(value) value = {} value['Normal'] = "" other["values"].append(value) value = {} value["Ping scan"] = '-sP' other["values"].append(value) value = {} value["More output"] = '-v' other["values"].append(value) value = {} value["Even more output"] = '-vv' other["values"].append(value) option["others"].append(other) netconf["options"].append(option) return netconf def get_modem(self, vessel_id, device): """ MODEM """ modem = {} modem["label"] = device['device'] modem["icon"] = "Router" modem["options"] = [] option = {} option["option"] = "Reboot" option["description"] = "Reboot device" modem["options"].append(option) option = {} option["option"] = "Beam Lock" option["description"] = "Lock modem satellite" modem["options"].append(option) option = {} option["option"] = "Beam Switch" option["description"] = "Switch to another VSAT-Beam." option["others"] = [] # OTHERS other = {} other["name"] = "Please select the beam:" other["type"] = "dropdown" other["values"] = [] values = self.couch_query.get_complete_values(vessel_id, device['device'], flag='one_doc') general = values['value'][device['device']]['General'] selected_flag = False for gen in general.keys(): if re.findall(r'Beam\[\d*\]', str(gen)): num = gen[(gen.index('[') + 1):gen.index(']')] opt = str(general[gen]) + "(" + num + ")" value = {} value[opt] = num other["values"].append(value) if not selected_flag: other["selected"] = num selected_flag = True option["others"].append(other) modem["options"].append(option) option = {} option["option"] = "New Map" option["description"] = "Load new map for modem" modem["options"].append(option) option = {} option["option"] = "Remove Map" option["description"] = "Remove map for modem'" modem["options"].append(option) return modem def get_power_switch(self, vessel_id, device): """ POWERSWITCH """ power = {} power["label"] = device['device'] power["icon"] = "PowerInput" power["options"] = [] option = {} option["option"] = "Reboot Outlet" option["description"] = "Reboot outlet" option["others"] = [] # OTHERS other = {} other["name"] = "Outlet number" other["type"] = "dropdown" other["values"] = [] values = self.couch_query.get_complete_values(vessel_id, device['device'], flag='one_doc') outlets = list(values['value'][device['device']].keys()) outlets.remove('General') outlets.sort() selected_flag = False if outlets: for outlet in outlets: if re.findall(r'outlet\d', outlet): num = int(re.search(r'\d+', outlet).group()) val = {} # value[str(num)] = values['value'][device['device']][outlet]['name'] val[str(num) + ' - ' + values['value'][device['device']] [outlet]['name']] = num other["values"].append(val) if not selected_flag: other["selected"] = num selected_flag = True option["others"].append(other) power["options"].append(option) return power def get_item(self, devices, pattern): """Return Item""" data = [] for device in devices: if re.findall(r'' + pattern + r'\d', device['doc']['device']): data.append(device['doc']) data = sorted(data, key=lambda i: i['device']) return data def get_parameters_value(self, parameters, pattern): """Return Parameters Value""" values = [] for key in parameters.keys(): if re.findall(r'' + pattern, key): values.append([key, parameters[key]]) return values
class DeviceOverview(Common): """Class for DeviceOverview""" # INITIALIZE def __init__(self): """The Constructor for DeviceOverview class""" self.postgres = PostgreSQL() self.couch_query = Queries() self.unit_conversion = UnitConversion() self.calc = calculate_alarm_trigger.CalculateAlarmTrigger() super(DeviceOverview, self).__init__() def device_overview(self): """ This API is for Getting OBU Summary per Vessel --- tags: - Alarm OBU Summary produces: - application/json parameters: - name: token in: header description: Token required: true type: string - name: userid in: header description: User ID required: true type: string - name: vessel_id in: query description: Vessel ID required: true type: string - name: format in: query description: Epoch Start Format required: false type: string responses: 500: description: Error 200: description: Alarm Device Overview """ data = {} # GET DATA token = request.headers.get('token') userid = request.headers.get('userid') vessel_id = request.args.get('vessel_id') epoch_format = request.args.get('format') # CHECK TOKEN if not self.validate_token(token, userid): data['alert'] = "Invalid Token" data['status'] = 'Failed' return self.return_data(data) alarm_types = self.get_alarm_types() ats = self.get_alarm_trigger() devices = self.couch_query.get_all_devices(vessel_id) standard_time = self.epoch_day(time.time()) epoch_time = time.time() temp_data = [] start_date = self.get_start_date(epoch_format) if not start_date and epoch_format not in ["day", "hours"]: data['alert'] = "Invalid format!" data['status'] = 'Failed' return self.return_data(data) for device in devices: if device['doc']['device'] in [ 'PARAMETERS', 'NTWCONF', 'NTWPERF1' ]: continue row = {} row['device'] = device['doc']['device'] row['name'] = device['doc']['device'] row['Alert'] = 0 row['Critical'] = 0 row['Warning'] = 0 row['Info'] = 0 row['Debug'] = 0 for atrigger in ats: trigger_type = self.get_alarm_type_name( alarm_types, atrigger['alarm_type_id']) at_id = atrigger['alarm_trigger_id'] device_id = device['id'] datas = self.calc.calculate_trigger([at_id], standard_time, epoch_time, vessel_id=vessel_id, device_id=device_id) if not datas == "No Alarm Trigger found.": datas_index_0 = datas[0] len_datas = datas_index_0['results'] if len_datas: row[trigger_type] = 1 if epoch_format in ['week', 'month', "quarter", 'annual']: sql_str = "SELECT COUNT(alarm_trigger_id) FROM alarm_data " sql_str += "WHERE device_id='{0}' ".format(device_id) sql_str += "AND epoch_date > {0} ".format(start_date) sql_str += "AND epoch_date < {0}".format(epoch_time) res = self.postgres.query_fetch_one(sql_str) row[trigger_type] = row[trigger_type] + res['count'] temp_data.append(row) final_data = {} final_data['data'] = temp_data final_data['status'] = 'ok' return self.return_data(final_data) def get_alarm_trigger(self): """Return Alarm Trigger""" sql_str = "SELECT * FROM alarm_trigger WHERE alarm_enabled=true" res = self.postgres.query_fetch_all(sql_str) return res def get_alarm_types(self): """Return Alarm Types""" # DATA sql_str = "SELECT * FROM alarm_type" datas = self.postgres.query_fetch_all(sql_str) data = {} data['rows'] = datas return data def get_alarm_type_name(self, a_types, alarm_type_id): """Return Alarm Type Name""" for a_type in a_types['rows']: if a_type['alarm_type_id'] == alarm_type_id: return a_type['alarm_type'] return 0 def get_start_date(self, type_format): """Return Start Date""" start_date = 0 if type_format not in ["annual", "quarter", "week", "month"]: return 0 if type_format.lower() == "week": start_date = self.days_update(time.time(), 7) elif type_format.lower() == "month": start_date = self.datedelta(time.time(), days=1, months=1) elif type_format.lower() in ["annual", "quarter"]: start_date = self.datedelta(time.time(), days=1, years=1) return start_date
class Vessel(Common): """Class for Vessel""" # INITIALIZE def __init__(self): """The Constructor for Vessel class""" # self._my_db = MySQLDatabase() self._couch_db = CouchDatabase() self.couch_query = Queries() self.postgres = PostgreSQL() self.epoch_default = 26763 self.aws3 = AwsS3() super(Vessel, self).__init__() # # INIT CONFIG # self.config = ConfigParser.ConfigParser() # # CONFIG FILE # self.config.read("config/config.cfg") # GET VESSEL FUNCTION def get_vessels_data(self): """ This API is for Getting Vessel Information --- tags: - Vessel produces: - application/json parameters: - name: token in: header description: Token required: true type: string - name: userid in: header description: User ID required: true type: string - name: vessel_ids in: query description: Vessels IDs required: false type: string responses: 500: description: Error 200: description: Vessel Information """ # INIT DATA data = {} # GET DATA token = request.headers.get('token') userid = request.headers.get('userid') # CHECK TOKEN token_validation = self.validate_token(token, userid) if not token_validation: data["alert"] = "Invalid Token" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) # GET ADMIN ROLE AND SUPER ADMIN ROLE sql_str = "SELECT role_id FROM role WHERE role_name in ('admin', 'super admin')" l_ids = self.postgres.query_fetch_all(sql_str) role_ids = [x['role_id'] for x in l_ids] str_ids = "" if len(role_ids) == 1: str_ids = "(" + str(role_ids[0]) + ")" else: str_ids = str(tuple(role_ids)) # CREATE SQL QUERY # GET ADMIN ACCOUNT sql_str = "SELECT * FROM account_role where account_id='" + str(userid) sql_str += "' AND role_id in " + str_ids res = self.postgres.query_fetch_one(sql_str) # EXTRACT VESSELS ID extracted_vessel_ids = request.args.get('vessel_ids') vessels = [] if res: if extracted_vessel_ids: for vessel_id in extracted_vessel_ids.split(","): res = self.couch_query.get_by_id(vessel_id) if res: ves = {} ves['id'] = res['_id'] ves['key'] = res['number'] vessels.append(ves) else: vessels = self.couch_query.get_vessels() else: vessel_ids = [] try: if not extracted_vessel_ids: # EMPTY vessel_ids = [] else: vessel_ids = extracted_vessel_ids.split(",") except: data["alert"] = "Invalid Vessel IDs" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) company_ids = self.get_company_id(userid) if not company_ids: data["message"] = "User Doesn't belong to any company." data['rows'] = [] data['status'] = 'ok' # RETURN ALERT return self.return_data(data) # ACCOUNT'S AVAILABLE VESSELS company_vessel_ids = self.get_company_vessels(company_ids)['rows'] #FILTER VESSELS TO GET vessels_to_get = [] if not vessel_ids: vessels_to_get = company_vessel_ids else: for vessel_id in vessel_ids: # found_vessel = None for company_vessel in company_vessel_ids: if vessel_id == company_vessel['vessel_id']: vessels_to_get.append(company_vessel) break if len(vessels_to_get) != len(vessel_ids): data["alert"] = "Some Vessel are not belong to this user." data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) temp_ids = [] for vessel_id in vessels_to_get: if vessel_id['vessel_id'] not in temp_ids: temp_ids.append(vessel_id['vessel_id']) res = self.couch_query.get_by_id(vessel_id['vessel_id']) if res: ves = {} ves['id'] = res['_id'] ves['key'] = res['number'] vessels.append(ves) # CHECK DATABASES rows = [] if vessels: vessel_ids = [x['id'] for x in vessels] # INIT SQL QUERY if len(vessel_ids) == 1: sql_str = "SELECT * FROM vessel WHERE state ='1'" sql_str += " AND vessel_id IN ('{0}')".format(vessel_ids[0]) else: sql_str = "SELECT * FROM vessel WHERE state ='1'" sql_str += " AND vessel_id IN {0}".format(tuple(vessel_ids)) # FETCH ALL vessels_state = self.postgres.query_fetch_all(sql_str) to_be_install = [x['vessel_id'] for x in vessels_state] # LOOP DATABASES for item in vessels: row = {} # GET VESSEL NAME vessel_name = self.get_vessel_name(item['id']) # self.vessel_name = vessel_name # GET LONGITUDE AND LATITUDE long_lat = self.get_long_lat(item['id']) if long_lat: # get nearest land from ocean to land google map # GET the nearest landmass # https://stackoverflow.com/questions/41539432/google-maps-reverse- # geocoding-api-returns-nearest-land-address-given-a-latlng-in row['long'] = long_lat['long'] row['lat'] = long_lat['lat'] row['position_source'] = long_lat['position_source'] else: row['long'] = 0 row['lat'] = 0 row['position_source'] = "" # GET HEADING heading, speed = self.get_heading(item['id']) if heading: row['heading'] = float(heading['heading']) row['heading_source'] = heading['heading_source'] else: row['heading_source'] = "" row['heading'] = 0 if speed: row['speed'] = float(speed) # GET UPDATE STATE last_update = self.get_last_update_with_option(item['id']) epoch_time = int(time.time()) update_state = self.check_time_lapse(epoch_time, last_update) # SET THE RETURN VALUE row['isOpen'] = False row['vessel_id'] = item['id'] row['vessel_number'] = item['key'] row['vessel_name'] = vessel_name row['company'] = self.get_vessel_company(item['id']) row['update_state'] = update_state # GET IMAGE URL row['image_url'] = self.aws3.get_vessel_image(item['id']) if item['id'] in to_be_install: row['update_state'] = 'white' rows.append(row) # SORT VESSELS ALPHABETICALLY rows = sorted(rows, key=lambda i: i['vessel_name'].upper()) # SET RETURN data['rows'] = rows data['companies'] = self.get_vessels_company() data['status'] = 'ok' # RETURN return self.return_data(data) # GET THE VESSEL NAME def get_vessel_name(self, vessel_id): """Return Vessel Name""" values = self.couch_query.get_complete_values(vessel_id, "PARAMETERS") if values: return values['PARAMETERS']['INFO']['VESSELNAME'] return '' def get_long_lat(self, vessel_id): """Return Longitude Latitude""" all_devices = self.couch_query.get_all_devices(vessel_id) devices = [] source = 'MODEM' if all_devices: devices = self.get_device(all_devices, source) devices_info = 0 if devices: devices_info = self.device_data(source, devices, vessel_id) if not devices_info: source = 'VSAT' devices = self.get_device(all_devices, source) if devices: devices_info = self.device_data(source, devices, vessel_id) if not devices_info: source = 'IOP' devices = self.get_device(all_devices, source) if devices: devices_info = self.device_data(source, devices, vessel_id) if not devices_info: source = 'NMEA' devices = self.get_device(all_devices, source) if devices: devices_info = self.device_data(source, devices, vessel_id) if not devices_info: source = 'SATC' devices = self.get_device(all_devices, source) if devices: devices_info = self.device_data(source, devices, vessel_id) if not devices_info: source = 'VHF' devices = self.get_device(all_devices, source) if devices: devices_info = self.device_data(source, devices, vessel_id) return devices_info return 0 def get_device(self, devices, pattern): """Return Device""" data = [] for device in devices: if re.findall(r'' + pattern + r'\d', device['doc']['device']): data.append(device['doc']) data = sorted(data, key=lambda i: i['device']) return data def get_heading(self, vessel_id): """Return Heading""" all_devices = self.couch_query.get_all_devices(vessel_id) source = 'VSAT' devices = self.get_device(all_devices, source) data = {} speed = 0 for device in devices: values = self.couch_query.get_complete_values( vessel_id, device['device']) if values: # GET DEVICE NUMBER number = device['device'].split(source)[1] # GET DEVICE COMPLETE NAME heading_source = self.device_complete_name(source, number) # SET RETURN data['heading'] = values[ device['device']]['General']['Heading'] data['heading_source'] = heading_source # RETURN # return [data, 0] source = 'NMEA' devices = self.get_device(all_devices, source) for device in devices: values = self.couch_query.get_complete_values( vessel_id, device['device']) if values: # GET DEVICE NUMBER number = device['device'].split(source)[1] # GET DEVICE COMPLETE NAME heading_source = self.device_complete_name(source, number) gen = values[device['device']].keys() if 'GP0001' in gen: gp0001 = values[device['device']]['GP0001'] # SET RETURN if not data: data['heading'] = gp0001['VTG'][ 'courseOverGroundTrueDegrees'] data['heading_source'] = heading_source speed = gp0001['VTG']['speedOverGroundKnots'] # RETURN return [data, speed] def get_last_update_with_option(self, vessel_id): """Return Last Update with option""" values = self.couch_query.get_complete_values(vessel_id, "COREVALUES", flag='one_doc') if values: return values['timestamp'] return '' def get_company_id(self, userid): """Return Company ID""" sql_str = "select company_id from account_company where account_id = {}".format( userid) res = self.postgres.query_fetch_all(sql_str) return res if res else 0 # GET VESSELS OF COMPANY def get_company_vessels(self, company_ids): """Return Company Vessels""" assert company_ids, "CompanyID is required." # DATA vessels = [] for company_id in company_ids: sql_str = "SELECT * FROM company_vessels" sql_str += " WHERE company_id={0}".format(company_id['company_id']) res = self.postgres.query_fetch_all(sql_str) if res: vessels = vessels + res data = {} data['rows'] = vessels return data def device_data(self, source, devices, vessel_id): """Return Device Data""" for device in devices: values = self.couch_query.get_complete_values( vessel_id, device['device']) if values: try: # GET DEVICE NUMBER number = device['device'].split(source)[1] # GET DEVICE COMPLETE NAME position_source = self.device_complete_name(source, number) # SET RETURN data = {} if source == 'NMEA': lnp = values[ device['device']]['GP0001']['GGA']['eastWest'] ltp = values[ device['device']]['GP0001']['GGA']['northSouth'] ln1 = values[ device['device']]['GP0001']['GGA']['longitude'] lt1 = values[ device['device']]['GP0001']['GGA']['latitude'] longitude = float(ln1) lat = float(lt1) lat /= 100. dec_lat, degrees_lat = math.modf(lat) dec_lat *= 100. dev_lat = degrees_lat + dec_lat / 60 longitude /= 100. dec_long, degrees_long = math.modf(longitude) dec_long *= 100. dev_long = degrees_long + dec_long / 60 data['lat'] = "%.4f" % float(dev_lat) data['long'] = "%.4f" % float(dev_long) if ltp == 'S': data['lat'] = "-" + str(data['lat']) if lnp == 'W': data['long'] = "-" + str(data['long']) elif source == 'SATC': lat_dir = values[ device['device']]['General']['latitudeDirection'] lon_dir = values[ device['device']]['General']['longitudeDirection'] lat = values[device['device']]['General']['latitude'] lon = values[device['device']]['General']['longitude'] lon_val = ''.join(lon.rsplit('.', 1)) if lon_dir == 'W': lon_val = "-" + lon_val lat_val = ''.join(lat.rsplit('.', 1)) if lat_dir == 'S': lat_val = "-" + lat_val data['long'] = lon_val data['lat'] = lat_val elif source == 'VHF': lat = values[device['device']]['General']['latitude'] lon = values[device['device']]['General']['longitude'] lon_val = str(lon[1:]) lon_val = lon_val.replace('.', '') lon_val = lon_val.replace(',', '.') if lon[0] == 'W': lon_val = "-" + lon_val lat_val = str(lat[1:]) lat_val = lat_val.replace('.', '') lat_val = lat_val.replace(',', '.') if lat[0] == 'S': lat_val = "-" + lat_val data['long'] = lon_val data['lat'] = lat_val else: data['long'] = values[ device['device']]['General']['Longitude'] data['lat'] = values[ device['device']]['General']['Latitude'] data['position_source'] = position_source # RETURN return data except: continue return 0 def get_vessel_company(self, vessel_id): """Return Company by Vessel ID""" assert vessel_id, "Vessel ID is required." data = [] sql_str = "SELECT * FROM company_vessels cv" sql_str += " LEFT JOIN company c ON cv.company_id = c.company_id" sql_str += " WHERE vessel_id='{0}'".format(vessel_id) result = self.postgres.query_fetch_all(sql_str) if result: for res in result: data.append({ 'company_id': res['company_id'], 'company_name': res['company_name'] }) return data def get_vessels_company(self): """ Return Vessel List by Company """ sql_str = "SELECT v.vessel_id, v.vessel_name, cv.company_id, c.company_name FROM vessel v" sql_str += " LEFT JOIN company_vessels cv ON v.vessel_id=cv.vessel_id" sql_str += " LEFT JOIN company c ON cv.company_id = c.company_id" sql_str += " GROUP BY v.vessel_id, cv.company_id,c.company_id" sql_str += " ORDER BY c.company_name" results = self.postgres.query_fetch_all(sql_str) data = {} if results: for result in results: if result['company_name'] is None: company = "Others" else: company = result['company_name'] formatted = [{ 'vessel_id': result['vessel_id'], 'vessel_name': result['vessel_name'] }] if company in data: data[company].append(formatted) else: data[company] = formatted return data
class Graph(Common): """Class for Graph""" # INITIALIZE def __init__(self): """The Constructor for Graph class""" self.postgres = PostgreSQL() self._couch_db = CouchDatabase() self.couch_query = Queries() super(Graph, self).__init__() def graph(self): """ This API is for Getting Graph --- tags: - Graph produces: - application/json parameters: - name: token in: header description: Token required: true type: string - name: userid in: header description: User ID required: true type: string - name: vessel_id in: query description: Vessel ID required: true type: string - name: device_id in: query description: Device ID required: true type: string - name: hours in: query description: Hours required: false type: integer - name: keys in: query description: Keys required: true type: string - name: combine in: query description: combine required: true type: boolean - name: start_time in: query description: Epoch start required: false type: string - name: end_time in: query description: Epoch end required: false type: string responses: 500: description: Error 200: description: Vessel Device Info """ data = {} # VESSEL ID vessel_id = request.args.get('vessel_id') device_id = request.args.get('device_id') keys = request.args.get('keys') combine = request.args.get('combine') hours = request.args.get('hours') start_time = request.args.get('start_time') end_time = request.args.get('end_time') # GET DATA token = request.headers.get('token') userid = request.headers.get('userid') # CHECK TOKEN token_validation = self.validate_token(token, userid) if not token_validation: data["alert"] = "Invalid Token" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) if not vessel_id: data["alert"] = "Please complete parameters!" data['status'] = 'Failed' # RETURN ALERT return self.return_data(data) if device_id in ['COREVALUES', 'FAILOVER', 'NTWPERF1']: all_devices = self.couch_query.get_all_devices(vessel_id) for dev in all_devices: if dev['doc']['device'] == device_id: device = dev['doc'] break else: device = self.couch_query.get_by_id(device_id) # hours_ago_epoch_ts = int(hours_ago.timestamp()) # current_time = int(ctime.timestamp()) if not start_time and not end_time: ctime = datetime.datetime.now() hours_ago = ctime - datetime.timedelta(hours=int(hours)) start_time = int(hours_ago.timestamp()) end_time = int(ctime.timestamp()) values = self.couch_query.get_complete_values( vessel_id, device['device'], str(start_time), str(end_time), 'all' ) # temp_available_options = [] # str_available_options = [] # available_options = [] opt = [] parameters = self.couch_query.get_complete_values( vessel_id, "PARAMETERS" ) if device['device'] == "COREVALUES": device_type = "COREVALUES" elif device['device'] == "NTWPERF1": device_type = "NTWPERF1" elif device['device'] == 'FAILOVER': device_type = 'FAILOVER' else: device_type = parameters['PARAMETERS'][device['device']]['TYPE'] if combine.upper() == 'TRUE': final_data = [] for value in values: timestamp = float(value['timestamp']) dev_value = value['value'][device['device']] # if re.findall(r'VDR\d', device['device']): # print("ALP ", dev_value) # pass if re.findall(r'NMEA\d', device['device']): nmea_data = self.get_nmea_data(dev_value) opt = list(set(self.get_graph_options(nmea_data))) options = self.get_device_options(nmea_data) if keys: final_data.append(self.set_values(options, keys, timestamp)) else: opt = list(set(self.get_graph_options(dev_value))) options = self.get_device_options(dev_value) if keys: final_data.append(self.set_values(options, keys, timestamp)) final_data = sorted(final_data, key=lambda i: i['name']) for fdata in final_data: fdata['name'] = time.strftime('%d/%m/%Y %H:%M:%S', time.localtime( float(fdata['name']))) data['data'] = final_data data['statistics'] = self.get_stat(final_data, flag=True) else: # FINAL DATA fnl_data = {} # SET DYNAMIC VARIABLE if keys: for key in keys.split(","): fnl_data[key] = [] for value in values: timestamp = float(value['timestamp']) dev_value = value['value'][device['device']] # if re.findall(r'VDR\d', device['device']): # print("ALP ", dev_value) # pass if re.findall(r'NMEA\d', device['device']): nmea_data = self.get_nmea_data(dev_value) opt = list(set(self.get_graph_options(nmea_data))) options = self.get_device_options(nmea_data) for key in keys.split(","): fnl_data[key].append(self.set_values(options, key, timestamp)) else: opt = list(set(self.get_graph_options(dev_value))) options = self.get_device_options(dev_value) for key in keys.split(","): fnl_data[key].append(self.set_values(options, key, timestamp)) for key in keys.split(","): fnl_data[key] = sorted(fnl_data[key], key=lambda i: i['name']) for fdata in fnl_data[key]: fdata['name'] = time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(float( fdata['name']))) data['data'] = fnl_data data['statistics'] = self.get_stat(fnl_data, flag=False) # SET SQL QUERY sql_str = "SELECT * FROM selected_label" sql_str += " WHERE device_type='{0}' and select_type != 'combine'".format(device_type) default_selected = self.postgres.query_fetch_all(sql_str) # SET SQL QUERY sql_str = "SELECT * FROM selected_label" sql_str += " WHERE device_type='{0}' and select_type = 'combine'".format(device_type) default_selected_combine = self.postgres.query_fetch_all(sql_str) data['default_selected_combine'] = self.set_select_values(default_selected_combine) data['default_selected'] = self.set_select_values(default_selected) data['available_options'] = self.format_filter(opt) data['status'] = 'ok' return self.return_data(data) def set_values(self, options, keys, timestamp): """Set Values""" temp_data = {} for key in keys.split(","): if key in options.keys(): if key in ['AntennaStatus', 'TxMode']: if options[key].upper() in ['TRACKING', 'ON']: temp_data[key] = 1 else: temp_data[key] = 0 elif key == 'error': if options[key] is True: temp_data[key] = 1 else: temp_data[key] = 0 else: temp_data[key] = options[key] else: temp_data[key] = None temp_data['name'] = timestamp return temp_data def get_available_options(self, options, temp_available_options, str_available_options): """Return Available Options""" # print("Options --------------------------- >>") # print(options) # print("Options --------------------------- >>") available_options = [] for opt in options.keys(): if opt not in temp_available_options and opt not in str_available_options: if not options[opt]: continue if type(options[opt]) == 'str': if options[opt].isdigit(): options[opt] = float(options[opt]) if self.isfloat(options[opt]) or self.isint(options[opt]) or opt in [ 'AntennaStatus', 'TxMode']: temp_available_options.append(opt) temp = {} temp['value'] = opt temp['label'] = opt available_options.append(temp) # else: # str_available_options.append(op) return available_options def get_nmea_data(self, datas): """ Return NMEA Data """ temp_data = {} # keys = [data for data in datas.keys()] # No need for key in list(datas.keys()): temp_data.update(datas[key]) return temp_data def get_graph_options(self, datas): """Return Options for Graph""" options = [] # modules = [data for data in datas] # No need for mod in list(datas): options += self.get_opt_available(datas[mod]) return options def get_opt_available(self, options): """Return Available Options""" available_options = [] for opt in options.keys(): if not options[opt]: continue if type(options[opt]) == 'str': if options[opt].isdigit(): options[opt] = float(options[opt]) if self.isfloat(options[opt]) or self.isint(options[opt]) or opt in [ 'AntennaStatus', 'TxMode']: available_options.append(opt) return available_options def get_device_options(self, datas): """ Return All Device Options Data """ tmp = [] temp = {} # modules = [data for data in datas] # No need for mod in list(datas): tmp.append(datas[mod]) for dta in tmp: temp.update(dta) return temp def set_select_values(self, datas): """Set Select Values""" final_data = [] for data in datas: temp = {} temp['value'] = data['label'] temp['label'] = data['label'] final_data.append(temp) return final_data def get_stat(self, datas, flag): """ Return Min and Max """ temp = {} tmp = [] if datas: if flag is True: temp_data = {} for data in datas[0].keys(): if data != "name": temp_data[data] = tuple(dta[data] for dta in datas) # keys = [data for data in temp_data.keys()] # for key in keys: # if all(res is None for res in temp_data[key]): # pass # else: # data = self.get_stat_range(temp_data, key) # temp.update({ # key : data # }) for dta in temp_data.values(): tmp += dta if tmp: tmp = [dta for dta in tmp if dta is not None] tmp = sorted(tmp, key=float) data = self.get_stat_range(tmp) temp.update({ "combine" : data }) else: # keys = [data for data in datas.keys()] for key in list(datas.keys()): result = [data[key] for data in datas[key] if data[key] is not None] result = sorted(result, key=float) # if all(res is None for res in result): # pass # else: if result: data = self.get_stat_range(result) temp.update({ key : data }) return temp def get_stat_range(self, data): """ Return Stat Range """ tmp = {} tmp['min'] = data[0] tmp['max'] = data[-1] # tmp['min'] = min(data) # tmp['max'] = max(data) return tmp