diff --git a/.gitignore b/.gitignore index 7e4fcaa..fb8c1bd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ doc .bundle/ vendor/ .DS_Store + +checksums/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c8fc81..fb6eede 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # AEMO Gem Changelog +## [v0.5.0] (2022-09-19) + +### Added + +* New method flags: + + | Type | `EST` and/or `SUB` | Descriptor | + | --- | --- | --- | + | Type 20 | `SUB` | Churn Correction (Like Day) | + | Type 21 | `SUB` | Five-minute No Historical Data | + | Type 59 | `SUB`, `EST` | Five-minute No Historical Data | + | Type 69 | `SUB` | Linear extrapolation | + ## [v0.4.1] (2022-01-20) ### Fixed diff --git a/Gemfile.lock b/Gemfile.lock index 32cc947..73d4a0d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - aemo (0.4.1) + aemo (0.5.0) activesupport (>= 4.2.6, < 7.1) httparty (~> 0.15, >= 0.15.6) json (>= 1.7.5, < 3) @@ -12,7 +12,7 @@ PATH GEM remote: https://rubygems.org/ specs: - activesupport (7.0.0) + activesupport (7.0.3.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -22,7 +22,7 @@ GEM ast (2.4.0) awesome_print (1.8.0) coderay (1.1.2) - concurrent-ruby (1.1.9) + concurrent-ruby (1.1.10) coveralls (0.8.23) json (>= 1.8, < 3) simplecov (~> 0.16.1) @@ -51,7 +51,7 @@ GEM httparty (0.20.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - i18n (1.8.11) + i18n (1.12.0) concurrent-ruby (~> 1.0) json (2.3.1) listen (3.7.0) @@ -61,11 +61,11 @@ GEM method_source (0.9.2) mime-types (3.4.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.1115) + mime-types-data (3.2022.0105) minitest (5.15.0) multi_xml (0.6.0) nenv (0.3.0) - nokogiri (1.12.5-x86_64-darwin) + nokogiri (1.13.7-x86_64-darwin) racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) @@ -119,7 +119,7 @@ GEM thor (0.20.3) timecop (0.9.1) tins (1.21.1) - tzinfo (2.0.4) + tzinfo (2.0.5) concurrent-ruby (~> 1.0) unicode-display_width (1.6.0) webmock (3.6.2) @@ -150,4 +150,4 @@ DEPENDENCIES yard (~> 0.9, >= 0.9.11)! BUNDLED WITH - 2.2.33 + 2.3.16 diff --git a/lib/aemo.rb b/lib/aemo.rb index 1ee3e7d..678fd9d 100644 --- a/lib/aemo.rb +++ b/lib/aemo.rb @@ -11,7 +11,6 @@ require 'aemo/meter.rb' require 'aemo/nem12.rb' require 'aemo/nmi.rb' -require 'aemo/nmi/allocation.rb' require 'aemo/msats.rb' require 'aemo/register.rb' require 'aemo/version.rb' diff --git a/lib/aemo/msats.rb b/lib/aemo/msats.rb index 6501c40..b684d96 100644 --- a/lib/aemo/msats.rb +++ b/lib/aemo/msats.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'aemo' require 'digest/sha1' require 'httparty' require 'nokogiri' diff --git a/lib/aemo/nem12.rb b/lib/aemo/nem12.rb index ce72450..744d0d3 100644 --- a/lib/aemo/nem12.rb +++ b/lib/aemo/nem12.rb @@ -3,264 +3,17 @@ require 'csv' require 'time' +require 'aemo/nem12/data_stream_suffix' +require 'aemo/nem12/quality_method' +require 'aemo/nem12/reason_codes' +require 'aemo/nem12/record_indicators' +require 'aemo/nem12/transaction_code_flags' +require 'aemo/nem12/unit_of_measurement' + module AEMO # Namespace for classes and modules that handle AEMO Gem NEM12 interactions # @since 0.1.4 class NEM12 - # As per AEMO NEM12 Specification - # http://www.aemo.com.au/Consultations/National-Electricity-Market/Open/~/media/ - # Files/Other/consultations/nem/Meter% 20Data% 20File% 20Format% 20Specification% 20 - # NEM12_NEM13/MDFF_Specification_NEM12_NEM13_Final_v102_clean.ashx - RECORD_INDICATORS = { - 100 => 'Header', - 200 => 'NMI Data Details', - 300 => 'Interval Data', - 400 => 'Interval Event', - 500 => 'B2B Details', - 900 => 'End' - }.freeze - - TRANSACTION_CODE_FLAGS = { - 'A' => 'Alteration', - 'C' => 'Meter Reconfiguration', - 'G' => 'Re-energisation', - 'D' => 'De-energisation', - 'E' => 'Forward Estimate', - 'N' => 'Normal Read', - 'O' => 'Other', - 'S' => 'Special Read', - 'R' => 'Removal of Meter' - }.freeze - - UOM = { - 'MWh' => { name: 'Megawatt Hour', multiplier: 1e6 }, - 'kWh' => { name: 'Kilowatt Hour', multiplier: 1e3 }, - 'Wh' => { name: 'Watt Hour', multiplier: 1 }, - 'MW' => { name: 'Megawatt', multiplier: 1e6 }, - 'kW' => { name: 'Kilowatt', multiplier: 1e3 }, - 'W' => { name: 'Watt', multiplier: 1 }, - 'MVArh' => { name: 'Megavolt Ampere Reactive Hour', multiplier: 1e6 }, - 'kVArh' => { name: 'Kilovolt Ampere Reactive Hour', multiplier: 1e3 }, - 'VArh' => { name: 'Volt Ampere Reactive Hour', multiplier: 1 }, - 'MVAr' => { name: 'Megavolt Ampere Reactive', multiplier: 1e6 }, - 'kVAr' => { name: 'Kilovolt Ampere Reactive', multiplier: 1e3 }, - 'VAr' => { name: 'Volt Ampere Reactive', multiplier: 1 }, - 'MVAh' => { name: 'Megavolt Ampere Hour', multiplier: 1e6 }, - 'kVAh' => { name: 'Kilovolt Ampere Hour', multiplier: 1e3 }, - 'VAh' => { name: 'Volt Ampere Hour', multiplier: 1 }, - 'MVA' => { name: 'Megavolt Ampere', multiplier: 1e6 }, - 'kVA' => { name: 'Kilovolt Ampere', multiplier: 1e3 }, - 'VA' => { name: 'Volt Ampere', multiplier: 1 }, - 'kV' => { name: 'Kilovolt', multiplier: 1e3 }, - 'V' => { name: 'Volt', multiplier: 1 }, - 'kA' => { name: 'Kiloampere', multiplier: 1e3 }, - 'A' => { name: 'Ampere', multiplier: 1 }, - 'pf' => { name: 'Power Factor', multiplier: 1 } - }.freeze - - UOM_NON_SPEC_MAPPING = { - 'MWH' => 'MWh', - 'KWH' => 'kWh', - 'WH' => 'Wh', - 'MW' => 'MW', - 'KW' => 'kW', - 'W' => 'W', - 'MVARH' => 'MVArh', - 'KVARH' => 'kVArh', - 'VARH' => 'VArh', - 'MVAR' => 'MVAr', - 'KVAR' => 'kVAr', - 'VAR' => 'VAr', - 'MVAH' => 'MVAh', - 'KVAH' => 'kVAh', - 'VAH' => 'VAh', - 'MVA' => 'MVA', - 'KVA' => 'kVA', - 'VA' => 'VA', - 'KV' => 'kV', - 'V' => 'V', - 'KA' => 'kA', - 'A' => 'A', - 'PF' => 'pf' - }.freeze - - QUALITY_FLAGS = { - 'A' => 'Actual Data', - 'E' => 'Forward Estimated Data', - 'F' => 'Final Substituted Data', - 'N' => 'Null Data', - 'S' => 'Substituted Data', - 'V' => 'Variable Data' - }.freeze - - METHOD_FLAGS = { - 11 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Check', description: '' }, - 12 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Calculated', description: '' }, - 13 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'SCADA', description: '' }, - 14 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Like Day', description: '' }, - 15 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Average Like Day', description: '' }, - 16 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Agreed', description: '' }, - 17 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Linear', description: '' }, - 18 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Alternate', description: '' }, - 19 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Zero', description: '' }, - 51 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Previous Year', description: '' }, - 52 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Previous Read', description: '' }, - 53 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Revision', description: '' }, - 54 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Linear', description: '' }, - 55 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Agreed', description: '' }, - 56 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Prior to First Read - Agreed', description: '' }, - 57 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Customer Class', description: '' }, - 58 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Zero', description: '' }, - 61 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Previous Year', description: '' }, - 62 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Previous Read', description: '' }, - 63 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Customer Class', description: '' }, - 64 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Agreed', description: '' }, - 65 => { type: %w[EST], installation_type: 6, short_descriptor: 'ADL', description: '' }, - 66 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Revision', description: '' }, - 67 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Customer Read', description: '' }, - 68 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Zero', description: '' }, - 71 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Recalculation', description: '' }, - 72 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Revised Table', description: '' }, - 73 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Revised Algorithm', description: '' }, - 74 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Agreed', description: '' }, - 75 => { type: %w[EST], installation_type: 7, short_descriptor: 'Existing Table', description: '' } - }.freeze - - REASON_CODES = { - 0 => 'Free Text Description', - 1 => 'Meter/Equipment Changed', - 2 => 'Extreme Weather/Wet', - 3 => 'Quarantine', - 4 => 'Savage Dog', - 5 => 'Meter/Equipment Changed', - 6 => 'Extreme Weather/Wet', - 7 => 'Unable To Locate Meter', - 8 => 'Vacant Premise', - 9 => 'Meter/Equipment Changed', - 10 => 'Lock Damaged/Seized', - 11 => 'In Wrong Walk', - 12 => 'Locked Premises', - 13 => 'Locked Gate', - 14 => 'Locked Meter Box', - 15 => 'Access - Overgrown', - 16 => 'Noxious Weeds', - 17 => 'Unsafe Equipment/Location', - 18 => 'Read Below Previous', - 19 => 'Consumer Wanted', - 20 => 'Damaged Equipment/Panel', - 21 => 'Switched Off', - 22 => 'Meter/Equipment Seals Missing', - 23 => 'Meter/Equipment Seals Missing', - 24 => 'Meter/Equipment Seals Missing', - 25 => 'Meter/Equipment Seals Missing', - 26 => 'Meter/Equipment Seals Missing', - 27 => 'Meter/Equipment Seals Missing', - 28 => 'Damaged Equipment/Panel', - 29 => 'Relay Faulty/Damaged', - 30 => 'Meter Stop Switch On', - 31 => 'Meter/Equipment Seals Missing', - 32 => 'Damaged Equipment/Panel', - 33 => 'Relay Faulty/Damaged', - 34 => 'Meter Not In Handheld', - 35 => 'Timeswitch Faulty/Reset Required', - 36 => 'Meter High/Ladder Required', - 37 => 'Meter High/Ladder Required', - 38 => 'Unsafe Equipment/Location', - 39 => 'Reverse Energy Observed', - 40 => 'Timeswitch Faulty/Reset Required', - 41 => 'Faulty Equipment Display/Dials', - 42 => 'Faulty Equipment Display/Dials', - 43 => 'Power Outage', - 44 => 'Unsafe Equipment/Location', - 45 => 'Readings Failed To Validate', - 46 => 'Extreme Weather/Hot', - 47 => 'Refused Access', - 48 => 'Timeswitch Faulty/Reset Required', - 49 => 'Wet Paint', - 50 => 'Wrong Tariff', - 51 => 'Installation Demolished', - 52 => 'Access - Blocked', - 53 => 'Bees/Wasp In Meter Box', - 54 => 'Meter Box Damaged/Faulty', - 55 => 'Faulty Equipment Display/Dials', - 56 => 'Meter Box Damaged/Faulty', - 57 => 'Timeswitch Faulty/Reset Required', - 58 => 'Meter Ok - Supply Failure', - 59 => 'Faulty Equipment Display/Dials', - 60 => 'Illegal Connection/Equipment Tampered', - 61 => 'Meter Box Damaged/Faulty', - 62 => 'Damaged Equipment/Panel', - 63 => 'Illegal Connection/Equipment Tampered', - 64 => 'Key Required', - 65 => 'Wrong Key Provided', - 66 => 'Lock Damaged/Seized', - 67 => 'Extreme Weather/Wet', - 68 => 'Zero Consumption', - 69 => 'Reading Exceeds Estimate', - 70 => 'Probe Reports Tampering', - 71 => 'Probe Read Error', - 72 => 'Meter/Equipment Changed', - 73 => 'Low Consumption', - 74 => 'High Consumption', - 75 => 'Customer Read', - 76 => 'Communications Fault', - 77 => 'Estimation Forecast', - 78 => 'Null Data', - 79 => 'Power Outage Alarm', - 80 => 'Short Interval Alarm', - 81 => 'Long Interval Alarm', - 82 => 'CRC Error', - 83 => 'RAM Checksum Error', - 84 => 'ROM Checksum Error', - 85 => 'Data Missing Alarm', - 86 => 'Clock Error Alarm', - 87 => 'Reset Occurred', - 88 => 'Watchdog Timeout Alarm', - 89 => 'Time Reset Occurred', - 90 => 'Test Mode', - 91 => 'Load Control', - 92 => 'Added Interval (Data Correction)', - 93 => 'Replaced Interval (Data Correction)', - 94 => 'Estimated Interval (Data Correction)', - 95 => 'Pulse Overflow Alarm', - 96 => 'Data Out Of Limits', - 97 => 'Excluded Data', - 98 => 'Parity Error', - 99 => 'Energy Type (Register Changed)' - }.freeze - - DATA_STREAM_SUFFIX = { - # Averaged Data Streams - 'A' => { stream: 'Average', description: 'Import', units: 'kWh' }, - 'D' => { stream: 'Average', description: 'Export', units: 'kWh' }, - 'J' => { stream: 'Average', description: 'Import', units: 'kVArh' }, - 'P' => { stream: 'Average', description: 'Export', units: 'kVArh' }, - 'S' => { stream: 'Average', description: '', units: 'kVAh' }, - # Master Data Streams - 'B' => { stream: 'Master', description: 'Import', units: 'kWh' }, - 'E' => { stream: 'Master', description: 'Export', units: 'kWh' }, - 'K' => { stream: 'Master', description: 'Import', units: 'kVArh' }, - 'Q' => { stream: 'Master', description: 'Export', units: 'kVArh' }, - 'T' => { stream: 'Master', description: '', units: 'kVAh' }, - 'G' => { stream: 'Master', description: 'Power Factor', units: 'PF' }, - 'H' => { stream: 'Master', description: 'Q Metering', units: 'Qh' }, - 'M' => { stream: 'Master', description: 'Par Metering', units: 'parh' }, - 'V' => { stream: 'Master', description: 'Volts or V2h or Amps or A2h', units: '' }, - # Check Meter Streams - 'C' => { stream: 'Check', description: 'Import', units: 'kWh' }, - 'F' => { stream: 'Check', description: 'Export', units: 'kWh' }, - 'L' => { stream: 'Check', description: 'Import', units: 'kVArh' }, - 'R' => { stream: 'Check', description: 'Export', units: 'kVArh' }, - 'U' => { stream: 'Check', description: '', units: 'kVAh' }, - 'Y' => { stream: 'Check', description: 'Q Metering', units: 'Qh' }, - 'W' => { stream: 'Check', description: 'Par Metering Path', units: '' }, - 'Z' => { stream: 'Check', description: 'Volts or V2h or Amps or A2h', units: '' }, - # Net Meter Streams - # AEMO: NOTE THAT D AND J ARE PREVIOUSLY DEFINED - # 'D' => { stream: 'Net', description: 'Net', units: 'kWh' }, - # 'J' => { stream: 'Net', description: 'Net', units: 'kVArh' } - }.freeze - @file_contents = nil @header = nil @nmi_data_details = [] diff --git a/lib/aemo/nem12/data_stream_suffix.rb b/lib/aemo/nem12/data_stream_suffix.rb new file mode 100644 index 0000000..d83705e --- /dev/null +++ b/lib/aemo/nem12/data_stream_suffix.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module AEMO + # Namespace for classes and modules that handle AEMO Gem NEM12 interactions + # @since 0.1.4 + class NEM12 + DATA_STREAM_SUFFIX = { + # Averaged Data Streams + 'A' => { stream: 'Average', description: 'Import', units: 'kWh' }, + 'D' => { stream: 'Average', description: 'Export', units: 'kWh' }, + 'J' => { stream: 'Average', description: 'Import', units: 'kVArh' }, + 'P' => { stream: 'Average', description: 'Export', units: 'kVArh' }, + 'S' => { stream: 'Average', description: '', units: 'kVAh' }, + # Master Data Streams + 'B' => { stream: 'Master', description: 'Import', units: 'kWh' }, + 'E' => { stream: 'Master', description: 'Export', units: 'kWh' }, + 'K' => { stream: 'Master', description: 'Import', units: 'kVArh' }, + 'Q' => { stream: 'Master', description: 'Export', units: 'kVArh' }, + 'T' => { stream: 'Master', description: '', units: 'kVAh' }, + 'G' => { stream: 'Master', description: 'Power Factor', units: 'PF' }, + 'H' => { stream: 'Master', description: 'Q Metering', units: 'Qh' }, + 'M' => { stream: 'Master', description: 'Par Metering', units: 'parh' }, + 'V' => { stream: 'Master', description: 'Volts or V2h or Amps or A2h', units: '' }, + # Check Meter Streams + 'C' => { stream: 'Check', description: 'Import', units: 'kWh' }, + 'F' => { stream: 'Check', description: 'Export', units: 'kWh' }, + 'L' => { stream: 'Check', description: 'Import', units: 'kVArh' }, + 'R' => { stream: 'Check', description: 'Export', units: 'kVArh' }, + 'U' => { stream: 'Check', description: '', units: 'kVAh' }, + 'Y' => { stream: 'Check', description: 'Q Metering', units: 'Qh' }, + 'W' => { stream: 'Check', description: 'Par Metering Path', units: '' }, + 'Z' => { stream: 'Check', description: 'Volts or V2h or Amps or A2h', units: '' }, + # Net Meter Streams + # AEMO: NOTE THAT D AND J ARE PREVIOUSLY DEFINED + # 'D' => { stream: 'Net', description: 'Net', units: 'kWh' }, + # 'J' => { stream: 'Net', description: 'Net', units: 'kVArh' } + }.freeze + end +end diff --git a/lib/aemo/nem12/quality_method.rb b/lib/aemo/nem12/quality_method.rb new file mode 100644 index 0000000..c7c9d5c --- /dev/null +++ b/lib/aemo/nem12/quality_method.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module AEMO + # Namespace for classes and modules that handle AEMO Gem NEM12 interactions + # @since 0.1.4 + class NEM12 + QUALITY_FLAGS = { + 'A' => 'Actual Data', + 'E' => 'Forward Estimated Data', + 'F' => 'Final Substituted Data', + 'N' => 'Null Data', + 'S' => 'Substituted Data', + 'V' => 'Variable Data' + }.freeze + + METHOD_FLAGS = { + 11 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Check', description: '' }, + 12 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Calculated', description: '' }, + 13 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'SCADA', description: '' }, + 14 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Like Day', description: '' }, + 15 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Average Like Day', description: '' }, + 16 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Agreed', description: '' }, + 17 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Linear', description: '' }, + 18 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Alternate', description: '' }, + 19 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Zero', description: '' }, + 20 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Churn Correction (Like Day)', description: '' }, + 21 => { type: %w[SUB], installation_type: [1, 2, 3, 4], short_descriptor: 'Five-minute No Historical Data', description: '' }, + 51 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Previous Year', description: '' }, + 52 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Previous Read', description: '' }, + 53 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Revision', description: '' }, + 54 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Linear', description: '' }, + 55 => { type: %w[SUB], installation_type: 5, short_descriptor: 'Agreed', description: '' }, + 56 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Prior to First Read - Agreed', description: '' }, + 57 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Customer Class', description: '' }, + 58 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Zero', description: '' }, + 59 => { type: %w[EST SUB], installation_type: 5, short_descriptor: 'Five-minute No Historical Data', description: '' }, + 61 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Previous Year', description: '' }, + 62 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Previous Read', description: '' }, + 63 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Customer Class', description: '' }, + 64 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Agreed', description: '' }, + 65 => { type: %w[EST], installation_type: 6, short_descriptor: 'ADL', description: '' }, + 66 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Revision', description: '' }, + 67 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Customer Read', description: '' }, + 68 => { type: %w[EST SUB], installation_type: 6, short_descriptor: 'Zero', description: '' }, + 69 => { type: %w[SUB], installation_type: 6, short_descriptor: 'Linear extrapolation', description: '' }, + 71 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Recalculation', description: '' }, + 72 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Revised Table', description: '' }, + 73 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Revised Algorithm', description: '' }, + 74 => { type: %w[SUB], installation_type: 7, short_descriptor: 'Agreed', description: '' }, + 75 => { type: %w[EST], installation_type: 7, short_descriptor: 'Existing Table', description: '' } + }.freeze + end +end diff --git a/lib/aemo/nem12/reason_codes.rb b/lib/aemo/nem12/reason_codes.rb new file mode 100644 index 0000000..83ec9fa --- /dev/null +++ b/lib/aemo/nem12/reason_codes.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +module AEMO + # Namespace for classes and modules that handle AEMO Gem NEM12 interactions + # @since 0.1.4 + class NEM12 + REASON_CODES = { + 0 => 'Free Text Description', + 1 => 'Meter/Equipment Changed', + 2 => 'Extreme Weather/Wet', + 3 => 'Quarantine', + 4 => 'Savage Dog', + 5 => 'Meter/Equipment Changed', + 6 => 'Extreme Weather/Wet', + 7 => 'Unable To Locate Meter', + 8 => 'Vacant Premise', + 9 => 'Meter/Equipment Changed', + 10 => 'Lock Damaged/Seized', + 11 => 'In Wrong Walk', + 12 => 'Locked Premises', + 13 => 'Locked Gate', + 14 => 'Locked Meter Box', + 15 => 'Access - Overgrown', + 16 => 'Noxious Weeds', + 17 => 'Unsafe Equipment/Location', + 18 => 'Read Below Previous', + 19 => 'Consumer Wanted', + 20 => 'Damaged Equipment/Panel', + 21 => 'Switched Off', + 22 => 'Meter/Equipment Seals Missing', + 23 => 'Meter/Equipment Seals Missing', + 24 => 'Meter/Equipment Seals Missing', + 25 => 'Meter/Equipment Seals Missing', + 26 => 'Meter/Equipment Seals Missing', + 27 => 'Meter/Equipment Seals Missing', + 28 => 'Damaged Equipment/Panel', + 29 => 'Relay Faulty/Damaged', + 30 => 'Meter Stop Switch On', + 31 => 'Meter/Equipment Seals Missing', + 32 => 'Damaged Equipment/Panel', + 33 => 'Relay Faulty/Damaged', + 34 => 'Meter Not In Handheld', + 35 => 'Timeswitch Faulty/Reset Required', + 36 => 'Meter High/Ladder Required', + 37 => 'Meter High/Ladder Required', + 38 => 'Unsafe Equipment/Location', + 39 => 'Reverse Energy Observed', + 40 => 'Timeswitch Faulty/Reset Required', + 41 => 'Faulty Equipment Display/Dials', + 42 => 'Faulty Equipment Display/Dials', + 43 => 'Power Outage', + 44 => 'Unsafe Equipment/Location', + 45 => 'Readings Failed To Validate', + 46 => 'Extreme Weather/Hot', + 47 => 'Refused Access', + 48 => 'Timeswitch Faulty/Reset Required', + 49 => 'Wet Paint', + 50 => 'Wrong Tariff', + 51 => 'Installation Demolished', + 52 => 'Access - Blocked', + 53 => 'Bees/Wasp In Meter Box', + 54 => 'Meter Box Damaged/Faulty', + 55 => 'Faulty Equipment Display/Dials', + 56 => 'Meter Box Damaged/Faulty', + 57 => 'Timeswitch Faulty/Reset Required', + 58 => 'Meter Ok - Supply Failure', + 59 => 'Faulty Equipment Display/Dials', + 60 => 'Illegal Connection/Equipment Tampered', + 61 => 'Meter Box Damaged/Faulty', + 62 => 'Damaged Equipment/Panel', + 63 => 'Illegal Connection/Equipment Tampered', + 64 => 'Key Required', + 65 => 'Wrong Key Provided', + 66 => 'Lock Damaged/Seized', + 67 => 'Extreme Weather/Wet', + 68 => 'Zero Consumption', + 69 => 'Reading Exceeds Estimate', + 70 => 'Probe Reports Tampering', + 71 => 'Probe Read Error', + 72 => 'Meter/Equipment Changed', + 73 => 'Low Consumption', + 74 => 'High Consumption', + 75 => 'Customer Read', + 76 => 'Communications Fault', + 77 => 'Estimation Forecast', + 78 => 'Null Data', + 79 => 'Power Outage Alarm', + 80 => 'Short Interval Alarm', + 81 => 'Long Interval Alarm', + 82 => 'CRC Error', + 83 => 'RAM Checksum Error', + 84 => 'ROM Checksum Error', + 85 => 'Data Missing Alarm', + 86 => 'Clock Error Alarm', + 87 => 'Reset Occurred', + 88 => 'Watchdog Timeout Alarm', + 89 => 'Time Reset Occurred', + 90 => 'Test Mode', + 91 => 'Load Control', + 92 => 'Added Interval (Data Correction)', + 93 => 'Replaced Interval (Data Correction)', + 94 => 'Estimated Interval (Data Correction)', + 95 => 'Pulse Overflow Alarm', + 96 => 'Data Out Of Limits', + 97 => 'Excluded Data', + 98 => 'Parity Error', + 99 => 'Energy Type (Register Changed)' + }.freeze + end +end diff --git a/lib/aemo/nem12/record_indicators.rb b/lib/aemo/nem12/record_indicators.rb new file mode 100644 index 0000000..6ad4ec1 --- /dev/null +++ b/lib/aemo/nem12/record_indicators.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module AEMO + # Namespace for classes and modules that handle AEMO Gem NEM12 interactions + # @since 0.1.4 + class NEM12 + # As per AEMO NEM12 Specification + # http://www.aemo.com.au/Consultations/National-Electricity-Market/Open/~/media/ + # Files/Other/consultations/nem/Meter% 20Data% 20File% 20Format% 20Specification% 20 + # NEM12_NEM13/MDFF_Specification_NEM12_NEM13_Final_v102_clean.ashx + RECORD_INDICATORS = { + 100 => 'Header', + 200 => 'NMI Data Details', + 300 => 'Interval Data', + 400 => 'Interval Event', + 500 => 'B2B Details', + 900 => 'End' + }.freeze + end +end diff --git a/lib/aemo/nem12/transaction_code_flags.rb b/lib/aemo/nem12/transaction_code_flags.rb new file mode 100644 index 0000000..4655478 --- /dev/null +++ b/lib/aemo/nem12/transaction_code_flags.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module AEMO + # Namespace for classes and modules that handle AEMO Gem NEM12 interactions + # @since 0.1.4 + class NEM12 + TRANSACTION_CODE_FLAGS = { + 'A' => 'Alteration', + 'C' => 'Meter Reconfiguration', + 'G' => 'Re-energisation', + 'D' => 'De-energisation', + 'E' => 'Forward Estimate', + 'N' => 'Normal Read', + 'O' => 'Other', + 'S' => 'Special Read', + 'R' => 'Removal of Meter' + }.freeze + end +end diff --git a/lib/aemo/nem12/unit_of_measurement.rb b/lib/aemo/nem12/unit_of_measurement.rb new file mode 100644 index 0000000..ef170d0 --- /dev/null +++ b/lib/aemo/nem12/unit_of_measurement.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module AEMO + # Namespace for classes and modules that handle AEMO Gem NEM12 interactions + # @since 0.1.4 + class NEM12 + UOM = { + 'MWh' => { name: 'Megawatt Hour', multiplier: 1e6 }, + 'kWh' => { name: 'Kilowatt Hour', multiplier: 1e3 }, + 'Wh' => { name: 'Watt Hour', multiplier: 1 }, + 'MW' => { name: 'Megawatt', multiplier: 1e6 }, + 'kW' => { name: 'Kilowatt', multiplier: 1e3 }, + 'W' => { name: 'Watt', multiplier: 1 }, + 'MVArh' => { name: 'Megavolt Ampere Reactive Hour', multiplier: 1e6 }, + 'kVArh' => { name: 'Kilovolt Ampere Reactive Hour', multiplier: 1e3 }, + 'VArh' => { name: 'Volt Ampere Reactive Hour', multiplier: 1 }, + 'MVAr' => { name: 'Megavolt Ampere Reactive', multiplier: 1e6 }, + 'kVAr' => { name: 'Kilovolt Ampere Reactive', multiplier: 1e3 }, + 'VAr' => { name: 'Volt Ampere Reactive', multiplier: 1 }, + 'MVAh' => { name: 'Megavolt Ampere Hour', multiplier: 1e6 }, + 'kVAh' => { name: 'Kilovolt Ampere Hour', multiplier: 1e3 }, + 'VAh' => { name: 'Volt Ampere Hour', multiplier: 1 }, + 'MVA' => { name: 'Megavolt Ampere', multiplier: 1e6 }, + 'kVA' => { name: 'Kilovolt Ampere', multiplier: 1e3 }, + 'VA' => { name: 'Volt Ampere', multiplier: 1 }, + 'kV' => { name: 'Kilovolt', multiplier: 1e3 }, + 'V' => { name: 'Volt', multiplier: 1 }, + 'kA' => { name: 'Kiloampere', multiplier: 1e3 }, + 'A' => { name: 'Ampere', multiplier: 1 }, + 'pf' => { name: 'Power Factor', multiplier: 1 } + }.freeze + + UOM_NON_SPEC_MAPPING = { + 'MWH' => 'MWh', + 'KWH' => 'kWh', + 'WH' => 'Wh', + 'MW' => 'MW', + 'KW' => 'kW', + 'W' => 'W', + 'MVARH' => 'MVArh', + 'KVARH' => 'kVArh', + 'VARH' => 'VArh', + 'MVAR' => 'MVAr', + 'KVAR' => 'kVAr', + 'VAR' => 'VAr', + 'MVAH' => 'MVAh', + 'KVAH' => 'kVAh', + 'VAH' => 'VAh', + 'MVA' => 'MVA', + 'KVA' => 'kVA', + 'VA' => 'VA', + 'KV' => 'kV', + 'V' => 'V', + 'KA' => 'kA', + 'A' => 'A', + 'PF' => 'pf' + }.freeze + end +end diff --git a/lib/aemo/nmi.rb b/lib/aemo/nmi.rb index 994e203..ac283c2 100644 --- a/lib/aemo/nmi.rb +++ b/lib/aemo/nmi.rb @@ -5,6 +5,8 @@ require 'time' require 'ostruct' +require 'aemo/nmi/allocation.rb' + module AEMO # [AEMO::NMI] # diff --git a/lib/aemo/version.rb b/lib/aemo/version.rb index 9f42b44..1fe6886 100644 --- a/lib/aemo/version.rb +++ b/lib/aemo/version.rb @@ -24,7 +24,7 @@ # @author Joel Courtney module AEMO # aemo version - VERSION = '0.4.1' + VERSION = '0.5.0' # aemo version split amongst different revisions MAJOR_VERSION, MINOR_VERSION, REVISION = VERSION.split('.').map(&:to_i)