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
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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
示例#5
0
 def setUp(self):
     self.instance = FrontendSettings().get_solo()
示例#6
0
    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)
示例#7
0
    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))
        print(context_data['electricity_by_tariff_week'])
        print(context_data['electricity_by_tariff_month'])
        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
示例#8
0
    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)
示例#9
0
    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()

        selected_base_datetime = timezone.make_aware(
            timezone.datetime.strptime(
                self.request.GET['base_date'],
                formats.get_format('DSMR_STRFTIME_DATE_FORMAT')))
        selected_comparison_datetime = timezone.make_aware(
            timezone.datetime.strptime(
                self.request.GET['comparison_date'],
                formats.get_format('DSMR_STRFTIME_DATE_FORMAT')))
        selected_level = self.request.GET['level']

        DATA_MAPPING = {
            'days': dsmr_stats.services.day_statistics,
            'months': dsmr_stats.services.month_statistics,
            'years': dsmr_stats.services.year_statistics,
        }

        base_data = DATA_MAPPING[selected_level](selected_base_datetime.date())
        comparison_data = 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') 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
        return context_data
示例#10
0
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