dcc 0.2.0 → 0.2.1

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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +19 -0
  3. data/.github/workflows/release.yml +28 -0
  4. data/.gitignore +4 -0
  5. data/.rubocop_todo.yml +560 -10
  6. data/CHANGELOG.adoc +34 -1
  7. data/CONTRIBUTING.adoc +8 -1
  8. data/Gemfile +5 -7
  9. data/README.adoc +162 -7
  10. data/dcc.gemspec +8 -2
  11. data/docs/schema-versions.adoc +20 -7
  12. data/examples/build_minimal_dcc.rb +0 -0
  13. data/examples/convert_all_formats.rb +2 -1
  14. data/examples/parse_and_inspect.rb +0 -0
  15. data/examples/quantity_math_demo.rb +7 -7
  16. data/examples/validate_full.rb +1 -1
  17. data/lib/dcc/base/calibration_laboratory.rb +2 -1
  18. data/lib/dcc/base/condition.rb +5 -2
  19. data/lib/dcc/base/core_data.rb +8 -3
  20. data/lib/dcc/base/formula.rb +3 -3
  21. data/lib/dcc/base/identification.rb +6 -3
  22. data/lib/dcc/base/mathml.rb +33 -0
  23. data/lib/dcc/base/quantity.rb +2 -1
  24. data/lib/dcc/base/resp_person.rb +4 -2
  25. data/lib/dcc/base/text.rb +1 -1
  26. data/lib/dcc/base.rb +2 -1
  27. data/lib/dcc/builder/dsl.rb +1 -1
  28. data/lib/dcc/builder/session.rb +16 -14
  29. data/lib/dcc/builder.rb +3 -3
  30. data/lib/dcc/cli/cli.rb +36 -18
  31. data/lib/dcc/cli/formatters.rb +35 -7
  32. data/lib/dcc/cli.rb +1 -1
  33. data/lib/dcc/context_configuration.rb +2 -1
  34. data/lib/dcc/context_options.rb +4 -2
  35. data/lib/dcc/convert/csv.rb +27 -9
  36. data/lib/dcc/convert/html.rb +26 -110
  37. data/lib/dcc/convert/json.rb +10 -7
  38. data/lib/dcc/convert/liquid_filters.rb +58 -0
  39. data/lib/dcc/convert/result.rb +1 -1
  40. data/lib/dcc/convert/templates/report.liquid +250 -0
  41. data/lib/dcc/convert/yaml.rb +1 -1
  42. data/lib/dcc/convert.rb +1 -0
  43. data/lib/dcc/diff/change.rb +1 -1
  44. data/lib/dcc/diff/result.rb +8 -4
  45. data/lib/dcc/diff.rb +43 -11
  46. data/lib/dcc/error.rb +7 -0
  47. data/lib/dcc/extract/file.rb +3 -4
  48. data/lib/dcc/extract/ring.rb +1 -1
  49. data/lib/dcc/extract.rb +1 -1
  50. data/lib/dcc/i18n/text_lookup.rb +8 -4
  51. data/lib/dcc/i18n.rb +1 -1
  52. data/lib/dcc/inspect/report.rb +51 -14
  53. data/lib/dcc/inspect.rb +1 -1
  54. data/lib/dcc/migrate/route.rb +44 -0
  55. data/lib/dcc/migrate/v2_to_v3.rb +445 -0
  56. data/lib/dcc/migrate.rb +130 -26
  57. data/lib/dcc/plugin/base.rb +64 -0
  58. data/lib/dcc/plugin/registry.rb +7 -2
  59. data/lib/dcc/plugin.rb +6 -2
  60. data/lib/dcc/quantity_format/formatter.rb +16 -10
  61. data/lib/dcc/quantity_format.rb +1 -1
  62. data/lib/dcc/quantity_math/quantity.rb +1 -1
  63. data/lib/dcc/quantity_math/real.rb +6 -6
  64. data/lib/dcc/quantity_math.rb +1 -1
  65. data/lib/dcc/schema/version.rb +2 -2
  66. data/lib/dcc/server/app.html +282 -0
  67. data/lib/dcc/server/app.rb +171 -87
  68. data/lib/dcc/server/demo_cert.xml +244 -0
  69. data/lib/dcc/server/storage/entry.rb +1 -1
  70. data/lib/dcc/server/storage/memory.rb +3 -2
  71. data/lib/dcc/server/storage.rb +1 -1
  72. data/lib/dcc/server.rb +1 -1
  73. data/lib/dcc/si/base/complex.rb +1 -1
  74. data/lib/dcc/si/base/complex_list_xml_list.rb +1 -1
  75. data/lib/dcc/si/base/constant.rb +1 -1
  76. data/lib/dcc/si/base/coverage_interval.rb +36 -0
  77. data/lib/dcc/si/base/coverage_interval_mu.rb +1 -1
  78. data/lib/dcc/si/base/expanded_mu.rb +1 -1
  79. data/lib/dcc/si/base/expanded_unc.rb +34 -0
  80. data/lib/dcc/si/base/expanded_unc_xml_list.rb +3 -2
  81. data/lib/dcc/si/base/hybrid.rb +3 -2
  82. data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +1 -1
  83. data/lib/dcc/si/base/real.rb +13 -3
  84. data/lib/dcc/si/base/real_list_xml_list.rb +5 -3
  85. data/lib/dcc/si/base/si_list.rb +3 -2
  86. data/lib/dcc/si/base/standard_mu.rb +1 -1
  87. data/lib/dcc/si/base.rb +5 -2
  88. data/lib/dcc/si/v1/coverage_interval.rb +8 -0
  89. data/lib/dcc/si/v1/expanded_unc.rb +1 -16
  90. data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +2 -1
  91. data/lib/dcc/si/v1.rb +5 -2
  92. data/lib/dcc/si/v2/coverage_interval.rb +8 -0
  93. data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +4 -2
  94. data/lib/dcc/si/v2/expanded_mu_xml_list.rb +2 -1
  95. data/lib/dcc/si/v2/expanded_unc.rb +8 -0
  96. data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +2 -1
  97. data/lib/dcc/si/v2.rb +8 -3
  98. data/lib/dcc/signature/result.rb +2 -2
  99. data/lib/dcc/signature/signer.rb +31 -18
  100. data/lib/dcc/signature/verifier.rb +23 -21
  101. data/lib/dcc/signature.rb +1 -1
  102. data/lib/dcc/transform/result.rb +1 -1
  103. data/lib/dcc/transform/xslt.rb +22 -12
  104. data/lib/dcc/transform.rb +5 -4
  105. data/lib/dcc/type/base64_binary.rb +5 -3
  106. data/lib/dcc/type/decimal_xml_list.rb +99 -13
  107. data/lib/dcc/type/iso_country_code.rb +3 -2
  108. data/lib/dcc/type/iso_language_code.rb +3 -2
  109. data/lib/dcc/type/schema_version.rb +3 -2
  110. data/lib/dcc/type/si_unit.rb +3 -2
  111. data/lib/dcc/type_guards.rb +3 -3
  112. data/lib/dcc/v2/calibration_laboratory.rb +2 -1
  113. data/lib/dcc/v2/condition.rb +22 -1
  114. data/lib/dcc/v2/configuration.rb +1 -1
  115. data/lib/dcc/v2/digital_calibration_certificate.rb +2 -1
  116. data/lib/dcc/v2/identification.rb +14 -1
  117. data/lib/dcc/v2/mathml.rb +8 -0
  118. data/lib/dcc/v2/measurement_meta_data_list.rb +2 -1
  119. data/lib/dcc/v2/quantity.rb +4 -2
  120. data/lib/dcc/v2.rb +4 -2
  121. data/lib/dcc/v3/calibration_laboratory.rb +2 -1
  122. data/lib/dcc/v3/configuration.rb +1 -1
  123. data/lib/dcc/v3/digital_calibration_certificate.rb +2 -1
  124. data/lib/dcc/v3/mathml.rb +8 -0
  125. data/lib/dcc/v3/measurement_meta_data_list.rb +2 -1
  126. data/lib/dcc/v3/quantity.rb +4 -2
  127. data/lib/dcc/v3.rb +12 -2
  128. data/lib/dcc/validate/business_rules.rb +23 -9
  129. data/lib/dcc/validate/issue.rb +2 -1
  130. data/lib/dcc/validate/result.rb +6 -4
  131. data/lib/dcc/validate/schematron/profile.rb +73 -18
  132. data/lib/dcc/validate/schematron/rule.rb +13 -3
  133. data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +11 -4
  134. data/lib/dcc/validate/schematron/rules/base.rb +1 -2
  135. data/lib/dcc/validate/schematron/rules/date_range_check.rb +11 -5
  136. data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +0 -3
  137. data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +22 -12
  138. data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +31 -14
  139. data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +12 -5
  140. data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +7 -4
  141. data/lib/dcc/validate/schematron/rules/release_format_check.rb +7 -4
  142. data/lib/dcc/validate/schematron/rules/schema_version_check.rb +13 -9
  143. data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +39 -10
  144. data/lib/dcc/validate/schematron/rules/unit_format_check.rb +2 -3
  145. data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +15 -10
  146. data/lib/dcc/validate/schematron/rules/used_software_placement.rb +15 -10
  147. data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +4 -3
  148. data/lib/dcc/validate/schematron/rules.rb +28 -14
  149. data/lib/dcc/validate/schematron.rb +1 -1
  150. data/lib/dcc/validate/xsd.rb +9 -3
  151. data/lib/dcc/validate.rb +1 -1
  152. data/lib/dcc/version.rb +1 -1
  153. data/lib/dcc/versioned_parser.rb +1 -1
  154. data/lib/dcc.rb +55 -7
  155. data/sample_dcc.xml +140 -0
  156. data/web/index.html +12 -0
  157. data/web/package-lock.json +1599 -0
  158. data/web/package.json +22 -0
  159. data/web/src/App.vue +349 -0
  160. data/web/src/lib/builder.ts +171 -0
  161. data/web/src/lib/dcc.ts +338 -0
  162. data/web/src/lib/units.json +5581 -0
  163. data/web/src/main.ts +5 -0
  164. data/web/src/style.css +27 -0
  165. data/web/tsconfig.json +15 -0
  166. data/web/vite.config.ts +14 -0
  167. metadata +125 -9
@@ -1,133 +1,217 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Loads Sinatra lazily so the gem works without it installed.
4
3
  begin
5
4
  require "sinatra/base"
6
5
  SINATRA_AVAILABLE = true
7
- rescue ::LoadError
6
+ rescue LoadError
8
7
  SINATRA_AVAILABLE = false
9
8
  end
10
9
 
11
10
  module Dcc
12
11
  module Server
13
- # Sinatra application exposing the DCC REST API. Mirrors PTB dcclib's
14
- # endpoints: POST /dccs, GET /dccs/:id, DELETE /dccs/:id,
15
- # POST /dccs/:id/validate/{xsd,schematron}, /convert/json,
16
- # /extract/{files,formulae}, /signature, /transform/xslt.
17
- #
18
- # Run via:
19
- # require "dcc/server"
20
- # Dcc::Server::App.run!
21
12
  class App < ::Sinatra::Base
22
- before do
23
- content_type :json
24
- end
25
-
26
- # Storage instance — override in config.ru for production swaps.
27
- set :storage, ::Dcc::Server::Storage::Memory.new
13
+ set :public_folder, File.expand_path("server", __dir__)
28
14
 
29
15
  get "/" do
30
- {
31
- title: "dcc gem REST API",
32
- version: ::Dcc::VERSION,
33
- endpoints: [
34
- "POST /dccs",
35
- "GET /dccs/:id",
36
- "DELETE /dccs/:id",
37
- "POST /dccs/:id/validate/xsd",
38
- "POST /dccs/:id/validate/schematron",
39
- "POST /dccs/:id/convert/json",
40
- "GET /dccs/:id/extract/files",
41
- "POST /dccs/:id/transform/xslt",
42
- ],
43
- }.to_json
16
+ content_type :html
17
+ File.read(File.expand_path("app.html", __dir__))
44
18
  end
45
19
 
46
- post "/dccs" do
47
- ensure_loaded!
48
- body = JSON.parse(request.body.read)
49
- xml = body.fetch("xml")
50
- entry = settings.storage.put(xml)
51
- status 201
52
- { id: entry.id, expires: entry.expires_at }.to_json
53
- rescue ::KeyError
54
- status 400
55
- { error: "missing 'xml' in request body" }.to_json
20
+ get "/demo.xml" do
21
+ content_type :xml
22
+ File.read(File.expand_path("demo_cert.xml", __dir__))
56
23
  end
57
24
 
58
- get "/dccs/:id" do
59
- entry = settings.storage.get(params[:id])
60
- halt 404, { error: "not found" }.to_json unless entry
25
+ post "/validate" do
26
+ ensure_loaded!
27
+ xml = request.body.read
28
+ content_type :json
29
+
30
+ cert_data = extract_cert_data(xml)
31
+ validation = run_validation(xml)
61
32
 
62
- { id: entry.id, xml: entry.xml, expires: entry.expires_at }.to_json
33
+ { cert: cert_data, validation: validation }.to_json
34
+ rescue StandardError => e
35
+ content_type :json
36
+ status 500
37
+ { error: e.message }.to_json
63
38
  end
64
39
 
65
- delete "/dccs/:id" do
66
- deleted = settings.storage.delete(params[:id])
67
- halt 404, { error: "not found" }.to_json unless deleted
40
+ private
41
+
42
+ def ensure_loaded!
43
+ return if @loaded
68
44
 
69
- status 204
45
+ ::Dcc.load_all!
46
+ @loaded = true
70
47
  end
71
48
 
72
- post "/dccs/:id/validate/xsd" do
73
- result = with_dcc(params[:id]) { |xml| ::Dcc::Validate::Xsd.call(xml) }
74
- result.to_json
49
+ def extract_cert_data(xml)
50
+ hash = ::Dcc::Convert::Json.xml_to_hash(xml)
51
+ admin = hash["administrativeData"] || {}
52
+ core = admin["coreData"] || {}
53
+ items = admin["items"] || {}
54
+ item = items["item"].is_a?(::Array) ? items["item"].first : items["item"]
55
+ item ||= {}
56
+ lab = admin["calibrationLaboratory"] || {}
57
+ lab_contact = lab["contact"] || {}
58
+
59
+ {
60
+ schemaVersion: hash["schemaVersion"],
61
+ uniqueId: core["uniqueIdentifier"],
62
+ country: core["countryCodeISO3166_1"],
63
+ itemName: text(item["name"]),
64
+ labName: text(lab_contact["name"]),
65
+ coreData: build_core_data(core),
66
+ lab: {
67
+ name: text(lab_contact["name"]),
68
+ email: lab_contact["eMail"],
69
+ address: build_address(lab_contact["location"]),
70
+ },
71
+ signers: build_signers(admin["respPersons"]),
72
+ measurements: build_measurements(hash["measurementResults"]),
73
+ }
75
74
  end
76
75
 
77
- post "/dccs/:id/validate/schematron" do
78
- result = with_dcc(params[:id]) { |xml| ::Dcc::Validate::Schematron.call(::Dcc.parse(xml)) }
79
- result.to_json
76
+ def text(node)
77
+ return "" unless node
78
+
79
+ c = node.is_a?(::Hash) ? node["content"] : node
80
+ return "" unless c
81
+
82
+ case c
83
+ when ::String then c
84
+ when ::Array
85
+ entry = c.find { |e| e.is_a?(::Hash) }
86
+ entry ? (entry["_text"] || "") : ""
87
+ when ::Hash then c["_text"] || ""
88
+ else ""
89
+ end
80
90
  end
81
91
 
82
- post "/dccs/:id/convert/json" do
83
- with_dcc(params[:id]) do |xml|
84
- ::Dcc::Convert::Json.call(::Dcc.parse(xml)).payload
92
+ def build_core_data(core)
93
+ fields = []
94
+ if core["uniqueIdentifier"]
95
+ fields << { label: "Unique ID", value: core["uniqueIdentifier"] }
96
+ end
97
+ if core["beginPerformanceDate"]
98
+ fields << { label: "Begin Date", value: core["beginPerformanceDate"] }
99
+ end
100
+ if core["endPerformanceDate"]
101
+ fields << { label: "End Date", value: core["endPerformanceDate"] }
85
102
  end
103
+ langs = core["usedLangCodeISO639_1"]
104
+ langs_str = case langs
105
+ when ::Array then langs.join(", ")
106
+ when ::String then langs
107
+ else ""
108
+ end
109
+ unless langs_str.empty?
110
+ fields << { label: "Languages",
111
+ value: langs_str }
112
+ end
113
+ fields
114
+ end
115
+
116
+ def build_address(loc)
117
+ return "" unless loc
118
+
119
+ parts = []
120
+ parts << "#{loc['street']} #{loc['streetNo']}" if loc["street"]
121
+ parts << "#{loc['postCode']} #{loc['city']}" if loc["postCode"]
122
+ parts << loc["countryCode"] if loc["countryCode"]
123
+ parts.join(", ")
86
124
  end
87
125
 
88
- get "/dccs/:id/extract/files" do
89
- with_dcc(params[:id]) do |xml|
90
- files = ::Dcc::Extract::File.each(::Dcc.parse(xml))
126
+ def build_signers(resp_persons)
127
+ return [] unless resp_persons
128
+
129
+ rp = resp_persons["respPerson"]
130
+ list = rp.is_a?(::Array) ? rp : [rp]
131
+ list.map do |p|
132
+ person = p["person"] || {}
91
133
  {
92
- files: files.map do |f|
93
- {
94
- name: f.name, file_name: f.file_name,
95
- mime_type: f.mime_type, ring: f.ring.to_s,
96
- data_base64: ::Base64.strict_encode64(f.data),
97
- }
98
- end,
99
- }.to_json
134
+ name: text(person["name"]),
135
+ email: person["eMail"],
136
+ main: p["mainSigner"] == "true",
137
+ }
100
138
  end
101
139
  end
102
140
 
103
- post "/dccs/:id/transform/xslt" do
104
- body = JSON.parse(request.body.read)
105
- xslt = body.fetch("xslt")
106
- with_dcc(params[:id]) do |xml|
107
- ::Dcc::Transform::Xslt.call(xml, xslt).payload
141
+ def build_measurements(mr_hash)
142
+ return [] unless mr_hash
143
+
144
+ mr = mr_hash["measurementResult"]
145
+ list = mr.is_a?(::Array) ? mr : [mr]
146
+ list.map do |m|
147
+ results = []
148
+ if m["results"]
149
+ r = m["results"]["result"]
150
+ r_list = r.is_a?(::Array) ? r : [r]
151
+ r_list.each do |res|
152
+ results << {
153
+ name: text(res["name"]),
154
+ values: extract_quantity_values(res["data"]),
155
+ }
156
+ end
157
+ end
158
+ {
159
+ name: text(m["name"]),
160
+ results: results,
161
+ }
108
162
  end
109
163
  end
110
164
 
111
- private
165
+ def extract_quantity_values(data)
166
+ return [] unless data
112
167
 
113
- def ensure_loaded!
114
- return if @loaded
168
+ values = []
169
+ d = data.is_a?(::Array) ? data.first : data
170
+ return values unless d.is_a?(::Hash)
115
171
 
116
- ::Dcc.load_all!
117
- @loaded = true
172
+ qty = d["quantity"]
173
+ q_list = qty.is_a?(::Array) ? qty : [qty]
174
+ q_list.each do |q|
175
+ next unless q.is_a?(::Hash)
176
+
177
+ real = q["real"]
178
+ next unless real
179
+
180
+ values << {
181
+ value: real["value"],
182
+ unit: real["unit"],
183
+ uncertainty: extract_uncertainty(real),
184
+ }
185
+ end
186
+ values
118
187
  end
119
188
 
120
- def with_dcc(id)
121
- entry = settings.storage.get(id)
122
- halt 404, { error: "not found" }.to_json unless entry
189
+ def extract_uncertainty(real)
190
+ mu = real["expandedMU"] || real["expandedUnc"]
191
+ return nil unless mu
123
192
 
124
- ensure_loaded!
125
- result = yield(entry.xml)
126
- result.is_a?(::String) ? result : result.to_json
193
+ mu["valueExpandedMU"] || mu["uncertainty"]
194
+ end
195
+
196
+ def run_validation(xml)
197
+ xsd_result = ::Dcc::Validate::Xsd.call(xml)
198
+ issues = xsd_result.issues || []
199
+ {
200
+ ok: issues.none? { |i| i.severity == :error },
201
+ errors: issues.select { |i| i.severity == :error }.map do |i|
202
+ { line: i.line, message: i.message }
203
+ end,
204
+ warnings: issues.select { |i| i.severity == :warning }.map do |i|
205
+ { line: i.line, message: i.message }
206
+ end,
207
+ }
208
+ rescue StandardError => e
209
+ {
210
+ ok: false,
211
+ errors: [{ line: nil, message: e.message }],
212
+ warnings: [],
213
+ }
127
214
  end
128
215
  end
129
216
  end
130
217
  end
131
-
132
- require "base64"
133
- require "json"
@@ -0,0 +1,244 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <dcc:digitalCalibrationCertificate
3
+ xmlns:dcc="https://ptb.de/dcc"
4
+ xmlns:si="https://ptb.de/si"
5
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
+ xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.3.0/dcc.xsd"
7
+ schemaVersion="3.3.0">
8
+
9
+ <dcc:administrativeData>
10
+ <dcc:dccSoftware>
11
+ <dcc:software>
12
+ <dcc:name>
13
+ <dcc:content lang="en">DCC Builder Demo</dcc:content>
14
+ </dcc:name>
15
+ <dcc:release>0.2.0</dcc:release>
16
+ </dcc:software>
17
+ </dcc:dccSoftware>
18
+
19
+ <dcc:coreData>
20
+ <dcc:countryCodeISO3166_1>NL</dcc:countryCodeISO3166_1>
21
+ <dcc:usedLangCodeISO639_1>en</dcc:usedLangCodeISO639_1>
22
+ <dcc:usedLangCodeISO639_1>de</dcc:usedLangCodeISO639_1>
23
+ <dcc:mandatoryLangCodeISO639_1>en</dcc:mandatoryLangCodeISO639_1>
24
+ <dcc:uniqueIdentifier>R117-2019-NL1-22.10-Rev2</dcc:uniqueIdentifier>
25
+ <dcc:identifications>
26
+ <dcc:identification>
27
+ <dcc:issuer>calibrationLaboratory</dcc:issuer>
28
+ <dcc:value>OIML-CS-R117-22.10</dcc:value>
29
+ </dcc:identification>
30
+ </dcc:identifications>
31
+ <dcc:beginPerformanceDate>2024-03-15</dcc:beginPerformanceDate>
32
+ <dcc:endPerformanceDate>2024-03-15</dcc:endPerformanceDate>
33
+ </dcc:coreData>
34
+
35
+ <dcc:items>
36
+ <dcc:name>
37
+ <dcc:content lang="en">Coriolis Mass Flow Transducer</dcc:content>
38
+ <dcc:content lang="de">Coriolis-Massendurchfluss-Messumformer</dcc:content>
39
+ </dcc:name>
40
+ <dcc:item id="promass-f-300">
41
+ <dcc:name>
42
+ <dcc:content lang="en">Promass F 300</dcc:content>
43
+ </dcc:name>
44
+ <dcc:equipmentClass>
45
+ <dcc:reference>OIML R117</dcc:reference>
46
+ <dcc:classID>Measurement transducer</dcc:classID>
47
+ </dcc:equipmentClass>
48
+ <dcc:manufacturer>
49
+ <dcc:name>
50
+ <dcc:content lang="en">Endress+Hauser Flowtec AG</dcc:content>
51
+ </dcc:name>
52
+ <dcc:location>
53
+ <dcc:street>Kägenstrasse</dcc:street>
54
+ <dcc:streetNo>7</dcc:streetNo>
55
+ <dcc:postCode>4153</dcc:postCode>
56
+ <dcc:city>Reinach</dcc:city>
57
+ <dcc:countryCode>CH</dcc:countryCode>
58
+ </dcc:location>
59
+ </dcc:manufacturer>
60
+ <dcc:model>Promass F 300 DNx</dcc:model>
61
+ </dcc:item>
62
+ </dcc:items>
63
+
64
+ <dcc:calibrationLaboratory>
65
+ <dcc:calibrationLaboratoryCode>NL1</dcc:calibrationLaboratoryCode>
66
+ <dcc:contact>
67
+ <dcc:name>
68
+ <dcc:content lang="en">NMi Certin B.V.</dcc:content>
69
+ </dcc:name>
70
+ <dcc:eMail>info@nmi.nl</dcc:eMail>
71
+ <dcc:location>
72
+ <dcc:countryCode>NL</dcc:countryCode>
73
+ </dcc:location>
74
+ </dcc:contact>
75
+ </dcc:calibrationLaboratory>
76
+
77
+ <dcc:respPersons>
78
+ <dcc:respPerson>
79
+ <dcc:person>
80
+ <dcc:name>
81
+ <dcc:content lang="en">M. Schmidt, Ph.D.</dcc:content>
82
+ </dcc:name>
83
+ <dcc:eMail>m.schmidt@nmi.nl</dcc:eMail>
84
+ </dcc:person>
85
+ <dcc:description>
86
+ <dcc:content lang="en">Person responsible</dcc:content>
87
+ </dcc:description>
88
+ <dcc:mainSigner>true</dcc:mainSigner>
89
+ </dcc:respPerson>
90
+ </dcc:respPersons>
91
+
92
+ <dcc:customer>
93
+ <dcc:name>
94
+ <dcc:content lang="en">Endress+Hauser Flowtec AG</dcc:content>
95
+ </dcc:name>
96
+ <dcc:location>
97
+ <dcc:street>Kägenstrasse</dcc:street>
98
+ <dcc:streetNo>7</dcc:streetNo>
99
+ <dcc:postCode>4153</dcc:postCode>
100
+ <dcc:city>Reinach</dcc:city>
101
+ <dcc:countryCode>CH</dcc:countryCode>
102
+ </dcc:location>
103
+ </dcc:customer>
104
+
105
+ <dcc:statements>
106
+ <dcc:statement refType="OIML_R117_conformity">
107
+ <dcc:countryCodeISO3166_1>NL</dcc:countryCodeISO3166_1>
108
+ <dcc:convention>OIML-CS</dcc:convention>
109
+ <dcc:declaration>
110
+ <dcc:content lang="en">The certified type conforms to OIML R 117 (2019).</dcc:content>
111
+ </dcc:declaration>
112
+ <dcc:valid>true</dcc:valid>
113
+ </dcc:statement>
114
+ </dcc:statements>
115
+ </dcc:administrativeData>
116
+
117
+ <dcc:measurementResults>
118
+ <dcc:measurementResult>
119
+ <dcc:name>
120
+ <dcc:content lang="en">Mass flow calibration — DN25</dcc:content>
121
+ </dcc:name>
122
+ <dcc:results>
123
+ <dcc:result>
124
+ <dcc:name>
125
+ <dcc:content lang="en">Maximum flow rate</dcc:content>
126
+ </dcc:name>
127
+ <dcc:data>
128
+ <dcc:quantity>
129
+ <dcc:name>
130
+ <dcc:content lang="en">Max mass flow</dcc:content>
131
+ </dcc:name>
132
+ <si:real>
133
+ <si:label>maxFlow</si:label>
134
+ <si:value>300</si:value>
135
+ <si:unit>\kilogram\per\minute</si:unit>
136
+ <si:expandedMU>
137
+ <si:valueExpandedMU>0.15</si:valueExpandedMU>
138
+ <si:coverageFactor>2</si:coverageFactor>
139
+ <si:coverageProbability>0.95</si:coverageProbability>
140
+ </si:expandedMU>
141
+ </si:real>
142
+ </dcc:quantity>
143
+ </dcc:data>
144
+ </dcc:result>
145
+ <dcc:result>
146
+ <dcc:name>
147
+ <dcc:content lang="en">Density range</dcc:content>
148
+ </dcc:name>
149
+ <dcc:data>
150
+ <dcc:quantity>
151
+ <dcc:name>
152
+ <dcc:content lang="en">Density min</dcc:content>
153
+ </dcc:name>
154
+ <si:real>
155
+ <si:label>densityMin</si:label>
156
+ <si:value>300</si:value>
157
+ <si:unit>\kilogram\per\metre\tothe{3}</si:unit>
158
+ </si:real>
159
+ </dcc:quantity>
160
+ <dcc:quantity>
161
+ <dcc:name>
162
+ <dcc:content lang="en">Density max</dcc:content>
163
+ </dcc:name>
164
+ <si:real>
165
+ <si:label>densityMax</si:label>
166
+ <si:value>1400</si:value>
167
+ <si:unit>\kilogram\per\metre\tothe{3}</si:unit>
168
+ </si:real>
169
+ </dcc:quantity>
170
+ </dcc:data>
171
+ </dcc:result>
172
+ <dcc:result>
173
+ <dcc:name>
174
+ <dcc:content lang="en">Temperature range</dcc:content>
175
+ </dcc:name>
176
+ <dcc:data>
177
+ <dcc:quantity>
178
+ <dcc:name>
179
+ <dcc:content lang="en">Temperature min</dcc:content>
180
+ </dcc:name>
181
+ <si:real>
182
+ <si:label>tempMin</si:label>
183
+ <si:value>-40</si:value>
184
+ <si:unit>\degreeCelsius</si:unit>
185
+ </si:real>
186
+ </dcc:quantity>
187
+ <dcc:quantity>
188
+ <dcc:name>
189
+ <dcc:content lang="en">Temperature max</dcc:content>
190
+ </dcc:name>
191
+ <si:real>
192
+ <si:label>tempMax</si:label>
193
+ <si:value>55</si:value>
194
+ <si:unit>\degreeCelsius</si:unit>
195
+ </si:real>
196
+ </dcc:quantity>
197
+ </dcc:data>
198
+ </dcc:result>
199
+ <dcc:result>
200
+ <dcc:name>
201
+ <dcc:content lang="en">Accuracy classes</dcc:content>
202
+ </dcc:name>
203
+ <dcc:data>
204
+ <dcc:list>
205
+ <dcc:name>
206
+ <dcc:content lang="en">Accuracy class ratings</dcc:content>
207
+ </dcc:name>
208
+ <dcc:quantity>
209
+ <dcc:name>
210
+ <dcc:content lang="en">Class 0.3</dcc:content>
211
+ </dcc:name>
212
+ <si:real>
213
+ <si:label>accuracyClass1</si:label>
214
+ <si:value>0.3</si:value>
215
+ <si:unit>\percent</si:unit>
216
+ </si:real>
217
+ </dcc:quantity>
218
+ <dcc:quantity>
219
+ <dcc:name>
220
+ <dcc:content lang="en">Class 0.5</dcc:content>
221
+ </dcc:name>
222
+ <si:real>
223
+ <si:label>accuracyClass2</si:label>
224
+ <si:value>0.5</si:value>
225
+ <si:unit>\percent</si:unit>
226
+ </si:real>
227
+ </dcc:quantity>
228
+ <dcc:quantity>
229
+ <dcc:name>
230
+ <dcc:content lang="en">Class 1.0</dcc:content>
231
+ </dcc:name>
232
+ <si:real>
233
+ <si:label>accuracyClass3</si:label>
234
+ <si:value>1.0</si:value>
235
+ <si:unit>\percent</si:unit>
236
+ </si:real>
237
+ </dcc:quantity>
238
+ </dcc:list>
239
+ </dcc:data>
240
+ </dcc:result>
241
+ </dcc:results>
242
+ </dcc:measurementResult>
243
+ </dcc:measurementResults>
244
+ </dcc:digitalCalibrationCertificate>
@@ -12,4 +12,4 @@ module Dcc
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -20,7 +20,8 @@ module Dcc
20
20
  # @return [Dcc::Server::Storage::Entry]
21
21
  def put(xml)
22
22
  id = ::Digest::SHA256.hexdigest(xml)
23
- entry = Entry.new(id: id, xml: xml, expires_at: Time.now + ttl_seconds)
23
+ entry = Entry.new(id: id, xml: xml,
24
+ expires_at: Time.now + ttl_seconds)
24
25
  @store[id] = entry
25
26
  entry
26
27
  end
@@ -54,4 +55,4 @@ module Dcc
54
55
  end
55
56
  end
56
57
  end
57
- end
58
+ end
@@ -10,4 +10,4 @@ module Dcc
10
10
  autoload :Entry, "dcc/server/storage/entry"
11
11
  end
12
12
  end
13
- end
13
+ end
data/lib/dcc/server.rb CHANGED
@@ -30,4 +30,4 @@ module Dcc
30
30
  "sinatra is required for the REST API"
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -40,4 +40,4 @@ module Dcc
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -36,4 +36,4 @@ module Dcc
36
36
  end
37
37
  end
38
38
  end
39
- end
39
+ end
@@ -36,4 +36,4 @@ module Dcc
36
36
  end
37
37
  end
38
38
  end
39
- end
39
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dcc
4
+ module Si
5
+ module Base
6
+ # `si:coverageIntervalType` — coverage interval stated directly on a real
7
+ # quantity, the sibling of `expandedUnc` in the same xs:choice. The v1
8
+ # form; v2 keeps it as a deprecated alternative.
9
+ module CoverageInterval
10
+ # rubocop:disable Metrics/MethodLength -- one lutaml mapping
11
+ # block, written the same way as every sibling D-SI module.
12
+ def self.included(klass)
13
+ klass.class_eval do
14
+ attribute :standard_unc, :string
15
+ attribute :interval_min, :string
16
+ attribute :interval_max, :string
17
+ attribute :coverage_probability, :string
18
+ attribute :distribution, :string
19
+
20
+ xml do
21
+ namespace ::Dcc::Namespace::Si
22
+ element "coverageInterval"
23
+ ordered
24
+ map_element "standardUnc", to: :standard_unc
25
+ map_element "intervalMin", to: :interval_min
26
+ map_element "intervalMax", to: :interval_max
27
+ map_element "coverageProbability", to: :coverage_probability
28
+ map_element "distribution", to: :distribution
29
+ end
30
+ end
31
+ end
32
+ # rubocop:enable Metrics/MethodLength
33
+ end
34
+ end
35
+ end
36
+ end
@@ -28,4 +28,4 @@ module Dcc
28
28
  end
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -26,4 +26,4 @@ module Dcc
26
26
  end
27
27
  end
28
28
  end
29
- end
29
+ end