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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +19 -0
- data/.github/workflows/release.yml +28 -0
- data/.gitignore +4 -0
- data/.rubocop_todo.yml +560 -10
- data/CHANGELOG.adoc +34 -1
- data/CONTRIBUTING.adoc +8 -1
- data/Gemfile +5 -7
- data/README.adoc +162 -7
- data/dcc.gemspec +8 -2
- data/docs/schema-versions.adoc +20 -7
- data/examples/build_minimal_dcc.rb +0 -0
- data/examples/convert_all_formats.rb +2 -1
- data/examples/parse_and_inspect.rb +0 -0
- data/examples/quantity_math_demo.rb +7 -7
- data/examples/validate_full.rb +1 -1
- data/lib/dcc/base/calibration_laboratory.rb +2 -1
- data/lib/dcc/base/condition.rb +5 -2
- data/lib/dcc/base/core_data.rb +8 -3
- data/lib/dcc/base/formula.rb +3 -3
- data/lib/dcc/base/identification.rb +6 -3
- data/lib/dcc/base/mathml.rb +33 -0
- data/lib/dcc/base/quantity.rb +2 -1
- data/lib/dcc/base/resp_person.rb +4 -2
- data/lib/dcc/base/text.rb +1 -1
- data/lib/dcc/base.rb +2 -1
- data/lib/dcc/builder/dsl.rb +1 -1
- data/lib/dcc/builder/session.rb +16 -14
- data/lib/dcc/builder.rb +3 -3
- data/lib/dcc/cli/cli.rb +36 -18
- data/lib/dcc/cli/formatters.rb +35 -7
- data/lib/dcc/cli.rb +1 -1
- data/lib/dcc/context_configuration.rb +2 -1
- data/lib/dcc/context_options.rb +4 -2
- data/lib/dcc/convert/csv.rb +27 -9
- data/lib/dcc/convert/html.rb +26 -110
- data/lib/dcc/convert/json.rb +10 -7
- data/lib/dcc/convert/liquid_filters.rb +58 -0
- data/lib/dcc/convert/result.rb +1 -1
- data/lib/dcc/convert/templates/report.liquid +250 -0
- data/lib/dcc/convert/yaml.rb +1 -1
- data/lib/dcc/convert.rb +1 -0
- data/lib/dcc/diff/change.rb +1 -1
- data/lib/dcc/diff/result.rb +8 -4
- data/lib/dcc/diff.rb +43 -11
- data/lib/dcc/error.rb +7 -0
- data/lib/dcc/extract/file.rb +3 -4
- data/lib/dcc/extract/ring.rb +1 -1
- data/lib/dcc/extract.rb +1 -1
- data/lib/dcc/i18n/text_lookup.rb +8 -4
- data/lib/dcc/i18n.rb +1 -1
- data/lib/dcc/inspect/report.rb +51 -14
- data/lib/dcc/inspect.rb +1 -1
- data/lib/dcc/migrate/route.rb +44 -0
- data/lib/dcc/migrate/v2_to_v3.rb +445 -0
- data/lib/dcc/migrate.rb +130 -26
- data/lib/dcc/plugin/base.rb +64 -0
- data/lib/dcc/plugin/registry.rb +7 -2
- data/lib/dcc/plugin.rb +6 -2
- data/lib/dcc/quantity_format/formatter.rb +16 -10
- data/lib/dcc/quantity_format.rb +1 -1
- data/lib/dcc/quantity_math/quantity.rb +1 -1
- data/lib/dcc/quantity_math/real.rb +6 -6
- data/lib/dcc/quantity_math.rb +1 -1
- data/lib/dcc/schema/version.rb +2 -2
- data/lib/dcc/server/app.html +282 -0
- data/lib/dcc/server/app.rb +171 -87
- data/lib/dcc/server/demo_cert.xml +244 -0
- data/lib/dcc/server/storage/entry.rb +1 -1
- data/lib/dcc/server/storage/memory.rb +3 -2
- data/lib/dcc/server/storage.rb +1 -1
- data/lib/dcc/server.rb +1 -1
- data/lib/dcc/si/base/complex.rb +1 -1
- data/lib/dcc/si/base/complex_list_xml_list.rb +1 -1
- data/lib/dcc/si/base/constant.rb +1 -1
- data/lib/dcc/si/base/coverage_interval.rb +36 -0
- data/lib/dcc/si/base/coverage_interval_mu.rb +1 -1
- data/lib/dcc/si/base/expanded_mu.rb +1 -1
- data/lib/dcc/si/base/expanded_unc.rb +34 -0
- data/lib/dcc/si/base/expanded_unc_xml_list.rb +3 -2
- data/lib/dcc/si/base/hybrid.rb +3 -2
- data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +1 -1
- data/lib/dcc/si/base/real.rb +13 -3
- data/lib/dcc/si/base/real_list_xml_list.rb +5 -3
- data/lib/dcc/si/base/si_list.rb +3 -2
- data/lib/dcc/si/base/standard_mu.rb +1 -1
- data/lib/dcc/si/base.rb +5 -2
- data/lib/dcc/si/v1/coverage_interval.rb +8 -0
- data/lib/dcc/si/v1/expanded_unc.rb +1 -16
- data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +2 -1
- data/lib/dcc/si/v1.rb +5 -2
- data/lib/dcc/si/v2/coverage_interval.rb +8 -0
- data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +4 -2
- data/lib/dcc/si/v2/expanded_mu_xml_list.rb +2 -1
- data/lib/dcc/si/v2/expanded_unc.rb +8 -0
- data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +2 -1
- data/lib/dcc/si/v2.rb +8 -3
- data/lib/dcc/signature/result.rb +2 -2
- data/lib/dcc/signature/signer.rb +31 -18
- data/lib/dcc/signature/verifier.rb +23 -21
- data/lib/dcc/signature.rb +1 -1
- data/lib/dcc/transform/result.rb +1 -1
- data/lib/dcc/transform/xslt.rb +22 -12
- data/lib/dcc/transform.rb +5 -4
- data/lib/dcc/type/base64_binary.rb +5 -3
- data/lib/dcc/type/decimal_xml_list.rb +99 -13
- data/lib/dcc/type/iso_country_code.rb +3 -2
- data/lib/dcc/type/iso_language_code.rb +3 -2
- data/lib/dcc/type/schema_version.rb +3 -2
- data/lib/dcc/type/si_unit.rb +3 -2
- data/lib/dcc/type_guards.rb +3 -3
- data/lib/dcc/v2/calibration_laboratory.rb +2 -1
- data/lib/dcc/v2/condition.rb +22 -1
- data/lib/dcc/v2/configuration.rb +1 -1
- data/lib/dcc/v2/digital_calibration_certificate.rb +2 -1
- data/lib/dcc/v2/identification.rb +14 -1
- data/lib/dcc/v2/mathml.rb +8 -0
- data/lib/dcc/v2/measurement_meta_data_list.rb +2 -1
- data/lib/dcc/v2/quantity.rb +4 -2
- data/lib/dcc/v2.rb +4 -2
- data/lib/dcc/v3/calibration_laboratory.rb +2 -1
- data/lib/dcc/v3/configuration.rb +1 -1
- data/lib/dcc/v3/digital_calibration_certificate.rb +2 -1
- data/lib/dcc/v3/mathml.rb +8 -0
- data/lib/dcc/v3/measurement_meta_data_list.rb +2 -1
- data/lib/dcc/v3/quantity.rb +4 -2
- data/lib/dcc/v3.rb +12 -2
- data/lib/dcc/validate/business_rules.rb +23 -9
- data/lib/dcc/validate/issue.rb +2 -1
- data/lib/dcc/validate/result.rb +6 -4
- data/lib/dcc/validate/schematron/profile.rb +73 -18
- data/lib/dcc/validate/schematron/rule.rb +13 -3
- data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +11 -4
- data/lib/dcc/validate/schematron/rules/base.rb +1 -2
- data/lib/dcc/validate/schematron/rules/date_range_check.rb +11 -5
- data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +0 -3
- data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +22 -12
- data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +31 -14
- data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +12 -5
- data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +7 -4
- data/lib/dcc/validate/schematron/rules/release_format_check.rb +7 -4
- data/lib/dcc/validate/schematron/rules/schema_version_check.rb +13 -9
- data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +39 -10
- data/lib/dcc/validate/schematron/rules/unit_format_check.rb +2 -3
- data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +15 -10
- data/lib/dcc/validate/schematron/rules/used_software_placement.rb +15 -10
- data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +4 -3
- data/lib/dcc/validate/schematron/rules.rb +28 -14
- data/lib/dcc/validate/schematron.rb +1 -1
- data/lib/dcc/validate/xsd.rb +9 -3
- data/lib/dcc/validate.rb +1 -1
- data/lib/dcc/version.rb +1 -1
- data/lib/dcc/versioned_parser.rb +1 -1
- data/lib/dcc.rb +55 -7
- data/sample_dcc.xml +140 -0
- data/web/index.html +12 -0
- data/web/package-lock.json +1599 -0
- data/web/package.json +22 -0
- data/web/src/App.vue +349 -0
- data/web/src/lib/builder.ts +171 -0
- data/web/src/lib/dcc.ts +338 -0
- data/web/src/lib/units.json +5581 -0
- data/web/src/main.ts +5 -0
- data/web/src/style.css +27 -0
- data/web/tsconfig.json +15 -0
- data/web/vite.config.ts +14 -0
- metadata +125 -9
data/lib/dcc/server/app.rb
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def ensure_loaded!
|
|
43
|
+
return if @loaded
|
|
68
44
|
|
|
69
|
-
|
|
45
|
+
::Dcc.load_all!
|
|
46
|
+
@loaded = true
|
|
70
47
|
end
|
|
71
48
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
165
|
+
def extract_quantity_values(data)
|
|
166
|
+
return [] unless data
|
|
112
167
|
|
|
113
|
-
|
|
114
|
-
|
|
168
|
+
values = []
|
|
169
|
+
d = data.is_a?(::Array) ? data.first : data
|
|
170
|
+
return values unless d.is_a?(::Hash)
|
|
115
171
|
|
|
116
|
-
|
|
117
|
-
|
|
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
|
|
121
|
-
|
|
122
|
-
|
|
189
|
+
def extract_uncertainty(real)
|
|
190
|
+
mu = real["expandedMU"] || real["expandedUnc"]
|
|
191
|
+
return nil unless mu
|
|
123
192
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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>
|
|
@@ -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,
|
|
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
|
data/lib/dcc/server/storage.rb
CHANGED
data/lib/dcc/server.rb
CHANGED
data/lib/dcc/si/base/complex.rb
CHANGED
data/lib/dcc/si/base/constant.rb
CHANGED
|
@@ -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
|