parse_p1 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .rvmrc
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 1.9.2
4
+ - 1.8.7
5
+
6
+ branches:
7
+ only:
8
+ - master
9
+
10
+ script: "bundle exec rake test"
data/CHANGELOG ADDED
@@ -0,0 +1,6 @@
1
+ * 0.0.2
2
+ Parsing of electricity and gas values
3
+
4
+ * 0.0.1
5
+
6
+ Initial release
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rake', '~>0.9.2.2'
4
+
5
+ # Specify your gem's dependencies in parse_p1.gemspec
6
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :test do
5
+ watch(%r{^lib/*/(.+)\.rb$}) {'test'}
6
+ watch(%r{^test/.+_test\.rb$})
7
+ watch('test/helper.rb') { "test" }
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Frank Oxener - Agile Dovadi BV
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ ParseP1
2
+ ========
3
+
4
+ [![Build Status](https://secure.travis-ci.org/dovadi/ParseP1.png?branch=master)](http://travis-ci.org/dovadi/ParseP1)
5
+
6
+ Basic parser for P1 Companion Standard used by Dutch Smart Meters.
7
+
8
+ *Library is by no means complete (yet), it is now implemented only on one real example of a so called Dutch smart meter, in this case a Iskra MT382*
9
+
10
+ Example of P1 data
11
+ ==================
12
+
13
+ <pre>
14
+ /ABc1\\1AB123-4567
15
+
16
+ 0-0:96.1.1(1A123456789012345678901234567890)
17
+ 1-0:1.8.1(00136.787*kWh)
18
+ 1-0:1.8.2(00131.849*kWh)
19
+ 1-0:2.8.1(00000.000*kWh)
20
+ 1-0:2.8.2(00000.000*kWh)
21
+ 0-0:96.14.0(0002)
22
+ 1-0:1.7.0(0003.20*kW)
23
+ 1-0:2.7.0(0000.00*kW)
24
+ 0-0:17.0.0(0999.00*kW)
25
+ 0-0:96.3.10(1)
26
+ 0-0:96.13.1()
27
+ 0-0:96.13.0()
28
+ 0-1:24.1.0(3)
29
+ 0-1:96.1.0(1234567890123456789012345678901234)
30
+ 0-1:24.3.0(120502150000)(00)(60)(1)(0-1:24.2.1)(m3)
31
+ (00092.112)
32
+ 0-1:24.4.0(1)
33
+ !
34
+ </pre>
35
+
36
+ Usage
37
+ =====
38
+
39
+ <pre>
40
+ p1 = ParseP1::Base.new(p1_string)
41
+ p1.electra_meter_id #-> 1A123456789012345678901234567890
42
+ p1.electricity(:type => :import, :tariff => :normal) #-> 116.34 (kWH)
43
+ p1.electricity(:type => :import, :actual => :true) #-> 1245 (watt)
44
+ p1.gas_usage #-> 91.224 (watt)
45
+ </pre>
46
+
47
+ See tests for futher available methods
48
+
49
+
50
+ Running tests
51
+ =============
52
+ First install libraries with:
53
+ <pre>
54
+ bundle
55
+ </pre>
56
+
57
+ Test with
58
+ <pre>
59
+ bundle exec rake test
60
+ </pre>
61
+ _or_
62
+ <pre>
63
+ bundle exec guard
64
+ </pre>
65
+
66
+ Caveats
67
+ =======
68
+
69
+ * Library is by no means complete (yet), it is now implemented only on one real example of a so called Dutch smart meter. In this case a Iskra MT382 (see docs and ([manuals](http://www.liander.nl/liander/meters/meterhandleidingen.htm))) delivered by [Liander](http://www.liander.nl/).
70
+ * See [ReadP1 Arduino library](https://github.com/dovadi/ReadP1), which is used for posted the P1 data to a Ruby on Rails application.
71
+ * Although P1 should be a standard, it is known there are different implementations in the Netherlands alone.
72
+ * The library is implemented on the base of one long string received by a Ruby on Rails application. Parsing a text file will fail!
73
+
74
+ Documentation
75
+ =============
76
+ See [Datalogging van "slimme meters"](http://www.zonstraal.be/wiki/Datalogging_van_%22slimme_meters%22) in Dutch
77
+
78
+ See [P1 Companion Standard Version 2.2 April 18th 2008 from Enbin](http://read.pudn.com/downloads145/doc/633047/DSMR%20v2.2%20final/Dutch%20Smart%20Meter%20Requirements%20v2.2%20final%20P1.pdf) (also in docs directory)
79
+
80
+ See [Representation of P1 telegram P1 Companion Standard Version 4.0 from Netbeheer Nederland](http://www.google.nl/url?sa=t&rct=j&q=p1%20companion%20standard&source=web&cd=1&sqi=2&ved=0CCkQFjAA&url=http%3A%2F%2Fwww.netbeheernederland.nl%2FDecosDocument%2FDownload%2F%3FfileName%3D1uII4GRHFdk98V78_gP-T4GttCG3SzdH9Vc0YXH328SvwKJJVRaTaKAmCYayrXZC%26name%3DDSMR%2BV4.0%2Bfinal%2BP1&ei=CHyeT5PgGc-VOs20-PsB&usg=AFQjCNE3sIY9JZ_RNEStaaA8YYv7iR0XkQ&sig2=PJXsfhIRCwWitgVgNrx2xQ) (also in docs directory)
81
+
82
+
83
+ Contributing to ParseP1
84
+ =====================
85
+
86
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
87
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
88
+ * Fork the project
89
+ * Start a feature/bugfix branch
90
+ * Commit and push until you are happy with your contribution
91
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
92
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
93
+
94
+ Copyright
95
+ ==========
96
+
97
+ Copyright (c) 2012 Frank Oxener - Agile Dovadi BV. See LICENSE.txt for further details.
98
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ # require "bundler/gem_tasks"
3
+
4
+ require 'rubygems'
5
+ require 'bundler/gem_helper'
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ require 'rake/testtask'
9
+ Rake::TestTask.new(:test) do |test|
10
+ test.libs << 'lib' << 'test'
11
+ test.pattern = 'test/**/*_test.rb'
12
+ test.verbose = true
13
+ end
14
+
15
+ task :default => :test
16
+
Binary file
@@ -0,0 +1,23 @@
1
+ /ABc1\\1AB123-4567
2
+
3
+ 0-0:96.1.1(1A123456789012345678901234567890)
4
+ 1-0:1.8.1(00136.787*kWh)
5
+ 1-0:1.8.2(00131.849*kWh)
6
+ 1-0:2.8.1(00000.000*kWh)
7
+ 1-0:2.8.2(00000.000*kWh)
8
+ 0-0:96.14.0(0002)
9
+ 1-0:1.7.0(0003.20*kW)
10
+ 1-0:2.7.0(0000.00*kW)
11
+ 0-0:17.0.0(0999.00*kW)
12
+ 0-0:96.3.10(1)
13
+ 0-0:96.13.1()
14
+ 0-0:96.13.0()
15
+ 0-1:24.1.0(3)
16
+ 0-1:96.1.0(1234567890123456789012345678901234)
17
+ 0-1:24.3.0(120502150000)(00)(60)(1)(0-1:24.2.1)(m3)
18
+ (00092.112)
19
+ 0-1:24.4.0(1)
20
+ !
21
+
22
+
23
+ "\r\n/ABc1\\1AB123-4567\r\n\r\n0-0:96.1.1(1A123456789012345678901234567890)\r\n1-0:1.8.1(00136.787*kWh)\r\n1-0:1.8.2(00131.849*kWh)\r\n1-0:2.8.1(00000.000*kWh)\r\n1-0:2.8.2(00000.000*kWh)\r\n0-0:96.14.0(0002)\r\n1-0:1.7.0(0003.20*kW)\r\n1-0:2.7.0(0000.00*kW)\r\n0-0:17.0.0(0999.00*kW)\r\n0-0:96.3.10(1)\r\n0-0:96.13.1()\r\n0-0:96.13.0()\r\n0-1:24.1.0(3)\r\n0-1:96.1.0(1234567890123456789012345678901234)\r\n0-1:24.3.0(120502150000)(00)(60)(1)(0-1:24.2.1)(m3)\r\n(00092.112)\r\n0-1:24.4.0(1)\r\n!\r\n"
@@ -0,0 +1,25 @@
1
+ module ParseP1
2
+
3
+ class Base
4
+
5
+ include ParseP1::Electricity
6
+ include ParseP1::Gas
7
+
8
+ attr_reader :data
9
+
10
+ def initialize(data)
11
+ @data = data
12
+ end
13
+
14
+ def valid?
15
+ !data.match(/!\r\n$/).nil? && !device_id.nil?
16
+ end
17
+
18
+ def device_id
19
+ data.match(/^\/([a-zA-Z]{3}\d{1}.+)\r$/)
20
+ $1
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,59 @@
1
+ module ParseP1
2
+
3
+ module Electricity
4
+
5
+ def electra_meter_id
6
+ data.match(/0:96.1.1\S(\d{1}[A-Z]{1}\d{1,96})\S/)
7
+ $1
8
+ end
9
+
10
+ def electricity_tariff_indicator
11
+ data.match(/0-0:96.14.0\S(\d{1,9})\S/)
12
+ $1.to_i
13
+ end
14
+
15
+ def electricity_actual_threshold
16
+ electricity('0-0:17.0.0')
17
+ end
18
+
19
+ def electricity(options)
20
+ if options.is_a?(Hash)
21
+ if options[:actual] == true
22
+ get_actual_electricity(options[:type])
23
+ else
24
+ get_electricity("1-0:#{first_electricity_code(options[:type])}.8.#{second_electricity_code(options[:tariff])}")
25
+ end
26
+ else
27
+ get_electricity(options)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def get_electricity(obis_code)
34
+ data.match(/#{obis_code}\S(\d{1,9}\.\d{1,3})\S/)
35
+ $1.to_f
36
+ end
37
+
38
+ def get_actual_electricity(type)
39
+ power = get_electricity("1-0:#{first_electricity_code(type)}.7.0")
40
+ (power * 1000).to_i #Return as watts instead of kW
41
+ end
42
+
43
+ def first_electricity_code(code)
44
+ case code
45
+ when :import; '1'
46
+ when :export; '2'
47
+ end
48
+ end
49
+
50
+ def second_electricity_code(tariff)
51
+ case tariff
52
+ when :normal; 1
53
+ when :low; 2
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,28 @@
1
+ module ParseP1
2
+
3
+ module Gas
4
+
5
+ def gas_meter_id
6
+ data.match(/1:96.1.0\S(\d{1,96})\S/)
7
+ $1
8
+ end
9
+
10
+ #Only 2 digits for year!
11
+ def last_hourly_reading_gas
12
+ data.match(/0-1:24.3.0\S(\d{12})\S/)
13
+ DateTime.new(('20'+$1[0..1]).to_i, $1[2..3].to_i, $1[4..5].to_i, $1[6..7].to_i, $1[8..9].to_i)
14
+ end
15
+
16
+ def measurement_unit_gas
17
+ data.match(/\S0-1:24.2.1\S\S(\w+)\S/)
18
+ $1
19
+ end
20
+
21
+ def gas_usage
22
+ data.match(/\S0-1:24.2.1\S\S\w+\S\r\n\S(\d+.\d+)\S/)
23
+ $1.to_f
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,3 @@
1
+ module ParseP1
2
+ VERSION = "0.0.2"
3
+ end
data/lib/parse_p1.rb ADDED
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'date'
5
+ require 'parse_p1/electricity'
6
+ require 'parse_p1/gas'
7
+ require 'parse_p1/base'
data/parse_p1.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "parse_p1/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "parse_p1"
7
+ s.version = ParseP1::VERSION
8
+ s.authors = ["Frank Oxener"]
9
+ s.email = ["frank.oxener@gmail.com"]
10
+ s.homepage = %q{http://github.com/dovadi/parse_p1}
11
+ s.summary = %q{Parsing P1 Companion Standard used by Dutch Smart Meters}
12
+ s.description = %q{Parsing P1 Companion Standard used by Dutch Smart Meters. Used in combination with a Nanode posting the P1 data to emonWeb.org}
13
+ s.licenses = ['MIT']
14
+ s.rubyforge_project = "parse_p1"
15
+
16
+ s.extra_rdoc_files = [
17
+ 'CHANGELOG',
18
+ 'LICENSE.txt',
19
+ 'README.md'
20
+ ]
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+
27
+ s.add_development_dependency 'shoulda'
28
+ s.add_development_dependency 'guard'
29
+ s.add_development_dependency 'guard-test'
30
+
31
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'parse_p1'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,106 @@
1
+ require 'helper'
2
+
3
+ class TestParseP1 < Test::Unit::TestCase
4
+
5
+ def setup
6
+ #Data string as received on a Ruby on Rails application
7
+ @data = "\r\n/ABc1\\1AB123-4567\r\n\r\n0-0:96.1.1(1A123456789012345678901234567890)\r\n1-0:1.8.1(00136.787*kWh)\r\n1-0:1.8.2(00131.849*kWh)\r\n1-0:2.8.1(00002.345*kWh)\r\n1-0:2.8.2(00054.976*kWh)\r\n0-0:96.14.0(0002)\r\n1-0:1.7.0(0003.20*kW)\r\n1-0:2.7.0(0000.12*kW)\r\n0-0:17.0.0(0999.00*kW)\r\n0-0:96.3.10(1)\r\n0-0:96.13.1()\r\n0-0:96.13.0()\r\n0-1:24.1.0(3)\r\n0-1:96.1.0(1234567890123456789012345678901234)\r\n0-1:24.3.0(120502150000)(00)(60)(1)(0-1:24.2.1)(m3)\r\n(00092.112)\r\n0-1:24.4.0(1)\r\n!\r\n"
8
+ @p1 = ParseP1::Base.new(@data)
9
+ end
10
+
11
+ should 'return the p1_string' do
12
+ assert_equal @data, @p1.data
13
+ end
14
+
15
+ should 'tell if string is P1 valid' do
16
+ assert_equal true, @p1.valid?
17
+ end
18
+
19
+ context 'Device identifiers' do
20
+
21
+ should 'return the device_id of the meter' do
22
+ assert_equal 'ABc1\1AB123-4567', @p1.device_id
23
+ end
24
+
25
+ #Sn (n=0..96), octet string is NOT true
26
+ should 'return the electra meter identifier of the meter' do
27
+ assert_equal '1A123456789012345678901234567890', @p1.electra_meter_id
28
+ end
29
+
30
+ #Sn (n=0..96) octet string
31
+ should 'return the gas meter identifier of the meter' do
32
+ assert_equal '1234567890123456789012345678901234', @p1.gas_meter_id
33
+ end
34
+
35
+ end
36
+
37
+ context 'Electricity data' do
38
+
39
+ #S4 tag 4 bit string is NOT true
40
+ should 'return the electricity tariff indicator' do
41
+ assert_equal 2, @p1.electricity_tariff_indicator
42
+ end
43
+
44
+ #F4(1,1)
45
+ should 'return the electricity actual threshold' do
46
+ assert_equal 999.0, @p1.electricity_actual_threshold
47
+ end
48
+
49
+ #F9 (3,3)
50
+ should 'return electricity with a corresponding obis code' do
51
+ assert_equal 136.787, @p1.electricity('1-0:1.8.1')
52
+ end
53
+
54
+ #F9 (3,3)
55
+ should 'return imported electricty with normal tarif' do
56
+ assert_equal 136.787, @p1.electricity(:type => :import, :tariff => :normal)
57
+ end
58
+
59
+ #F9 (3,3)
60
+ should 'return imported electricty with low tarif' do
61
+ assert_equal 131.849, @p1.electricity(:type => :import, :tariff => :low)
62
+ end
63
+
64
+ #F9 (3,3)
65
+ should 'return electricty produced by client normal tarif' do
66
+ assert_equal 2.345, @p1.electricity(:type => :export, :tariff => :normal)
67
+ end
68
+
69
+ #F9 (3,3)
70
+ should 'return electricty produced by client low tarif' do
71
+ assert_equal 54.976, @p1.electricity(:type => :export, :tariff => :low)
72
+ end
73
+
74
+ context 'Actual data' do
75
+
76
+ #F5 (3,3)
77
+ should 'return actual power imported' do
78
+ assert_equal 3200, @p1.electricity(:type => :import, :actual => true)
79
+ end
80
+
81
+ #F5 (3,3)
82
+ should 'return actual power in case of a low tarif' do
83
+ assert_equal 120, @p1.electricity(:type => :export, :actual => true)
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ context 'Gas data' do
91
+
92
+ should 'return the last hourly reading of gas usage' do
93
+ assert_equal DateTime.new(2012,5,2,15,0), @p1.last_hourly_reading_gas
94
+ end
95
+
96
+ should 'return the measurement unit of gas usage' do
97
+ assert_equal 'm3', @p1.measurement_unit_gas
98
+ end
99
+
100
+ should 'return the total usage of gas' do
101
+ assert_equal 92.112, @p1.gas_usage
102
+ end
103
+
104
+ end
105
+
106
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parse_p1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Frank Oxener
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: shoulda
16
+ requirement: &2151918740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2151918740
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard
27
+ requirement: &2151918120 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2151918120
36
+ - !ruby/object:Gem::Dependency
37
+ name: guard-test
38
+ requirement: &2151917380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2151917380
47
+ description: Parsing P1 Companion Standard used by Dutch Smart Meters. Used in combination
48
+ with a Nanode posting the P1 data to emonWeb.org
49
+ email:
50
+ - frank.oxener@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files:
54
+ - CHANGELOG
55
+ - LICENSE.txt
56
+ - README.md
57
+ files:
58
+ - .gitignore
59
+ - .travis.yml
60
+ - CHANGELOG
61
+ - Gemfile
62
+ - Guardfile
63
+ - LICENSE.txt
64
+ - README.md
65
+ - Rakefile
66
+ - docs/DSMR V4-2.0 final P1.pdf
67
+ - docs/Dutch Smart Meter Requirements v2.2 final P1.pdf
68
+ - docs/Meterhandleiding ME382-MT382_tcm300-197291.pdf
69
+ - docs/example_p1_output.txt
70
+ - lib/parse_p1.rb
71
+ - lib/parse_p1/base.rb
72
+ - lib/parse_p1/electricity.rb
73
+ - lib/parse_p1/gas.rb
74
+ - lib/parse_p1/version.rb
75
+ - parse_p1.gemspec
76
+ - test/helper.rb
77
+ - test/parse_p1_test.rb
78
+ homepage: http://github.com/dovadi/parse_p1
79
+ licenses:
80
+ - MIT
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project: parse_p1
99
+ rubygems_version: 1.8.6
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Parsing P1 Companion Standard used by Dutch Smart Meters
103
+ test_files:
104
+ - test/helper.rb
105
+ - test/parse_p1_test.rb