def testSitePinot(self): # Get All Pinots Readings for the current season season = get_current_season() site = Site.objects.get(id=1) dates = get_site_season_start_end(site, season) readings = Reading.objects.filter(site=site, date__range=(dates.period_from, dates.period_to)) self.assertEquals(site.name, 'Pinot Noir Springstone') # There are 7 readings including Full Point and Refill self.assertEquals(readings.count(), 7)
def testNuetronProbeFileUpload(self): # Update season to 2019-2020 season = Season.objects.get(name="2018-2019") season.current_flag = False season = Season.objects.get(name="2019-2020") season.current_flag = True c = Client() # Need a meter reading before uplaoding file for that date or else the upload will complain c.post('/readings/onsite/', { 'site': '1', 'date': '2019-11-18', 'meter': '37000' }) with open('skeleton/tests/files/neutron_probe_test_upload_1_site.csv' ) as fp: c.post('/upload_readings_file/', { 'description': 'test', 'attachment': fp }) site = Site.objects.get(id=1) dates = get_site_season_start_end(site, season) readings = Reading.objects.filter(site=site, date__range=(dates.period_from, dates.period_to)) for reading in readings: logger.debug(str(reading)) if str(reading.date) == '2019-11-18': self.assertEquals(reading.depth1, 23.0) if str(reading.date) == '2019-8-23': self.assertEquals(reading.depth1, 15256.0) self.assertEquals(reading.depth2, 15420.0) self.assertEquals(reading.depth3, 14866.6666666667) self.assertEquals(reading.depth4, 14256.0) self.assertEquals(reading.depth5, 14501.3333333333) self.assertEquals(reading.depth6, 15121.3333333333) self.assertEquals(reading.depth7, 15282.6666666667) self.assertEquals(reading.depth8, 17916.0)
def handle(self, *args, **kwargs): logger.info('Running processdailywateruse.....') # Get sites in current season that have readngs with a rz1 defined but no deficit season = get_current_season() if kwargs['sites']: sites = kwargs['sites'] logger.info( 'Starting update of daily water use readings for sites that have just been uploaded.' + str(sites)) else: sites = Site.objects.filter( is_active=True, readings__rz1__isnull=False, readings__deficit__isnull=True, readings__type__name='Probe').distinct() logger.info( 'Starting update of daily water use readings for all sites that have a reading deficit of null.' + str(sites)) for site in sites: dates = get_site_season_start_end(site, season) readings = Reading.objects.filter( site=site.id, type=1, date__range=(dates.period_from, dates.period_to)).order_by('-date') # Get Full Point Reading for the Season rz1_full = get_rz1_full_point_reading(site, season) logger.info('Full Point RZ1 reading:' + str(rz1_full)) previous_date = None previous_reading = 0 previous_deficit = 0 for reading in readings: logger.debug(str(reading)) date = reading.date logger.debug('Getting RT and KC readings for date: ' + str(date)) month = date.strftime("%m") day = date.strftime("%d") logger.debug('Ignoring year and getting month:day' + str(month) + ':' + str(day)) # Get Evapotranspiration (ET) for the site on the reading date. Ignore year as this data is by day and is the same every season try: et = ETReading.objects.get(date__month=month, date__day=day) except: raise SiteReadingException( "No ET reading found for " + str(date), site) daily_et = round(et.daily, 2) logger.debug('ET Reading:' + str(daily_et)) # Get Crop Co-efficient (KC) for site. Need to get it between periods try: kc = KCReading.objects.get(period_from__lte=date, period_to__gte=date, crop__product__site__id=site.id) except: raise SiteReadingException( "No KC reading found for " + str(date), site) crop_kc = round(kc.kc, 2) logger.debug('KC Reading:' + str(crop_kc)) # Get EDWU as et * kc edwu = daily_et * crop_kc edwu = round(edwu, 2) logger.debug('EDWU:' + str(edwu)) reading.estimated_dwu = edwu rz1 = reading.rz1 if rz1 == None: raise SiteReadingException( "Root Zone 1 is blank for reading date " + str(date), site) deficit = round(rz1_full - rz1, 2) logger.debug('Deficit:' + str(deficit)) reading.deficit = deficit if previous_date: logger.debug('Date:' + str(date) + ' PreviousDate:' + str(previous_date)) # Find the amount of days between days = previous_date - date logger.debug('Days:' + str(days.days)) pdwu = round((previous_deficit - deficit) / days.days, 2) logger.debug('PDWU:' + str(pdwu)) previous_reading.probe_dwu = pdwu previous_reading.save() else: logger.debug('No previous date.') previous_date = date previous_deficit = deficit previous_reading = reading reading.save() logger.info('Finished processdailywateruse.....')
def testProcesses(self): season = get_current_season() site = Site.objects.get(id=1) dates = get_site_season_start_end(site, season) management.call_command('request_to_hortplus') management.call_command('processrootzones') management.call_command('processdailywateruse') management.call_command('processmeter') management.call_command('processrainirrigation') readings = Reading.objects.filter(site=site, date__range=(dates.period_from, dates.period_to)) for reading in readings: logger.debug(str(reading)) if str(reading.date) == '2018-12-14': self.assertEquals(reading.rz1, 224) self.assertEquals(reading.rz2, 147) self.assertEquals(reading.rz3, 82) self.assertEquals(reading.deficit, -4) self.assertEquals(reading.probe_dwu, None) self.assertEquals(reading.estimated_dwu, 9.6) self.assertEquals(reading.irrigation_litres, None) self.assertEquals(reading.irrigation_mms, None) #self.assertEquals(reading.effective_rainfall, None) #self.assertEquals(reading.effective_irrigation, None) if str(reading.date) == '2019-05-02': self.assertEquals(reading.rz1, 321) self.assertEquals(reading.rz2, 178) self.assertEquals(reading.rz3, 76) self.assertEquals(reading.deficit, -101) self.assertEquals(reading.probe_dwu, -0.7) self.assertEquals(reading.estimated_dwu, 4.13) self.assertEquals(reading.irrigation_litres, 1.33) self.assertEquals(reading.irrigation_mms, 0.11) #self.assertEquals(reading.effective_rainfall, None) #self.assertEquals(reading.effective_irrigation, None) if str(reading.date) == '2019-05-07': self.assertEquals(reading.rz1, 314) self.assertEquals(reading.rz2, 223) self.assertEquals(reading.rz3, 132) self.assertEquals(reading.deficit, -94) self.assertEquals(reading.probe_dwu, 1.4) self.assertEquals(reading.estimated_dwu, 3.87) self.assertEquals(reading.irrigation_litres, 0.33) self.assertEquals(reading.irrigation_mms, 0.03) #self.assertEquals(reading.effective_rainfall, None) #self.assertEquals(reading.effective_irrigation, 0.0) if str(reading.date) == '2019-05-14': self.assertEquals(reading.rz1, 220) self.assertEquals(reading.rz2, 145) self.assertEquals(reading.rz3, 82) self.assertEquals(reading.deficit, 0) self.assertEquals(reading.probe_dwu, 13.43) self.assertEquals(reading.estimated_dwu, 4.88) self.assertEquals(reading.irrigation_litres, 5) self.assertEquals(reading.irrigation_mms, 0.4) #self.assertEquals(reading.effective_rainfall, 0) #self.assertEquals(reading.effective_irrigation, 0) if str(reading.date) == '2019-05-21': self.assertEquals(reading.rz1, 205) self.assertEquals(reading.rz2, 144) self.assertEquals(reading.rz3, 82) self.assertEquals(reading.deficit, 15) self.assertEquals(reading.probe_dwu, 2.14) self.assertEquals(reading.estimated_dwu, 4.41) self.assertEquals(reading.irrigation_litres, 8.33) self.assertEquals(reading.irrigation_mms, 0.67) #self.assertEquals(reading.effective_rainfall, 0.7) #self.assertEquals(reading.effective_irrigation, 0.67) # Test non standard irrigation site = Site.objects.get(name='Jazz') dates = get_site_season_start_end(site, season) readings = Reading.objects.filter(site=site, date__range=(dates.period_from, dates.period_to)) for reading in readings: if str(reading.date) == '2019-05-21': self.assertEquals(reading.irrigation_litres, 157.49) self.assertEquals(reading.irrigation_mms, 19.3) if str(reading.date) == '2019-05-14': self.assertEquals(reading.irrigation_litres, 107.71) self.assertEquals(reading.irrigation_mms, 13.2) if str(reading.date) == '2019-05-7': self.assertEquals(reading.irrigation_litres, 0) self.assertEquals(reading.irrigation_mms, 0)
def handle(self, *args, **kwargs): response_text = None # get arguments from command line or use ones that will be done autoamtically serial = kwargs['serial'] if kwargs['serial'] else os.getenv( 'HORTPLUS_JACK_KEY') if kwargs['purpose'] is None: data = { 'period': kwargs['period'], # 7 'format': kwargs['format'], # csv 'interval': kwargs['interval'], # D 'stations': kwargs['stations'], # HAV 'metvars': kwargs['metvars'] # RN_T } # startdate is optional if kwargs['startdate']: data['startdate'] = kwargs['startdate'] response_text = post_request(data, serial) elif kwargs['purpose'] == 'process_readings': logger.info('Start processing of readings') readings = None if kwargs['sites']: sites = kwargs['sites'] logger.info( 'Starting update of rainfall for sites that have just been uploaded and have a null rain reading.' + str(sites)) readings = Reading.objects.select_related( 'site__farm__weatherstation').filter(site__in=sites, rain__isnull=True, type=1) else: logger.info( 'Starting update of rainfall for all sites that have a null rain reading' ) readings = Reading.objects.select_related( 'site__farm__weatherstation').filter(rain__isnull=True, type=1) for reading in readings: logger.debug('Reading object to process: ' + str(reading)) season = get_current_season() dates = get_site_season_start_end(reading.site, season) # If a site has only one reading we cannot calculate the previous reading date. A try block is the only way to catch this try: previous_reading = reading.get_previous_by_date( site=reading.site, type=1, date__range=(dates.period_from, dates.period_to)) except: previous_reading = None if previous_reading: site = reading.site farm = site.farm weatherstation = farm.weatherstation days = (reading.date - previous_reading.date).days - 1 logger.debug('Previous Reading:' + str(previous_reading)) logger.debug(days) startdate = previous_reading.date + timedelta(days=1) logger.debug('startdate' + str(startdate)) data = { 'period': days, 'startdate': str(startdate), 'format': 'csv', 'interval': 'D', 'stations': weatherstation.code, 'metvars': 'RN_T' } response_text = post_request(data, serial) lines = response_text.split("\n") del lines[0] rainfall = 0 for line in lines: valid = re.search( "^\w.*", line) # make sure we have a valid line to split if valid: fields = line.split(",") if fields[3] != '-' and fields[3] != '.': rainfall += float(fields[3]) logger.debug(str(rainfall)) reading.rain = round(rainfall, 1) reading.save() else: logger.debug( 'No previous reading for site so cannot calculate a rain reading' ) elif kwargs['purpose'] == 'generate_eoy_data': rain_data = { } # Keyed by the weatherstation code and the value will be the sum of rain / 10 years #current_rain_data = {} start_dates = [ ] # 10 start dates starting at the 1st October of current year. Actually 2nd cause of the way API works season = Season.objects.get(current_flag=True) current_year = season.formatted_season_start_year current_year_date = str(current_year) + '-10-02' start_dates.append(current_year_date) station = kwargs['stations'] logger.debug( "Generating average rainfall for last 10 years back from " + current_year_date + " for station " + station) for month in [ '10', '11', '12', '01', '02', '03', '04', '05', '06' ]: rain_data[month] = {'avg': 0, 'cur': 0} x = 0 while x < 10: year = (int(current_year) - 1) - x # Start Date will always be 1st of October of year we got for current. date = str(year) + '-10-02' start_dates.append(date) x = x + 1 logger.debug('We will be getting rainfall data for ' + str(start_dates) + ' + 272 days') # We will have the current year, and the previous 10 years in array for start_date in start_dates: data = { 'period': 272, # 272 days will take us to 30th of June (except leap years but don't need to be exact) 'startdate': start_date, 'format': 'csv', 'interval': 'D', 'stations': station, 'metvars': 'RN_T' } response_text = post_request(data, serial) lines = response_text.split("\n") del lines[0] for line in lines: valid = re.search( "^\w.*", line) # make sure we have a valid line to split if valid: fields = line.split(",") station = fields[0] start = fields[1] split_start = start.split( "-") # Split from date "2019-10-17 08:00:00" month = split_start[ 1] # Month which is the key to our rain_data dict is the second part of date rain = fields[3] if rain != '-' and rain != '.': if start_date == current_year_date: rain_data[month]['cur'] += float(rain) else: rain_data[month]['avg'] += float(rain) else: logger.error("Unidentifiable value for rain of:" + rain) return json.dumps(rain_data) else: logger.error('Unidentified purpose of requesting hortplus data')
def handle(self, *args, **kwargs): logger.info('Running processmeter.....') logger.info('Check for meter and null irrigation (litres).....') # Get sites in current season that have readngs with at least one meter reading but no irrigation in litres season = get_current_season() if kwargs['sites']: sites = kwargs['sites'] logger.info( 'Starting update of meter readings for sitesthat have just been uploaded.' + str(sites)) else: sites = Site.objects.filter( is_active=True, readings__meter__isnull=False, readings__irrigation_litres__isnull=True, readings__type__name='Probe').distinct() logger.info( 'Starting update of sites that have meter readings but null irrigation readings.' + str(sites)) for site in sites: logger.info('Processing Site ' + site.name + ' irrigation method ' + str(site.irrigation_method)) dates = get_site_season_start_end(site, season) readings = Reading.objects.filter( site=site.id, type=1, date__range=(dates.period_from, dates.period_to)).order_by('-date') previous_date = None previous_meter = None previous_reading = None for reading in readings: date = reading.date meter = reading.meter rain = reading.rain # Drip method (standard) is one if site.irrigation_method: logger.debug('Calculating standard irrigation method') if previous_date and meter is not None: logger.debug('Date:' + str(date) + ' meter:' + str(meter) + ' PreviousDate:' + str(previous_date) + ' previous meter:' + str(previous_meter)) # Site needs an irrigation_position if site.irrigation_position == None: raise SiteReadingException( "No irrigation position defined", site) # When it comes to processing the standar meter reading, if the difference between last week and this week is less than one, # the system will realise that this is a faulty meter and data cannot be derived between the reset and previous meter reading. # This will cause zero's for the derived fields that depend on this for that weeks reading. if meter > previous_meter: irrigation_litres = 0 irrigation_mms = 0 else: irrigation_litres = round( (previous_meter - meter) / site.irrigation_position, 2) irrigation_mms = round( irrigation_litres / ((site.row_spacing * site.plant_spacing * 10000) / 10000), 2) logger.debug('Irrigation litres:' + str(irrigation_litres)) logger.debug('Irrigation mms:' + str(irrigation_mms)) previous_reading.irrigation_litres = irrigation_litres previous_reading.irrigation_mms = irrigation_mms logger.debug('Previous Reading:' + str(previous_reading)) previous_reading.save() else: logger.debug('No previous date for reading date:' + str(date)) if meter == None: raise SiteReadingException( "No meter reading for latest reading date " + str(date), site) # non standard irrigation else: logger.debug( 'Calculating non-standard fixed irrigation method') if meter is None: meter = 0 if rain is None: rain = 0 if (meter - rain) > 0: irrigation_mms = round(meter - rain + 5, 2) irrigation_litres = round( irrigation_mms * site.row_spacing * site.plant_spacing, 2) else: irrigation_litres = 0 irrigation_mms = 0 logger.debug('Irrigation litres:' + str(irrigation_litres)) logger.debug('Irrigation mms:' + str(irrigation_mms)) reading.irrigation_litres = irrigation_litres reading.irrigation_mms = irrigation_mms reading.save() # reset figures for readings loop previous_date = date previous_meter = meter previous_reading = reading logger.info('Finished running processmeter.....')
def handle(self, *args, **kwargs): logger.info('Running processrainirrigation.....') season = get_current_season() if kwargs['sites']: sites = kwargs['sites'] logger.info( 'Starting update of rain and irrigation readings for sites that have just been uploaded.' + str(sites)) else: sites = Site.objects.filter( is_active=True, readings__effective_irrigation__isnull=True, readings__type__name='Probe').distinct() logger.info( 'Starting update of rain and irrigation readings for all sites that have a null effective irrigation.' + str(sites)) for site in sites: dates = get_site_season_start_end(site, season) # Get Full Point Reading for the Season rz1_full = get_rz1_full_point_reading(site, season) readings = Reading.objects.filter( site=site.id, type=1, date__range=(dates.period_from, dates.period_to)).order_by('-date') previous_date = None previous_rz1 = 0 previous_reading = None previous_edwu = 0 previous_rain = 0 previous_irrigation_mms = 0 for reading in readings: if reading.serial_number is None: raise SiteReadingException( "No serial number found for reading date " + str(date), site) date = reading.date rz1 = reading.rz1 edwu = reading.estimated_dwu rain = reading.rain irrigation_mms = reading.irrigation_mms if irrigation_mms is None: irrigation_mms = 0 if previous_date: effrain1 = 0 effectiverainfall = 0 logger.debug('Date:' + str(date) + ' RZ1:' + str(rz1) + ' PreviousDate:' + str(previous_date) + ' RZ1 ' + str(previous_rz1)) diff = previous_rz1 - rz1 logger.debug('Diff between Now and Previous:' + str(diff)) rz1_diff = previous_rz1 - diff logger.debug('RZ1-Diff:' + str(rz1_diff)) edwu_factor3 = previous_edwu * 3 logger.debug('EDWU Factor for Rain (*3):' + str(edwu_factor3)) edwu_factor5 = previous_edwu * 5 logger.debug('EDWU Factor for Irrigation (*5):' + str(edwu_factor5)) logger.debug('Rain:' + str(previous_rain)) sub_total_rain = rz1_diff - edwu_factor3 + previous_rain logger.debug('RZ1-Diff - EDWU Factor 3 + Rain =' + str(sub_total_rain)) sub_total_irrigation = 0 logger.debug('irrigation_mms:' + str(previous_irrigation_mms)) if irrigation_mms > 0: sub_total_irrigation = rz1_diff - edwu_factor5 + ( previous_irrigation_mms / 4) logger.debug( 'RZ1-Diff - EDWU Factor 5 + (Irrigation mms / 4) =' + str(sub_total_irrigation)) # Compare sub_total_rain to full point reading if rz1_full >= sub_total_rain: effrain1 = round(previous_rain - 5, 2) else: effrain1 = round(rz1_full - (rz1_diff + edwu_factor3), 2) logger.debug('Effrain1 for date ' + str(previous_date) + ':' + str(effrain1)) if effrain1 > 0: effectiverainfall = effrain1 logger.debug('Effective Rainfall for date ' + str(previous_date) + ':' + str(effectiverainfall)) # # Compare sub_total_irrigation to full point reading if rz1_full >= sub_total_irrigation: efflrr1 = previous_irrigation_mms else: efflrr1 = round(rz1_full - (rz1_diff + edwu_factor5), 2) if efflrr1 > 0: efflrr2 = efflrr1 else: efflrr2 = 0 effective_irrigation = 0 if previous_irrigation_mms > 0: effective_irrigation = efflrr2 logger.debug('Effective Irrigation for date ' + str(previous_date) + ':' + str(effective_irrigation)) previous_reading.effective_rain_1 = effrain1 previous_reading.effective_rainfall = effectiverainfall previous_reading.effective_irrigation = effective_irrigation previous_reading.save() else: logger.debug('No previous date.') previous_date = date previous_rz1 = rz1 previous_edwu = edwu previous_rain = rain previous_reading = reading previous_irrigation_mms = irrigation_mms logger.debug('End loop of readings for a site') logger.info('Finishing processrain.....')
def handle(self, *args, **kwargs): logger.info('Running processrootzones.....') season = get_current_season() if kwargs['sites']: sites = kwargs['sites'] logger.info( 'Starting update of root zone readings for sites that have just been uploaded.' + str(sites)) else: sites = Site.objects.filter(is_active=True, readings__rz1__isnull=True).distinct() logger.info( 'Starting update of root zone readings for all sites that have rz1 empty.' + str(sites)) for site in sites: dates = get_site_season_start_end(site, season) rootzones = get_rootzone_mapping(site) readings = vsw_reading.objects.filter( site_id=site.id, date__range=(dates.period_from, dates.period_to)).order_by('date') for reading in readings: # find rootzones in map for site and rz logger.debug("Reading Date: " + str(reading.date) + " Type: " + reading.type) for z in range(1, 4): rootzone = 'rz' + str(z) key = str(reading.site_id) + rootzone logger.debug("Key:" + key) required_depths = rootzones[key] logger.debug("Required Depths:" + str(required_depths)) total = 0 previous_vsw = 0 previous_he = 0 running_depth = 0 for depths_key in required_depths: he = depths_key['he'] depth = depths_key['depth'] bottom = depths_key['rz_bottom'] logger.debug("Reading He:" + str(he) + ' Depth:' + str(depth) + ' preious he ' + str(previous_he)) # he can be zero if we are requiring a half for final reading if he: column = 'vsw' + str(he) + '_perc' vsw = getattr(reading, column) logger.debug("VSW reading for depth " + str(depth) + ' is ' + str(vsw)) if vsw: # We no have some wierd rules. 1. If running depth is 0 and first depth is 20 add half of vsw to total if depth == 20 and running_depth == 0: logger.debug( "In running depth is 0 and first depth is 20" ) logger.debug("Adding " + str(vsw) + ' for interpoloated depth 10') total += vsw # 2. If depth minus running depth equals 20 add together previous vsw with present vsw then divide by 2 elif (depth - running_depth) == 20: logger.debug( "depth minus running depth equals 20") logger.debug("previous_vsw:" + str(previous_vsw) + "vsw:" + str(vsw)) average = (previous_vsw + vsw) / 2 logger.debug("Adding " + str(average) + ' for interpoloated depth ' + str(depth - 10)) total += average if depth <= bottom: logger.debug("Adding VSW " + str(vsw) + " for depth " + str(depth)) total += vsw previous_vsw = vsw previous_he = he running_depth = depth ''' else: logger.debug('In else ' + str(previous_he)) # We have the last interpolated value. We need the two previous values column1 = 'vsw' + str(previous_he) + '_perc' column2 = 'vsw' + str(previous_he - 1) + '_perc' vsw1 = getattr(reading, column1) vsw2 = getattr(reading, column2) average = (vsw1 + vsw2) / 2 logger.debug("Adding " + str(average) + ' for interpoloated depth ' + str(depth)) total += average ''' logger.info('Updating ' + rootzone + ' to ' + str(total) + ' for ' + site.name + ' on ' + str(reading.date) + ' for type ' + str(reading.type)) # Need to get a Reading object to update as we cannot update vsw_readings as it is a view r = Reading.objects.get(site=reading.site_id, date=reading.date, type=reading.reading_type_id) total = decimal.Decimal(total).quantize( decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP) setattr(r, rootzone, total) r.save() # Update # Finished looping through rootzones # Finished looping through readings # Finished looping through sites logger.info('Finished Update of Rootzones')
def getSummarySerializedData(season_id, site_ids, reviewed): season = Season.objects.get(id=season_id) reviewed = reviewed if reviewed else 'False' logger.debug('Reviewed:' + str(reviewed)) strategy_serialized_data = [] for site_id in site_ids: try: site = Site.objects.get(pk=site_id) dates = get_site_season_start_end(site, season) if reviewed == 'False': latest_reading = vsw_reading.objects.filter( site_id=site_id, date__range=(dates.period_from, dates.period_to), type='Probe').latest('date') else: latest_reading = vsw_reading.objects.filter( site_id=site_id, date__range=(dates.period_from, dates.period_to), type='Probe', reviewed=True).latest('date') full = vsw_reading.objects.get(site_id=site_id, type='Full Point', date__range=(dates.period_from, dates.period_to)) refill = vsw_reading.objects.get(site_id=site_id, type='Refill', date__range=(dates.period_from, dates.period_to)) after_strategy = vsw_strategy.objects.filter( site_id=site_id).filter( Q(strategy_date__gte=latest_reading.date)).order_by( 'strategy_date')[0] before_strategy = vsw_strategy.objects.filter( site_id=site_id).filter( Q(strategy_date__lte=latest_reading.date)).order_by( '-strategy_date')[0] strategy_max, strategy_min = calculateStrategyPosition( after_strategy, before_strategy, latest_reading, full, refill) alert_level = calculateAlertLevel(strategy_max, strategy_min, latest_reading, full, refill) reading_serializer = VSWSerializer(latest_reading) before_strategy_serializer = VSWStrategySerializer(before_strategy) after_strategy_serializer = VSWStrategySerializer(after_strategy) # Calculation for irrigation gauge # Work out the divider, which is between full point and refill divider = full.rz1 - refill.rz1 # Work out diff between the 4 points in order and divide by divider to give top, middle and bottom top = round((full.rz1 - strategy_max) / divider * 100) middle = round((strategy_max - strategy_min) / divider * 100) bottom = round((strategy_min - refill.rz1) / divider * 100) # Latest reading needs the same treatment. Then we make sure it is between 0 and a 100. latest_reading_perc = round( (latest_reading.rz1 - refill.rz1) / divider * 100) if (latest_reading_perc < 0): latest_reading_perc = 0 elif (latest_reading_perc > 100): latest_reading_perc = 100 # bottom can be a negative, turn it positive and remove value from other figures if (bottom < 0): bottom = abs(bottom) middle = middle - bottom top = top - bottom strategy_serialized_data.append({ 'site_id': site.id, 'latest_reading_date': latest_reading.date, 'latest_reading_date_rz1': latest_reading.rz1, 'full_point': full.rz1, 'refill_point': refill.rz1, 'strategy_max': round(strategy_max, 2), 'strategy_min': round(strategy_min, 2), 'alert_level': alert_level, 'irrigation_gauge_top': top, 'irrigation_gauge_middle': middle, 'irrigation_gauge_bottom': bottom, 'irrigation_gauge_percentage': latest_reading_perc, 'latest_reading': reading_serializer.data, 'closest_strategies': [ before_strategy_serializer.data, after_strategy_serializer.data ] }) except ObjectDoesNotExist: logger.error('No latest reading') pass except IndexError: logger.error('No strategy') pass data = { 'sites': strategy_serialized_data, } return data
def get(self, request, site_ids, format=None): ids = request.GET.getlist('sites[]') season = get_current_season() strategy_serialized_data = [] for site_id in ids: try: site = Site.objects.get(pk=site_id) dates = get_site_season_start_end(site, season) latest_reading = vsw_reading.objects.filter( site_id=site_id, date__range=(dates.period_from, dates.period_to), type='Probe', reviewed=True).latest('date') full = vsw_reading.objects.get(site_id=site_id, type='Full Point', date__range=(dates.period_from, dates.period_to)) refill = vsw_reading.objects.get( site_id=site_id, type='Refill', date__range=(dates.period_from, dates.period_to)) after_strategy = vsw_strategy.objects.filter( site_id=site_id).filter( Q(strategy_date__gte=latest_reading.date)).order_by( 'strategy_date')[0] before_strategy = vsw_strategy.objects.filter( site_id=site_id).filter( Q(strategy_date__lte=latest_reading.date)).order_by( '-strategy_date')[0] strategy_max, strategy_min = calculateStrategyPosition( after_strategy, before_strategy, latest_reading, full, refill) alert_level = calculateAlertLevel(strategy_max, strategy_min, latest_reading, full, refill) reading_serializer = VSWSerializer(latest_reading) before_strategy_serializer = VSWStrategySerializer( before_strategy) after_strategy_serializer = VSWStrategySerializer( after_strategy) strategy_serialized_data.append({ 'site_id': site.id, 'latest_reading_date': latest_reading.date, 'latest_reading_date_rz1': latest_reading.rz1, 'full_point': full.rz1, 'refill_point': refill.rz1, 'strategy_max': round(strategy_max, 2), 'strategy_min': round(strategy_min, 2), 'alert_level': alert_level, 'latest_reading': reading_serializer.data, 'closest_strategies': [ before_strategy_serializer.data, after_strategy_serializer.data ] }) except ObjectDoesNotExist: pass # No latest reading except IndexError: pass # No strategy data = { 'sites': strategy_serialized_data, } return Response(data)