Skip to content

Commit fcbcc62

Browse files
Actuele Amperes weergeven #875
1 parent d0b766a commit fcbcc62

33 files changed

+456
-68
lines changed

docs/changelog.rst

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ Changelog
22
=========
33

44

5+
v3.5.0 - 2020-xx-xx
6+
7+
- [`#875 <https://github.com/dennissiemensma/dsmr-reader/issues/875>`_] Actuele Amperes weergeven
8+
9+
10+
----
11+
12+
513
v3.4.0 - 2020-02-20
614

715
- [`#879 <https://github.com/dennissiemensma/dsmr-reader/issues/879>`_] Soms 100% CPU load datalogger

dsmr_backend/services/backend.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def get_capabilities(capability=None):
3232

3333
if capabilities is None:
3434
capabilities = {
35-
# We rely on consumption because DSMR readings might be flushed in the future.
35+
# We rely on consumption because source readings might be deleted after a while.
3636
'electricity': ElectricityConsumption.objects.exists(),
3737
'electricity_returned': ElectricityConsumption.objects.filter(
3838
# We can not rely on meter positions, as the manufacturer sometimes initializes meters
@@ -46,6 +46,9 @@ def get_capabilities(capability=None):
4646
'voltage': ElectricityConsumption.objects.filter(
4747
phase_voltage_l1__isnull=False,
4848
).exists(),
49+
'power_current': ElectricityConsumption.objects.filter(
50+
phase_power_current_l1__isnull=False,
51+
).exists(),
4952
'gas': GasConsumption.objects.exists(),
5053
'weather': WeatherSettings.get_solo().track and TemperatureReading.objects.exists()
5154
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 3.0.3 on 2020-02-20 18:56
2+
3+
import django.core.validators
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('dsmr_consumption', '0014_gas_grouping'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='electricityconsumption',
16+
name='phase_power_current_l1',
17+
field=models.IntegerField(db_index=True, default=None, help_text='Power/current for phase L1 (in A)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(999)]),
18+
),
19+
migrations.AddField(
20+
model_name='electricityconsumption',
21+
name='phase_power_current_l2',
22+
field=models.IntegerField(default=None, help_text='Power/current for phase L2 (in A)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(999)]),
23+
),
24+
migrations.AddField(
25+
model_name='electricityconsumption',
26+
name='phase_power_current_l3',
27+
field=models.IntegerField(default=None, help_text='Power/current for phase L3 (in A)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(999)]),
28+
),
29+
]

dsmr_consumption/models/consumption.py

+20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.core.validators import MinValueValidator, MaxValueValidator
12
from django.db import models
23
from django.utils.translation import gettext_lazy as _
34

@@ -108,6 +109,25 @@ class ElectricityConsumption(ModelUpdateMixin, models.Model):
108109
help_text=_("Current voltage for phase L3 (in V)"),
109110
db_index=True
110111
)
112+
phase_power_current_l1 = models.IntegerField(
113+
null=True,
114+
default=None,
115+
validators=[MinValueValidator(0), MaxValueValidator(999)],
116+
help_text=_("Power/current for phase L1 (in A)"),
117+
db_index=True
118+
)
119+
phase_power_current_l2 = models.IntegerField(
120+
null=True,
121+
default=None,
122+
validators=[MinValueValidator(0), MaxValueValidator(999)],
123+
help_text=_("Power/current for phase L2 (in A)")
124+
)
125+
phase_power_current_l3 = models.IntegerField(
126+
null=True,
127+
default=None,
128+
validators=[MinValueValidator(0), MaxValueValidator(999)],
129+
help_text=_("Power/current for phase L3 (in A)")
130+
)
111131

112132
def __sub__(self, other):
113133
""" Allows models to be subtracted from each other. """

dsmr_consumption/services.py

+9
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ def _compact_electricity(dsmr_reading, electricity_grouping_type, reading_start)
100100
phase_voltage_l1=dsmr_reading.phase_voltage_l1,
101101
phase_voltage_l2=dsmr_reading.phase_voltage_l2,
102102
phase_voltage_l3=dsmr_reading.phase_voltage_l3,
103+
phase_power_current_l1=dsmr_reading.phase_power_current_l1,
104+
phase_power_current_l2=dsmr_reading.phase_power_current_l2,
105+
phase_power_current_l3=dsmr_reading.phase_power_current_l3,
103106
)
104107
except IntegrityError:
105108
# This might happen, even though rarely, when the same timestamp with different values comes by.
@@ -131,6 +134,9 @@ def _compact_electricity(dsmr_reading, electricity_grouping_type, reading_start)
131134
avg_phase_voltage_l1=Avg('phase_voltage_l1'),
132135
avg_phase_voltage_l2=Avg('phase_voltage_l2'),
133136
avg_phase_voltage_l3=Avg('phase_voltage_l3'),
137+
avg_phase_power_current_l1=Avg('phase_power_current_l1'),
138+
avg_phase_power_current_l2=Avg('phase_power_current_l2'),
139+
avg_phase_power_current_l3=Avg('phase_power_current_l3'),
134140
)
135141

136142
# This instance is the average/max and combined result.
@@ -151,6 +157,9 @@ def _compact_electricity(dsmr_reading, electricity_grouping_type, reading_start)
151157
phase_voltage_l1=grouped_reading['avg_phase_voltage_l1'],
152158
phase_voltage_l2=grouped_reading['avg_phase_voltage_l2'],
153159
phase_voltage_l3=grouped_reading['avg_phase_voltage_l3'],
160+
phase_power_current_l1=grouped_reading['avg_phase_power_current_l1'],
161+
phase_power_current_l2=grouped_reading['avg_phase_power_current_l2'],
162+
phase_power_current_l3=grouped_reading['avg_phase_power_current_l3'],
154163
)
155164

156165

dsmr_datalogger/management/commands/dsmr_fake_datasource.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,12 @@ def _generate_data(self, with_gas, with_electricity_returned, hour_offset):
117117
currently_returned_l2 = 0
118118
currently_returned_l3 = 0
119119
currently_returned = 0
120-
phase_voltage_l1 = random.randint(225, 235)
121-
phase_voltage_l2 = random.randint(225, 235)
122-
phase_voltage_l3 = random.randint(225, 235)
120+
phase_voltage_l1 = random.randint(228, 232)
121+
phase_voltage_l2 = random.randint(228, 232)
122+
phase_voltage_l3 = random.randint(228, 232)
123+
phase_power_current_l1 = random.randint(5, 8)
124+
phase_power_current_l2 = random.randint(2, 3)
125+
phase_power_current_l3 = random.randint(0, 1)
123126

124127
# Randomly switch between electricity delivered and returned each 5 seconds for a more 'realistic' graph.
125128
if with_electricity_returned and second_since % 10 < 5:
@@ -161,9 +164,9 @@ def _generate_data(self, with_gas, with_electricity_returned, hour_offset):
161164
"1-0:32.7.0({}.0*V)\r\n".format(phase_voltage_l1),
162165
"1-0:52.7.0({}.1*V)\r\n".format(phase_voltage_l2),
163166
"1-0:72.7.0({}.2*V)\r\n".format(phase_voltage_l3),
164-
"1-0:31.7.0(000*A)\r\n",
165-
"1-0:51.7.0(000*A)\r\n",
166-
"1-0:71.7.0(001*A)\r\n",
167+
"1-0:31.7.0({}*A)\r\n".format(phase_power_current_l1),
168+
"1-0:51.7.0({}*A)\r\n".format(phase_power_current_l2),
169+
"1-0:71.7.0({}*A)\r\n".format(phase_power_current_l3),
167170
"1-0:21.7.0({}*kW)\r\n".format(self._round_precision(currently_delivered_l1, 6)),
168171
"1-0:41.7.0({}*kW)\r\n".format(self._round_precision(currently_delivered_l2, 6)),
169172
"1-0:61.7.0({}*kW)\r\n".format(self._round_precision(currently_delivered_l3, 6)),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 3.0.3 on 2020-02-20 18:56
2+
3+
import django.core.validators
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('dsmr_datalogger', '0019_verbose_field_translations'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='dsmrreading',
16+
name='phase_power_current_l1',
17+
field=models.IntegerField(default=None, help_text='Power/current for phase L1 (in A)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(999)]),
18+
),
19+
migrations.AddField(
20+
model_name='dsmrreading',
21+
name='phase_power_current_l2',
22+
field=models.IntegerField(default=None, help_text='Power/current for phase L2 (in A)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(999)]),
23+
),
24+
migrations.AddField(
25+
model_name='dsmrreading',
26+
name='phase_power_current_l3',
27+
field=models.IntegerField(default=None, help_text='Power/current for phase L3 (in A)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(999)]),
28+
),
29+
]

dsmr_datalogger/models/reading.py

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.core.validators import MinValueValidator, MaxValueValidator
12
from django.utils.translation import gettext_lazy as _
23
from django.db import models
34
from django.utils import timezone
@@ -133,6 +134,24 @@ class DsmrReading(ModelUpdateMixin, models.Model):
133134
decimal_places=1,
134135
help_text=_("Current voltage for phase L3 (in V)")
135136
)
137+
phase_power_current_l1 = models.IntegerField(
138+
null=True,
139+
default=None,
140+
validators=[MinValueValidator(0), MaxValueValidator(999)],
141+
help_text=_("Power/current for phase L1 (in A)")
142+
)
143+
phase_power_current_l2 = models.IntegerField(
144+
null=True,
145+
default=None,
146+
validators=[MinValueValidator(0), MaxValueValidator(999)],
147+
help_text=_("Power/current for phase L2 (in A)")
148+
)
149+
phase_power_current_l3 = models.IntegerField(
150+
null=True,
151+
default=None,
152+
validators=[MinValueValidator(0), MaxValueValidator(999)],
153+
help_text=_("Power/current for phase L3 (in A)")
154+
)
136155

137156
class Meta:
138157
default_permissions = tuple()

dsmr_datalogger/services.py

+3
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ def _get_dsmrreader_mapping(version):
261261
obis_references.INSTANTANEOUS_VOLTAGE_L1: 'phase_voltage_l1',
262262
obis_references.INSTANTANEOUS_VOLTAGE_L2: 'phase_voltage_l2',
263263
obis_references.INSTANTANEOUS_VOLTAGE_L3: 'phase_voltage_l3',
264+
obis_references.INSTANTANEOUS_CURRENT_L1: 'phase_power_current_l1',
265+
obis_references.INSTANTANEOUS_CURRENT_L2: 'phase_power_current_l2',
266+
obis_references.INSTANTANEOUS_CURRENT_L3: 'phase_power_current_l3',
264267

265268
# For some reason this identifier contains two fields, therefor we split them.
266269
obis_references.HOURLY_GAS_METER_READING: SPLIT_GAS_FIELD,

dsmr_datalogger/tests/datalogger/test_belgium_dsmr.py

+3
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ def test_reading_values(self, now_mock):
8585
self.assertEqual(reading.phase_voltage_l1, Decimal('231.0'))
8686
self.assertEqual(reading.phase_voltage_l2, Decimal('0'))
8787
self.assertEqual(reading.phase_voltage_l3, Decimal('230.9'))
88+
self.assertEqual(reading.phase_power_current_l1, 0)
89+
self.assertEqual(reading.phase_power_current_l2, 0)
90+
self.assertEqual(reading.phase_power_current_l3, 0)
8891

8992
meter_statistics = MeterStatistics.get_solo()
9093
self.assertIsNone(meter_statistics.dsmr_version)

dsmr_datalogger/tests/datalogger/test_example_dsmr50.py

+3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ def test_reading_values(self):
9797
self.assertEqual(reading.phase_voltage_l1, Decimal('220.1'))
9898
self.assertEqual(reading.phase_voltage_l2, Decimal('220.2'))
9999
self.assertEqual(reading.phase_voltage_l3, Decimal('220.3'))
100+
self.assertEqual(reading.phase_power_current_l1, 1)
101+
self.assertEqual(reading.phase_power_current_l2, 2)
102+
self.assertEqual(reading.phase_power_current_l3, 3)
100103

101104
meter_statistics = MeterStatistics.get_solo()
102105
self.assertEqual(meter_statistics.dsmr_version, '50')

dsmr_datalogger/tests/datalogger/test_iskra.py

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ def test_reading_values(self, now_mock):
8080
self.assertIsNone(reading.phase_voltage_l1)
8181
self.assertIsNone(reading.phase_voltage_l2)
8282
self.assertIsNone(reading.phase_voltage_l3)
83+
self.assertIsNone(reading.phase_power_current_l1)
84+
self.assertIsNone(reading.phase_power_current_l2)
85+
self.assertIsNone(reading.phase_power_current_l3)
8386

8487
meter_statistics = MeterStatistics.get_solo()
8588
self.assertIsNone(meter_statistics.dsmr_version)

dsmr_datalogger/tests/datalogger/test_iskra_dsmr5_bus2.py

+3
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ def test_reading_values(self, now_mock):
9090
self.assertEqual(reading.phase_voltage_l1, Decimal('235.4'))
9191
self.assertIsNone(reading.phase_voltage_l2)
9292
self.assertIsNone(reading.phase_voltage_l3)
93+
self.assertEqual(reading.phase_power_current_l1, 1)
94+
self.assertEqual(reading.phase_power_current_l2, None)
95+
self.assertEqual(reading.phase_power_current_l3, None)
9396

9497
meter_statistics = MeterStatistics.get_solo()
9598
self.assertEqual(meter_statistics.dsmr_version, '50')

dsmr_datalogger/tests/datalogger/test_kaifa_dsmr42.py

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ def test_reading_values(self):
8383
self.assertIsNone(reading.phase_voltage_l1)
8484
self.assertIsNone(reading.phase_voltage_l2)
8585
self.assertIsNone(reading.phase_voltage_l3)
86+
self.assertEqual(reading.phase_power_current_l1, 0)
87+
self.assertEqual(reading.phase_power_current_l2, None)
88+
self.assertEqual(reading.phase_power_current_l3, None)
8689

8790
meter_statistics = MeterStatistics.get_solo()
8891
self.assertEqual(meter_statistics.dsmr_version, '42')

dsmr_datalogger/tests/datalogger/test_landisgyr350_dsmr40.py

+3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ def test_reading_values(self):
9797
self.assertIsNone(reading.phase_voltage_l1)
9898
self.assertIsNone(reading.phase_voltage_l2)
9999
self.assertIsNone(reading.phase_voltage_l3)
100+
self.assertEqual(reading.phase_power_current_l1, 0)
101+
self.assertEqual(reading.phase_power_current_l2, 0)
102+
self.assertEqual(reading.phase_power_current_l3, 1)
100103

101104
# Different data source.
102105
meter_statistics = MeterStatistics.get_solo()

dsmr_datalogger/tests/datalogger/test_landisgyr350_dsmr42.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ def _dsmr_dummy_data(self):
3838
"1-0:72.36.0(00000)\r\n",
3939
"0-0:96.13.1()\r\n",
4040
"0-0:96.13.0()\r\n",
41-
"1-0:31.7.0(000*A)\r\n",
42-
"1-0:51.7.0(000*A)\r\n",
43-
"1-0:71.7.0(001*A)\r\n",
41+
"1-0:31.7.0(111*A)\r\n",
42+
"1-0:51.7.0(222*A)\r\n",
43+
"1-0:71.7.0(333*A)\r\n",
4444
"1-0:21.7.0(00.123*kW)\r\n",
4545
"1-0:41.7.0(00.456*kW)\r\n",
4646
"1-0:61.7.0(00.789*kW)\r\n",
@@ -50,7 +50,7 @@ def _dsmr_dummy_data(self):
5050
"0-1:24.1.0(003)\r\n",
5151
"0-1:96.1.0(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)\r\n",
5252
"0-1:24.2.1(160210200000W)(01197.484*m3)\r\n",
53-
"!E1A4\n",
53+
"!8774\n",
5454
]
5555

5656
@mock.patch('serial.Serial.open')
@@ -95,6 +95,9 @@ def test_reading_values(self):
9595
self.assertIsNone(reading.phase_voltage_l1)
9696
self.assertIsNone(reading.phase_voltage_l2)
9797
self.assertIsNone(reading.phase_voltage_l3)
98+
self.assertEqual(reading.phase_power_current_l1, 111)
99+
self.assertEqual(reading.phase_power_current_l2, 222)
100+
self.assertEqual(reading.phase_power_current_l3, 333)
98101

99102
# Different data source.
100103
meter_statistics = MeterStatistics.get_solo()

dsmr_datalogger/tests/datalogger/test_landisgyr350_other_dsmr42.py

+3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ def test_reading_values(self):
8686
self.assertIsNone(reading.phase_voltage_l1)
8787
self.assertIsNone(reading.phase_voltage_l2)
8888
self.assertIsNone(reading.phase_voltage_l3)
89+
self.assertEqual(reading.phase_power_current_l1, 1)
90+
self.assertEqual(reading.phase_power_current_l2, None)
91+
self.assertEqual(reading.phase_power_current_l3, None)
8992

9093
# Different data source.
9194
meter_statistics = MeterStatistics.get_solo()

dsmr_datalogger/tests/datalogger/test_luxembourg_smarty.py

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ def test_reading_values(self, now_mock):
7979
self.assertIsNone(reading.phase_voltage_l1)
8080
self.assertIsNone(reading.phase_voltage_l2)
8181
self.assertIsNone(reading.phase_voltage_l3)
82+
self.assertIsNone(reading.phase_power_current_l1)
83+
self.assertIsNone(reading.phase_power_current_l2)
84+
self.assertIsNone(reading.phase_power_current_l3)
8285

8386
meter_statistics = MeterStatistics.get_solo()
8487
self.assertEqual(meter_statistics.dsmr_version, '42')

dsmr_frontend/forms.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class DashboardElectricityConsumptionForm(forms.Form):
2929
returned = forms.BooleanField(required=False, initial=False)
3030
phases = forms.BooleanField(required=False, initial=False)
3131
voltage = forms.BooleanField(required=False, initial=False)
32+
power_current = forms.BooleanField(required=False, initial=False)
3233
latest_delta_id = forms.IntegerField(required=False, initial=None)
3334

3435
def __init__(self, *args, **kwargs):
@@ -39,7 +40,7 @@ def _clean_type(self, field, capability):
3940
value = self.cleaned_data[field]
4041

4142
if value and not self.capabilities[capability]:
42-
raise forms.ValidationError(capability)
43+
raise forms.ValidationError('Capability not enabled: {}'.format(capability))
4344

4445
return value
4546

@@ -55,6 +56,9 @@ def clean_phases(self):
5556
def clean_voltage(self):
5657
return self._clean_type('voltage', 'voltage')
5758

59+
def clean_power_current(self):
60+
return self._clean_type('power_current', 'power_current')
61+
5862

5963
class NotificationReadForm(forms.Form):
6064
notification_id = forms.IntegerField()

dsmr_frontend/static/dsmr_frontend/css/dsmr-reader/global.css

+4
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,8 @@ div.date-selector {
4747

4848
.logo-version {
4949
font-size: 11px;
50+
}
51+
52+
.graph_controls_help {
53+
color: gray;
5054
}

0 commit comments

Comments
 (0)