eeml 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2009, Neill Bogie, Samuel Mulube.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name of the <ORGANIZATION> nor the names of its contributors
13
+ may be used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Manifest ADDED
@@ -0,0 +1,30 @@
1
+ example.rb
2
+ eeml.gemspec
3
+ LICENSE
4
+ CHANGELOG
5
+ README
6
+ test/test_environment.rb
7
+ test/test_libxml_test_helper.rb
8
+ test/libxml_test_helper.rb
9
+ test/test_libxml_eeml_parser_v005.rb
10
+ test/test_helper.rb
11
+ test/data/minimal.xml
12
+ test/data/out_empty.xml
13
+ test/data/doc_1.xml
14
+ test/data/doc_1.json
15
+ lib/eeml.rb
16
+ lib/eeml/constants.rb
17
+ lib/eeml/feed_retriever.rb
18
+ lib/eeml/json_environment_parser.rb
19
+ lib/eeml/output_registry.rb
20
+ lib/eeml/parser_registry.rb
21
+ lib/eeml/libxml_eeml_output_v005.rb
22
+ lib/eeml/feed_output.rb
23
+ lib/eeml/libxml_eeml_parser_v005.rb
24
+ lib/eeml/exceptions.rb
25
+ lib/eeml/csv_parser.rb
26
+ lib/eeml/environment.rb
27
+ lib/blank.rb
28
+ schemas/eeml/005.xsd
29
+ Rakefile
30
+ Manifest
data/README ADDED
@@ -0,0 +1,8 @@
1
+ = eeml
2
+
3
+ * http://eeml.rubyforge.org
4
+
5
+ == DESCRIPTION:
6
+
7
+ Library for interacting with the API of pachube.com. Also aims to simplify
8
+ the process of creating, parsing and manipulating EEML documents.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require 'echoe'
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), "lib"))
4
+
5
+ require 'eeml'
6
+
7
+ Echoe.new("eeml") do |p|
8
+ p.author = "Neill Bogie, Sam Mulube"
9
+ p.email = "sam.mulube@gmail.com"
10
+ p.description = "Simple little library for programmatically manipulating EEML documents, in particular this library is designed to work with the Pachube web service."
11
+ p.summary = "Simple little library for programmatically manipulating EEML documents."
12
+ p.version = Eeml::VERSION
13
+ p.runtime_dependencies = [
14
+ "libxml-ruby >= 1.1.3",
15
+ "json >= 1.1.3"
16
+ ]
17
+ p.development_dependencies = [
18
+ "rake >= 0.8.4",
19
+ "mocha >= 0.9.6"
20
+ ]
21
+ p.ignore_pattern = [
22
+ "test/data/real_xmls/v005/oks/*",
23
+ "test/data/real_xmls/v005/*"
24
+ ]
25
+ end
data/eeml.gemspec ADDED
@@ -0,0 +1,46 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{eeml}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Neill Bogie, Sam Mulube"]
9
+ s.cert_chain = ["/home/sam/.gem/gem-public_cert.pem"]
10
+ s.date = %q{2009-04-17}
11
+ s.description = %q{Simple little library for programmatically manipulating EEML documents, in particular this library is designed to work with the Pachube web service.}
12
+ s.email = %q{sam.mulube@gmail.com}
13
+ s.extra_rdoc_files = ["LICENSE", "CHANGELOG", "README", "lib/eeml.rb", "lib/eeml/constants.rb", "lib/eeml/feed_retriever.rb", "lib/eeml/json_environment_parser.rb", "lib/eeml/output_registry.rb", "lib/eeml/parser_registry.rb", "lib/eeml/libxml_eeml_output_v005.rb", "lib/eeml/feed_output.rb", "lib/eeml/libxml_eeml_parser_v005.rb", "lib/eeml/exceptions.rb", "lib/eeml/csv_parser.rb", "lib/eeml/environment.rb", "lib/blank.rb"]
14
+ s.files = ["example.rb", "eeml.gemspec", "LICENSE", "CHANGELOG", "README", "test/test_environment.rb", "test/test_libxml_test_helper.rb", "test/libxml_test_helper.rb", "test/test_libxml_eeml_parser_v005.rb", "test/test_helper.rb", "test/data/minimal.xml", "test/data/out_empty.xml", "test/data/doc_1.xml", "test/data/doc_1.json", "lib/eeml.rb", "lib/eeml/constants.rb", "lib/eeml/feed_retriever.rb", "lib/eeml/json_environment_parser.rb", "lib/eeml/output_registry.rb", "lib/eeml/parser_registry.rb", "lib/eeml/libxml_eeml_output_v005.rb", "lib/eeml/feed_output.rb", "lib/eeml/libxml_eeml_parser_v005.rb", "lib/eeml/exceptions.rb", "lib/eeml/csv_parser.rb", "lib/eeml/environment.rb", "lib/blank.rb", "schemas/eeml/005.xsd", "Rakefile", "Manifest"]
15
+ s.has_rdoc = true
16
+ s.homepage = %q{}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Eeml", "--main", "README"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{eeml}
20
+ s.rubygems_version = %q{1.3.1}
21
+ s.signing_key = %q{/home/sam/.gem/gem-private_key.pem}
22
+ s.summary = %q{Simple little library for programmatically manipulating EEML documents.}
23
+ s.test_files = ["test/test_environment.rb", "test/test_libxml_test_helper.rb", "test/test_libxml_eeml_parser_v005.rb", "test/test_helper.rb"]
24
+
25
+ if s.respond_to? :specification_version then
26
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
+ s.specification_version = 2
28
+
29
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
+ s.add_runtime_dependency(%q<libxml-ruby>, [">= 0", "= 1.1.3"])
31
+ s.add_runtime_dependency(%q<json>, [">= 0", "= 1.1.3"])
32
+ s.add_development_dependency(%q<rake>, [">= 0", "= 0.8.4"])
33
+ s.add_development_dependency(%q<mocha>, [">= 0", "= 0.9.6"])
34
+ else
35
+ s.add_dependency(%q<libxml-ruby>, [">= 0", "= 1.1.3"])
36
+ s.add_dependency(%q<json>, [">= 0", "= 1.1.3"])
37
+ s.add_dependency(%q<rake>, [">= 0", "= 0.8.4"])
38
+ s.add_dependency(%q<mocha>, [">= 0", "= 0.9.6"])
39
+ end
40
+ else
41
+ s.add_dependency(%q<libxml-ruby>, [">= 0", "= 1.1.3"])
42
+ s.add_dependency(%q<json>, [">= 0", "= 1.1.3"])
43
+ s.add_dependency(%q<rake>, [">= 0", "= 0.8.4"])
44
+ s.add_dependency(%q<mocha>, [">= 0", "= 0.9.6"])
45
+ end
46
+ end
data/example.rb ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #should invoke this with (e.g.) ruby -Ilib example.rb in order to add lib/ to your search path
4
+
5
+ require 'rubygems' #only if your libxml is installed under rubygems
6
+ require 'eeml'
7
+
8
+ include Eeml #allows you to refer to Environment rather than Eeml::Environment
9
+
10
+ #Example: make an environment from scratch
11
+ env = Environment.new(:creator => 'http://www.example.com/ourstudio/', :feed_url => 'http://www.example.com/ourstudio/feeds/house.xml')
12
+
13
+ env.title = 'my example feed'
14
+ env.datastreams << DataStream.new(:value => 93.0, :identifier => 'room.1.humidity')
15
+ env.datastreams << DataStream.new(:value => 91.0, :identifier => 'room.2.humidity')
16
+
17
+ #print out its eeml representation
18
+ puts env.to_eeml
19
+
20
+
21
+ #Example: parse an environment from an eeml doc:
22
+ eeml_str = File.read('test/data/doc_1.xml')
23
+ env2 = Environment.new_from_eeml(eeml_str)
24
+ env2.datastreams.each do |ds|
25
+ puts "ds %8s value is %6s (min:%8s, max:%8s)" %[ds.identifier, ds.value, ds.min_value, ds.max_value]
26
+ end
27
+
28
+ #TODO: Example: http-fetch an environment
29
+
30
+ #TODO: Example: publish an environment to pachube
31
+
32
+ #TODO: Example: configure a different logger (to file; to stderr; different timestamp / format; use an existing rails logger)
33
+
data/lib/blank.rb ADDED
@@ -0,0 +1,50 @@
1
+ class Object
2
+ # An object is blank if it's nil, empty, or a whitespace string.
3
+ # For example, "", " ", nil, [], and {} are blank.
4
+ #
5
+ # This simplifies
6
+ # if !address.nil? && !address.empty?
7
+ # to
8
+ # if !address.blank?
9
+ def blank?
10
+ respond_to?(:empty?) ? empty? : !self
11
+ end
12
+ end
13
+
14
+ class NilClass #:nodoc:
15
+ def blank?
16
+ true
17
+ end
18
+ end
19
+
20
+ class FalseClass #:nodoc:
21
+ def blank?
22
+ true
23
+ end
24
+ end
25
+
26
+ class TrueClass #:nodoc:
27
+ def blank?
28
+ false
29
+ end
30
+ end
31
+
32
+ class Array #:nodoc:
33
+ alias_method :blank?, :empty?
34
+ end
35
+
36
+ class Hash #:nodoc:
37
+ alias_method :blank?, :empty?
38
+ end
39
+
40
+ class String #:nodoc:
41
+ def blank?
42
+ self !~ /\S/
43
+ end
44
+ end
45
+
46
+ class Numeric #:nodoc:
47
+ def blank?
48
+ false
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ module Eeml
2
+ module Constants
3
+ #LOCAL_EEML_SCHEMA_LOCATION = "schemas/eeml/005.xsd"
4
+ EEML_HREF = "http://www.eeml.org/xsd/005"
5
+ EEML_VERSION = "5"
6
+ EEML_SCHEMA_LOCATION = "http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"
7
+
8
+ EEML_NAMESPACE = ":#{EEML_HREF}"
9
+ XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance"
10
+
11
+ #TODO: better encapsulated as a set of methods.
12
+ XML_TIME_FORMAT_STRING = "%Y-%m-%dT%H:%M:%SZ"
13
+
14
+ DEFAULT_HOST = 'pachube.com'
15
+ end
16
+ end
17
+
@@ -0,0 +1,16 @@
1
+ module Eeml
2
+ class CsvParser
3
+
4
+ #update the datastreams for the given environment, using the content in the given csv string.
5
+ def update_datastreams_from_csv(csv_content, environment)
6
+ # split values at commas
7
+ datastream_values = csv_content.split(/,/)
8
+
9
+ # now strip any whitespace
10
+ datastream_values.map! { |d| d.strip }
11
+
12
+ logger.debug("*** New datastream values: #{datastream_values}")
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,113 @@
1
+ module Eeml
2
+ include Eeml::Constants
3
+
4
+ class Location
5
+ attr_accessor :name, :latitude, :longitude, :elevation
6
+ attr_accessor :domain, :exposure, :disposition
7
+ end
8
+
9
+ class DataStream
10
+ # include FeedOutput::DataStreamNode
11
+ attr_accessor :identifier, :value, :tags, :min_value, :max_value, :unit_symbol, :unit_type, :unit_value
12
+
13
+ def initialize(options = {})
14
+ @identifier = options[:identifier]
15
+ @value = options[:value]
16
+ @max_value = options[:max_value]
17
+ @min_value = options[:min_value]
18
+ @tags = []
19
+ @unit_symbol = options[:unit_symbol]
20
+ @unit_type = options[:unit_type]
21
+ @unit_value = options[:unit_value]
22
+ end
23
+
24
+ def to_s
25
+ "identifier: '#{@identifier}', value: '#{@value}', min_value: '#{@min_value}', max_value: '#{@max_value}', tags: '#{@tags.join(", ")}'"
26
+ end
27
+
28
+ end
29
+
30
+ class Environment
31
+ include FeedOutput::EnvironmentNode
32
+ attr_accessor :identifier, :updated, :creator
33
+ attr_accessor :title, :description, :feed_url, :website, :email, :icon, :status
34
+ attr_accessor :location
35
+ attr_accessor :datastreams
36
+
37
+ # stuff so far needed only for FeedOutput module
38
+ # attr_accessor :retrieved_at
39
+
40
+ @@logger = nil
41
+ def self.logger=(logger)
42
+ @@logger = logger
43
+ end
44
+
45
+ def logger
46
+ return @@logger
47
+ end
48
+
49
+ def initialize(options = {})
50
+ @datastreams = []
51
+ @identifier = options[:identifier]
52
+ @creator = options[:creator]
53
+ @title = options[:title]
54
+ @status = options[:status]
55
+ @feed_url = options[:feed_url]
56
+ end
57
+
58
+ def add_datastream(datastream)
59
+ #TODO: consider checking for unique identifier
60
+ datastreams << datastream
61
+ end
62
+
63
+ def remove_last_datastream
64
+ datastreams.pop
65
+ end
66
+
67
+ def self.new_from_eeml(xml_str)
68
+ parser = ParserRegistry.get_xml_parser_for(xml_str)
69
+ return parser.make_environment_from_xml(xml_str)
70
+ end
71
+
72
+ def self.new_from_json(json_str)
73
+ parser = ParserRegistry.get_json_parser_for(json_str)
74
+ return parser.make_environment_from_json(json_str)
75
+ end
76
+
77
+ def update_datastreams_from_csv_values!(csv_values)
78
+
79
+ csv_values.each_with_index do |new_val, index|
80
+ datastream = datastreams[index]
81
+ #if we don't have an existing datastream at same index, create new one
82
+ if datastream.nil?
83
+ self.datastreams << DataStream.new(:identifier => index, :value => new_val, :ordering => index)
84
+ else
85
+ #we had a match, so update the existing datastream
86
+ datastream.value = new_val
87
+ end
88
+ end
89
+
90
+ # if the csv specifies FEWER feeds than the env currently has.
91
+ if csv_values.size < self.datastreams.size
92
+ # remove the excess from the end of the env's list.
93
+ num_extra = datastreams.size - csv_values.size
94
+ 1.upto(num_extra) { remove_last_datastream }
95
+ end
96
+ end
97
+
98
+ #--------------------------------------------------------------------------
99
+ #----- state tracking stuff -----------------------------------------------
100
+ #--------------------------------------------------------------------------
101
+ def live?
102
+ #TODO
103
+ true
104
+ end
105
+
106
+ def to_eeml(version = Constants::EEML_VERSION)
107
+ outputter = OutputRegistry.get_xml_output_for(version)
108
+ outputter.to_eeml(self)
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,59 @@
1
+ module Eeml
2
+ # exceptions
3
+ #TODO: have these inherit from a base parser error
4
+ class Unavailable < StandardError; end
5
+ class BadResponse < StandardError; end
6
+ class ApiKeyMissing < StandardError; end
7
+ class AuthenticationFailure < StandardError; end
8
+
9
+ class BadEeml < StandardError #eeml being parsed was ok xml but bad eeml
10
+ attr_accessor :line_num, :node_name #no guarantees either is available
11
+ def to_s
12
+ extras = []
13
+ extras << " node name: '" + node_name + "'" if node_name
14
+ extras << " line_num: #{line_num}" if line_num
15
+ super.to_s + extras.join(',')
16
+ end
17
+ end
18
+
19
+ class BadXML < StandardError; end #xml being parsed was malformed
20
+ class DataMissingValue < BadEeml; end
21
+ class DataHasMultipleUnits < BadEeml; end
22
+ class DataHasMultipleValues < BadEeml; end
23
+ class NoDataStreams < BadEeml; end
24
+
25
+
26
+ #A structured exception which holds info about what was missing and from where.
27
+ #Note: Some reasons we don't just hold everything in an unstructured exception message:
28
+ #1. some bits might be useful for dev but not for the public,
29
+ #2. testing is simplified by having the missing node name recorded explicitly (rather than in a human-readable, changeable string).
30
+ class MissingNode < BadEeml
31
+ attr_accessor :base_node_name, :sought_description, :sought_xpath
32
+
33
+ def initialize(base_node_name, sought_description, sought_xpath = nil)
34
+ @base_node_name = base_node_name
35
+ @sought_description = sought_description
36
+ @sought_xpath = sought_xpath
37
+ end
38
+
39
+ def to_s
40
+ "Missing '#@sought_description' node from base node: '#@base_node_name'" +
41
+ (@sought_xpath ? "with xpath: '#@sought_xpath'" : "")
42
+ end
43
+ end
44
+
45
+
46
+ class MissingAttribute < BadEeml
47
+ attr_accessor :node_name, :attribute_name
48
+
49
+ def initialize(node_name, attribute_name)
50
+ @node_name = node_name
51
+ @attribute_name = attribute_name
52
+ end
53
+
54
+ def to_s
55
+ "Missing attribute '#@attribute_name' from node '#@node_name'"
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,169 @@
1
+ module FeedOutput # :nodoc:
2
+ #TODO: move away from mixins for this functionality.
3
+ #TODO: This is v005-specific.
4
+ module EnvironmentNode # :nodoc:
5
+ include LibXML
6
+ #assumes a logger()
7
+ #assumes retrieved_at()
8
+
9
+ #TODO: Move these (now unused) methods to the publisher (e.g. a rails controller?) which will decide where it's going to host the env,
10
+ # and which will set the feed property accordingly before serialising the env.
11
+ # def public_feed_url
12
+ # return "http://#{DEFAULT_HOST}/api/#{self.id}.xml"
13
+ # end
14
+
15
+ # def public_csv_url
16
+ # return "http://#{DEFAULT_HOST}/api/#{self.id}.csv"
17
+ # end
18
+
19
+ # def public_json_url
20
+ # return "http://#{DEFAULT_HOST}/api/#{self.id}.json"
21
+ # end
22
+
23
+
24
+ def create_eeml_document
25
+ doc = XML::Document.new
26
+ eeml = doc.root = XML::Node.new('eeml')
27
+ XML::Namespace.new(eeml, nil, Eeml::EEML_HREF)
28
+ XML::Namespace.new(eeml, 'xsi', Eeml::XSI_NAMESPACE)
29
+ eeml['version'] = Eeml::EEML_VERSION
30
+ eeml['xsi:schemaLocation'] = Eeml::EEML_SCHEMA_LOCATION
31
+ return doc
32
+ end
33
+
34
+ # Create a csv representation of this environment by iterating through all datastreams and returning
35
+ # their values.
36
+ def to_csv
37
+ return self.datastreams.map { |d| d.value }.join(",")
38
+ end
39
+
40
+ # Create an xml representation of this environment. The document returned should be valid EEML.
41
+ # def to_eeml(options = { :full => true })
42
+ # # Returns the public feed URL for this environment.
43
+
44
+
45
+ # logger.debug("*** Returning eeml representation of environment: #{self.identifier}")
46
+
47
+ # doc = create_eeml_document
48
+
49
+ # doc.root << to_xml_node(options)
50
+
51
+ # return doc.to_s(:encoding => XML::Encoding::UTF_8)
52
+ # end
53
+
54
+ def to_xml_node_old(options = { :full => true })
55
+ logger.debug("*** Creating xml node for environment: #{self.identifier}")
56
+
57
+ environment_node = XML::Node.new('environment')
58
+ #TODO: this was retrieved_at in the db, but it's 'updated' in the xml. Clarify w sam...
59
+ # ... env.retrieved_at doesn't make much sense to clients generating eeml using the gem.
60
+ environment_node['updated'] = self.updated.strftime(XML_TIME_FORMAT_STRING) unless self.updated.nil?
61
+ environment_node['id'] = self.identifier.to_s unless self.identifier.blank?
62
+ #TODO: write all these strings out safely for xml
63
+ environment_node['creator'] = self.creator.to_s unless self.creator.blank?
64
+
65
+ #TODO: these all should really appear, even when absent? likely make conditional.
66
+ unless self.title.blank?
67
+ environment_node << title_node = XML::Node.new('title')
68
+ title_node << self.title
69
+ end
70
+
71
+ unless self.feed_url.blank?
72
+ environment_node << feed_node = XML::Node.new('feed')
73
+ feed_node << self.feed_url
74
+ end
75
+
76
+ unless self.status.blank?
77
+ environment_node << status_node = XML::Node.new('status')
78
+ status_node << self.status
79
+ end
80
+
81
+ unless self.description.blank?
82
+ environment_node << description_node = XML::Node.new('description')
83
+ description_node << self.description
84
+ end
85
+
86
+ unless self.icon.blank?
87
+ environment_node << icon_node = XML::Node.new('icon')
88
+ icon_node << self.icon
89
+ end
90
+
91
+ unless self.website.blank?
92
+ environment_node << website_node = XML::Node.new('website')
93
+ website_node << self.website
94
+ end
95
+
96
+ unless self.email.blank?
97
+ environment_node << email_node = XML::Node.new('email')
98
+ email_node << self.email
99
+ end
100
+
101
+ unless self.location.nil?
102
+ environment_node << location_node = XML::Node.new('location')
103
+ location_node['domain'] = self.location.domain
104
+ location_node['exposure'] = self.location.exposure unless self.location.exposure.blank?
105
+ location_node['disposition'] = self.location.disposition unless self.location.disposition.blank?
106
+
107
+ unless self.location.name.blank?
108
+ location_node << location_name_node = XML::Node.new('name')
109
+ location_name_node << self.location.name
110
+ end
111
+
112
+ location_node << lat_node = XML::Node.new('lat')
113
+ lat_node << self.location.latitude
114
+
115
+ location_node << lng_node = XML::Node.new('lon')
116
+ lng_node << self.location.longitude
117
+
118
+ unless self.location.elevation.blank?
119
+ location_node << elevation_node = XML::Node.new('ele')
120
+ elevation_node << self.location.elevation
121
+ end
122
+ end
123
+
124
+ if options[:full] == true
125
+ self.datastreams.each do |datastream|
126
+ environment_node << datastream.to_xml_node unless datastream.nil?
127
+ end
128
+ end
129
+
130
+ return environment_node
131
+ end
132
+ end
133
+
134
+
135
+
136
+ module DataStreamNode # :nodoc:
137
+ include LibXML
138
+ # Create and return an XML::Node object representing this datastream. This method creates all
139
+ # required child nodes of the datastream object, including the list of tag elements, any units element
140
+ # and the value.
141
+ def to_xml_node
142
+ datastream_node = XML::Node.new('data')
143
+ datastream_node['id'] = self.identifier.to_s
144
+
145
+ self.tags.each do |tag|
146
+ tag_node = XML::Node.new('tag')
147
+ tag_node << tag
148
+ datastream_node << tag_node
149
+ end
150
+
151
+ datastream_node << value_node = XML::Node.new('value')
152
+
153
+ value_node['minValue'] = self.min_value.to_s unless self.min_value.to_s.empty?
154
+ value_node['maxValue'] = self.max_value.to_s unless self.max_value.to_s.empty?
155
+
156
+ value_node << self.value.to_s
157
+
158
+ unless self.unit_value.to_s.empty? && self.unit_type.to_s.empty? && self.unit_symbol.to_s.empty?
159
+ datastream_node << unit_node = XML::Node.new('unit')
160
+ unit_node['type'] = self.unit_type.to_s unless self.unit_type.to_s.empty?
161
+ unit_node['symbol'] = self.unit_symbol.to_s unless self.unit_symbol.to_s.empty?
162
+ unit_node << self.unit_value.to_s unless self.unit_value.to_s.empty?
163
+ end
164
+
165
+ return datastream_node
166
+ end
167
+ end
168
+
169
+ end