msg-chumby-display 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -13,10 +13,11 @@ begin
13
13
  gem.add_dependency "flukso4r", ">= 0.3.1"
14
14
  gem.add_dependency "mongrel", ">= 1.1.5"
15
15
  gem.add_dependency "xml-simple", ">= 1.0.12"
16
+ gem.add_dependency "msg-flukso-localinterface", ">= 0.0.1"
16
17
  gem.bindir='bin'
17
18
  gem.executables=['msg-chumby-daemon']
18
19
  gem.default_executable = 'msg-chumby-daemon'
19
- gem.files = FileList["[A-Z]*", "{bin,widget,lib,test}/**/*"]
20
+ gem.files = FileList["[A-Z]*", "{bin,etc,widget,lib,test}/**/*"]
20
21
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
21
22
  end
22
23
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -1,17 +1,102 @@
1
1
  #!/usr/bin/env ruby
2
+ ###
3
+ ##
4
+ # msg-chumby-daemon: A Ruby library for the Chumby mySmartGrid daemon
5
+ # Copyright (C) 2010 Mathias Dalheimer (md@gonium.net)
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with this program; if not, write to the Free Software Foundation, Inc.,
19
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ ##
21
+ ###
2
22
 
3
23
  libpath=File.join(File.dirname(__FILE__), '..', 'lib')
4
24
  $:.unshift << libpath
5
25
  #puts "Using library path #{$:.join(":")}"
6
26
  require 'rubygems'
7
27
  require 'msg-chumby-daemon.rb'
28
+ require 'msg-flukso-localinterface.rb'
29
+ require 'optparse'
30
+ require 'ostruct'
8
31
 
9
- #TODO: Make generic. This is the ID of the CC-HPC flukso.
10
- sensor_id="67e9fa794684e4902730be208e9d734e"
11
- token="bb8640e074de14b9d444be7b1359707f"
32
+ ###
33
+ ## Commandline parser
34
+ #
35
+ class Optparser
36
+ CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
37
+ CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
38
+ #
39
+ # Return a structure describing the options.
40
+ #
41
+ def self.parse(args)
42
+ # The options specified on the command line will be collected in *options*.
43
+ # We set default values here.
44
+ options = OpenStruct.new
45
+ options.inplace = false
46
+ options.encoding = "utf8"
47
+ options.verbose = false
48
+ opts = OptionParser.new do |opts|
49
+ opts.banner = "Usage: #{$0} [options]"
50
+ opts.separator ""
51
+ opts.separator "Specific options:"
52
+ opts.on("-c", "--config FILE", "The file where the configuration lives.") do |file|
53
+ options.config_file = file
54
+ end
55
+ # Boolean switch.
56
+ opts.on("-v", "--verbose", "Run verbosely") do |v|
57
+ options.verbose = v
58
+ end
59
+ opts.on_tail("-h", "--help", "Show this message") do
60
+ puts opts
61
+ exit
62
+ end
63
+ end
64
+ opts.parse!(args)
65
+ options
66
+ end
67
+ end
68
+
69
+ ###
70
+ ## Script startup
71
+ #
72
+ options = Optparser.parse(ARGV)
73
+ $verbose = options.verbose
74
+ if options.config_file == nil
75
+ puts "Please provide a configuration file... (-h for details)."
76
+ exit(-1);
77
+ end
78
+ if not File.exists?(options.config_file)
79
+ puts " Configuration file #{options.config_file} not found - no database configuration available!"
80
+ exit(-3);
81
+ else
82
+ $CONFIG=YAML.load_file(options.config_file);
83
+ puts "Using this configuration:" if $verbose
84
+ puts "#{$CONFIG}" if $verbose
85
+ sensor_id=$CONFIG['SENSOR_ID']
86
+ token=$CONFIG['ACCESS_TOKEN']
87
+ if $CONFIG['FLUKSO_LOCATION_METHOD'].upcase == "STATIC"
88
+ host=$CONFIG['FLUKSO_HOST'];
89
+ port=$CONFIG['FLUKSO_PORT'];
90
+ discoveryMechanism=FluksoLocal::DiscoverStaticConfiguration.new(host, port);
91
+ location=discoveryMechanism.getFluksoLocation();
92
+ end
93
+ local_id=$CONFIG['FLUKSO_LOCAL_ID']
94
+ puts "Using Flukso at location #{location} with ID #{local_id}" if $verbose
95
+ end
12
96
 
13
97
  reading_cache=MSG_Chumby::Reading_Cache.new();
14
- $demo_importer=MSG_Chumby::DemoReadingImporter.new(reading_cache, 400);
98
+ #$demo_importer=MSG_Chumby::RandomReadingImporter.new(reading_cache, 400);
99
+ $demo_importer=MSG_Chumby::LastMinuteImporter.new(reading_cache, location, local_id);
15
100
  $lasthour_importer=MSG_Chumby::LastHourImporter.new(reading_cache, sensor_id, token);
16
101
  $lastday_importer=MSG_Chumby::LastDayImporter.new(reading_cache, sensor_id, token);
17
102
  $shortterm_thread=nil;
@@ -23,25 +108,25 @@ def startAll
23
108
  $server.start();
24
109
  $shortterm_thread=Thread.new() {
25
110
  loop do
26
- puts "Running short term import"
27
- begin
28
- $demo_importer.doWork();
29
- rescue StandardError => e
30
- puts "ERROR in short-term thread: #{e}"
31
- end
32
- sleep(3);
111
+ puts "Running short term import"
112
+ begin
113
+ $demo_importer.doWork();
114
+ rescue StandardError => e
115
+ puts "ERROR in short-term thread: #{e}"
116
+ end
117
+ sleep(3);
33
118
  end
34
119
  }
35
120
  $longterm_thread=Thread.new() {
36
121
  loop do
37
- puts "Running long term import"
38
- begin
39
- $lasthour_importer.doWork();
40
- $lastday_importer.doWork();
41
- rescue StandardError => e
42
- puts "ERROR in long-term thread: #{e}"
43
- end
44
- sleep(10);
122
+ puts "Running long term import"
123
+ begin
124
+ $lasthour_importer.doWork();
125
+ $lastday_importer.doWork();
126
+ rescue StandardError => e
127
+ puts "ERROR in long-term thread: #{e}"
128
+ end
129
+ sleep(10);
45
130
  end
46
131
  }
47
132
  $server.join();
@@ -0,0 +1,8 @@
1
+ # These are the access parameters of the CC-HPC demo flukso - replace
2
+ # with your own parameters!
3
+ ACCESS_TOKEN: "bb8640e074de14b9d444be7b1359707f"
4
+ SENSOR_ID: "67e9fa794684e4902730be208e9d734e"
5
+ FLUKSO_LOCATION_METHOD: "static"
6
+ FLUKSO_HOST: "192.168.1.102"
7
+ FLUKSO_PORT: "80"
8
+ FLUKSO_LOCAL_ID: "d69779ec53a9323b695ee86b5328dd28"
@@ -49,6 +49,40 @@ module MSG_Chumby
49
49
  end
50
50
  end
51
51
 
52
+ class LastMinuteHandler < Mongrel::HttpHandler
53
+ def initialize(reading_cache)
54
+ @reading_cache=reading_cache;
55
+ end
56
+ def process(request, response)
57
+ response.start(200) do |head,out|
58
+ head["Content-Type"] = "text/xml"
59
+ readings=(@reading_cache.last_minute())
60
+ # Even if there are currently no readings we need to provide
61
+ # them.
62
+ if readings==nil
63
+ readings = Array.new();
64
+ (0..59).each {|i|
65
+ timestamp = Time.now.to_i - i
66
+ readings << Flukso::UTCReading.new(timestamp, 0.0)
67
+ }
68
+ end
69
+ flat_data=Array.new;
70
+ readings.each{|reading|
71
+ if not reading.nan? #(reading.value*1.0).nan?
72
+ # Skip NaN values.
73
+ #else
74
+ time=Time.at(reading.utc_timestamp);
75
+ current_reading=
76
+ {'time' => [ time.strftime("%H:%M:%S")], 'value' => [reading.value]};
77
+ flat_data << current_reading
78
+ end
79
+ }
80
+ #pp flat_data
81
+ out.write(XmlSimple.xml_out( { 'reading' => flat_data} ,{'RootName' => "last_minute"}));
82
+ end
83
+ end
84
+ end
85
+
52
86
  class LastHourHandler < Mongrel::HttpHandler
53
87
  def initialize(reading_cache)
54
88
  @reading_cache=reading_cache;
@@ -124,6 +158,7 @@ module MSG_Chumby
124
158
  @server.register("/time", TimeHandler.new)
125
159
  @server.register("/reset", ResetHandler.new)
126
160
  @server.register("/last_reading", LastReadingHandler.new(reading_cache))
161
+ @server.register("/last_minute", LastMinuteHandler.new(reading_cache))
127
162
  @server.register("/last_hour", LastHourHandler.new(reading_cache))
128
163
  @server.register("/last_day", LastDayHandler.new(reading_cache))
129
164
  end
@@ -5,6 +5,8 @@ module MSG_Chumby
5
5
  def initialize
6
6
  @last_reading=nil;
7
7
  @last_reading_mutex=Mutex.new();
8
+ @last_minute=nil;
9
+ @last_minute_mutex=Mutex.new();
8
10
  @last_hour=nil;
9
11
  @last_hour_mutex=Mutex.new();
10
12
  @last_day=nil;
@@ -23,6 +25,20 @@ module MSG_Chumby
23
25
  end
24
26
  return retval
25
27
  end
28
+ def update_last_minute(readings)
29
+ raise "Please provide an Array instance" if readings.class != Array
30
+ @last_minute_mutex.synchronize do
31
+ @last_minute=readings
32
+ end
33
+ end
34
+ def last_minute
35
+ retval=nil
36
+ @last_minute_mutex.synchronize do
37
+ retval=@last_minute
38
+ end
39
+ return retval
40
+ end
41
+
26
42
  def update_last_hour(readings)
27
43
  raise "Please provide an Array instance" if readings.class != Array
28
44
  @last_hour_mutex.synchronize do
@@ -6,7 +6,8 @@ end
6
6
 
7
7
  module MSG_Chumby
8
8
  BASE_URL="https://api.mysmartgrid.de/sensor"
9
- class DemoReadingImporter
9
+ # Generates random readings for standalone demos.
10
+ class RandomReadingImporter
10
11
  def initialize(reading_cache, max_reading)
11
12
  @reading_cache=reading_cache
12
13
  @max_reading=max_reading
@@ -18,6 +19,35 @@ module MSG_Chumby
18
19
  @reading_cache.update_last_reading(reading);
19
20
  end
20
21
  end
22
+ class LastMinuteImporter
23
+ def initialize(reading_cache, location, local_id)
24
+ @reading_cache=reading_cache
25
+ @query=FluksoLocal::Query.new(location)
26
+ @local_id=local_id
27
+ end
28
+ def doWork
29
+ begin
30
+ values=@query.getReadings(@local_id);
31
+ # handle last value
32
+ last_value=values.max
33
+ #puts "Last reading: timestamp = #{last_value[0]}, value=#{last_value[1]}"
34
+ reading=Flukso::UTCReading.new(last_value[0], last_value[1])
35
+ @reading_cache.update_last_reading(reading);
36
+ # now handle last minute
37
+ last_minute=Array.new();
38
+ values.each{|current|
39
+ currentreading=Flukso::UTCReading.new(current[0], current[1])
40
+ last_minute << currentreading
41
+ }
42
+ last_minute.sort! {|a, b|
43
+ a.utc_timestamp <=> b.utc_timestamp
44
+ }
45
+ @reading_cache.update_last_minute(last_minute);
46
+ rescue StandardError => bam
47
+ puts "Cannot retrieve last minute: #{bam}"
48
+ end
49
+ end
50
+ end
21
51
  class LastHourImporter
22
52
  def initialize(reading_cache, sensor_id, token)
23
53
  @reading_cache=reading_cache
@@ -0,0 +1,33 @@
1
+ currentpower.swf Filmbericht
2
+ -----------------------------
3
+
4
+ Metadaten
5
+ ---------
6
+ Byte Wert
7
+ ---- ----
8
+ 1290 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/"> <xmp:CreatorTool>Adobe Flash CS4 Professional</xmp:CreatorTool> <xmp:CreateDate>2010-03-15T15:58:56+01:00</xmp:CreateDate> <xmp:MetadataDate>2010-06-10T12:00:10+02:00</xmp:MetadataDate> <xmp:ModifyDate>2010-06-10T12:00:10+02:00</xmp:ModifyDate> </rdf:Description> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"> <xmpMM:InstanceID>xmp.iid:05801174072068118F62D3F217E0363A</xmpMM:InstanceID> <xmpMM:DocumentID>xmp.did:05801174072068118F62D3F217E0363A</xmpMM:DocumentID> <xmpMM:OriginalDocumentID>xmp.did:F77F11740720681193E68700E4C8E173</xmpMM:OriginalDocumentID> <xmpMM:DerivedFrom rdf:parseType="Resource"> <stRef:instanceID>xmp.iid:F87F11740720681191099C69294AD041</stRef:instanceID> <stRef:documentID>xmp.did:F87F11740720681191099C69294AD041</stRef:documentID> <stRef:originalDocumentID>xmp.did:F77F11740720681193E68700E4C8E173</stRef:originalDocumentID> </xmpMM:DerivedFrom> </rdf:Description> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:format>application/x-shockwave-flash</dc:format> </rdf:Description> </rdf:RDF>
9
+
10
+ Bild # Bild Byte Gesamt Byte Szene
11
+ ------ --------- ----------- ----------------
12
+ 1 16089 16089 Szene 1 (AS 2.0-Klassen Exportbild)
13
+
14
+ Szene Form Byte Text Byte ActionScript Byte
15
+ ------------------------- --------- --------- -----------------
16
+ Szene 1 0 523 1275
17
+
18
+ Symbol Form Byte Text Byte ActionScript Byte
19
+ ------------------------- --------- --------- -----------------
20
+ reset_button 9877 0 0
21
+
22
+ Schriftart Byte Zeichen
23
+ ----------------------- -------- -----------
24
+ AllerDisplay 1502 AWaekltu
25
+ Aller 1375 Wenortv
26
+
27
+ ActionScript Byte Position
28
+ ----------------- --------
29
+ 1275 Szene 1:Ebene 1:1
30
+
31
+
32
+
33
+
Binary file
@@ -299,13 +299,13 @@ function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
299
299
  'play', 'true',
300
300
  'loop', 'true',
301
301
  'scale', 'showall',
302
- 'wmode', 'window',
302
+ 'wmode', 'direct',
303
303
  'devicefont', 'false',
304
304
  'id', 'currentpower',
305
305
  'bgcolor', '#ffffff',
306
306
  'name', 'currentpower',
307
307
  'menu', 'true',
308
- 'allowFullScreen', 'false',
308
+ 'allowFullScreen', 'true',
309
309
  'allowScriptAccess','sameDomain',
310
310
  'movie', 'currentpower',
311
311
  'salign', ''
@@ -314,8 +314,8 @@ function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
314
314
  <noscript>
315
315
  <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="320" height="240" id="currentpower" align="middle">
316
316
  <param name="allowScriptAccess" value="sameDomain" />
317
- <param name="allowFullScreen" value="false" />
318
- <param name="movie" value="currentpower.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /> <embed src="currentpower.swf" quality="high" bgcolor="#ffffff" width="320" height="240" name="currentpower" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer_de" />
317
+ <param name="allowFullScreen" value="true" />
318
+ <param name="movie" value="currentpower.swf" /><param name="quality" value="high" /><param name="wmode" value="direct" /><param name="bgcolor" value="#ffffff" /> <embed src="currentpower.swf" quality="high" wmode="direct" bgcolor="#ffffff" width="320" height="240" name="currentpower" align="middle" allowScriptAccess="sameDomain" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer_de" />
319
319
  </object>
320
320
  </noscript>
321
321
  </body>
Binary file
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msg-chumby-display
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Mathias Dalheimer
@@ -9,39 +15,73 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-06-08 00:00:00 +02:00
18
+ date: 2010-07-08 00:00:00 +02:00
13
19
  default_executable: msg-chumby-daemon
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: flukso4r
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 17
30
+ segments:
31
+ - 0
32
+ - 3
33
+ - 1
23
34
  version: 0.3.1
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: mongrel
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 25
46
+ segments:
47
+ - 1
48
+ - 1
49
+ - 5
33
50
  version: 1.1.5
34
- version:
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  - !ruby/object:Gem::Dependency
36
54
  name: xml-simple
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
40
58
  requirements:
41
59
  - - ">="
42
60
  - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 1
64
+ - 0
65
+ - 12
43
66
  version: 1.0.12
44
- version:
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: msg-flukso-localinterface
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 29
78
+ segments:
79
+ - 0
80
+ - 0
81
+ - 1
82
+ version: 0.0.1
83
+ type: :runtime
84
+ version_requirements: *id004
45
85
  description: "The mySmartGrid project provides means to manage your household energy consumption. This gem provides the runtime environment for the Chumby: it queries the mySmartGrid webservice and forwards that information to a Flash application running on the Chumby."
46
86
  email: md@gonium.net
47
87
  executables:
@@ -57,6 +97,7 @@ files:
57
97
  - Rakefile
58
98
  - VERSION
59
99
  - bin/msg-chumby-daemon
100
+ - etc/msgchumbydaemonrc
60
101
  - lib/msg-chumby-daemon.rb
61
102
  - lib/msg-chumby-daemon/http-xml-server.rb
62
103
  - lib/msg-chumby-daemon/reading-cache.rb
@@ -65,8 +106,10 @@ files:
65
106
  - test/helper.rb
66
107
  - test/test_msg-chumby-display.rb
67
108
  - widget/currentpower/Makefile
109
+ - widget/currentpower/currentpower Report.txt
68
110
  - widget/currentpower/currentpower.fla
69
111
  - widget/currentpower/currentpower.html
112
+ - widget/currentpower/currentpower.swd
70
113
  - widget/currentpower/currentpower.swf
71
114
  has_rdoc: true
72
115
  homepage: http://github.com/gonium/msg-chumby-display
@@ -78,21 +121,27 @@ rdoc_options:
78
121
  require_paths:
79
122
  - lib
80
123
  required_ruby_version: !ruby/object:Gem::Requirement
124
+ none: false
81
125
  requirements:
82
126
  - - ">="
83
127
  - !ruby/object:Gem::Version
128
+ hash: 3
129
+ segments:
130
+ - 0
84
131
  version: "0"
85
- version:
86
132
  required_rubygems_version: !ruby/object:Gem::Requirement
133
+ none: false
87
134
  requirements:
88
135
  - - ">="
89
136
  - !ruby/object:Gem::Version
137
+ hash: 3
138
+ segments:
139
+ - 0
90
140
  version: "0"
91
- version:
92
141
  requirements: []
93
142
 
94
143
  rubyforge_project:
95
- rubygems_version: 1.3.5
144
+ rubygems_version: 1.3.7
96
145
  signing_key:
97
146
  specification_version: 3
98
147
  summary: Displays various information from the mySmartGrid project on your Chumby