currentcostd 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
data/COPYING ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008 James Smith (james@floppy.org.uk)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,42 @@
1
+ == currentcostd
2
+
3
+ A system daemon for monitoring and publishing data from a CurrentCost energy meter
4
+ (http://www.currentcost.com)
5
+
6
+ Licensed under the MIT license (See COPYING file for details)
7
+
8
+ Author: James Smith (james@floppy.org.uk / http://www.floppy.org.uk)
9
+
10
+ Homepage: http://github.com/Floppy/currentcost-daemon
11
+
12
+ == INSTALLATION
13
+
14
+ 1) Enable gems from gemcutter, if you haven't already done so:
15
+ > sudo gem install gemcutter
16
+ > sudo gem tumble
17
+
18
+ 2) Install gem
19
+ > sudo gem install currentcostd
20
+
21
+ == REQUIREMENTS
22
+
23
+ Floppy-currentcost >= 0.2.4
24
+ Floppy-eeml >= 0.1.0
25
+ daemons >= 1.0.10
26
+ builder >= 2.1.2
27
+
28
+ == USAGE
29
+
30
+ 1) Copy config/currentcostd.example.yml to /etc/currentcostd.yml
31
+
32
+ 2) Edit the settings in your new currentcostd.yml
33
+
34
+ 3) Run "sudo currentcostd start" to start the daemon.
35
+
36
+ == AVAILABLE PUBLISHERS
37
+
38
+ * AMEE (www.amee.cc)
39
+ * Carbon Diet (www.carbondiet.org)
40
+ * Pachube (www.pachube.com)
41
+ * Twitter (www.twitter.com)
42
+ * Local HTTP server
data/bin/currentcostd ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #
23
+ # http://www.opensource.org/licenses/mit-license.php
24
+
25
+ require 'rubygems'
26
+ require 'daemons'
27
+ require 'currentcost/meter'
28
+ require 'yaml'
29
+
30
+ # Load config
31
+ config = nil
32
+ config_files = [
33
+ "/etc/currentcostd.yml",
34
+ File.join(File.dirname(__FILE__), '/../config/currentcostd.yml')
35
+ ]
36
+ config_files.each do |c|
37
+ if File.exists?(c)
38
+ config = YAML.load_file(c)
39
+ break
40
+ end
41
+ end
42
+ if config.nil?
43
+ puts "Couldn't load configuration from " + config_files.join(" or ")
44
+ exit
45
+ end
46
+
47
+ # Require all available publishers
48
+ Dir.glob(File.join(File.dirname(__FILE__), '/../lib/currentcostd/publishers/*.rb')).each { |f| require f }
49
+
50
+ Daemons.run_proc('currentcostd', :dir_mode => :system) do
51
+
52
+ # Create meter object
53
+ meter = CurrentCost::Meter.new config['currentcost']['port'], :cc128 => config['currentcost']['cc128']
54
+
55
+ # Register publishers with meter if their configuration sections are defined
56
+ CurrentCostDaemon::Publishers.constants.each do |publisher|
57
+ pub_class = CurrentCostDaemon::Publishers.const_get(publisher)
58
+ if config[pub_class.config_section] && config[pub_class.config_section]['enabled'] == true
59
+ meter.add_observer(pub_class.new(config))
60
+ end
61
+ end
62
+
63
+ # Just let it run
64
+ while (true)
65
+ sleep(30)
66
+ end
67
+
68
+ end
@@ -0,0 +1,43 @@
1
+ # Copy this file to /etc/currentcostd.yml OR ./currentcostd.yml and add your
2
+ # own settings.
3
+
4
+ currentcost:
5
+ port: /dev/ttyS0
6
+ cc128: true
7
+
8
+ # Enable this to dump meter data to standard output
9
+ debug:
10
+ enabled: true
11
+
12
+ # Enable this to publish to a feed on www.pachube.com
13
+ pachube:
14
+ enabled: false
15
+ feed_id: your_pachube_feed_id_goes_here (e.g. 123)
16
+ api_key: your_pachube_api_key_goes_here
17
+
18
+ # Enable this to run a web server which you can look at in a browser
19
+ http:
20
+ enabled: false
21
+ port: 3500
22
+
23
+ # Enable this section to post data to www.carbondiet.org
24
+ carbondiet:
25
+ enabled: false
26
+ username: your_carbondiet_username_goes_here
27
+ password: your_carbondiet_password_goes_here
28
+
29
+ # Enable this section to send data directly to an AMEE profile
30
+ # The profile with the specified UID should already exist.
31
+ amee:
32
+ enabled: false
33
+ server: dev.amee.com
34
+ username: your_amee_username_goes_here
35
+ password: your_amee_password_goes_here
36
+ profile_uid: ABC123DEF456
37
+
38
+ # Enable this section to post to Twitter.
39
+ # This will post once a minute - I don't suggest you use your normal Twitter account ;)
40
+ twitter:
41
+ enabled: false
42
+ username: your_twitter_username_goes_here
43
+ password: your_twitter_password_goes_here
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ #
21
+ # http://www.opensource.org/licenses/mit-license.php
22
+
23
+ require 'net/http'
24
+
25
+ module CurrentCostDaemon
26
+
27
+ module Publishers
28
+
29
+ class AMEEPublisher
30
+
31
+ def self.config_section
32
+ 'amee'
33
+ end
34
+
35
+ def initialize(config)
36
+ @profile_uid = config['amee']['profile_uid']
37
+ @last_minute = Time.now.min - 1
38
+ # Store AMEE connection details
39
+ @server = config['amee']['server']
40
+ @username = config['amee']['username']
41
+ @password = config['amee']['password']
42
+ # Get electricity UID for later
43
+ req = Net::HTTP::Get.new("/data/home/energy/quantity/drill?type=electricity")
44
+ req.basic_auth @username, @password
45
+ req['Accept'] = "application/xml"
46
+ http = Net::HTTP.new(@server)
47
+ http.start do
48
+ response = http.request(req)
49
+ raise response.body if (response.code != "200" && response.code != "201")
50
+ @uid = response.body.match("<Choices><Name>uid</Name><Choices><Choice><Name>.*?</Name><Value>(.*?)</Value></Choice></Choices></Choices>")[1]
51
+ end
52
+ end
53
+
54
+ def update(reading)
55
+ return if reading.total_watts == 0
56
+ # Let's put data into AMEE every minute.
57
+ if Time.now.min != @last_minute
58
+ # Store time
59
+ @last_minute = Time.now.min
60
+ # Estimate kwh figure from current power usage
61
+ kwh = (reading.total_watts / 1000.0)
62
+ # Create POST options
63
+ raise "No Data Item UID found!" if @uid.nil?
64
+ options = {
65
+ :dataItemUid => @uid,
66
+ :startDate => Time.now.xmlschema,
67
+ :endDate => (Time.now + 60).xmlschema,
68
+ :energyConsumption => kwh,
69
+ :energyConsumptionUnit => "kWh",
70
+ :energyConsumptionPerUnit => "h",
71
+ :name => "currentcost"
72
+ }
73
+ puts "Storing in AMEE..."
74
+ # Post data to AMEE
75
+ req = Net::HTTP::Post.new("/profiles/#{@profile_uid}/home/energy/quantity")
76
+ req.basic_auth @username, @password
77
+ req['Accept'] = "application/xml"
78
+ req.set_form_data(options)
79
+ http = Net::HTTP.new(@server)
80
+ http.start do
81
+ response = http.request(req)
82
+ raise response.body if (response.code != "200" && response.code != "201")
83
+ end
84
+ puts "done"
85
+ end
86
+ rescue
87
+ puts "Something went wrong (AMEE)!"
88
+ puts $!.inspect
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ #
21
+ # http://www.opensource.org/licenses/mit-license.php
22
+
23
+ module CurrentCostDaemon
24
+
25
+ module Publishers
26
+
27
+ class CarbonDiet
28
+
29
+ def self.config_section
30
+ 'carbondiet'
31
+ end
32
+
33
+ def initialize(config)
34
+ @account = config['carbondiet']['account_id']
35
+ @username = config['carbondiet']['username']
36
+ @password = config['carbondiet']['password']
37
+ end
38
+
39
+ def update(reading)
40
+ # Carbon Diet is daily, so we only want to do something if there is
41
+ # history data, and only once a day, ideally. If it's 3am, upload history
42
+ # if we have it.
43
+ # This is horribly hacky, it post every time there is day history during
44
+ # this hour. Also the carbondiet code at the other end is hacky.
45
+ # All this needs improving.
46
+ puts reading.to_yaml
47
+ puts "stuff"
48
+ if !reading.history.nil? && reading.hour == 3
49
+ puts "Storing in Carbon Diet..."
50
+ # Create http post request
51
+ post = Net::HTTP::Post.new("/data_entry/electricity/#{@account}/currentcost")
52
+ post.basic_auth(@username, @password)
53
+ # Add XML document
54
+ xml = Builder::XmlMarkup.new
55
+ xml.instruct!
56
+ post.body = xml.data do
57
+ reading.history[:days].each_index do |i|
58
+ unless reading.history[:days][i].nil?
59
+ xml.entry do
60
+ xml.date Date.today - i
61
+ xml.value reading.history[:days][i][0]
62
+ end
63
+ end
64
+ end
65
+ end
66
+ # Send data
67
+ http = Net::HTTP.new('www.carbondiet.org')
68
+ http.start
69
+ http.request(post)
70
+ puts "done"
71
+ end
72
+ rescue
73
+ puts "Something went wrong (carbondiet)!"
74
+ puts $!.inspect
75
+ nil
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ #
21
+ # http://www.opensource.org/licenses/mit-license.php
22
+
23
+ module CurrentCostDaemon
24
+
25
+ module Publishers
26
+
27
+ class Debug
28
+
29
+ def self.config_section
30
+ 'debug'
31
+ end
32
+
33
+ def initialize(config)
34
+ end
35
+
36
+ def update(reading)
37
+ # Print out measurement
38
+ if reading.total_watts > 0
39
+ puts "New reading received: #{reading.total_watts} W"
40
+ else
41
+ puts "0 reading received: probably history data"
42
+ end
43
+ rescue
44
+ puts "Something went wrong (debug)!"
45
+ puts $!.inspect
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,121 @@
1
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ #
21
+ # http://www.opensource.org/licenses/mit-license.php
22
+
23
+ require 'webrick'
24
+
25
+ module CurrentCostDaemon
26
+
27
+ module Publishers
28
+
29
+ class Http
30
+
31
+ def self.config_section
32
+ 'http'
33
+ end
34
+
35
+ class Servlet < WEBrick::HTTPServlet::AbstractServlet
36
+ def do_GET(request, response)
37
+ if request.query['format'].nil? || request.query['format'] == "html"
38
+ response.status = 200
39
+ response['Content-Type'] = "text/html"
40
+ response.body = "
41
+ <html>
42
+ <head>
43
+ <meta http-equiv='refresh' content='6' />
44
+ <meta name='viewport' content='width=420'/>
45
+ </head>
46
+ <body>
47
+ <div style='float:right'>
48
+ <a title='EEML' href='/?format=eeml'><span style='border:1px solid;border-color:#9C9 #030 #030 #696;padding:0 3px;font:bold 10px verdana,sans-serif;color:#FFF;background:#090;text-decoration:none;margin:0;'>EEML</span></a>
49
+ <a title='XML' href='/?format=xml'><span style='border:1px solid;border-color:#FC9 #630 #330 #F96;padding:0 3px;font:bold 10px verdana,sans-serif;color:#FFF;background:#F60;text-decoration:none;margin:0;'>XML</span></a>
50
+ </div>
51
+ <h1>#{@@total} Watts</h2>
52
+ <p>updated at #{@@updated_at}</p>
53
+ <h2>History</h2>
54
+ <h3>Hourly</h3>
55
+ <img src='http://chart.apis.google.com/chart?cht=lc&chs=400x125&chd=t:#{@@history[:hours].reverse.delete_if{|x|x.nil?}.join(',')}&chds=0,#{@@history[:hours].delete_if{|x|x.nil?}.max}'/>
56
+ <h3>Daily</h3>
57
+ <img src='http://chart.apis.google.com/chart?cht=lc&chs=400x125&chd=t:#{@@history[:days].reverse.map{|x| x.nil? ? 0 : x[0]}.join(',')}&chds=0,#{@@history[:days].delete_if{|x|x.nil?}.max}'/>
58
+ <h3>Monthly</h3>
59
+ <img src='http://chart.apis.google.com/chart?cht=lc&chs=400x125&chd=t:#{@@history[:months].reverse.map{|x| x.nil? ? 0 : x[0]}.join(',')}&chds=0,#{@@history[:months].delete_if{|x|x.nil?}.max}'/>
60
+ <h3>Yearly</h3>
61
+ <img src='http://chart.apis.google.com/chart?cht=lc&chs=400x125&chd=t:#{@@history[:years].reverse.map{|x| x.nil? ? 0 : x[0]}.join(',')}&chds=0,#{@@history[:years].delete_if{|x|x.nil?}.max}'/>
62
+ </body>
63
+ </html>"
64
+ elsif request.query['format'] == "eeml"
65
+ # Create EEML document
66
+ eeml = EEML::Environment.new
67
+ # Create data object
68
+ data = EEML::Data.new(0)
69
+ data.unit = EEML::Unit.new("Watts", :symbol => 'W', :type => :derivedSI)
70
+ eeml << data
71
+ eeml[0].value = @@total
72
+ eeml.updated_at = @@updated_at
73
+ response.status = 200
74
+ response['Content-Type'] = "text/xml"
75
+ response.body = eeml.to_eeml
76
+ elsif request.query['format'] == "xml"
77
+ response.status = 200
78
+ response['Content-Type'] = "text/xml"
79
+ # Create XML
80
+ xml = Builder::XmlMarkup.new
81
+ xml.instruct!
82
+ response.body = xml.currentcost { xml.watts @@total }
83
+ else
84
+ response.status = 400
85
+ end
86
+ end
87
+ def self.update(reading)
88
+ @@reading = reading
89
+ @@updated_at = Time.now
90
+ # Add all channels to get real total
91
+ @@total = @@reading.total_watts
92
+ # Store history if available
93
+ @@history = @@reading.history if @@reading.history
94
+ end
95
+ end
96
+
97
+ def initialize(config)
98
+ # Initialise storage
99
+ @watts = 0
100
+ # Create WEBrick server
101
+ @server = WEBrick::HTTPServer.new(:Port => config['http']['port'] )
102
+ # Create a simple webrick servlet for HTML output
103
+ @server.mount("/", Servlet)
104
+ trap("INT") {@server.shutdown}
105
+ Thread.new{@server.start}
106
+ end
107
+
108
+ def update(reading)
109
+ puts "Updating HTTP publisher..."
110
+ Servlet.update(reading)
111
+ puts "done"
112
+ rescue
113
+ puts "Something went wrong (http)!"
114
+ puts $!.inspect
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ #
21
+ # http://www.opensource.org/licenses/mit-license.php
22
+
23
+ require 'eeml'
24
+ require 'net/http'
25
+
26
+ module CurrentCostDaemon
27
+
28
+ module Publishers
29
+
30
+ class Pachube
31
+
32
+ def self.config_section
33
+ 'pachube'
34
+ end
35
+
36
+ def initialize(config)
37
+ @feed = config['pachube']['feed_id']
38
+ @api_key = config['pachube']['api_key']
39
+ end
40
+
41
+ def update(reading)
42
+ return if reading.total_watts == 0
43
+ # Create EEML document
44
+ eeml = EEML::Environment.new
45
+ # Create data object
46
+ data = EEML::Data.new(0)
47
+ data.unit = EEML::Unit.new("Watts", :symbol => 'W', :type => :derivedSI)
48
+ eeml << data
49
+ eeml[0].value = reading.total_watts
50
+ eeml.set_updated!
51
+ # Put data
52
+ puts "Storing in Pachube..."
53
+ put = Net::HTTP::Put.new("/api/#{@feed}.xml")
54
+ put.body = eeml.to_eeml
55
+ put['X-PachubeApiKey'] = @api_key
56
+ http = Net::HTTP.new('www.pachube.com')
57
+ http.start
58
+ response = http.request(put)
59
+ raise response.code if response.code != "200"
60
+ puts "done"
61
+ rescue
62
+ puts "Something went wrong (pachube)!"
63
+ puts $!.inspect
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2008 James Smith (www.floppy.org.uk)
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ #
21
+ # http://www.opensource.org/licenses/mit-license.php
22
+
23
+ require 'cgi'
24
+
25
+ module CurrentCostDaemon
26
+
27
+ module Publishers
28
+
29
+ class Twitter
30
+
31
+ def self.config_section
32
+ 'twitter'
33
+ end
34
+
35
+ def initialize(config)
36
+ @username = config['twitter']['username']
37
+ @password = config['twitter']['password']
38
+ @last_minute = Time.now.min - 1
39
+ end
40
+
41
+ def update(reading)
42
+ return if reading.total_watts == 0
43
+ # Tweet once a minute
44
+ if Time.now.min != @last_minute
45
+ # Store time
46
+ @last_minute = Time.now.min
47
+ message = "At the moment, I'm using #{reading.total_watts} watts"
48
+ # Tweet
49
+ puts "Tweeting..."
50
+ req = Net::HTTP::Post.new("/statuses/update.json")
51
+ req.basic_auth @username, @password
52
+ req.set_form_data "status" => message
53
+ http = Net::HTTP.new("twitter.com")
54
+ http.start do
55
+ response = http.request(req)
56
+ raise response.body if (response.code[0] != "2")
57
+ end
58
+ puts "done"
59
+ end
60
+ rescue
61
+ puts "Something went wrong (twitter)!"
62
+ puts $!.inspect
63
+ nil
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: currentcostd
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.5
5
+ platform: ruby
6
+ authors:
7
+ - James Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-15 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: currentcost
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.3.4
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: amee
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.5
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: eeml-simple
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.1.1
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: daemons
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.10
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: builder
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.1.2
64
+ version:
65
+ description:
66
+ email: james@floppy.org.uk
67
+ executables:
68
+ - currentcostd
69
+ extensions: []
70
+
71
+ extra_rdoc_files: []
72
+
73
+ files:
74
+ - README
75
+ - COPYING
76
+ - lib/currentcostd/publishers/debug.rb
77
+ - lib/currentcostd/publishers/pachube.rb
78
+ - lib/currentcostd/publishers/http.rb
79
+ - lib/currentcostd/publishers/carbondiet.rb
80
+ - lib/currentcostd/publishers/amee.rb
81
+ - lib/currentcostd/publishers/twitter.rb
82
+ - config/currentcostd.example.yml
83
+ - bin/currentcostd
84
+ has_rdoc: true
85
+ homepage: http://github.com/Floppy/currentcost-daemon
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ requirements: []
106
+
107
+ rubyforge_project:
108
+ rubygems_version: 1.3.5
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: A system daemon for monitoring and publishing currentcost data
112
+ test_files: []
113
+