def get_context_data(self, **kwargs): frontend_settings = FrontendSettings.get_solo() weather_settings = WeatherSettings.get_solo() context_data = super(Dashboard, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.get_capabilities() context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['frontend_settings'] = frontend_settings context_data['track_temperature'] = weather_settings.track context_data['notifications'] = Notification.objects.unread() try: latest_electricity = ElectricityConsumption.objects.all().order_by( '-read_at')[0] except IndexError: # Don't even bother when no data available. return context_data context_data[ 'consumption'] = dsmr_consumption.services.day_consumption( day=timezone.localtime(latest_electricity.read_at).date()) today = timezone.localtime(timezone.now()).date() context_data[ 'month_statistics'] = dsmr_stats.services.month_statistics( target_date=today) return context_data
def get_context_data(self, **kwargs): context_data = super(Dashboard, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['notification_count'] = Notification.objects.unread( ).count() context_data['django_date_format'] = 'DSMR_GRAPH_LONG_DATE_FORMAT' try: latest_electricity = ElectricityConsumption.objects.all().order_by( '-read_at')[0] except IndexError: # Don't even bother when no data available. return context_data context_data[ 'consumption'] = dsmr_consumption.services.day_consumption( day=timezone.localtime(latest_electricity.read_at).date()) month_statistics, days_in_month = dsmr_stats.services.month_statistics( target_date=timezone.localtime(timezone.now()).date()) context_data['month_statistics'] = month_statistics context_data['days_in_month'] = days_in_month return context_data
def test_compare_xhr(self, now_mock): now_mock.return_value = timezone.make_aware( timezone.datetime(2016, 1, 1)) response = self.client.get(reverse('{}:archive'.format( self.namespace))) # XHR's. data = { 'base_date': formats.date_format(timezone.now().date(), 'DSMR_DATEPICKER_DATE_FORMAT'), 'comparison_date': formats.date_format(timezone.now().date(), 'DSMR_DATEPICKER_DATE_FORMAT'), } for current_level in ('days', 'months', 'years'): # Test both with tariffs separated and merged. for merge in (False, True): frontend_settings = FrontendSettings.get_solo() frontend_settings.merge_electricity_tariffs = merge frontend_settings.save() data.update({'level': current_level}) response = self.client.get(reverse( '{}:compare-xhr-summary'.format(self.namespace)), data=data) self.assertEqual(response.status_code, 200, response.content) # Invalid XHR. data.update({'level': 'INVALID DATA'}) response = self.client.get(reverse('{}:archive-xhr-summary'.format( self.namespace)), data=data) self.assertEqual(response.status_code, 500)
def get(self, request): # noqa: C901 capabilities = dsmr_backend.services.backend.get_capabilities() frontend_settings = FrontendSettings.get_solo() data = {} translation_mapping = { 'electricity1': frontend_settings.tariff_1_delivered_name, 'electricity2': frontend_settings.tariff_2_delivered_name, } if not capabilities['any'] or not DayStatistics.objects.exists(): return JsonResponse(data) now = timezone.localtime(timezone.now()) week_date = now.date() - timezone.timedelta(days=7) month_date = now.date() - relativedelta(months=1) data['week'] = [ {'name': translation_mapping[k], 'value': v} for k, v in dsmr_stats.services.electricity_tariff_percentage(start_date=week_date).items() ] data['month'] = [ {'name': translation_mapping[k], 'value': v} for k, v in dsmr_stats.services.electricity_tariff_percentage(start_date=month_date).items() ] return JsonResponse(data)
def get(self, request): form = TrendsPeriodForm(request.GET) if not form.is_valid(): return JsonResponse(dict(errors=form.errors), status=400) frontend_settings = FrontendSettings.get_solo() translation_mapping = { 'electricity1': frontend_settings.tariff_1_delivered_name.capitalize(), 'electricity2': frontend_settings.tariff_2_delivered_name.capitalize(), } electricity_tariff_percentage = dsmr_stats.services.electricity_tariff_percentage( start=form.cleaned_data['start_date'], end=form.cleaned_data['end_date'], ) result = { 'data': [{ 'name': translation_mapping[k], 'value': v } for k, v in electricity_tariff_percentage.items()] } response = JsonResponse(result) patch_response_headers(response) return response
def get_context_data(self, **kwargs): context_data = super(About, self).get_context_data(**kwargs) context_data[ 'monitoring_issues'] = dsmr_backend.services.backend.request_monitoring_status( ) context_data['frontend_settings'] = FrontendSettings.get_solo() return context_data
def get_context_data(self, **kwargs): context_data = super(EnergyContracts, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['energy_contracts'] = dsmr_consumption.services.summarize_energy_contracts() return context_data
def dispatch(self, request, *args, **kwargs): if not FrontendSettings.get_solo().always_require_login: return super().dispatch(request, *args, **kwargs) if not request.user.is_authenticated: return super().handle_no_permission() return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs): capabilities = dsmr_backend.services.backend.get_capabilities() context_data = super(Trends, self).get_context_data(**kwargs) context_data['capabilities'] = capabilities context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['has_statistics'] = DayStatistics.objects.exists() and HourStatistics.objects.exists() return context_data
def get_context_data(self, **kwargs): context_data = super(Configuration, self).get_context_data(**kwargs) context_data['api_settings'] = APISettings.get_solo() context_data['consumption_settings'] = ConsumptionSettings.get_solo() context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['weather_settings'] = WeatherSettings.get_solo() context_data['backup_settings'] = BackupSettings.get_solo() context_data['dropbox_settings'] = DropboxSettings.get_solo() context_data['mindergas_settings'] = MinderGasSettings.get_solo() return context_data
def setUp(self): frontend_settings = FrontendSettings.get_solo() frontend_settings.always_require_login = self.ALWAYS_REQUIRE_LOGIN frontend_settings.save() self.client = Client() user = User.objects.create_user('testuser', 'unknown@localhost', 'testpasswd') if self.LOGGED_IN: self.client.login(username=user.username, password='******')
def get_context_data(self, **kwargs): context_data = super(Dashboard, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.get_capabilities() context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['notifications'] = Notification.objects.unread() today = timezone.localtime(timezone.now()).date() context_data[ 'month_statistics'] = dsmr_stats.services.month_statistics( target_date=today) return context_data
def get_context_data(self, **kwargs): context_data = super(ArchiveXhrSummary, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() selected_datetime = timezone.make_aware( timezone.datetime.strptime( self.request.GET['date'], formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_level = self.request.GET['level'] context_data['statistics'] = { 'days': dsmr_stats.services.day_statistics(selected_datetime.date()), 'months': dsmr_stats.services.month_statistics(selected_datetime.date()), 'years': dsmr_stats.services.year_statistics(selected_datetime.date()), }[selected_level] context_data['title'] = { 'days': formats.date_format(selected_datetime.date(), 'DSMR_GRAPH_LONG_DATE_FORMAT'), 'months': formats.date_format(selected_datetime.date(), 'DSMR_DATEPICKER_MONTH'), 'years': selected_datetime.date().year, }[selected_level] # Only day level allows some additional data. if selected_level == 'days': try: # This WILL fail when we either have no prices at all or conflicting ranges. context_data[ 'energy_price'] = EnergySupplierPrice.objects.by_date( target_date=selected_datetime.date()) except (EnergySupplierPrice.DoesNotExist, EnergySupplierPrice.MultipleObjectsReturned): # Default to zero prices. context_data['energy_price'] = EnergySupplierPrice() context_data['notes'] = Note.objects.filter( day=selected_datetime.date()) context_data['selected_level'] = selected_level context_data['selected_datetime'] = selected_datetime context_data['django_date_format'] = 'DJANGO_DATE_FORMAT' return context_data
def get_context_data(self, **kwargs): context_data = super(Dashboard, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['notification_count'] = Notification.objects.unread( ).count() context_data['today_date_format'] = 'DSMR_DATEPICKER_DAY' context_data['month_date_format'] = 'DSMR_DATEPICKER_MONTH' context_data['year_date_format'] = 'DSMR_DATEPICKER_YEAR' context_data['period_totals'] = dsmr_stats.services.period_totals() return context_data
def get_context_data(self, **kwargs): context_data = super(ArchiveXhrSummary, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() now = timezone.now().strftime( formats.get_format('DSMR_STRFTIME_DATE_FORMAT')) given_date = self.request.GET.get('date', now) selected_datetime = timezone.make_aware( timezone.datetime.strptime( given_date, formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_level = self.request.GET.get('level', 'days') DATA_MAPPING = { 'days': dsmr_stats.services.day_statistics, 'months': dsmr_stats.services.month_statistics, 'years': dsmr_stats.services.year_statistics, } data = DATA_MAPPING[selected_level](selected_datetime.date()) context_data['statistics'] = data context_data['title'] = { 'days': formats.date_format(selected_datetime.date(), 'DSMR_GRAPH_LONG_DATE_FORMAT'), 'months': formats.date_format(selected_datetime.date(), 'DSMR_DATEPICKER_MONTH'), 'years': selected_datetime.date().year, }[selected_level] # Only day level allows some additional data. if selected_level == 'days': context_data['notes'] = Note.objects.filter( day=selected_datetime.date()) try: context_data['day_statistics'] = DayStatistics.objects.get( day=selected_datetime.date()) except DayStatistics.DoesNotExist: pass context_data['selected_level'] = selected_level context_data['selected_datetime'] = selected_datetime context_data['django_date_format'] = 'DJANGO_DATE_FORMAT' return context_data
def test_dashboard(self, now_mock): now_mock.return_value = timezone.make_aware( timezone.datetime(2015, 11, 15)) weather_settings = WeatherSettings.get_solo() weather_settings.track = True weather_settings.save() response = self.client.get( reverse('{}:dashboard'.format(self.namespace))) self.assertEqual(response.status_code, 200, response.content) self.assertIn('frontend_settings', response.context) self.assertEqual( response.context['frontend_settings'].dashboard_graph_width, FrontendSettings.get_solo().dashboard_graph_width)
def get_context_data(self, **kwargs): context_data = super(DashboardXhrConsumption, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() try: latest_electricity = ElectricityConsumption.objects.all().order_by('-read_at')[0] except IndexError: # Don't even bother when no data available. return context_data context_data['consumption'] = dsmr_consumption.services.day_consumption( day=timezone.localtime(latest_electricity.read_at).date() ) return context_data
def get_context_data(self, **kwargs): context_data = super(Archive, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() day_statistics = DayStatistics.objects.all().order_by('pk') try: context_data['start_date'] = day_statistics[0].day context_data['end_date'] = day_statistics.order_by('-pk')[0].day except IndexError: pass context_data['datepicker_locale_format'] = formats.get_format('DSMR_DATEPICKER_LOCALE_FORMAT') context_data['datepicker_date_format'] = 'DSMR_DATEPICKER_DATE_FORMAT' return context_data
def get_context_data(self, **kwargs): context_data = super(Archive, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() day_statistics = DayStatistics.objects.all().order_by('pk') try: context_data['start_date'] = day_statistics[0].day context_data['end_date'] = day_statistics.order_by('-pk')[0].day except IndexError: pass context_data['datepicker_locale_format'] = formats.get_format( 'DSMR_DATEPICKER_LOCALE_FORMAT') context_data['datepicker_date_format'] = 'DSMR_DATEPICKER_DATE_FORMAT' return context_data
def get_context_data(self, **kwargs): context_data = super(ArchiveXhrSummary, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() selected_datetime = timezone.make_aware( timezone.datetime.strptime( self.request.GET['date'], formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_level = self.request.GET['level'] context_data['statistics'] = { 'days': dsmr_stats.services.day_statistics(selected_datetime.date()), 'months': dsmr_stats.services.month_statistics(selected_datetime.date()), 'years': dsmr_stats.services.year_statistics(selected_datetime.date()), }[selected_level] context_data['title'] = { 'days': formats.date_format(selected_datetime.date(), 'DSMR_GRAPH_LONG_DATE_FORMAT'), 'months': formats.date_format(selected_datetime.date(), 'DSMR_DATEPICKER_MONTH'), 'years': selected_datetime.date().year, }[selected_level] # Only day level allows some additional data. if selected_level == 'days': context_data[ 'energy_price'] = dsmr_consumption.services.get_day_prices( day=selected_datetime.date()) context_data['notes'] = Note.objects.filter( day=selected_datetime.date()) context_data['selected_level'] = selected_level context_data['selected_datetime'] = selected_datetime context_data['django_date_format'] = 'DJANGO_DATE_FORMAT' return context_data
def get_context_data(self, **kwargs): context_data = super(LiveGraphs, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['meter_statistics'] = MeterStatistics.get_solo() context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['notification_count'] = Notification.objects.unread( ).count() context_data['sorted_graphs_json'] = json.dumps( list(SortedGraph.objects.all().values_list('graph_type', flat=True))) today = timezone.localtime(timezone.now()).date() context_data[ 'month_statistics'] = dsmr_stats.services.month_statistics( target_date=today) return context_data
def get(self, request): # noqa: C901 data = { 'read_at': [], 'degrees_celcius': [], } # Optimize queries for large datasets by restricting the data to the last week in the first place. base_timestamp = timezone.now() - timezone.timedelta( hours=FrontendSettings.get_solo().live_graphs_hours_range) temperature = TemperatureReading.objects.filter( read_at__gt=base_timestamp).order_by('read_at') for current in temperature: read_at = formats.date_format(timezone.localtime(current.read_at), 'DSMR_GRAPH_LONG_TIME_FORMAT') data['read_at'].append(read_at) data['degrees_celcius'].append(float(current.degrees_celcius)) return JsonResponse(data)
def get_context_data(self, **kwargs): context_data = super(Configuration, self).get_context_data(**kwargs) # 20+ queries, we should cache this at some point. context_data.update( dict( api_settings=APISettings.get_solo(), backend_settings=BackendSettings.get_solo(), backup_settings=BackupSettings.get_solo(), consumption_settings=ConsumptionSettings.get_solo(), datalogger_settings=DataloggerSettings.get_solo(), dropbox_settings=DropboxSettings.get_solo(), email_settings=EmailSettings.get_solo(), frontend_settings=FrontendSettings.get_solo(), mindergas_settings=MinderGasSettings.get_solo(), mqtt_broker_settings=MQTTBrokerSettings.get_solo(), mqtt_jsondaytotals_settings=JSONDayTotalsMQTTSettings.get_solo( ), mqtt_splittopicdaytotals_settings= SplitTopicDayTotalsMQTTSettings.get_solo(), mqtt_jsoncurrentperiodtotals_settings= JSONCurrentPeriodTotalsMQTTSettings.get_solo(), mqtt_splittopiccurrentperiodtotals_settings= SplitTopicCurrentPeriodTotalsMQTTSettings.get_solo(), mqtt_jsongasconsumption_settings=JSONGasConsumptionMQTTSettings .get_solo(), mqtt_splittopicgasconsumption_settings= SplitTopicGasConsumptionMQTTSettings.get_solo(), mqtt_splittopicmeterstatistics_settings= SplitTopicMeterStatisticsMQTTSettings.get_solo(), mqtt_jsontelegram_settings=JSONTelegramMQTTSettings.get_solo(), mqtt_rawtelegram_settings=RawTelegramMQTTSettings.get_solo(), mqtt_splittopictelegram_settings=SplitTopicTelegramMQTTSettings .get_solo(), notification_settings=NotificationSetting.get_solo(), pvoutput_api_settings=PVOutputAPISettings.get_solo(), pvoutput_addstatus_settings=PVOutputAddStatusSettings.get_solo( ), retention_settings=RetentionSettings.get_solo(), weather_settings=WeatherSettings.get_solo(), influxdb_settings=InfluxdbIntegrationSettings.get_solo(), )) return context_data
def get(self, request): # noqa: C901 data = { 'read_at': [], 'currently_delivered': [], } # Optimize queries for large datasets by restricting the data to the last week in the first place. base_timestamp = timezone.now() - timezone.timedelta( hours=FrontendSettings.get_solo().live_graphs_hours_range) gas = GasConsumption.objects.filter( read_at__gt=base_timestamp).order_by('read_at') for current in gas: read_at = formats.date_format(timezone.localtime(current.read_at), 'DSMR_GRAPH_LONG_TIME_FORMAT') data['read_at'].append(read_at) data['currently_delivered'].append( float(current.currently_delivered)) response = JsonResponse(data) patch_response_headers(response) return response
def get_context_data(self, **kwargs): context_data = super(Statistics, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data[ 'electricity_statistics'] = ElectricityStatistics.get_solo( ).export() context_data['frontend_settings'] = FrontendSettings.get_solo() try: latest_reading = DsmrReading.objects.all().order_by('-pk')[0] except IndexError: pass else: context_data['latest_reading'] = latest_reading context_data['delivered_sum'] = latest_reading.electricity_delivered_1 + \ latest_reading.electricity_delivered_2 context_data['returned_sum'] = latest_reading.electricity_returned_1 + \ latest_reading.electricity_returned_2 context_data['datalogger_settings'] = DataloggerSettings.get_solo() context_data['meter_statistics'] = MeterStatistics.get_solo() return context_data
def get_context_data(self, **kwargs): capabilities = dsmr_backend.services.get_capabilities() context_data = super(Trends, self).get_context_data(**kwargs) context_data['capabilities'] = capabilities context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['day_statistics_count'] = DayStatistics.objects.count() context_data['hour_statistics_count'] = HourStatistics.objects.count() if not capabilities['any']: return context_data # Average of real consumption/return per hour. average_consumption_by_hour = dsmr_stats.services.average_consumption_by_hour() context_data['avg_consumption_x'] = json.dumps( ['{}:00'.format(int(x['hour_start'])) for x in average_consumption_by_hour] ) now = timezone.localtime(timezone.now()) context_data['electricity_by_tariff_week'] = dsmr_stats.services.\ electricity_tariff_percentage(start_date=now.date() - timezone.timedelta(days=7)) context_data['electricity_by_tariff_month'] = dsmr_stats.services.\ electricity_tariff_percentage(start_date=now.date() - relativedelta(months=1)) graph_data = defaultdict(list) for current in average_consumption_by_hour: graph_data['x_hours'].append('{}:00'.format(int(current['hour_start']))) current['avg_electricity'] = (current['avg_electricity1'] + current['avg_electricity2']) / 2 graph_data['avg_electricity_consumed'].append( float(dsmr_consumption.services.round_decimal(current['avg_electricity'])) ) if capabilities['electricity_returned']: current['avg_electricity_returned'] = ( current['avg_electricity1_returned'] + current['avg_electricity2_returned'] ) / 2 graph_data['avg_electricity_returned'].append( float(dsmr_consumption.services.round_decimal(current['avg_electricity_returned'])) ) if capabilities['gas']: graph_data['avg_gas_consumption'].append( float(dsmr_consumption.services.round_decimal(current['avg_gas'])) ) # We need the sums to calculate percentage. sums = { 'avg_electricity_consumed': sum(graph_data['avg_electricity_consumed']), 'avg_electricity_returned': sum(graph_data['avg_electricity_returned']), 'avg_gas_consumption': sum(graph_data['avg_gas_consumption']), } # Map to percentages and JSON. for key, values in graph_data.items(): try: current_sum = sums[key] values = [ float(dsmr_consumption.services.round_decimal(current / current_sum * 100)) for current in values ] except (KeyError, ZeroDivisionError): pass context_data[key] = json.dumps(values) return context_data
def get_context_data(self, **kwargs): frontend_settings = FrontendSettings.get_solo() context_data = super(Dashboard, self).get_context_data(**kwargs) context_data['capabilities'] = dsmr_backend.services.get_capabilities() context_data['frontend_settings'] = frontend_settings context_data['notifications'] = Notification.objects.unread() electricity = ElectricityConsumption.objects.all().order_by('read_at') gas = GasConsumption.objects.all().order_by('read_at') temperature = TemperatureReading.objects.all().order_by('read_at') # User might want to sort things backwards. if frontend_settings.reverse_dashboard_graphs: electricity = electricity.reverse()[:self.electricity_max] gas = gas.reverse()[:self.gas_max] temperature = temperature.reverse()[:self.temperature_max] else: # We can't slice using negative offsets, so we should fetch a (quick) count first) electricity_offset = max(0, electricity.count() - self.electricity_max) gas_offset = max(0, gas.count() - self.gas_max) temperature_offset = max(0, temperature.count() - self.temperature_max) electricity = electricity[electricity_offset:] gas = gas[gas_offset:] temperature = temperature[temperature_offset:] context_data['electricity_x'] = json.dumps( [formats.date_format( timezone.localtime(x.read_at), 'DSMR_GRAPH_SHORT_TIME_FORMAT' ) for x in electricity] ) context_data['electricity_y'] = json.dumps( [float(x.currently_delivered * 1000) for x in electricity] ) context_data['electricity_returned_y'] = json.dumps( [float(x.currently_returned * 1000) for x in electricity] ) context_data['gas_x'] = json.dumps( [formats.date_format( timezone.localtime(x.read_at), 'DSMR_GRAPH_SHORT_TIME_FORMAT' ) for x in gas] ) context_data['gas_y'] = json.dumps( [float(x.currently_delivered) for x in gas] ) context_data['track_temperature'] = WeatherSettings.get_solo().track context_data['temperature_count'] = temperature.count() if context_data['track_temperature']: context_data['temperature_x'] = json.dumps( [formats.date_format( timezone.localtime(x.read_at), 'DSMR_GRAPH_SHORT_TIME_FORMAT' ) for x in temperature] ) context_data['temperature_y'] = json.dumps( [float(x.degrees_celcius) for x in temperature] ) try: latest_temperature = TemperatureReading.objects.all().order_by('-read_at')[0] except IndexError: pass else: context_data['latest_temperature_read'] = latest_temperature.read_at context_data['latest_temperature'] = latest_temperature.degrees_celcius try: latest_electricity = ElectricityConsumption.objects.all().order_by('-read_at')[0] except IndexError: # Don't even bother when no data available. return context_data context_data['latest_electricity_read'] = latest_electricity.read_at context_data['latest_electricity'] = int( latest_electricity.currently_delivered * 1000 ) context_data['latest_electricity_returned'] = int( latest_electricity.currently_returned * 1000 ) try: latest_gas = GasConsumption.objects.all().order_by('-read_at')[0] except IndexError: pass else: context_data['latest_gas_read'] = latest_gas.read_at context_data['latest_gas'] = latest_gas.currently_delivered context_data['consumption'] = dsmr_consumption.services.day_consumption( day=timezone.localtime(latest_electricity.read_at).date() ) today = timezone.localtime(timezone.now()).date() context_data['month_statistics'] = dsmr_stats.services.month_statistics(target_date=today) return context_data
def get_context_data(self, **kwargs): context_data = super(CompareXhrSummary, self).get_context_data(**kwargs) context_data[ 'capabilities'] = dsmr_backend.services.backend.get_capabilities() context_data['frontend_settings'] = FrontendSettings.get_solo() now = timezone.now().strftime( formats.get_format('DSMR_STRFTIME_DATE_FORMAT')) selected_base_datetime = timezone.make_aware( timezone.datetime.strptime( self.request.GET.get('base_date', now), formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_comparison_datetime = timezone.make_aware( timezone.datetime.strptime( self.request.GET.get('comparison_date', now), formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_level = self.request.GET.get('level', 'days') DATA_MAPPING = { 'days': dsmr_stats.services.day_statistics, 'months': dsmr_stats.services.month_statistics, 'years': dsmr_stats.services.year_statistics, } base_data, base_count = DATA_MAPPING[selected_level]( selected_base_datetime.date()) comparison_data, comparison_count = DATA_MAPPING[selected_level]( selected_comparison_datetime.date()) diff_data = {} context_data['base_title'] = { 'days': formats.date_format(selected_base_datetime.date(), 'DSMR_GRAPH_LONG_DATE_FORMAT'), 'months': formats.date_format(selected_base_datetime.date(), 'DSMR_DATEPICKER_MONTH'), 'years': selected_base_datetime.date().year, }[selected_level] context_data['comparison_title'] = { 'days': formats.date_format(selected_comparison_datetime.date(), 'DSMR_GRAPH_LONG_DATE_FORMAT'), 'months': formats.date_format(selected_comparison_datetime.date(), 'DSMR_DATEPICKER_MONTH'), 'years': selected_comparison_datetime.date().year, }[selected_level] # Remove unused keys. unused_keys = [] for k in base_data.keys(): if k in ('temperature_avg', 'temperature_max', 'temperature_min', 'number_of_days') or 'cost' in k: unused_keys.append(k) base_data = { k: v for k, v in base_data.items() if k not in unused_keys } comparison_data = { k: v for k, v in comparison_data.items() if k not in unused_keys } # Calculate percentages of selection compared to base, as difference in percent. for k in base_data.keys(): try: diff_data[k] = 100 - (comparison_data[k] / base_data[k] * 100) except (TypeError, decimal.InvalidOperation, decimal.DivisionByZero): diff_data[k] = 0 diff_data[k] = diff_data[ k] * -1 # If the result above is 10%, then we'd like to display it as -10% usage. diff_data[k] = dsmr_consumption.services.round_decimal( diff_data[k]) context_data['diff'] = diff_data context_data['base'] = base_data context_data['comparison'] = comparison_data context_data['data_count'] = dict(base=base_count, comparison=comparison_count) return context_data
def get(self, request): # noqa: C901 capabilities = dsmr_backend.services.backend.get_capabilities() frontend_settings = FrontendSettings.get_solo() selected_datetime = timezone.make_aware( timezone.datetime.strptime( self.request.GET['date'], formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_level = self.request.GET['level'] data = defaultdict(list) response = { 'merge_electricity_tariffs': frontend_settings.merge_electricity_tariffs, } x_format_callback = None FIELDS = ('electricity1', 'electricity2', 'electricity1_returned', 'electricity2_returned', 'electricity_merged', 'electricity_returned_merged', 'gas') # Zoom to hourly data. if selected_level == 'days': source_data = HourStatistics.objects.filter( hour_start__gte=selected_datetime, hour_start__lte=selected_datetime + timezone.timedelta(days=1)).order_by('hour_start') x_format = 'DSMR_GRAPH_SHORT_TIME_FORMAT' x_axis = 'hour_start' x_format_callback = timezone.localtime # Zoom to daily data. elif selected_level == 'months': start_of_month = timezone.datetime(year=selected_datetime.year, month=selected_datetime.month, day=1) end_of_month = timezone.datetime.combine( start_of_month + relativedelta(months=1), time.min) source_data = DayStatistics.objects.filter( day__gte=start_of_month, day__lt=end_of_month).order_by('day') x_format = 'DSMR_GRAPH_SHORT_DATE_FORMAT' x_axis = 'day' # Zoom to monthly data. elif selected_level == 'years': source_data = [] start_of_year = timezone.datetime(year=selected_datetime.year, month=1, day=1) for increment in range(0, 12): current_month = start_of_year + relativedelta(months=increment) current_month_stats = dsmr_stats.services.month_statistics( current_month.date()) current_month_stats['month'] = current_month.date() source_data.append(current_month_stats) x_format = 'DSMR_DATEPICKER_MONTH' x_axis = 'month' for current_item in source_data: try: x_value = getattr(current_item, x_axis) except AttributeError: x_value = current_item[x_axis] if x_format_callback: x_value = x_format_callback(x_value) data['x'].append(formats.date_format(x_value, x_format)) for current_field in FIELDS: try: y_value = getattr(current_item, current_field) or 0 except AttributeError: y_value = current_item[current_field] or 0 data[current_field].append(float(y_value)) if frontend_settings.merge_electricity_tariffs: response['electricity'] = { 'x': data['x'], 'electricity_merged': data['electricity_merged'], } else: response['electricity'] = { 'x': data['x'], 'electricity1': data['electricity1'], 'electricity2': data['electricity2'], } if capabilities['electricity_returned']: if frontend_settings.merge_electricity_tariffs: response['electricity_returned'] = { 'x': data['x'], 'electricity_returned_merged': data['electricity_returned_merged'], } else: response['electricity_returned'] = { 'x': data['x'], 'electricity1_returned': data['electricity1_returned'], 'electricity2_returned': data['electricity2_returned'], } if capabilities['gas']: response['gas'] = { 'x': data['x'], 'gas': data['gas'], } return JsonResponse(response)
def live_electricity_consumption() -> Dict: """ Returns the current latest/live electricity consumption. """ data = {} try: latest_reading = DsmrReading.objects.all().order_by('-timestamp')[0] except IndexError: return data latest_timestamp = timezone.localtime(latest_reading.timestamp) # In case the smart meter's clock is running in the future. latest_timestamp = min(timezone.now(), latest_timestamp) data['timestamp'] = latest_timestamp data['currently_delivered'] = int( latest_reading.electricity_currently_delivered * 1000) data['currently_returned'] = int( latest_reading.electricity_currently_returned * 1000) data['cost_per_hour'] = None data['tariff_name'] = None tariff = MeterStatistics.get_solo().electricity_tariff frontend_settings = FrontendSettings.get_solo() tariff_names = { 1: frontend_settings.tariff_1_delivered_name.capitalize(), 2: frontend_settings.tariff_2_delivered_name.capitalize(), } try: data['tariff_name'] = tariff_names[tariff] except KeyError: pass try: prices = get_day_prices(day=timezone.now().date()) except EnergySupplierPrice.DoesNotExist: return data delivered_prices_per_tariff = { 1: prices.electricity_delivered_1_price, 2: prices.electricity_delivered_2_price, } returned_prices_per_tariff = { 1: prices.electricity_returned_1_price, 2: prices.electricity_returned_2_price, } try: delivered_cost_per_hour = latest_reading.electricity_currently_delivered * delivered_prices_per_tariff[ tariff] returned_cost_per_hour = latest_reading.electricity_currently_returned * returned_prices_per_tariff[ tariff] except KeyError: return data # Some users have a setup that delivers and returns simultaneously. So we need to take both into account. data['cost_per_hour'] = formats.number_format( round_decimal(delivered_cost_per_hour - returned_cost_per_hour)) return data
def get(self, request): # noqa: C901 form = DashboardElectricityConsumptionForm(request.GET) if not form.is_valid(): return JsonResponse({'errors': form.errors}, status=400) data = { 'latest_delta_id': 0, 'read_at': [], 'currently_delivered': [], 'currently_returned': [], 'phases_delivered': { 'l1': [], 'l2': [], 'l3': [], }, 'phases_returned': { 'l1': [], 'l2': [], 'l3': [], }, 'phase_voltage': { 'l1': [], 'l2': [], 'l3': [], }, 'phase_power_current': { 'l1': [], 'l2': [], 'l3': [], }, } # Optional delta. latest_delta_id = form.cleaned_data.get('latest_delta_id') # Optimize queries for large datasets by restricting the data (when using the installation default). base_timestamp = timezone.now() - timezone.timedelta( hours=FrontendSettings.get_solo().live_graphs_hours_range) electricity = ElectricityConsumption.objects.filter( read_at__gt=base_timestamp).order_by('read_at') if latest_delta_id: electricity = electricity.filter(id__gt=latest_delta_id) for current in electricity: read_at = formats.date_format(timezone.localtime(current.read_at), 'DSMR_GRAPH_LONG_TIME_FORMAT') data['read_at'].append(read_at) if form.cleaned_data.get('delivered'): data['currently_delivered'].append( self._convert_to_watt(current.currently_delivered)) if form.cleaned_data.get('returned'): data['currently_returned'].append( self._convert_to_watt(current.currently_returned)) if form.cleaned_data.get('phases'): # 'or 0' is required due to empty data. data['phases_delivered']['l1'].append( self._convert_to_watt( current.phase_currently_delivered_l1)) data['phases_delivered']['l2'].append( self._convert_to_watt( current.phase_currently_delivered_l2)) data['phases_delivered']['l3'].append( self._convert_to_watt( current.phase_currently_delivered_l3)) if form.cleaned_data.get('returned'): # 'or 0' is required due to backwards compatibility. data['phases_returned']['l1'].append( self._convert_to_watt( current.phase_currently_returned_l1)) data['phases_returned']['l2'].append( self._convert_to_watt( current.phase_currently_returned_l2)) data['phases_returned']['l3'].append( self._convert_to_watt( current.phase_currently_returned_l3)) if form.cleaned_data.get('voltage'): data['phase_voltage']['l1'].append( float(current.phase_voltage_l1 or 0)) data['phase_voltage']['l2'].append( float(current.phase_voltage_l2 or 0)) data['phase_voltage']['l3'].append( float(current.phase_voltage_l3 or 0)) if form.cleaned_data.get('power_current'): data['phase_power_current']['l1'].append( current.phase_power_current_l1 or 0) data['phase_power_current']['l2'].append( current.phase_power_current_l2 or 0) data['phase_power_current']['l3'].append( current.phase_power_current_l3 or 0) data['latest_delta_id'] = current.id return JsonResponse(data)
def get(self, request): # noqa: C901 capabilities = dsmr_backend.services.get_capabilities() frontend_settings = FrontendSettings.get_solo() selected_datetime = timezone.make_aware( timezone.datetime.strptime( self.request.GET['date'], formats.get_format('DSMR_STRFTIME_DATE_FORMAT'))) selected_level = self.request.GET['level'] data = defaultdict(list) charts = {} x_format_callback = None FIELDS = ('electricity1', 'electricity2', 'electricity1_returned', 'electricity2_returned', 'electricity_merged', 'electricity_returned_merged', 'gas') # Zoom to hourly data. if selected_level == 'days': source_data = HourStatistics.objects.filter( hour_start__gte=selected_datetime, hour_start__lte=selected_datetime + timezone.timedelta(days=1)).order_by('hour_start') x_format = 'DSMR_GRAPH_SHORT_TIME_FORMAT' x_axis = 'hour_start' x_format_callback = timezone.localtime # Zoom to daily data. elif selected_level == 'months': start_of_month = timezone.datetime(year=selected_datetime.year, month=selected_datetime.month, day=1) end_of_month = timezone.datetime.combine( start_of_month + relativedelta(months=1), time.min) source_data = DayStatistics.objects.filter( day__gte=start_of_month, day__lt=end_of_month).order_by('day') x_format = 'DSMR_GRAPH_SHORT_DATE_FORMAT' x_axis = 'day' # Zoom to monthly data. elif selected_level == 'years': source_data = [] start_of_year = timezone.datetime(year=selected_datetime.year, month=1, day=1) for increment in range(0, 12): current_month = start_of_year + relativedelta(months=increment) current_month_stats = dsmr_stats.services.month_statistics( current_month.date()) current_month_stats['month'] = current_month.date() source_data.append(current_month_stats) x_format = 'DSMR_DATEPICKER_MONTH' x_axis = 'month' for current_item in source_data: try: x_value = getattr(current_item, x_axis) except AttributeError: x_value = current_item[x_axis] if x_format_callback: x_value = x_format_callback(x_value) data['x'].append(formats.date_format(x_value, x_format)) for current_field in FIELDS: try: y_value = getattr(current_item, current_field) or 0 except AttributeError: y_value = current_item[current_field] or 0 data[current_field].append(float(y_value)) if frontend_settings.merge_electricity_tariffs: charts['electricity'] = { 'labels': data['x'], 'datasets': [{ 'data': data['electricity_merged'], 'label': _('Electricity (single tariff)'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb( frontend_settings.electricity_delivered_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_delivered_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_delivered_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }] } else: charts['electricity'] = { 'labels': data['x'], 'datasets': [{ 'data': data['electricity1'], 'label': _('Electricity 1 (low tariff)'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb(frontend_settings. electricity_delivered_alternate_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb(frontend_settings. electricity_delivered_alternate_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb(frontend_settings. electricity_delivered_alternate_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }, { 'data': data['electricity2'], 'label': _('Electricity 2 (high tariff)'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb( frontend_settings.electricity_delivered_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_delivered_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_delivered_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }] } if capabilities['electricity_returned']: if frontend_settings.merge_electricity_tariffs: charts['electricity_returned'] = { 'labels': data['x'], 'datasets': [{ 'data': data['electricity_returned_merged'], 'label': _('Electricity returned (single tariff)'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb( frontend_settings.electricity_returned_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_returned_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_returned_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }] } else: charts['electricity_returned'] = { 'labels': data['x'], 'datasets': [{ 'data': data['electricity1_returned'], 'label': _('Electricity 1 returned (low tariff)'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb(frontend_settings. electricity_returned_alternate_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb(frontend_settings. electricity_returned_alternate_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb(frontend_settings. electricity_returned_alternate_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }, { 'data': data['electricity2_returned'], 'label': _('Electricity 2 returned (high tariff)'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb( frontend_settings.electricity_returned_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_returned_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb( frontend_settings.electricity_returned_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }] } if capabilities['gas']: charts['gas'] = { 'labels': data['x'], 'datasets': [{ 'data': data['gas'], 'label': _('Gas'), 'backgroundColor': "rgba({},0.1)".format( hex_to_rgb(frontend_settings.gas_delivered_color)), 'borderColor': "rgba({},1)".format( hex_to_rgb(frontend_settings.gas_delivered_color)), 'pointColor': "rgba({},1)".format( hex_to_rgb(frontend_settings.gas_delivered_color)), 'pointStrokeColor': "#fff", 'pointHoverBackgroundColor': "#fff", }] } return HttpResponse(json.dumps({ 'charts': charts, }), content_type='application/json')
def get(self, request): data = {} data['capabilities'] = dsmr_backend.services.get_capabilities() frontend_settings = FrontendSettings.get_solo() form = DashboardGraphForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(form.errors) # Optimize queries for large datasets by restricting the data to the last week in the first place. base_timestamp = timezone.now() - timezone.timedelta(days=7) electricity = ElectricityConsumption.objects.filter( read_at__gt=base_timestamp).order_by('-read_at') gas = GasConsumption.objects.filter( read_at__gt=base_timestamp).order_by('-read_at') temperature = TemperatureReading.objects.filter( read_at__gt=base_timestamp).order_by('-read_at') # Apply any offset requested by the user. electricity_offset = form.cleaned_data.get('electricity_offset') electricity = electricity[electricity_offset:electricity_offset + frontend_settings.dashboard_graph_width] gas_offset = form.cleaned_data.get('gas_offset') gas = gas[gas_offset:gas_offset + frontend_settings.dashboard_graph_width] temperature = temperature[:frontend_settings.dashboard_graph_width] # Reverse all sets gain. electricity = electricity[::-1] gas = gas[::-1] temperature = temperature[::-1] # By default we only display the time, scrolling should enable a more verbose x-axis. graph_x_format_electricity = 'DSMR_GRAPH_SHORT_TIME_FORMAT' graph_x_format_gas = 'DSMR_GRAPH_SHORT_TIME_FORMAT' if electricity_offset > 0: graph_x_format_electricity = 'DSMR_GRAPH_LONG_TIME_FORMAT' if gas_offset > 0: graph_x_format_gas = 'DSMR_GRAPH_LONG_TIME_FORMAT' data['electricity_x'] = [ formats.date_format(timezone.localtime(x.read_at), graph_x_format_electricity) for x in electricity ] data['electricity_y'] = [ float(x.currently_delivered * 1000) for x in electricity ] data['electricity_returned_y'] = [ float(x.currently_returned * 1000) for x in electricity ] data['gas_x'] = [ formats.date_format(timezone.localtime(x.read_at), graph_x_format_gas) for x in gas ] data['gas_y'] = [float(x.currently_delivered) for x in gas] # Some users have multiple phases installed. if DataloggerSettings.get_solo( ).track_phases and data['capabilities']['multi_phases']: data['phases_l1_y'] = self._parse_phases_data( electricity, 'phase_currently_delivered_l1') data['phases_l2_y'] = self._parse_phases_data( electricity, 'phase_currently_delivered_l2') data['phases_l3_y'] = self._parse_phases_data( electricity, 'phase_currently_delivered_l3') if WeatherSettings.get_solo().track: data['temperature_x'] = [ formats.date_format(timezone.localtime(x.read_at), 'DSMR_GRAPH_SHORT_TIME_FORMAT') for x in temperature ] data['temperature_y'] = [ float(x.degrees_celcius) for x in temperature ] return HttpResponse(json.dumps(data), content_type='application/json')
def get_context_data(self, **kwargs): capabilities = dsmr_backend.services.get_capabilities() context_data = super(Trends, self).get_context_data(**kwargs) context_data['capabilities'] = capabilities context_data['frontend_settings'] = FrontendSettings.get_solo() context_data['day_statistics_count'] = DayStatistics.objects.count() context_data['hour_statistics_count'] = HourStatistics.objects.count() if not capabilities['any']: return context_data # Average of real consumption/return per hour. average_consumption_by_hour = dsmr_stats.services.average_consumption_by_hour( max_weeks_ago=4) context_data['avg_consumption_x'] = json.dumps([ '{}:00'.format(int(x['hour_start'])) for x in average_consumption_by_hour ]) now = timezone.localtime(timezone.now()) context_data['electricity_by_tariff_week'] = dsmr_stats.services.\ electricity_tariff_percentage(start_date=now.date() - timezone.timedelta(days=7)) context_data['electricity_by_tariff_month'] = dsmr_stats.services.\ electricity_tariff_percentage(start_date=now.date() - relativedelta(months=1)) graph_data = defaultdict(list) for current in average_consumption_by_hour: graph_data['x_hours'].append('{}:00'.format( int(current['hour_start']))) current['avg_electricity'] = (current['avg_electricity1'] + current['avg_electricity2']) / 2 graph_data['avg_electricity_consumed'].append( float( dsmr_consumption.services.round_decimal( current['avg_electricity']))) if capabilities['electricity_returned']: current['avg_electricity_returned'] = ( current['avg_electricity1_returned'] + current['avg_electricity2_returned']) / 2 graph_data['avg_electricity_returned'].append( float( dsmr_consumption.services.round_decimal( current['avg_electricity_returned']))) if capabilities['gas']: graph_data['avg_gas_consumption'].append( float( dsmr_consumption.services.round_decimal( current['avg_gas']))) # We need the sums to calculate percentage. sums = { 'avg_electricity_consumed': sum(graph_data['avg_electricity_consumed']), 'avg_electricity_returned': sum(graph_data['avg_electricity_returned']), 'avg_gas_consumption': sum(graph_data['avg_gas_consumption']), } # Map to percentages and JSON. for key, values in graph_data.items(): try: current_sum = sums[key] values = [ float( dsmr_consumption.services.round_decimal( current / current_sum * 100)) for current in values ] except (KeyError, ZeroDivisionError): pass context_data[key] = json.dumps(values) return context_data