def revise_plants_status(current_pot: Pot, new_plants_status: dict): revised_plants_status = {} new_plants_objs: Plants = Plants.parse_obj(new_plants_status) old_plants_objs: Plants = current_pot.session.plants # Fields are ordered https://pydantic-docs.helpmanual.io/usage/models/#field-ordering for old_plant_tuple, new_plant_tuple in zip(old_plants_objs, new_plants_objs): old_plant: Plant = old_plant_tuple[1] new_plant: Plant = new_plant_tuple[1] ring_colour = old_plant.ringColour # NOTE: After harvest, slot will be empty so None. For UT, no new seeds after harvest, so keep it at None # TODO: Ideally to remove this once UI allows users to indicate to plant new seed if old_plant.growthStage == None: new_plant = Plant(growthStage=None, ringColour=new_plant.ringColour) # TODO: Future work: start time of seed planting based on user indication in app, not session start time # NOTE: Add replace(tzinfo=None) to avoid error "can't subtract offset-naive and offset-aware datetimes" elif is_seed(datetime.utcnow(), current_pot.session.sessionStartTime.replace(tzinfo=None)): new_plant.growthStage = GrowthStage.seed elif is_sprouting(new_plant.growthStage, datetime.utcnow(), current_pot.session.sessionStartTime.replace(tzinfo=None)): new_plant.growthStage = GrowthStage.sprouting else: logger.info("No revision to plants status needed") revised_plants_status[ring_colour] = new_plant.dict() return revised_plants_status
def create(self, analysis=Analysis()): """ (Analysis) -> (Analysis) Add analysis to database """ analysisDB = AnalysisDB(analysis=analysis) session = self.session_factory() session.add(analysisDB) session.flush() session.refresh(analysisDB) session.commit() return Analysis( analysisDB.id, image=Image( analysisDB.image.id, Disease( analysisDB.image.disease.id, Plant(analysisDB.image.disease.plant.id, analysisDB.image.disease.plant.scientificName, analysisDB.image.disease.plant.commonName), analysisDB.image.disease.scientificName, analysisDB.image.disease.commonName), analysisDB.image.url, analysisDB.image.description, analysisDB.image.source, analysisDB.image.size), classifier=Classifier( analysisDB.classifier.id, Plant(analysisDB.classifier.plant.id, analysisDB.classifier.plant.scientificName, analysisDB.classifier.plant.commonName), analysisDB.classifier.tag, analysisDB.classifier.path), user=User(id=analysisDB.user.id, idType=analysisDB.user.idType, email=analysisDB.user.email, username=analysisDB.user.username))
def test_searchPlantByScientificName(): """ Test function created for analyze searchPlantByScientificName """ plants = [ Plant(commonName="orange"), Plant(commonName="banana"), Plant(commonName="grape") ] assert searchPlantByScientificName(plants, "grape") == 2
def create(self, plant=Plant()): """ (Plant) -> (Plant) """ plantDB = PlantDB(plant=plant) session = self.session_factory() session.add(plantDB) session.flush() session.refresh(plantDB) session.commit() return Plant(plantDB.id, plantDB.scientificName, plantDB.commonName)
def create(self, analysisResult=AnalysisResult()): """ (AnalysisResult) -> (AnalysisResult) Add analysis result to database """ analysisResultDB = AnalysisResultDB(analysisResult=analysisResult) session = self.session_factory() session.add(analysisResultDB) session.flush() session.commit() session.refresh(analysisResultDB) return AnalysisResult( analysisResultDB.id, Analysis( analysisResultDB.analysis.id, Image( analysisResultDB.analysis.image.id, Disease( analysisResultDB.analysis.image.disease.id, Plant( analysisResultDB.analysis.image.disease.plant.id, analysisResultDB.analysis.image.disease.plant. scientificName, analysisResultDB.analysis.image. disease.plant.commonName), analysisResultDB.analysis.image.disease.scientificName, analysisResultDB.analysis.image.disease.commonName), analysisResultDB.analysis.image.url, analysisResultDB.analysis.image.description, analysisResultDB.analysis.image.source, analysisResultDB.analysis.image.size), Classifier( analysisResultDB.analysis.classifier.id, Plant( analysisResultDB.analysis.classifier.plant.id, analysisResultDB.analysis.classifier.plant. scientificName, analysisResultDB.analysis.classifier.plant.commonName), analysisResultDB.analysis.classifier.tag, analysisResultDB.analysis.classifier.path), user=User(id=analysisResultDB.analysis.user.id, idType=analysisResultDB.analysis.user.idType, email=analysisResultDB.analysis.user.email, username=analysisResultDB.analysis.user.username)), Disease( analysisResultDB.disease.id, Plant(analysisResultDB.disease.plant.id, analysisResultDB.disease.plant.scientificName, analysisResultDB.disease.plant.commonName), analysisResultDB.disease.scientificName, analysisResultDB.disease.commonName), analysisResultDB.score, analysisResultDB.frame)
def searchByID(self, id): """ (int) -> (AnalysisResult) Search analysis result by ID """ session = self.session_factory() analysisResultDB = session.query(AnalysisResultDB).get(id) if (analysisResultDB is None): raise Exception("AnalysisResults not found!") return AnalysisResult( analysisResultDB.id, Analysis( analysisResultDB.analysis.id, Image( analysisResultDB.analysis.image.id, Disease( analysisResultDB.analysis.image.disease.id, Plant( analysisResultDB.analysis.image.disease.plant.id, analysisResultDB.analysis.image.disease.plant. scientificName, analysisResultDB.analysis.image. disease.plant.commonName), analysisResultDB.analysis.image.disease.scientificName, analysisResultDB.analysis.image.disease.commonName), analysisResultDB.analysis.image.url, analysisResultDB.analysis.image.description, analysisResultDB.analysis.image.source, analysisResultDB.analysis.image.size), Classifier( analysisResultDB.analysis.classifier.id, Plant( analysisResultDB.analysis.classifier.plant.id, analysisResultDB.analysis.classifier.plant. scientificName, analysisResultDB.analysis.classifier.plant.commonName), analysisResultDB.analysis.classifier.tag, analysisResultDB.analysis.classifier.path), user=User(id=analysisResultDB.analysis.user.id, idType=analysisResultDB.analysis.user.idType, email=analysisResultDB.analysis.user.email, username=analysisResultDB.analysis.user.username)), Disease( analysisResultDB.disease.id, Plant(analysisResultDB.disease.plant.id, analysisResultDB.disease.plant.scientificName, analysisResultDB.disease.plant.commonName), analysisResultDB.disease.scientificName, analysisResultDB.disease.commonName), analysisResultDB.score, analysisResultDB.frame)
def get(self): parser = reqparse.RequestParser() parser.add_argument('name', type=str, help='Common Name of the plant you want to search') args = parser.parse_args() try: plant = json.loads(Plant.objects().to_json()) except Exception as e: print(e) return {} plant_names = [x['name'] for x in plant] plant_choices = process.extract(args['name'], plant_names) plant_choices = [x for x in plant_choices if x[1] > 80] plant_list = [] for x in plant_choices: for y in plant: if y['name'] == x[0]: plant_list.append(y) return jsonify(plant_list)
def searchByID(self, plantId): """ (Int) -> (Plant) """ session = self.session_factory() plantDB = session.query(PlantDB).get(plantId) return Plant(plantDB.id, plantDB.scientificName, plantDB.commonName)
def search(self, plant=Plant(), pageSize=10, offset=0): """ (Plant, pageSize, offset) -> {'total': int, 'content':[Plant]} """ session = self.session_factory() query = session.query(PlantDB).filter( or_(PlantDB.scientificName.like('%' + plant.scientificName + '%'), PlantDB.commonName == plant.commonName)) content = query.slice(offset, pageSize).all() total = query.count() plants = [] for plantDB in content: plants.append( Plant(plantDB.id, plantDB.scientificName, plantDB.commonName)) dic = {'total': total, 'content': plants} return dic
def harvest_ready(new_plants_status: dict): for ring_colour in new_plants_status: plant = Plant.parse_obj(new_plants_status[ring_colour]) if plant.growthStage == GrowthStage.harvest: # As long as there is harvest stage for any plant inform return True return False
def update(self, image=Image()): """ (Image) -> (Image) Update database image """ session = self.session_factory() imageDB = session.query(ImageDB).filter_by(id=image.id).first() dic = {} if (imageDB.disease.id != image.disease.id): dic['idDisease'] = image.disease.id if (imageDB.url != image.url): dic['url'] = image.url if (imageDB.description != image.description): dic['description'] = image.description if (imageDB.source != image.source): dic['source'] = image.source if (imageDB.size != image.size): dic['size'] = image.size if (dic != {}): session.query(ImageDB).filter_by(id=image.id).update(dic) session.commit() session.flush() session.refresh(imageDB) return Image( imageDB.id, Disease( imageDB.disease.id, Plant(imageDB.disease.plant.id, imageDB.disease.plant.scientificName, imageDB.disease.plant.commonName), imageDB.disease.scientificName, imageDB.disease.commonName), imageDB.url, imageDB.description, imageDB.source, imageDB.size)
def __init__(self, id=0, plant=Plant(), tag="", path="", analyses=list()): self.id = id self.plant = plant self.tag = tag self.path = path self.analyses = analyses
def plant_full_setup(app): testPlantType = PlantType(plantName, requiredWater, waterFrequency, minTemp, maxTemp, minHumidity, maxHumidity, minMoisture, maxMoisture, idealMoistureLevel, minLightIntensity, maxLightIntensity) device = Device(testMACAddress, testTime) client = app.test_client() db.session.add(device) db.session.add(testPlantType) db.session.commit() testPlant = Plant(type=testPlantType.id, level=testLevel, location=testLocation) print(testPlantType.id) db.session.add(testPlant) db.session.commit() yield "" db.session.delete(testPlant) db.session.delete(testPlantType) db.session.delete(device) # num_rows_deleted = db.session.query(Plant).delete() db.session.commit()
def search(self, image=Image(), pageSize=10, offset=0): """ (Image, pageSize, offset) -> [Image] """ session = self.session_factory() query = session.query(ImageDB).filter( or_(ImageDB.url.like('%' + image.url + '%'), ImageDB.description == image.description, ImageDB.source == image.source)) content = query.slice(offset, pageSize).all() total = query.count() images = [] for imageDB in content: images.append( Image( imageDB.id, Disease( imageDB.disease.id, Plant(imageDB.disease.plant.id, imageDB.disease.plant.scientificName, imageDB.disease.plant.commonName), imageDB.disease.scientificName, imageDB.disease.commonName), imageDB.url, imageDB.description, imageDB.source, imageDB.size)) return {'total': total, 'content': images}
def searchByID(self, id): """ (int) -> (Analysis) Search analysis by ID """ session = self.session_factory() analysisDB = session.query(AnalysisDB).get(id) if (analysisDB is None): raise Exception("Analysis not found!") results = [] for result in analysisDB.analysis_results: results.append( AnalysisResult( id=result.id, disease=Disease( id=result.disease.id, scientificName=result.disease.scientificName, commonName=result.disease.commonName), frame=result.frame, score=result.score)) return Analysis( id=analysisDB.id, image=Image( analysisDB.image.id, Disease( analysisDB.image.disease.id, Plant(analysisDB.image.disease.plant.id, analysisDB.image.disease.plant.scientificName, analysisDB.image.disease.plant.commonName), analysisDB.image.disease.scientificName, analysisDB.image.disease.commonName), analysisDB.image.url, analysisDB.image.description, analysisDB.image.source, analysisDB.image.size), classifier=Classifier( analysisDB.classifier.id, Plant(analysisDB.classifier.plant.id, analysisDB.classifier.plant.scientificName, analysisDB.classifier.plant.commonName), analysisDB.classifier.tag, analysisDB.classifier.path), analysis_results=results, user=User(id=analysisDB.user.id, idType=analysisDB.user.idType, email=analysisDB.user.email, username=analysisDB.user.username))
async def cv_inference(pot_id, encoded_img_data): if CV_SERVER_URL_PREFIX == None: raise Exception("CV_SERVER_URL_PREFIX not set") data = { "potId": pot_id, "encoded_data": encoded_img_data } async with aiohttp.request(method='GET', url=CV_SERVER_URL_PREFIX, json=data) as resp: if resp.status == 200: response = await resp.json() for ring_colour in response: try: Plant.parse_obj(response[ring_colour]) # Validate data with model except Exception as e: raise Exception("CV server's response validation error") return response else: response = await resp.json() logger.error("Respose status={}, response={}".format(resp.status, response)) raise Exception("Something went wrong in CV Server")
def update(self, plant=Plant()): """ (Plant) -> (Plant) """ session = self.session_factory() plantDB = session.query(PlantDB).filter_by(id=plant.id).first() dic = {} if (plantDB.scientificName != plant.scientificName): dic['scientificName'] = plant.scientificName if (plantDB.commonName != plant.commonName): dic['commonName'] = plant.commonName if (dic != {}): session.query(PlantDB).filter_by(id=plant.id).update(dic) session.commit() session.flush() session.refresh(plantDB) return Plant(plantDB.id, plantDB.scientificName, plantDB.commonName)
def get_harvests_completed(current_pot: Pot, new_plants_status: dict): harvest_count = 0 after_harvest_plants_status = {} new_plants_objs: Plants = Plants.parse_obj(new_plants_status) old_plants_objs: Plants = current_pot.session.plants # Fields are ordered https://pydantic-docs.helpmanual.io/usage/models/#field-ordering for old_plant_tuple, new_plant_tuple in zip(old_plants_objs, new_plants_objs): old_plant: Plant = old_plant_tuple[1] new_plant: Plant = new_plant_tuple[1] ring_colour = old_plant.ringColour if is_harvested(old_plant, new_plant): # NOTE: After harvest, slot will be empty so None, since CV can't differentiate null, seed and sprout new_plant = Plant(growthStage=None, ringColour=new_plant.ringColour) harvest_count += 1 after_harvest_plants_status[ring_colour] = new_plant.dict() return harvest_count, after_harvest_plants_status
def update(self, analysis=Analysis()): """ (Analysis) -> (Analysis) update analysis table """ session = self.session_factory() analysisDB = session.query(AnalysisDB).filter_by( id=analysis.id).first() dic = {} if (analysisDB.idImage != analysis.image.id): dic['idImage'] = analysis.image.id if (analysisDB.idClassifier != analysis.classifier.id): dic['idClassifier'] = analysis.classifier.id if (dic != {}): session.query(AnalysisDB).filter_by(id=analysis.id).update(dic) session.commit() session.flush() session.refresh(analysisDB) return Analysis( analysisDB.id, image=Image( analysisDB.image.id, Disease( analysisDB.image.disease.id, Plant(analysisDB.image.disease.plant.id, analysisDB.image.disease.plant.scientificName, analysisDB.image.disease.plant.commonName), analysisDB.image.disease.scientificName, analysisDB.image.disease.commonName), analysisDB.image.url, analysisDB.image.description, analysisDB.image.source, analysisDB.image.size), classifier=Classifier( analysisDB.classifier.id, Plant(analysisDB.classifier.plant.id, analysisDB.classifier.plant.scientificName, analysisDB.classifier.plant.commonName), analysisDB.classifier.tag, analysisDB.classifier.path), user=User(id=analysisDB.user.id, idType=analysisDB.user.idType, email=analysisDB.user.email, username=analysisDB.user.username))
def searchByID(self, id): """ (Int) -> (Disease) """ session = self.session_factory() diseaseDB = session.query(DiseaseDB).get(id) return Disease( diseaseDB.id, Plant(diseaseDB.plant.id, diseaseDB.plant.scientificName, diseaseDB.plant.commonName), diseaseDB.scientificName, diseaseDB.commonName)
def __init__(self, id=0, plant=Plant(), scientificName="", commonName="", images=list()): self.id = id self.plant = plant self.scientificName = scientificName self.commonName = commonName self.images = images
def searchByID(self, id): """ (Int) -> (Classifier) """ session = self.session_factory() classifierDB = session.query(ClassifierDB).get(id) return Classifier( classifierDB.id, Plant(classifierDB.plant.id, classifierDB.plant.scientificName, classifierDB.plant.commonName), classifierDB.tag, classifierDB.path)
def to_show_trim(new_plants_status): after_check_trim_status = {} for ring_colour in new_plants_status: if new_plants_status[ring_colour] == None: plant = None else: plant = Plant.parse_obj(new_plants_status[ring_colour]) if plant.yellowness.value > 0.3: plant.yellowness.toShowTrim = True after_check_trim_status[ring_colour] = plant.dict() if plant != None else plant return after_check_trim_status
def search(self, analysis=Analysis(), pageSize=10, offset=0): """ (Analysis, pageSize, offset) -> [Analysis] search by analysis """ session = self.session_factory() query = session.query(AnalysisDB).filter( and_(AnalysisDB.idImage == analysis.image.id, AnalysisDB.idClassifier == analysis.classifier.id)) content = query.slice(offset, pageSize).all() total = query.count() analyses = [] for analysisDB in content: analyses.append( Analysis( analysisDB.id, image=Image( analysisDB.image.id, Disease( analysisDB.image.disease.id, Plant( analysisDB.image.disease.plant.id, analysisDB.image.disease.plant.scientificName, analysisDB.image.disease.plant.commonName), analysisDB.image.disease.scientificName, analysisDB.image.disease.commonName), analysisDB.image.url, analysisDB.image.description, analysisDB.image.source, analysisDB.image.size), classifier=Classifier( analysisDB.classifier.id, Plant(analysisDB.classifier.plant.id, analysisDB.classifier.plant.scientificName, analysisDB.classifier.plant.commonName), analysisDB.classifier.tag, analysisDB.classifier.path), user=User(id=analysisDB.user.id, idType=analysisDB.user.idType, email=analysisDB.user.email, username=analysisDB.user.username))) return {'total': total, 'content': analyses}
def delete(self, plant=Plant()): """ (Plant) -> (Boolean) """ status = False session = self.session_factory() plantDB = session.query(PlantDB).filter_by(id=plant.id).first() session.delete(plantDB) session.commit() session.flush() if (not session.query(PlantDB).filter_by(id=plantDB.id).count()): status = True session.close() return status
def create(self, disease=Disease()): """ (Disease) -> (Disease) """ diseaseDB = DiseaseDB(disease=disease) session = self.session_factory() session.add(diseaseDB) session.flush() session.refresh(diseaseDB) session.commit() return Disease( diseaseDB.id, Plant(diseaseDB.plant.id, diseaseDB.plant.scientificName, diseaseDB.plant.commonName), diseaseDB.scientificName, diseaseDB.commonName)
def create(self, classifier=Classifier()): """ (Classifier) -> (Classifier) """ classifierDB = ClassifierDB(classifier=classifier) session = self.session_factory() session.add(classifierDB) session.flush() session.refresh(classifierDB) session.commit() return Classifier( classifierDB.id, Plant(classifierDB.plant.id, classifierDB.plant.scientificName, classifierDB.plant.commonName), classifierDB.tag, classifierDB.path)
def searchByID(self, id): """ (Int) -> (Image) Method used to get image object by ID """ session = self.session_factory() imageDB = session.query(ImageDB).get(id) return Image( imageDB.id, Disease( imageDB.disease.id, Plant(imageDB.disease.plant.id, imageDB.disease.plant.scientificName, imageDB.disease.plant.commonName), imageDB.disease.scientificName, imageDB.disease.commonName), imageDB.url, imageDB.description, imageDB.source, imageDB.size)
def searchByID(self, plantId): """ (Int) -> (Plant) """ session = self.session_factory() plantDB = session.query(PlantDB).get(plantId) diseases = [] for disease in plantDB.diseases: diseases.append(Disease( id=disease.id, scientificName=disease.scientificName, commonName=disease.commonName)) return Plant(plantDB.id, plantDB.scientificName, plantDB.commonName, diseases)
def create(self, image=Image()): """ (Image) -> (Image) Add image to database """ imageDB = ImageDB(image=image) session = self.session_factory() session.add(imageDB) session.flush() session.refresh(imageDB) session.commit() return Image( imageDB.id, Disease( imageDB.disease.id, Plant(imageDB.disease.plant.id, imageDB.disease.plant.scientificName, imageDB.disease.plant.commonName), imageDB.disease.scientificName, imageDB.disease.commonName), imageDB.url, imageDB.description, imageDB.source, imageDB.size)