def add_test_haul(self): """ Method to add a test haul to the model + database :param haul: QJSValue - dictionary contained in a QJSValue object :return: None """ # Add to the Database sql = "INSERT INTO HAULS('HAUL_NUMBER', 'START_DATETIME', 'END_DATETIME', 'PROCESSING_STATUS', 'IS_TEST') " + \ "VALUES(?, ?, ?, ?, ?);" now = datetime.now() date = now.strftime("%m/%d/%Y") start = now start_time = start.strftime("%H:%M:%S") end = (now + timedelta(hours=1)) end_time = end.strftime("%H:%M:%S") haul_number = "t" + str(round((now - datetime.utcfromtimestamp(0)).total_seconds() * 1000.0)) # Get all Test Hauls - Adjust the last three digits to be 900 and greater so as to not conflict # with other haul numbers when we print specimen labels where we only keep the last three digits # of the haul test_hauls = Hauls.select(fn.substr(Hauls.haul_number, 12, 3).alias('test_haul_number'))\ .where(Hauls.haul_number.contains("t"))\ .order_by(fn.substr(Hauls.haul_number, 12, 3).desc()) # for test_haul in test_hauls: # logging.info('{0}'.format(test_haul.test_haul_number)) try: last_test_haul_num = test_hauls.get().test_haul_number if int(last_test_haul_num) < 900: haul_last_three = "900" else: haul_last_three = str(int(last_test_haul_num) + 1) except DoesNotExist as dne: haul_last_three = "900" except Exception as ex: haul_last_three = "900" haul_number = haul_number[:-3] + haul_last_three # logging.info('last test haul num: {0} > {1}'.format(last_test_haul_num, haul_number)) haul = {"haulNumber": haul_number, "date": date, "startTime": start_time, "endTime": end_time, "status": "Active", "isTest": "True"} params = [haul_number, start.isoformat(), end.isoformat(), "Active", "True"] self._db.execute(query=sql, parameters=params) haul_id = self._db.get_last_rowid() # Return the primary key of the newly added record # Add to the Model - N.B. need to first get the newly added HAUL_ID and add that to haul haul["haulId"] = haul_id is_added = False for i in range(self.count): if "t" in self.get(i)["haulNumber"]: continue self.insertItem(i, haul) is_added = True break if not is_added: self.appendItem(haul)
def _get_hauls_from_db(self, time_frame="today"): """ Method to query the trawl_backdeck.db to retrieve all of the test hauls :return: """ if time_frame not in ["today", "two days", "all"]: return adapter = {"today": 0, "two days": 1, "all": 1000} time_frame = adapter[time_frame] # Retrieve all test hauls from the database self._local_hauls = [] # logging.info('timedelta: ' + str(timedelta(days=time_frame))) # start_datetime = (datetime.now() - timedelta(hours=48)).isoformat() start_datetime = (datetime.now().date() - timedelta(days=time_frame)).isoformat() # logging.info('start_datetime: ' + str(start_datetime)) local_hauls = Hauls.select().where((Hauls.start_datetime >= start_datetime) | (Hauls.is_test == "True")) for haul in local_hauls: self._local_hauls.append(model_to_dict(haul)) # self._local_hauls = sorted(self._local_hauls, key=lambda x: (x["haul_number"].isdigit(), x["haul_number"])) self._hauls_model.clear() self._add_model_items(hauls=self._local_hauls)
def delete_test_haul(self, index): """ Method to delete the test haul and associated catch_partition + specimen data from the DB :param index: int - representing the index location in the model :return: """ if index is None or index == -1 or not isinstance(index, int): return item = self.get(index) status = item["status"] haul_id = item["haulId"] # Delete from the Model self.removeItem(index) # Update the state machine as appropriate if status == "Selected" or self.count == 0: self._app.state_machine.haul = None try: haul = Hauls.get(Hauls.haul == haul_id) haul.delete_instance(recursive=True, delete_nullable=True) except Exception as ex: pass
def _get_operations_from_db(self, time_frame="today"): """ Method to query the trawl_backdeck.db to retrieve all of the test hauls :return: """ if time_frame not in ["today", "two days", "all"]: return adapter = {"today": 0, "two days": 1, "all": 1000} time_frame = adapter[time_frame] # Retrieve all test hauls from the database self._local_operations = [] start_datetime = (datetime.now().date() - timedelta(days=time_frame)).isoformat() local_operations = Hauls.select().where((Hauls.start_datetime >= start_datetime) | (Hauls.is_test == "True")) for op in local_operations: self._local_operations.append(model_to_dict(op)) self._operations_model.clear() self._add_model_items(operations=self._local_operations)
def print_job(self, comport, pi_id, action, specimen_number): """ Great reference + example code for printing using EPL commands: https://www.xtuple.org/node/1083 EPL Reference: https://www.zebra.com/content/dam/zebra/manuals/en-us/printer/epl2-pm-en.pdf :return: """ if self._printer_thread.isRunning(): return if specimen_number is None: return # Line 1 - Header header = "NOAA/NWFSC/FRAM - WCGBT Survey" # Line 2a - Principal Investigator try: investigator = PrincipalInvestigatorLu.select() \ .where(PrincipalInvestigatorLu.principal_investigator == pi_id).get().last_name except DoesNotExist as ex: investigator = "PI Not Available" # Line 2b - Action Type # action - that was passed in # Line 3 - Haul # haul_id = self._app.state_machine.haul["haul_number"] if "t" in haul_id and len(haul_id) > 3: haul_id = "t" + haul_id[-4:] # Line 4 - Species Scientific Name species = self._app.state_machine.species["scientific_name"] # Line 5 - Length / Weight / Sex try: length = weight = sex = stomach = tissue = ovary = testes = "" parent_specimen = self._app.state_machine.specimen[ "parentSpecimenId"] specimens = (Specimen.select(Specimen, TypesLu).join( TypesLu, on=(Specimen.action_type == TypesLu.type_id ).alias('types')).where( Specimen.parent_specimen == parent_specimen)) for specimen in specimens: if "length" in specimen.types.type.lower(): length = specimen.numeric_value elif "weight" in specimen.types.type.lower(): weight = round(specimen.numeric_value, 2) elif "sex" in specimen.types.type.lower(): sex = specimen.alpha_value elif "stomach" in specimen.types.type.lower(): stomach = specimen.alpha_value elif "tissue" in specimen.types.type.lower(): tissue = specimen.alpha_value elif "ovary" in specimen.types.type.lower(): ovary = specimen.alpha_value elif "testes" in specimen.types.type.lower(): testes = specimen.alpha_value except DoesNotExist as ex: pass except Exception as ex: logging.info('Error creating the measurement line: ' + str(ex)) measurement = "Len: " + str(length) + "cm, Wt: " + str( weight) + "kg, Sex: " + str(sex) # Line 3B - Shortened Specimen Number - on the same line as the haul ID short_specimen_number = "" try: if investigator == "FRAM": print_iteration = "" specimen_number_split = specimen_number.split("-") if len(specimen_number_split) == 5: vessel_id = specimen_number_split[1] spec_num = specimen_number_split[4] if not specimen_number[-1:].isdigit(): print_iteration = specimen_number[-1] if stomach != "" or tissue != "": short_specimen_number = vessel_id + spec_num + print_iteration elif ovary != "" or testes != "": short_specimen_number = vessel_id + haul_id + spec_num + print_iteration short_specimen_number = ", Short #: " + short_specimen_number except Exception as ex: logging.error( f"Error creating the shortened specimen number: {ex}") # Line 7 - Latitude / Longitude / Depth # location = "47 15.54N, 126 27.55W" try: haul = Hauls.select().where( Hauls.haul == self._app.state_machine.haul["haul_id"]).get() haul_start = haul.start_datetime latitude = haul.latitude_min longitude = haul.longitude_min depth = haul.depth_min depth_uom = haul.depth_uom if isinstance(depth, float) and depth_uom == "ftm": depth = 1.8288 * depth if latitude and longitude and depth: location = f"{latitude:.6f}, {longitude:.6f}, {depth:.1f}m" else: location = f"{latitude:.6f}, {longitude:.6f}, Unknown" except Exception as ex: location = "Unknown, Unknown, Unknown" # Line 6 - Date/Time try: date = datetime.now().strftime( "%Y%m%d %H%M%S") # date = "08/16/2015" date_year = datetime.now().year haul_dt = arrow.get(haul_start) haul_year = haul_dt.datetime.year logging.info( f"date_year={date_year}, haul_year={haul_year}, date={date} > haul_dt = {haul_dt}" ) if date_year != haul_year: haul_dt = haul_dt.format('YYYYMMDD HH:mm:ss') if haul_year > date_year: date = haul_dt logging.info(f"new date: {date}") except Exception as ex: logging.info(f"error getting the proper date/time: {ex}") # Line 8 - Specimen number # If no character at the end, add an A, other increase the character by 1 and update the list item if specimen_number[-1:].isdigit(): specimen_number += "A" else: char = chr(ord(specimen_number[-1:]) + 1) specimen_number = str(specimen_number[:-1]) + char # TODO Todd Hay Update_list_item - should I call back to special_actions.upsert here? # self.update_list_item(action_type, specimen_number) self.tagIdChanged.emit(specimen_number) # Line 9 - barcode_number # barcode_number = re.sub(r'[^\d.]+', '', specimen_number) # barcode_number = re.sub(r'[\W]+', '', specimen_number) # strips the hyphens # barcode_number = specimen_number # Strip all hypens and alpha characters barcode_number = re.sub(r'[^\d]', '', specimen_number) # TODO Todd Hay - I might need to strip the - from the barcode to have it get properly encoded # Per p. 54 - printer specification (epl2 programming manual), hyphens may be used but they'll be ignored # barcode_number = int(specimen_number.strip('-')) # logging.info('specimen number: ' + str(specimen_number)) # logging.info('barcode number: ' + str(barcode_number)) suffix = "\"\n" lead_in = """ N O q500 S3 D10 ZT\n""" lead_in_bytes = bytes(lead_in, "UTF-8") count = 1 lead_out = "\nP" + str( count) + "\n\n" # lead out sends the label count (number to print) lead_out_bytes = bytes(lead_out, "UTF-8") header_bytes = bytes("A0,10,0,4,1,1,N,\"" + header + suffix, "UTF-8") investigator_bytes = bytes( "A0,50,0,4,1,1,N,\"" + "PI: " + investigator + ", " + str(action) + suffix, "UTF-8") haul_id_bytes = bytes( "A0,90,0,4,1,1,N,\"" + "Haul ID: " + str(haul_id) + str(short_specimen_number) + suffix, "UTF-8") species_bytes = bytes( "A0,130,0,4,1,1,N,\"" + "Species: " + species + suffix, "UTF-8") measurement_bytes = bytes("A0,170,0,4,1,1,N,\"" + measurement + suffix, "UTF-8") date_bytes = bytes( "A0,210,0,4,1,1,N,\"" + "Date: " + str(date) + suffix, "UTF-8") location_bytes = bytes("A0,250,0,4,1,1,N,\"" + str(location) + suffix, "UTF-8") specimen_number_bytes = bytes( "A0,290,0,4,1,1,N,\"" + "Spec #: " + str(specimen_number) + suffix, "UTF-8") barcode_bytes = bytes( "B0,330,0,1,3,3,72,N,\"" + str(barcode_number) + suffix, "UTF-8") rows = [ lead_in_bytes, header_bytes, investigator_bytes, haul_id_bytes, species_bytes, measurement_bytes, date_bytes, location_bytes, specimen_number_bytes, barcode_bytes, lead_out_bytes ] if comport is None: comport = "COM9" kwargs = {"comport": comport, "rows": rows} self._printer_worker = PrinterWorker(kwargs=kwargs) self._printer_worker.moveToThread(self._printer_thread) self._printer_worker.printerStatus.connect( self._printer_status_received) self._printer_thread.started.connect(self._printer_worker.run) self._printer_thread.start()
def run(self): self._is_running = True haul_data = [] # Query the wheelhouse via the RpcServer for the daily hauls ip = self._app.settings.wheelhouseIpAddress port = self._app.settings.wheelhouseRpcServerPort logging.info('Wheelhouse RpcServer address: ' + str(ip) + ", " + str(port)) real_hauls = [] try: server = xrc.ServerProxy('http://' + ip + ':' + str(port), allow_none=True, use_builtin_types=True) real_hauls = server.get_hauls() logging.info('Number of hauls received from wheelhouse: ' + str(len(real_hauls))) except Exception as ex: logging.info('Error contacting wheelhouse computer: ' + str(ex)) # template = ['haul_number', 'start_datetime', 'end_datetime', 'latitude_min', 'longitude_min', 'latitude_max', 'longitude_max', # 'depth_min', 'depth_max', 'vessel_name', 'vessel_color', 'pass_number', 'leg_number'] # template = {x:None for x in template} # For the newly retrieve haul, insert into the database if the haul doesn't exist, otherwise get the haul for real_haul in real_hauls: # logging.info('real_haul: ' + str(real_haul)) try: logging.info(f"real_haul: {real_haul}") logging.info(f"real_haul depth data: {real_haul['depth']}, {real_haul['depth_uom']}") except Exception as ex: logging.error(f"real haul depth data is blowing up: {ex}") current_haul, created = Hauls.get_or_create(haul_number=real_haul["haul_number"], defaults={'start_datetime': real_haul["start_time"] if "start_time" in real_haul else None, 'end_datetime': real_haul["end_time"] if "end_time" in real_haul else None, 'latitude_min': real_haul["latitude"] if "latitude" in real_haul else None, 'longitude_min': real_haul["longitude"] if "longitude" in real_haul else None, 'latitude_max': real_haul["latitude"] if "latitude" in real_haul else None, 'longitude_max': real_haul["longitude"] if "longitude" in real_haul else None, 'depth_min': real_haul["depth"] if "depth" in real_haul else None, 'depth_max': real_haul["depth"] if "depth" in real_haul else None, 'depth_uom': real_haul["depth_uom"] if "depth_uom" in real_haul else None, 'vessel_name': real_haul["vessel_name"] if "vessel_name" in real_haul else None, 'vessel_color': real_haul["vessel_color"] if "vessel_color" in real_haul else None, 'pass_number': real_haul["pass"] if "pass" in real_haul else None, 'leg_number': real_haul["leg"] if "leg" in real_haul else None, 'is_test': "False"}) if created: Hauls.update(processing_status="Active").where(Hauls.haul_number == real_haul["haul_number"]).execute() else: if "start_time" in real_haul: # logging.info('start > db / real_haul: ' + str(real_haul["haul_number"]) + ', '+ str(current_haul.start_datetime) + ' / ' + str(real_haul["start_time"])) if current_haul.start_datetime != real_haul["start_time"]: Hauls.update(start_datetime = real_haul["start_time"], end_datetime = None).where(Hauls.haul_number == real_haul["haul_number"]).execute() else: Hauls.update(start_datetime=None).where(Hauls.haul_number == real_haul["haul_number"]).execute() if "end_time" in real_haul: if current_haul.end_datetime != real_haul["end_time"]: Hauls.update(end_datetime = real_haul["end_time"]).where(Hauls.haul_number == real_haul["haul_number"]).execute() # logging.info('end > db / real_haul: ' + str(real_haul["haul_number"]) + ', ' + str( # current_haul.end_datetime) + ' / ' + str(real_haul["end_time"])) else: Hauls.update(end_datetime=None).where(Hauls.haul_number == real_haul["haul_number"]).execute() current_haul = Hauls.get(haul_number=real_haul["haul_number"]) haul_data.append(model_to_dict(current_haul)) self._is_running = False self.haulsReceived.emit(haul_data)