]> git.basschouten.com Git - openhab-addons.git/blob
3ad8494e6e6a4575322b480b07deddce406d6070
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.bluetooth.generic.internal;
14
15 import java.math.BigInteger;
16 import java.util.UUID;
17
18 import javax.measure.Quantity;
19 import javax.measure.Unit;
20 import javax.measure.quantity.Angle;
21 import javax.measure.quantity.Area;
22 import javax.measure.quantity.Dimensionless;
23 import javax.measure.quantity.ElectricCharge;
24 import javax.measure.quantity.Frequency;
25 import javax.measure.quantity.Length;
26 import javax.measure.quantity.Mass;
27 import javax.measure.quantity.Speed;
28
29 import org.eclipse.jdt.annotation.NonNullByDefault;
30 import org.eclipse.jdt.annotation.Nullable;
31 import org.openhab.binding.bluetooth.BluetoothBindingConstants;
32 import org.openhab.core.library.dimension.ArealDensity;
33 import org.openhab.core.library.dimension.VolumetricFlowRate;
34 import org.openhab.core.library.unit.ImperialUnits;
35 import org.openhab.core.library.unit.MetricPrefix;
36 import org.openhab.core.library.unit.SIUnits;
37 import org.openhab.core.library.unit.SmartHomeUnits;
38
39 import tec.uom.se.format.SimpleUnitFormat;
40 import tec.uom.se.function.MultiplyConverter;
41 import tec.uom.se.function.PiMultiplierConverter;
42 import tec.uom.se.function.RationalConverter;
43 import tec.uom.se.unit.ProductUnit;
44 import tec.uom.se.unit.TransformedUnit;
45 import tec.uom.se.unit.Units;
46
47 /**
48  * The {@link BluetoothUnit} maps bluetooth units to openHAB units.
49  *
50  * @author Connor Petty - Initial contribution
51  */
52 @NonNullByDefault
53 public enum BluetoothUnit {
54
55     UNITLESS(0x2700, "org.bluetooth.unit.unitless", SmartHomeUnits.ONE),
56     METRE(0x2701, "org.bluetooth.unit.length.metre", SIUnits.METRE),
57     KILOGRAM(0x2702, "org.bluetooth.unit.mass.kilogram", SIUnits.KILOGRAM),
58     SECOND(0x2703, "org.bluetooth.unit.time.second", SmartHomeUnits.SECOND),
59     AMPERE(0x2704, "org.bluetooth.unit.electric_current.ampere", SmartHomeUnits.AMPERE),
60     KELVIN(0x2705, "org.bluetooth.unit.thermodynamic_temperature.kelvin", SmartHomeUnits.KELVIN),
61     MOLE(0x2706, "org.bluetooth.unit.amount_of_substance.mole", SmartHomeUnits.MOLE),
62     CANDELA(0x2707, "org.bluetooth.unit.luminous_intensity.candela", SmartHomeUnits.CANDELA),
63     SQUARE_METRES(0x2710, "org.bluetooth.unit.area.square_metres", SIUnits.SQUARE_METRE),
64     CUBIC_METRES(0x2711, "org.bluetooth.unit.volume.cubic_metres", SIUnits.CUBIC_METRE),
65     METRE_PER_SECOND(0x2712, "org.bluetooth.unit.velocity.metres_per_second", SmartHomeUnits.METRE_PER_SECOND),
66     METRE_PER_SQUARE_SECOND(0X2713, "org.bluetooth.unit.acceleration.metres_per_second_squared",
67             SmartHomeUnits.METRE_PER_SQUARE_SECOND),
68     WAVENUMBER(0x2714, "org.bluetooth.unit.wavenumber.reciprocal_metre", SmartHomeUnits.ONE),
69     KILOGRAM_PER_CUBIC_METRE(0x2715, "org.bluetooth.unit.density.kilogram_per_cubic_metre",
70             SmartHomeUnits.KILOGRAM_PER_CUBICMETRE),
71     KILOGRAM_PER_SQUARE_METRE(0x2716, "org.bluetooth.unit.surface_density.kilogram_per_square_metre",
72             BUnits.KILOGRAM_PER_SQUARE_METER),
73     CUBIC_METRE_PER_KILOGRAM(0x2717, "org.bluetooth.unit.specific_volume.cubic_metre_per_kilogram", SmartHomeUnits.ONE),
74     AMPERE_PER_SQUARE_METRE(0x2718, "org.bluetooth.unit.current_density.ampere_per_square_metre", SmartHomeUnits.ONE),
75     AMPERE_PER_METRE(0x2719, "org.bluetooth.unit.magnetic_field_strength.ampere_per_metre", SmartHomeUnits.ONE),
76     MOLE_PER_CUBIC_METRE(0x271A, "org.bluetooth.unit.amount_concentration.mole_per_cubic_metre", SmartHomeUnits.ONE),
77     CONCENTRATION_KILOGRAM_PER_CUBIC_METRE(0x271B, "org.bluetooth.unit.mass_concentration.kilogram_per_cubic_metre",
78             SmartHomeUnits.KILOGRAM_PER_CUBICMETRE),
79     CANDELA_PER_SQUARE_METRE(0x271C, "org.bluetooth.unit.luminance.candela_per_square_metre", SmartHomeUnits.ONE),
80     REFRACTIVE_INDEX(0x271D, "org.bluetooth.unit.refractive_index", SmartHomeUnits.ONE),
81     RELATIVE_PERMEABILITY(0x271E, "org.bluetooth.unit.relative_permeability", SmartHomeUnits.ONE),
82     RADIAN(0x2720, "org.bluetooth.unit.plane_angle.radian", SmartHomeUnits.RADIAN),
83     STERADIAN(0x2721, "org.bluetooth.unit.solid_angle.steradian", SmartHomeUnits.STERADIAN),
84     HERTZ(0x2722, "org.bluetooth.unit.frequency.hertz", SmartHomeUnits.HERTZ),
85     NEWTON(0x2723, "org.bluetooth.unit.force.newton", SmartHomeUnits.NEWTON),
86     PASCAL(0x2724, "org.bluetooth.unit.pressure.pascal", SIUnits.PASCAL),
87     JOULE(0x2725, "org.bluetooth.unit.energy.joule", SmartHomeUnits.JOULE),
88     WATT(0x2726, "org.bluetooth.unit.power.watt", SmartHomeUnits.WATT),
89     COULOMB(0x2727, "org.bluetooth.unit.electric_charge.coulomb", SmartHomeUnits.COULOMB),
90     VOLT(0x2728, "org.bluetooth.unit.electric_potential_difference.volt", SmartHomeUnits.VOLT),
91     FARAD(0x2729, "org.bluetooth.unit.capacitance.farad", SmartHomeUnits.FARAD),
92     OHM(0x272A, "org.bluetooth.unit.electric_resistance.ohm", SmartHomeUnits.OHM),
93     SIEMENS(0x272B, "org.bluetooth.unit.electric_conductance.siemens", SmartHomeUnits.SIEMENS),
94     WEBER(0x272C, "org.bluetooth.unit.magnetic_flux.weber", SmartHomeUnits.WEBER),
95     TESLA(0x272D, "org.bluetooth.unit.magnetic_flux_density.tesla", SmartHomeUnits.TESLA),
96     HENRY(0x272E, "org.bluetooth.unit.inductance.henry", SmartHomeUnits.HENRY),
97     DEGREE_CELSIUS(0x272F, "org.bluetooth.unit.thermodynamic_temperature.degree_celsius", SIUnits.CELSIUS),
98     LUMEN(0x2730, "org.bluetooth.unit.luminous_flux.lumen", SmartHomeUnits.LUMEN),
99     LUX(0x2731, "org.bluetooth.unit.illuminance.lux", SmartHomeUnits.LUX),
100     BECQUEREL(0x2732, "org.bluetooth.unit.activity_referred_to_a_radionuclide.becquerel", SmartHomeUnits.BECQUEREL),
101     GRAY(0x2733, "org.bluetooth.unit.absorbed_dose.gray", SmartHomeUnits.GRAY),
102     SIEVERT(0x2734, "org.bluetooth.unit.dose_equivalent.sievert", SmartHomeUnits.SIEVERT),
103     KATAL(0x2735, "org.bluetooth.unit.catalytic_activity.katal", SmartHomeUnits.KATAL),
104     PASCAL_SECOND(0x2740, "org.bluetooth.unit.dynamic_viscosity.pascal_second", SmartHomeUnits.ONE),
105     NEWTON_METRE(0x2741, "org.bluetooth.unit.moment_of_force.newton_metre", SmartHomeUnits.ONE),
106     NEWTON_PER_METRE(0x2742, "org.bluetooth.unit.surface_tension.newton_per_metre", SmartHomeUnits.ONE),
107     RADIAN_PER_SECOND(0x2743, "org.bluetooth.unit.angular_velocity.radian_per_second", SmartHomeUnits.ONE),
108     RADIAN_PER_SECOND_SQUARED(0x2744, "org.bluetooth.unit.angular_acceleration.radian_per_second_squared",
109             SmartHomeUnits.ONE),
110     FLUX_WATT_PER_SQUARE_METRE(0x2745, "org.bluetooth.unit.heat_flux_density.watt_per_square_metre",
111             SmartHomeUnits.ONE),
112     JOULE_PER_KELVIN(0x2746, "org.bluetooth.unit.heat_capacity.joule_per_kelvin", SmartHomeUnits.ONE),
113     JOULE_PER_KILOGRAM_KELVIN(0x2747, "org.bluetooth.unit.specific_heat_capacity.joule_per_kilogram_kelvin",
114             SmartHomeUnits.ONE),
115     JOULE_PER_KILOGRAM(0x2748, "org.bluetooth.unit.specific_energy.joule_per_kilogram", SmartHomeUnits.ONE),
116     WATT_PER_METRE_KELVIN(0x2749, "org.bluetooth.unit.thermal_conductivity.watt_per_metre_kelvin", SmartHomeUnits.ONE),
117     JOULE_PER_CUBIC_METRE(0x274A, "org.bluetooth.unit.energy_density.joule_per_cubic_metre", SmartHomeUnits.ONE),
118     VOLT_PER_METRE(0x274B, "org.bluetooth.unit.electric_field_strength.volt_per_metre", SmartHomeUnits.ONE),
119     CHARGE_DENSITY_COULOMB_PER_CUBIC_METRE(0x274C, "org.bluetooth.unit.electric_charge_density.coulomb_per_cubic_metre",
120             SmartHomeUnits.ONE),
121     CHARGE_DENSITY_COULOMB_PER_SQUARE_METRE(0x274D,
122             "org.bluetooth.unit.surface_charge_density.coulomb_per_square_metre", SmartHomeUnits.ONE),
123     FLUX_DENSITY_COULOMB_PER_SQUARE_METRE(0x274E, "org.bluetooth.unit.electric_flux_density.coulomb_per_square_metre",
124             SmartHomeUnits.ONE),
125     FARAD_PER_METRE(0x274F, "org.bluetooth.unit.permittivity.farad_per_metre", SmartHomeUnits.ONE),
126     HENRY_PER_METRE(0x2750, "org.bluetooth.unit.permeability.henry_per_metre", SmartHomeUnits.ONE),
127     JOULE_PER_MOLE(0x2751, "org.bluetooth.unit.molar_energy.joule_per_mole", SmartHomeUnits.ONE),
128     JOULE_PER_MOLE_KELVIN(0x2752, "org.bluetooth.unit.molar_entropy.joule_per_mole_kelvin", SmartHomeUnits.ONE),
129     COULOMB_PER_KILOGRAM(0x2753, "org.bluetooth.unit.exposure.coulomb_per_kilogram", SmartHomeUnits.ONE),
130     GRAY_PER_SECOND(0x2754, "org.bluetooth.unit.absorbed_dose_rate.gray_per_second", BUnits.GRAY_PER_SECOND),
131     WATT_PER_STERADIAN(0x2755, "org.bluetooth.unit.radiant_intensity.watt_per_steradian", BUnits.WATT_PER_STERADIAN),
132     WATT_PER_STERADIAN_PER_SQUARE_METRE(0x2756, "org.bluetooth.unit.radiance.watt_per_square_metre_steradian",
133             BUnits.WATT_PER_STERADIAN_PER_SQUARE_METRE),
134     KATAL_PER_CUBIC_METRE(0x2757, "org.bluetooth.unit.catalytic_activity_concentration.katal_per_cubic_metre",
135             SmartHomeUnits.ONE),
136     MINUTE(0x2760, "org.bluetooth.unit.time.minute", SmartHomeUnits.MINUTE),
137     HOUR(0x2761, "org.bluetooth.unit.time.hour", SmartHomeUnits.HOUR),
138     DAY(0x2762, "org.bluetooth.unit.time.day", SmartHomeUnits.DAY),
139     ANGLE_DEGREE(0x2763, "org.bluetooth.unit.plane_angle.degree", SmartHomeUnits.DEGREE_ANGLE),
140     ANGLE_MINUTE(0x2764, "org.bluetooth.unit.plane_angle.minute", BUnits.MINUTE_ANGLE),
141     ANGLE_SECOND(0x2765, "org.bluetooth.unit.plane_angle.second", BUnits.SECOND_ANGLE),
142     HECTARE(0x2766, "org.bluetooth.unit.area.hectare", BUnits.HECTARE),
143     LITRE(0x2767, "org.bluetooth.unit.volume.litre", SmartHomeUnits.LITRE),
144     TONNE(0x2768, "org.bluetooth.unit.mass.tonne", MetricPrefix.KILO(SIUnits.KILOGRAM)),
145     BAR(0x2780, "org.bluetooth.unit.pressure.bar", SmartHomeUnits.BAR),
146     MILLIMETRE_OF_MERCURY(0x2781, "org.bluetooth.unit.pressure.millimetre_of_mercury",
147             SmartHomeUnits.MILLIMETRE_OF_MERCURY),
148     ÅNGSTRÖM(0x2782, "org.bluetooth.unit.length.ångström", SmartHomeUnits.ONE),
149     NAUTICAL_MILE(0x2783, "org.bluetooth.unit.length.nautical_mile", BUnits.NAUTICAL_MILE),
150     BARN(0x2784, "org.bluetooth.unit.area.barn", BUnits.BARN),
151     KNOT(0x2785, "org.bluetooth.unit.velocity.knot", SmartHomeUnits.KNOT),
152     NEPER(0x2786, "org.bluetooth.unit.logarithmic_radio_quantity.neper", SmartHomeUnits.ONE),
153     BEL(0x2787, "org.bluetooth.unit.logarithmic_radio_quantity.bel", SmartHomeUnits.ONE),
154     YARD(0x27A0, "org.bluetooth.unit.length.yard", ImperialUnits.YARD),
155     PARSEC(0x27A1, "org.bluetooth.unit.length.parsec", SmartHomeUnits.ONE),
156     INCH(0x27A2, "org.bluetooth.unit.length.inch", ImperialUnits.INCH),
157     FOOT(0x27A3, "org.bluetooth.unit.length.foot", ImperialUnits.FOOT),
158     MILE(0x27A4, "org.bluetooth.unit.length.mile", ImperialUnits.MILE),
159     POUND_FORCE_PER_SQUARE_INCH(0x27A5, "org.bluetooth.unit.pressure.pound_force_per_square_inch", SmartHomeUnits.ONE),
160     KILOMETRE_PER_HOUR(0x27A6, "org.bluetooth.unit.velocity.kilometre_per_hour", SIUnits.KILOMETRE_PER_HOUR),
161     MILES_PER_HOUR(0x27A7, "org.bluetooth.unit.velocity.mile_per_hour", ImperialUnits.MILES_PER_HOUR),
162     REVOLUTION_PER_MINUTE(0x27A8, "org.bluetooth.unit.angular_velocity.revolution_per_minute",
163             BUnits.REVOLUTION_PER_MINUTE),
164     GRAM_CALORIE(0x27A9, "org.bluetooth.unit.energy.gram_calorie", SmartHomeUnits.ONE),
165     KILOGRAM_CALORIE(0x27AA, "org.bluetooth.unit.energy.kilogram_calorie", SmartHomeUnits.ONE),
166     KILOWATT_HOUR(0x27AB, "org.bluetooth.unit.energy.kilowatt_hour", SmartHomeUnits.KILOWATT_HOUR),
167     DEGREE_FAHRENHEIT(0x27AC, "org.bluetooth.unit.thermodynamic_temperature.degree_fahrenheit",
168             ImperialUnits.FAHRENHEIT),
169     PERCENTAGE(0x27AD, "org.bluetooth.unit.percentage", SmartHomeUnits.PERCENT),
170     PER_MILLE(0x27AE, "org.bluetooth.unit.per_mille", SmartHomeUnits.ONE),
171     BEATS_PER_MINUTE(0x27AF, "org.bluetooth.unit.period.beats_per_minute", BUnits.BEATS_PER_MINUTE),
172     AMPERE_HOURS(0x27B0, "org.bluetooth.unit.electric_charge.ampere_hours", BUnits.AMPERE_HOUR),
173     MILLIGRAM_PER_DECILITRE(0x27B1, "org.bluetooth.unit.mass_density.milligram_per_decilitre", SmartHomeUnits.ONE),
174     MILLIMOLE_PER_LITRE(0x27B2, "org.bluetooth.unit.mass_density.millimole_per_litre", SmartHomeUnits.ONE),
175     YEAR(0x27B3, "org.bluetooth.unit.time.year", SmartHomeUnits.YEAR),
176     MONTH(0x27B4, "org.bluetooth.unit.time.month", SmartHomeUnits.ONE),
177     COUNT_PER_CUBIC_METRE(0x27B5, "org.bluetooth.unit.concentration.count_per_cubic_metre", SmartHomeUnits.ONE),
178     WATT_PER_SQUARE_METRE(0x27B6, "org.bluetooth.unit.irradiance.watt_per_square_metre", SmartHomeUnits.IRRADIANCE),
179     MILLILITER_PER_KILOGRAM_PER_MINUTE(0x27B7, "org.bluetooth.unit.transfer_rate.milliliter_per_kilogram_per_minute",
180             SmartHomeUnits.ONE),
181     POUND(0x27B8, "org.bluetooth.unit.mass.pound", BUnits.POUND),
182     METABOLIC_EQUIVALENT(0x27B9, "org.bluetooth.unit.metabolic_equivalent", SmartHomeUnits.ONE),
183     STEP_PER_MINUTE(0x27BA, "org.bluetooth.unit.step_per_minute", BUnits.STEP_PER_MINUTE),
184     STROKE_PER_MINUTE(0x27BC, "org.bluetooth.unit.stroke_per_minute", BUnits.STROKE_PER_MINUTE),
185     KILOMETER_PER_MINUTE(0x27BD, "org.bluetooth.unit.velocity.kilometer_per_minute", BUnits.KILOMETRE_PER_MINUTE),
186     LUMEN_PER_WATT(0x27BE, "org.bluetooth.unit.luminous_efficacy.lumen_per_watt", BUnits.LUMEN_PER_WATT),
187     LUMEN_HOUR(0x27BF, "org.bluetooth.unit.luminous_energy.lumen_hour", BUnits.LUMEN_HOUR),
188     LUX_HOUR(0x27C0, "org.bluetooth.unit.luminous_exposure.lux_hour", BUnits.LUX_HOUR),
189     GRAM_PER_SECOND(0x27C1, "org.bluetooth.unit.mass_flow.gram_per_second", BUnits.GRAM_PER_SECOND),
190     LITRE_PER_SECOND(0x27C2, "org.bluetooth.unit.volume_flow.litre_per_second", BUnits.LITRE_PER_SECOND),
191     DECIBEL_SPL(0x27C3, "org.bluetooth.unit.sound_pressure.decibel_spl", SmartHomeUnits.ONE),
192     PARTS_PER_MILLION(0x27C4, "org.bluetooth.unit.concentration.parts_per_million", SmartHomeUnits.PARTS_PER_MILLION),
193     PARTS_PER_BILLION(0x27C5, "org.bluetooth.unit.concentration.parts_per_billion", SmartHomeUnits.PARTS_PER_BILLION);
194
195     private UUID uuid;
196
197     private String type;
198
199     private Unit<?> unit;
200
201     private BluetoothUnit(long key, String type, Unit<?> unit) {
202         this.uuid = new UUID((key << 32) | 0x1000, BluetoothBindingConstants.BLUETOOTH_BASE_UUID);
203         this.type = type;
204         this.unit = unit;
205     }
206
207     public static @Nullable BluetoothUnit findByType(String type) {
208         for (BluetoothUnit unit : BluetoothUnit.values()) {
209             if (unit.type.equals(type)) {
210                 return unit;
211             }
212         }
213         return null;
214     }
215
216     public UUID getUUID() {
217         return uuid;
218     }
219
220     public String getType() {
221         return type;
222     }
223
224     public Unit<?> getUnit() {
225         return unit;
226     }
227
228     /**
229      * This class contains the set of units that are not yet defined in SmarthomeUnits.
230      * Once these units are added to the core then this class will be removed.
231      *
232      * @author cpetty
233      * @deprecated
234      */
235     @Deprecated
236     public static class BUnits {
237         public static final Unit<ArealDensity> KILOGRAM_PER_SQUARE_METER = addUnit(
238                 new ProductUnit<ArealDensity>(Units.KILOGRAM.divide(Units.SQUARE_METRE)));
239
240         public static final Unit<RadiationExposure> COULOMB_PER_KILOGRAM = addUnit(
241                 new ProductUnit<RadiationExposure>(Units.COULOMB.divide(Units.KILOGRAM)));
242
243         public static final Unit<RadiationDoseAbsorptionRate> GRAY_PER_SECOND = addUnit(
244                 new ProductUnit<RadiationDoseAbsorptionRate>(Units.GRAY.divide(Units.SECOND)));
245
246         public static final Unit<Mass> POUND = addUnit(
247                 new TransformedUnit<Mass>(Units.KILOGRAM, new MultiplyConverter(0.45359237)));
248
249         public static final Unit<Angle> MINUTE_ANGLE = addUnit(new TransformedUnit<Angle>(Units.RADIAN,
250                 new PiMultiplierConverter().concatenate(new RationalConverter(1, 180 * 60))));
251
252         public static final Unit<Angle> SECOND_ANGLE = addUnit(new TransformedUnit<Angle>(Units.RADIAN,
253                 new PiMultiplierConverter().concatenate(new RationalConverter(1, 180 * 60 * 60))));
254
255         public static final Unit<Area> HECTARE = addUnit(Units.SQUARE_METRE.multiply(10000.0));
256         public static final Unit<Area> BARN = addUnit(Units.SQUARE_METRE.multiply(10E-28));
257
258         public static final Unit<Length> NAUTICAL_MILE = addUnit(SIUnits.METRE.multiply(1852.0));
259
260         public static final Unit<RadiantIntensity> WATT_PER_STERADIAN = addUnit(
261                 new ProductUnit<RadiantIntensity>(Units.WATT.divide(Units.STERADIAN)));
262
263         public static final Unit<Radiance> WATT_PER_STERADIAN_PER_SQUARE_METRE = addUnit(
264                 new ProductUnit<Radiance>(WATT_PER_STERADIAN.divide(Units.SQUARE_METRE)));
265
266         public static final Unit<Frequency> CYCLES_PER_MINUTE = addUnit(new TransformedUnit<Frequency>(Units.HERTZ,
267                 new RationalConverter(BigInteger.valueOf(60), BigInteger.ONE)));
268
269         public static final Unit<Angle> REVOLUTION = addUnit(new TransformedUnit<Angle>(Units.RADIAN,
270                 new PiMultiplierConverter().concatenate(new RationalConverter(2, 1))));
271         public static final Unit<AngularVelocity> REVOLUTION_PER_MINUTE = addUnit(
272                 new ProductUnit<AngularVelocity>(REVOLUTION.divide(Units.MINUTE)));
273
274         public static final Unit<Dimensionless> STEPS = addUnit(SmartHomeUnits.ONE.alternate("steps"));
275         public static final Unit<Dimensionless> BEATS = addUnit(SmartHomeUnits.ONE.alternate("beats"));
276         public static final Unit<Dimensionless> STROKE = addUnit(SmartHomeUnits.ONE.alternate("stroke"));
277
278         public static final Unit<Frequency> STEP_PER_MINUTE = addUnit(
279                 new ProductUnit<Frequency>(STEPS.divide(Units.MINUTE)));
280
281         public static final Unit<Frequency> BEATS_PER_MINUTE = addUnit(
282                 new ProductUnit<Frequency>(BEATS.divide(Units.MINUTE)));
283
284         public static final Unit<Frequency> STROKE_PER_MINUTE = addUnit(
285                 new ProductUnit<Frequency>(STROKE.divide(Units.MINUTE)));
286
287         public static final Unit<MassFlowRate> GRAM_PER_SECOND = addUnit(
288                 new ProductUnit<MassFlowRate>(Units.GRAM.divide(Units.SECOND)));
289
290         public static final Unit<LuminousEfficacy> LUMEN_PER_WATT = addUnit(
291                 new ProductUnit<LuminousEfficacy>(Units.LUMEN.divide(Units.WATT)));
292
293         public static final Unit<LuminousEnergy> LUMEN_SECOND = addUnit(
294                 new ProductUnit<LuminousEnergy>(Units.LUMEN.multiply(Units.SECOND)));
295
296         public static final Unit<LuminousEnergy> LUMEN_HOUR = addUnit(
297                 new ProductUnit<LuminousEnergy>(Units.LUMEN.multiply(Units.HOUR)));
298
299         public static final Unit<ElectricCharge> AMPERE_HOUR = addUnit(
300                 new ProductUnit<ElectricCharge>(Units.AMPERE.multiply(Units.HOUR)));
301
302         public static final Unit<LuminousExposure> LUX_HOUR = addUnit(
303                 new ProductUnit<LuminousExposure>(Units.LUX.multiply(Units.HOUR)));
304
305         public static final Unit<Speed> KILOMETRE_PER_MINUTE = addUnit(Units.KILOMETRE_PER_HOUR.multiply(60.0));
306
307         public static final Unit<VolumetricFlowRate> LITRE_PER_SECOND = addUnit(
308                 new ProductUnit<VolumetricFlowRate>(Units.LITRE.divide(Units.SECOND)));
309
310         static {
311             SimpleUnitFormat.getInstance().label(GRAY_PER_SECOND, "Gy/s");
312             SimpleUnitFormat.getInstance().label(MINUTE_ANGLE, "'");
313             SimpleUnitFormat.getInstance().label(SECOND_ANGLE, "\"");
314             SimpleUnitFormat.getInstance().label(HECTARE, "ha");
315             SimpleUnitFormat.getInstance().label(NAUTICAL_MILE, "NM");
316             SimpleUnitFormat.getInstance().label(KILOGRAM_PER_SQUARE_METER, "kg/m²");
317             SimpleUnitFormat.getInstance().label(POUND, "lb");
318             SimpleUnitFormat.getInstance().label(CYCLES_PER_MINUTE, "cpm");
319             SimpleUnitFormat.getInstance().label(GRAM_PER_SECOND, "g/s");
320             SimpleUnitFormat.getInstance().label(LUMEN_SECOND, "lm·s");
321             SimpleUnitFormat.getInstance().label(LUMEN_HOUR, "lm·h");
322             SimpleUnitFormat.getInstance().label(LUMEN_PER_WATT, "lm/W");
323             SimpleUnitFormat.getInstance().label(LUX_HOUR, "lx·h");
324             SimpleUnitFormat.getInstance().label(KILOMETRE_PER_MINUTE, "km/min");
325             SimpleUnitFormat.getInstance().label(LITRE_PER_SECOND, "l/s");
326             SimpleUnitFormat.getInstance().label(BEATS_PER_MINUTE, "bpm");
327             SimpleUnitFormat.getInstance().label(STEP_PER_MINUTE, "steps/min");
328             SimpleUnitFormat.getInstance().label(STROKE_PER_MINUTE, "spm");
329             SimpleUnitFormat.getInstance().label(REVOLUTION_PER_MINUTE, "rpm");
330         }
331
332         private static <U extends Unit<?>> U addUnit(U unit) {
333             return unit;
334         }
335
336         public interface AngularVelocity extends Quantity<AngularVelocity> {
337         }
338
339         public interface LuminousEnergy extends Quantity<LuminousEnergy> {
340         }
341
342         public interface LuminousEfficacy extends Quantity<LuminousEfficacy> {
343         }
344
345         public interface LuminousExposure extends Quantity<LuminousExposure> {
346         }
347
348         public interface RadiantIntensity extends Quantity<RadiantIntensity> {
349         }
350
351         public interface Radiance extends Quantity<Radiance> {
352         }
353
354         public interface RadiationExposure extends Quantity<RadiationExposure> {
355         }
356
357         public interface RadiationDoseAbsorptionRate extends Quantity<RadiationDoseAbsorptionRate> {
358         }
359
360         public interface MassFlowRate extends Quantity<MassFlowRate> {
361         }
362     }
363 }