Skip to content

Commit ed94ed6

Browse files
authored
feat: new method flags Type 20, Type 21, Type 59, Type 69 (#78)
1 parent 25c7852 commit ed94ed6

14 files changed

+333
-265
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ doc
1010
.bundle/
1111
vendor/
1212
.DS_Store
13+
14+
checksums/

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# AEMO Gem Changelog
22

3+
## [v0.5.0] (2022-09-19)
4+
5+
### Added
6+
7+
* New method flags:
8+
9+
| Type | `EST` and/or `SUB` | Descriptor |
10+
| --- | --- | --- |
11+
| Type 20 | `SUB` | Churn Correction (Like Day) |
12+
| Type 21 | `SUB` | Five-minute No Historical Data |
13+
| Type 59 | `SUB`, `EST` | Five-minute No Historical Data |
14+
| Type 69 | `SUB` | Linear extrapolation |
15+
316
## [v0.4.1] (2022-01-20)
417

518
### Fixed

Gemfile.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
aemo (0.4.1)
4+
aemo (0.5.0)
55
activesupport (>= 4.2.6, < 7.1)
66
httparty (~> 0.15, >= 0.15.6)
77
json (>= 1.7.5, < 3)
@@ -12,7 +12,7 @@ PATH
1212
GEM
1313
remote: https://rubygems.org/
1414
specs:
15-
activesupport (7.0.0)
15+
activesupport (7.0.3.1)
1616
concurrent-ruby (~> 1.0, >= 1.0.2)
1717
i18n (>= 1.6, < 2)
1818
minitest (>= 5.1)
@@ -22,7 +22,7 @@ GEM
2222
ast (2.4.0)
2323
awesome_print (1.8.0)
2424
coderay (1.1.2)
25-
concurrent-ruby (1.1.9)
25+
concurrent-ruby (1.1.10)
2626
coveralls (0.8.23)
2727
json (>= 1.8, < 3)
2828
simplecov (~> 0.16.1)
@@ -51,7 +51,7 @@ GEM
5151
httparty (0.20.0)
5252
mime-types (~> 3.0)
5353
multi_xml (>= 0.5.2)
54-
i18n (1.8.11)
54+
i18n (1.12.0)
5555
concurrent-ruby (~> 1.0)
5656
json (2.3.1)
5757
listen (3.7.0)
@@ -61,11 +61,11 @@ GEM
6161
method_source (0.9.2)
6262
mime-types (3.4.1)
6363
mime-types-data (~> 3.2015)
64-
mime-types-data (3.2021.1115)
64+
mime-types-data (3.2022.0105)
6565
minitest (5.15.0)
6666
multi_xml (0.6.0)
6767
nenv (0.3.0)
68-
nokogiri (1.12.5-x86_64-darwin)
68+
nokogiri (1.13.7-x86_64-darwin)
6969
racc (~> 1.4)
7070
notiffany (0.1.3)
7171
nenv (~> 0.1)
@@ -119,7 +119,7 @@ GEM
119119
thor (0.20.3)
120120
timecop (0.9.1)
121121
tins (1.21.1)
122-
tzinfo (2.0.4)
122+
tzinfo (2.0.5)
123123
concurrent-ruby (~> 1.0)
124124
unicode-display_width (1.6.0)
125125
webmock (3.6.2)
@@ -150,4 +150,4 @@ DEPENDENCIES
150150
yard (~> 0.9, >= 0.9.11)!
151151

152152
BUNDLED WITH
153-
2.2.33
153+
2.3.16

lib/aemo.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
require 'aemo/meter.rb'
1212
require 'aemo/nem12.rb'
1313
require 'aemo/nmi.rb'
14-
require 'aemo/nmi/allocation.rb'
1514
require 'aemo/msats.rb'
1615
require 'aemo/register.rb'
1716
require 'aemo/version.rb'

lib/aemo/msats.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# frozen_string_literal: true
22

3-
require 'aemo'
43
require 'digest/sha1'
54
require 'httparty'
65
require 'nokogiri'

lib/aemo/nem12.rb

Lines changed: 7 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -3,264 +3,17 @@
33
require 'csv'
44
require 'time'
55

6+
require 'aemo/nem12/data_stream_suffix'
7+
require 'aemo/nem12/quality_method'
8+
require 'aemo/nem12/reason_codes'
9+
require 'aemo/nem12/record_indicators'
10+
require 'aemo/nem12/transaction_code_flags'
11+
require 'aemo/nem12/unit_of_measurement'
12+
613
module AEMO
714
# Namespace for classes and modules that handle AEMO Gem NEM12 interactions
815
# @since 0.1.4
916
class NEM12
10-
# As per AEMO NEM12 Specification
11-
# http://www.aemo.com.au/Consultations/National-Electricity-Market/Open/~/media/
12-
# Files/Other/consultations/nem/Meter% 20Data% 20File% 20Format% 20Specification% 20
13-
# NEM12_NEM13/MDFF_Specification_NEM12_NEM13_Final_v102_clean.ashx
14-
RECORD_INDICATORS = {
15-
100 => 'Header',
16-
200 => 'NMI Data Details',
17-
300 => 'Interval Data',
18-
400 => 'Interval Event',
19-
500 => 'B2B Details',
20-
900 => 'End'
21-
}.freeze
22-
23-
TRANSACTION_CODE_FLAGS = {
24-
'A' => 'Alteration',
25-
'C' => 'Meter Reconfiguration',
26-
'G' => 'Re-energisation',
27-
'D' => 'De-energisation',
28-
'E' => 'Forward Estimate',
29-
'N' => 'Normal Read',
30-
'O' => 'Other',
31-
'S' => 'Special Read',
32-
'R' => 'Removal of Meter'
33-
}.freeze
34-
35-
UOM = {
36-
'MWh' => { name: 'Megawatt Hour', multiplier: 1e6 },
37-
'kWh' => { name: 'Kilowatt Hour', multiplier: 1e3 },
38-
'Wh' => { name: 'Watt Hour', multiplier: 1 },
39-
'MW' => { name: 'Megawatt', multiplier: 1e6 },
40-
'kW' => { name: 'Kilowatt', multiplier: 1e3 },
41-
'W' => { name: 'Watt', multiplier: 1 },
42-
'MVArh' => { name: 'Megavolt Ampere Reactive Hour', multiplier: 1e6 },
43-
'kVArh' => { name: 'Kilovolt Ampere Reactive Hour', multiplier: 1e3 },
44-
'VArh' => { name: 'Volt Ampere Reactive Hour', multiplier: 1 },
45-
'MVAr' => { name: 'Megavolt Ampere Reactive', multiplier: 1e6 },
46-
'kVAr' => { name: 'Kilovolt Ampere Reactive', multiplier: 1e3 },
47-
'VAr' => { name: 'Volt Ampere Reactive', multiplier: 1 },
48-
'MVAh' => { name: 'Megavolt Ampere Hour', multiplier: 1e6 },
49-
'kVAh' => { name: 'Kilovolt Ampere Hour', multiplier: 1e3 },
50-
'VAh' => { name: 'Volt Ampere Hour', multiplier: 1 },
51-
'MVA' => { name: 'Megavolt Ampere', multiplier: 1e6 },
52-
'kVA' => { name: 'Kilovolt Ampere', multiplier: 1e3 },
53-
'VA' => { name: 'Volt Ampere', multiplier: 1 },
54-
'kV' => { name: 'Kilovolt', multiplier: 1e3 },
55-
'V' => { name: 'Volt', multiplier: 1 },
56-
'kA' => { name: 'Kiloampere', multiplier: 1e3 },
57-
'A' => { name: 'Ampere', multiplier: 1 },
58-
'pf' => { name: 'Power Factor', multiplier: 1 }
59-
}.freeze
60-
61-
UOM_NON_SPEC_MAPPING = {
62-
'MWH' => 'MWh',
63-
'KWH' => 'kWh',
64-
'WH' => 'Wh',
65-
'MW' => 'MW',
66-
'KW' => 'kW',
67-
'W' => 'W',
68-
'MVARH' => 'MVArh',
69-
'KVARH' => 'kVArh',
70-
'VARH' => 'VArh',
71-
'MVAR' => 'MVAr',
72-
'KVAR' => 'kVAr',
73-
'VAR' => 'VAr',
74-
'MVAH' => 'MVAh',
75-
'KVAH' => 'kVAh',
76-
'VAH' => 'VAh',
77-
'MVA' => 'MVA',
78-
'KVA' => 'kVA',
79-
'VA' => 'VA',
80-
'KV' => 'kV',
81-
'V' => 'V',
82-
'KA' => 'kA',
83-
'A' => 'A',
84-
'PF' => 'pf'
85-
}.freeze
86-
87-
QUALITY_FLAGS = {
88-
'A' => 'Actual Data',
89-
'E' => 'Forward Estimated Data',
90-
'F' => 'Final Substituted Data',
91-
'N' => 'Null Data',
92-
'S' => 'Substituted Data',
93-
'V' => 'Variable Data'
94-
}.freeze
95-
96-
METHOD_FLAGS = {
97-
11 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Check', description: '' },
98-
12 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Calculated', description: '' },
99-
13 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'SCADA', description: '' },
100-
14 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Like Day', description: '' },
101-
15 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Average Like Day', description: '' },
102-
16 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Agreed', description: '' },
103-
17 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Linear', description: '' },
104-
18 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Alternate', description: '' },
105-
19 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Zero', description: '' },
106-
51 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Previous Year', description: '' },
107-
52 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Previous Read', description: '' },
108-
53 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Revision', description: '' },
109-
54 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Linear', description: '' },
110-
55 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Agreed', description: '' },
111-
56 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Prior to First Read - Agreed', description: '' },
112-
57 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Customer Class', description: '' },
113-
58 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Zero', description: '' },
114-
61 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Previous Year', description: '' },
115-
62 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Previous Read', description: '' },
116-
63 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Customer Class', description: '' },
117-
64 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Agreed', description: '' },
118-
65 => { type: %w[EST], installation_type: 6, short_descriptor: 'ADL', description: '' },
119-
66 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Revision', description: '' },
120-
67 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Customer Read', description: '' },
121-
68 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Zero', description: '' },
122-
71 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Recalculation', description: '' },
123-
72 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Revised Table', description: '' },
124-
73 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Revised Algorithm', description: '' },
125-
74 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Agreed', description: '' },
126-
75 => { type: %w[EST], installation_type: 7, short_descriptor: 'Existing Table', description: '' }
127-
}.freeze
128-
129-
REASON_CODES = {
130-
0 => 'Free Text Description',
131-
1 => 'Meter/Equipment Changed',
132-
2 => 'Extreme Weather/Wet',
133-
3 => 'Quarantine',
134-
4 => 'Savage Dog',
135-
5 => 'Meter/Equipment Changed',
136-
6 => 'Extreme Weather/Wet',
137-
7 => 'Unable To Locate Meter',
138-
8 => 'Vacant Premise',
139-
9 => 'Meter/Equipment Changed',
140-
10 => 'Lock Damaged/Seized',
141-
11 => 'In Wrong Walk',
142-
12 => 'Locked Premises',
143-
13 => 'Locked Gate',
144-
14 => 'Locked Meter Box',
145-
15 => 'Access - Overgrown',
146-
16 => 'Noxious Weeds',
147-
17 => 'Unsafe Equipment/Location',
148-
18 => 'Read Below Previous',
149-
19 => 'Consumer Wanted',
150-
20 => 'Damaged Equipment/Panel',
151-
21 => 'Switched Off',
152-
22 => 'Meter/Equipment Seals Missing',
153-
23 => 'Meter/Equipment Seals Missing',
154-
24 => 'Meter/Equipment Seals Missing',
155-
25 => 'Meter/Equipment Seals Missing',
156-
26 => 'Meter/Equipment Seals Missing',
157-
27 => 'Meter/Equipment Seals Missing',
158-
28 => 'Damaged Equipment/Panel',
159-
29 => 'Relay Faulty/Damaged',
160-
30 => 'Meter Stop Switch On',
161-
31 => 'Meter/Equipment Seals Missing',
162-
32 => 'Damaged Equipment/Panel',
163-
33 => 'Relay Faulty/Damaged',
164-
34 => 'Meter Not In Handheld',
165-
35 => 'Timeswitch Faulty/Reset Required',
166-
36 => 'Meter High/Ladder Required',
167-
37 => 'Meter High/Ladder Required',
168-
38 => 'Unsafe Equipment/Location',
169-
39 => 'Reverse Energy Observed',
170-
40 => 'Timeswitch Faulty/Reset Required',
171-
41 => 'Faulty Equipment Display/Dials',
172-
42 => 'Faulty Equipment Display/Dials',
173-
43 => 'Power Outage',
174-
44 => 'Unsafe Equipment/Location',
175-
45 => 'Readings Failed To Validate',
176-
46 => 'Extreme Weather/Hot',
177-
47 => 'Refused Access',
178-
48 => 'Timeswitch Faulty/Reset Required',
179-
49 => 'Wet Paint',
180-
50 => 'Wrong Tariff',
181-
51 => 'Installation Demolished',
182-
52 => 'Access - Blocked',
183-
53 => 'Bees/Wasp In Meter Box',
184-
54 => 'Meter Box Damaged/Faulty',
185-
55 => 'Faulty Equipment Display/Dials',
186-
56 => 'Meter Box Damaged/Faulty',
187-
57 => 'Timeswitch Faulty/Reset Required',
188-
58 => 'Meter Ok - Supply Failure',
189-
59 => 'Faulty Equipment Display/Dials',
190-
60 => 'Illegal Connection/Equipment Tampered',
191-
61 => 'Meter Box Damaged/Faulty',
192-
62 => 'Damaged Equipment/Panel',
193-
63 => 'Illegal Connection/Equipment Tampered',
194-
64 => 'Key Required',
195-
65 => 'Wrong Key Provided',
196-
66 => 'Lock Damaged/Seized',
197-
67 => 'Extreme Weather/Wet',
198-
68 => 'Zero Consumption',
199-
69 => 'Reading Exceeds Estimate',
200-
70 => 'Probe Reports Tampering',
201-
71 => 'Probe Read Error',
202-
72 => 'Meter/Equipment Changed',
203-
73 => 'Low Consumption',
204-
74 => 'High Consumption',
205-
75 => 'Customer Read',
206-
76 => 'Communications Fault',
207-
77 => 'Estimation Forecast',
208-
78 => 'Null Data',
209-
79 => 'Power Outage Alarm',
210-
80 => 'Short Interval Alarm',
211-
81 => 'Long Interval Alarm',
212-
82 => 'CRC Error',
213-
83 => 'RAM Checksum Error',
214-
84 => 'ROM Checksum Error',
215-
85 => 'Data Missing Alarm',
216-
86 => 'Clock Error Alarm',
217-
87 => 'Reset Occurred',
218-
88 => 'Watchdog Timeout Alarm',
219-
89 => 'Time Reset Occurred',
220-
90 => 'Test Mode',
221-
91 => 'Load Control',
222-
92 => 'Added Interval (Data Correction)',
223-
93 => 'Replaced Interval (Data Correction)',
224-
94 => 'Estimated Interval (Data Correction)',
225-
95 => 'Pulse Overflow Alarm',
226-
96 => 'Data Out Of Limits',
227-
97 => 'Excluded Data',
228-
98 => 'Parity Error',
229-
99 => 'Energy Type (Register Changed)'
230-
}.freeze
231-
232-
DATA_STREAM_SUFFIX = {
233-
# Averaged Data Streams
234-
'A' => { stream: 'Average', description: 'Import', units: 'kWh' },
235-
'D' => { stream: 'Average', description: 'Export', units: 'kWh' },
236-
'J' => { stream: 'Average', description: 'Import', units: 'kVArh' },
237-
'P' => { stream: 'Average', description: 'Export', units: 'kVArh' },
238-
'S' => { stream: 'Average', description: '', units: 'kVAh' },
239-
# Master Data Streams
240-
'B' => { stream: 'Master', description: 'Import', units: 'kWh' },
241-
'E' => { stream: 'Master', description: 'Export', units: 'kWh' },
242-
'K' => { stream: 'Master', description: 'Import', units: 'kVArh' },
243-
'Q' => { stream: 'Master', description: 'Export', units: 'kVArh' },
244-
'T' => { stream: 'Master', description: '', units: 'kVAh' },
245-
'G' => { stream: 'Master', description: 'Power Factor', units: 'PF' },
246-
'H' => { stream: 'Master', description: 'Q Metering', units: 'Qh' },
247-
'M' => { stream: 'Master', description: 'Par Metering', units: 'parh' },
248-
'V' => { stream: 'Master', description: 'Volts or V2h or Amps or A2h', units: '' },
249-
# Check Meter Streams
250-
'C' => { stream: 'Check', description: 'Import', units: 'kWh' },
251-
'F' => { stream: 'Check', description: 'Export', units: 'kWh' },
252-
'L' => { stream: 'Check', description: 'Import', units: 'kVArh' },
253-
'R' => { stream: 'Check', description: 'Export', units: 'kVArh' },
254-
'U' => { stream: 'Check', description: '', units: 'kVAh' },
255-
'Y' => { stream: 'Check', description: 'Q Metering', units: 'Qh' },
256-
'W' => { stream: 'Check', description: 'Par Metering Path', units: '' },
257-
'Z' => { stream: 'Check', description: 'Volts or V2h or Amps or A2h', units: '' },
258-
# Net Meter Streams
259-
# AEMO: NOTE THAT D AND J ARE PREVIOUSLY DEFINED
260-
# 'D' => { stream: 'Net', description: 'Net', units: 'kWh' },
261-
# 'J' => { stream: 'Net', description: 'Net', units: 'kVArh' }
262-
}.freeze
263-
26417
@file_contents = nil
26518
@header = nil
26619
@nmi_data_details = []

0 commit comments

Comments
 (0)