diff --git a/ui-ngx/src/app/core/services/unit/converter-unit.ts b/ui-ngx/src/app/core/services/unit/converter-unit.ts index aa04521b55..6a33688523 100644 --- a/ui-ngx/src/app/core/services/unit/converter-unit.ts +++ b/ui-ngx/src/app/core/services/unit/converter-unit.ts @@ -21,12 +21,11 @@ import { isDefinedAndNotNull, isUndefinedOrNull } from '@core/utils'; export interface Conversion< TMeasures extends string, - TSystems extends string, TUnits extends string, > { abbr: TUnits; measure: TMeasures; - system: TSystems; + system: UnitSystem; unit: Unit; } @@ -39,10 +38,10 @@ export interface Conversion< type Entries = [S, T[keyof T]]; -export type UnitCache = Map< +export type UnitCache = Map< string, { - system: TSystems; + system: UnitSystem; measure: TMeasures; unit: Unit; abbr: TUnits; @@ -51,14 +50,13 @@ export type UnitCache = Map< export class Converter< TMeasures extends AllMeasures, - TSystems extends UnitSystem, TUnits extends string, > { - private measureData: Record>; + private readonly measureData: Record>; private unitCache: Map< string, { - system: TSystems; + system: UnitSystem; measure: TMeasures; unit: Unit; abbr: TUnits; @@ -66,8 +64,8 @@ export class Converter< >; constructor( - measures: Record>, - unitCache: UnitCache + measures: Record>, + unitCache: UnitCache ) { this.measureData = measures; this.unitCache = unitCache; @@ -96,18 +94,8 @@ export class Converter< if (origin.system !== destination.system) { const measure = this.measureData[origin.measure]; - const anchors = measure.anchors; - if (!anchors) { - throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`); - } - - const anchor = anchors[origin.system]; - if (!anchor) { - throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`); - } - - const transform = anchor[destination.system]?.transform; - const ratio = anchor[destination.system]?.ratio; + const transform = measure[origin.system]?.transform; + const ratio = measure[origin.system]?.ratio; if (typeof transform === 'function') { result = transform(result); @@ -146,16 +134,8 @@ export class Converter< } if (origin.system !== destination.system) { const measure = this.measureData[origin.measure]; - const anchors = measure.anchors; - if (!anchors) { - throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`); - } - const anchor = anchors[origin.system]; - if (!anchor) { - throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`); - } - const transform = anchor[destination.system]?.transform; - const ratio = anchor[destination.system]?.ratio; + const transform = measure[origin.system]?.transform; + const ratio = measure[origin.system]?.ratio; if (typeof transform === 'function') { result = transform(result); } else if (typeof ratio === 'number') { @@ -234,7 +214,7 @@ export class Converter< // return best; // } - getUnit(abbr: TUnits | (string & {})): Conversion | null { + getUnit(abbr: TUnits | (string & {})): Conversion | null { return this.unitCache.get(abbr) ?? null; } @@ -247,7 +227,7 @@ export class Converter< return null; } - private describeUnit(unit: Conversion): UnitDescription { + private describeUnit(unit: Conversion): UnitDescription { return { abbr: unit.abbr, measure: unit.measure, @@ -268,11 +248,11 @@ export class Converter< const measure = this.measureData[measureName]; if (isDefinedAndNotNull(unitSystem)) { let currentUnitSystem = unitSystem; - let units = measure.systems[currentUnitSystem]; + let units = measure[currentUnitSystem]; if (isUndefinedOrNull(units)) { if (currentUnitSystem === UnitSystem.IMPERIAL) { currentUnitSystem = UnitSystem.METRIC; - units = measure.systems[currentUnitSystem]; + units = measure[currentUnitSystem]; } if (!units) { console.log(`Measure "${measureName}" in ${currentUnitSystem} system is not found.`); @@ -280,29 +260,29 @@ export class Converter< } } for (const [abbr, unit] of Object.entries( - units + units.units )) { list.push( this.describeUnit({ abbr: abbr as TUnits, measure: measureName as TMeasures, - system: currentUnitSystem as TSystems, + system: currentUnitSystem, unit: unit as Unit, }) ); } } else { for (const [systemName, units] of Object.entries( - (measure as TbMeasure).systems - )) { + measure + ) as Entries, UnitSystem>[]) { for (const [abbr, unit] of Object.entries( - units as Partial> + units.units as Partial> )) { list.push( this.describeUnit({ abbr: abbr as TUnits, measure: measureName as TMeasures, - system: systemName as TSystems, + system: systemName, unit: unit as Unit, }) ); @@ -313,11 +293,11 @@ export class Converter< for (const [name, measure] of Object.entries(this.measureData)) { if (isDefinedAndNotNull(unitSystem)) { let currentUnitSystem = unitSystem; - let units = (measure as TbMeasure).systems[currentUnitSystem]; + let units = (measure as TbMeasure)[currentUnitSystem]?.units; if (isUndefinedOrNull(units)) { if (currentUnitSystem === UnitSystem.IMPERIAL) { currentUnitSystem = UnitSystem.METRIC; - units = (measure as TbMeasure).systems[currentUnitSystem]; + units = (measure as TbMeasure)[currentUnitSystem]?.units; } if (!units) { console.log(`Measure "${measureName}" in ${currentUnitSystem} system is not found.`); @@ -331,23 +311,23 @@ export class Converter< this.describeUnit({ abbr: abbr as TUnits, measure: name as TMeasures, - system: currentUnitSystem as TSystems, + system: currentUnitSystem, unit: unit as Unit, }) ); } } else { for (const [systemName, units] of Object.entries( - (measure as TbMeasure).systems - )) { + measure + ) as Entries, UnitSystem>[]) { for (const [abbr, unit] of Object.entries( - units as Partial> + units.units as Partial> )) { list.push( this.describeUnit({ abbr: abbr as TUnits, measure: name as TMeasures, - system: systemName as TSystems, + system: systemName, unit: unit as Unit, }) ); @@ -397,21 +377,20 @@ export class Converter< export function buildUnitCache< TMeasures extends string, - TSystems extends UnitSystem, TUnits extends string, ->(measures: Record>, +>(measures: Record>, translate: TranslateService ) { - const unitCache: UnitCache = new Map(); + const unitCache: UnitCache = new Map(); for (const [measureName, measure] of Object.entries(measures) as Entries< typeof measures, TMeasures >[]) { for (const [systemName, system] of Object.entries( - measure.systems - ) as Entries>, TSystems>[]) { - for (const [testAbbr, unit] of Object.entries(system) as Entries< - typeof system, + measure + ) as Entries, UnitSystem>[]) { + for (const [testAbbr, unit] of Object.entries(system.units) as Entries< + Record, TUnits >[]) { unit.name = translate.instant(unit.name); @@ -429,16 +408,15 @@ export function buildUnitCache< export function configureMeasurements< TMeasures extends AllMeasures, - TSystems extends UnitSystem, TUnits extends string, >( - measures: Record>, + measures: Record>, translate: TranslateService -): Converter { +): Converter { if (typeof measures !== 'object') { throw new TypeError('The measures argument needs to be an object'); } const unitCache = buildUnitCache(measures, translate); - return new Converter(measures, unitCache); + return new Converter(measures, unitCache); } diff --git a/ui-ngx/src/app/core/services/unit/definitions/acceleration.ts b/ui-ngx/src/app/core/services/unit/definitions/acceleration.ts new file mode 100644 index 0000000000..1a39b0b814 --- /dev/null +++ b/ui-ngx/src/app/core/services/unit/definitions/acceleration.ts @@ -0,0 +1,66 @@ +/// +/// Copyright © 2016-2025 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models'; + +export type AccelerationMetricUnits = 'G' | 'm/s²' | 'km/h²' | 'Gal'; +export type AccelerationImperialUnits = 'ft/s²'; + +export type AccelerationUnits = AccelerationMetricUnits | AccelerationImperialUnits; + +const METRIC: TbMeasureUnits = { + ratio: 3.28084, + units: { + 'G': { + name: 'unit.g-force', + tags: ['acceleration', 'gravity', 'g-force', 'load', 'G'], + to_anchor: 9.80665, + }, + 'm/s²': { + name: 'unit.meters-per-second-squared', + tags: ['peak', 'peak to peak', 'root mean square (RMS)', 'vibration', 'meters per second squared', 'm/s²'], + to_anchor: 1, + }, + 'Gal': { + name: 'unit.gal', + tags: ['acceleration', 'gravity', 'g-force', 'Gal'], + to_anchor: 1, + }, + 'km/h²': { + name: 'unit.kilometer-per-hour-squared', + tags: ['acceleration', 'rate of change of velocity', 'kilometer per hour squared', 'km/h²'], + to_anchor: 1 / 12960, + } + } +}; + +const IMPERIAL: TbMeasureUnits = { + ratio: 1 / 3.28084, + units: { + 'ft/s²': { + name: 'unit.foot-per-second-squared', + tags: ['acceleration', 'rate of change of velocity', 'foot per second squared', 'ft/s²'], + to_anchor: 1 + } + } +}; + +const measure: TbMeasure = { + METRIC, + IMPERIAL +}; + +export default measure; diff --git a/ui-ngx/src/app/core/services/unit/definitions/all.ts b/ui-ngx/src/app/core/services/unit/definitions/all.ts index 7ae88112d3..300f985f70 100644 --- a/ui-ngx/src/app/core/services/unit/definitions/all.ts +++ b/ui-ngx/src/app/core/services/unit/definitions/all.ts @@ -14,24 +14,38 @@ /// limitations under the License. /// -import temperature, { - TemperatureUnits, -} from './temperature'; +import { TbMeasure } from '@shared/models/unit.models'; +import acceleration, { AccelerationUnits } from '@core/services/unit/definitions/acceleration'; +import angle, { AngleUnits } from '@core/services/unit/definitions/angle'; +import angularAcceleration, { AngularAccelerationUnits } from '@core/services/unit/definitions/angular-acceleration'; +import area, { AreaUnits } from '@core/services/unit/definitions/area'; +import temperature, { TemperatureUnits } from './temperature'; import time, { TimeUnits } from './time'; -import { TbMeasure, UnitSystem } from '@shared/models/unit.models'; export type AllMeasuresUnits = + | AccelerationUnits + | AngleUnits + | AngularAccelerationUnits + | AreaUnits | TemperatureUnits | TimeUnits; export type AllMeasures = + | 'acceleration' + | 'angle' + | 'angularAcceleration' + | 'area' | 'temperature' | 'time'; const allMeasures: Record< AllMeasures, - TbMeasure + TbMeasure > = { + acceleration, + angle, + angularAcceleration, + area, temperature, time, }; diff --git a/ui-ngx/src/app/core/services/unit/definitions/angle.ts b/ui-ngx/src/app/core/services/unit/definitions/angle.ts new file mode 100644 index 0000000000..2be1cc9a97 --- /dev/null +++ b/ui-ngx/src/app/core/services/unit/definitions/angle.ts @@ -0,0 +1,67 @@ +/// +/// Copyright © 2016-2025 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models'; + +export type AngleUnits = AngleSIUnits; + +export type AngleSIUnits = 'rad' | 'deg' | 'grad' | 'arcmin' | 'arcsec' | 'mil' | 'rev'; + +const METRIC: TbMeasureUnits = { + units: { + rad: { + name: 'unit.rad', + tags: ['angle', 'radian', 'radians', 'rad'], + to_anchor: 180 / Math.PI, + }, + deg: { + name: 'unit.degree', + tags: ['angle', 'degree', 'degrees', 'deg'], + to_anchor: 1, + }, + grad: { + name: 'unit.gradian', + tags: ['angle', 'gradian', 'grades', 'grad'], + to_anchor: 9 / 10, + }, + arcmin: { + name: 'unit.arcminute', + tags: ['angle', 'arcminute', 'arcminutes', 'arcmin'], + to_anchor: 1 / 60 + }, + arcsec: { + name: 'unit.arcsecond', + tags: ['angle', 'arcsecond', 'arcseconds', 'arcsec'], + to_anchor: 1 / 3600 + }, + mil: { + name: 'unit.mil', + tags: ['angle', 'military angle', 'angular mil', 'mil'], + to_anchor: 9 / (50 * Math.PI), + }, + rev: { + name: 'revolution', + tags: ['angle', 'revolution', 'full circle', 'complete turn', 'rev'], + to_anchor: 360, + }, + } +}; + +const measure: TbMeasure = { + METRIC, +}; + +export default measure; diff --git a/ui-ngx/src/app/core/services/unit/definitions/angular-acceleration.ts b/ui-ngx/src/app/core/services/unit/definitions/angular-acceleration.ts new file mode 100644 index 0000000000..4e5085d7bf --- /dev/null +++ b/ui-ngx/src/app/core/services/unit/definitions/angular-acceleration.ts @@ -0,0 +1,51 @@ +/// +/// Copyright © 2016-2025 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models'; + +export type AngularAccelerationMetricUnits = 'rad/s²'; +export type AngularAccelerationImperialUnits = 'rpm/s'; + +export type AngularAccelerationUnits = AngularAccelerationMetricUnits | AngularAccelerationImperialUnits; + +const METRIC: TbMeasureUnits = { + ratio: 30 / Math.PI, + units: { + 'rad/s²': { + name: 'unit.radian-per-second-squared', + tags: ['angular acceleration', 'rotation rate of change', 'rad/s²'], + to_anchor: 1, + } + } +}; + +const IMPERIAL: TbMeasureUnits = { + ratio: Math.PI / 30, + units: { + 'rpm/s': { + name: 'unit.revolutions-per-minute-per-second', + tags: ['angular acceleration', 'rotation rate of change', 'rpm/s'], + to_anchor: 1 + } + } +} + +const measure: TbMeasure = { + METRIC, + IMPERIAL +}; + +export default measure; diff --git a/ui-ngx/src/app/core/services/unit/definitions/area.ts b/ui-ngx/src/app/core/services/unit/definitions/area.ts new file mode 100644 index 0000000000..6a364496b5 --- /dev/null +++ b/ui-ngx/src/app/core/services/unit/definitions/area.ts @@ -0,0 +1,101 @@ +/// +/// Copyright © 2016-2025 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models'; + +export type AreaMetricUnits = 'mm²' | 'cm²' | 'm²' | 'a' | 'ha' | 'km²'; +export type AreaImperialUnits = 'in²' | 'yd²' | 'ft²' | 'ac' | 'ml²' | 'cin'; + +export type AreaUnits = AreaMetricUnits | AreaImperialUnits; + +const METRIC: TbMeasureUnits = { + ratio: 10.7639, + units: { + 'mm²': { + name: 'unit.square-millimeter', + tags: ['area','lot','zone','space','region','square millimeter','square millimeters','mm²','sq-mm'], + to_anchor: 1 / 1000000, + }, + 'cm²': { + name: 'unit.square-centimeter', + tags: ['area','lot','zone','space','region','square centimeter','square centimeters','cm²','sq-cm'], + to_anchor: 1 / 10000, + }, + 'm²': { + name: 'unit.square-meter', + tags: ['area','lot','zone','space','region','square meter','square meters','m²','sq-m'], + to_anchor: 1, + }, + a: { + name: 'unit.are', + tags: ['area','land measurement','are'], + to_anchor: 100, + }, + ha: { + name: 'unit.hectare', + tags: ['area','lot','zone','space','region','hectare','hectares','ha'], + to_anchor: 10000, + }, + 'km²': { + name: 'unit.square-kilometer', + tags: ['area','lot','zone','space','region','square kilometer','square kilometers','km²','sq-km'], + to_anchor: 1000000, + }, + } +}; + +const IMPERIAL: TbMeasureUnits = { + ratio: 1 / 10.7639, + units: { + 'in²': { + name: 'unit.square-inch', + tags: ['area','lot','zone','space','region','square inch','square inches','in²','sq-in'], + to_anchor: 1 / 144, + }, + 'yd²': { + name: 'unit.square-yard', + tags: ['area','lot','zone','space','region','square yard','square yards','yd²','sq-yd'], + to_anchor: 9, + }, + 'ft²': { + name: 'unit.square-foot', + tags: ['area','lot','zone','space','region','square foot','square feet','ft²','sq-ft'], + to_anchor: 1, + }, + ac: { + name: 'unit.acre', + tags: ['area','lot','zone','space','region','acre','acres','a'], + to_anchor: 43560, + }, + 'ml²': { + name: 'unit.square-mile', + tags: ['area','lot','zone','space','region','square mile','square miles','ml²','sq-mi'], + to_anchor: 27878400, + }, + cin: { + name: 'unit.circular-inch', + tags: ['area','circular measurement','circular inch','circin'], + to_anchor: Math.PI / 576 + } + } +} + +const measure: TbMeasure = { + METRIC, + IMPERIAL +}; + +export default measure; diff --git a/ui-ngx/src/app/core/services/unit/definitions/temperature.ts b/ui-ngx/src/app/core/services/unit/definitions/temperature.ts index 23b5831dcb..67f17f0a4b 100644 --- a/ui-ngx/src/app/core/services/unit/definitions/temperature.ts +++ b/ui-ngx/src/app/core/services/unit/definitions/temperature.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { TbMeasure, Unit, UnitSystem } from '@shared/models/unit.models'; +import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models'; export type TemperatureMetricUnits = '°C' | 'K'; export type TemperatureImperialUnits = '°F' | '°R'; @@ -23,55 +23,43 @@ export type TemperatureUnits = | TemperatureMetricUnits | TemperatureImperialUnits; -const METRIC: Record = { - '°C': { - name: 'unit.celsius', - tags: ['temperature','heat','cold','warmth','degrees','celsius','shipment condition','°C'], - to_anchor: 1, - }, - K: { - name: 'unit.kelvin', - tags: ['temperature','heat','cold','warmth','degrees','kelvin','K','color quality','white balance','color temperature'], - to_anchor: 1, - anchor_shift: 273.15, - }, +const METRIC: TbMeasureUnits = { + transform: (C) => C / (5 / 9) + 32, + units: { + '°C': { + name: 'unit.celsius', + tags: ['temperature', 'heat', 'cold', 'warmth', 'degrees', 'celsius', 'shipment condition', '°C'], + to_anchor: 1, + }, + K: { + name: 'unit.kelvin', + tags: ['temperature', 'heat', 'cold', 'warmth', 'degrees', 'kelvin', 'K', 'color quality', 'white balance', 'color temperature'], + to_anchor: 1, + anchor_shift: 273.15, + }, + } }; -const IMPERIAL: Record = { - '°F': { - name: 'unit.fahrenheit', - tags: ['temperature','heat','cold','warmth','degrees','fahrenheit','°F'], - to_anchor: 1, - }, - '°R': { - name: 'unit.rankine', - tags: ['temperature','heat','cold','warmth','Rankine','°R'], - to_anchor: 1, - anchor_shift: 459.67, - }, +const IMPERIAL: TbMeasureUnits = { + transform: (F) => (F - 32) * (5 / 9), + units: { + '°F': { + name: 'unit.fahrenheit', + tags: ['temperature', 'heat', 'cold', 'warmth', 'degrees', 'fahrenheit', '°F'], + to_anchor: 1, + }, + '°R': { + name: 'unit.rankine', + tags: ['temperature', 'heat', 'cold', 'warmth', 'Rankine', '°R'], + to_anchor: 1, + anchor_shift: 459.67, + }, + } }; -const measure: TbMeasure = { - systems: { - METRIC, - IMPERIAL, - }, - anchors: { - METRIC: { - IMPERIAL: { - transform: function (C: number): number { - return C / (5 / 9) + 32; - }, - }, - }, - IMPERIAL: { - METRIC: { - transform: function (F: number): number { - return (F - 32) * (5 / 9); - }, - }, - }, - }, +const measure: TbMeasure = { + METRIC, + IMPERIAL }; export default measure; diff --git a/ui-ngx/src/app/core/services/unit/definitions/time.ts b/ui-ngx/src/app/core/services/unit/definitions/time.ts index aead2db33c..a78a9450fb 100644 --- a/ui-ngx/src/app/core/services/unit/definitions/time.ts +++ b/ui-ngx/src/app/core/services/unit/definitions/time.ts @@ -14,11 +14,14 @@ /// limitations under the License. /// -import { TbMeasure, Unit, UnitSystem } from '@shared/models/unit.models'; +import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models'; export type TimeUnits = TimeSIUnits; export type TimeSIUnits = + | 'ns' + | 'μs' + | 'ms' | 's' | 'min' | 'h' @@ -29,48 +32,63 @@ export type TimeSIUnits = const daysInYear = 365.25; -const METRIC: Record = { - s: { - name: 'unit.second', - tags: ["time","duration","interval","angle","second","arcsecond","sec"], - to_anchor: 1, - }, - min: { - name: 'unit.minute', - tags: ["time","duration","interval","angle","minute","arcminute","min"], - to_anchor: 60, - }, - h: { - name: 'unit.hour', - tags: ["time","duration","interval","h"], - to_anchor: 60 * 60, - }, - d: { - name: 'unit.day', - tags: ["time","duration","interval","d"], - to_anchor: 60 * 60 * 24, - }, - wk: { - name: 'unit.week', - tags: ["time","duration","interval","wk"], - to_anchor: 60 * 60 * 24 * 7, - }, - mo: { - name: 'unit.month', - tags: ["time","duration","interval","mo"], - to_anchor: (60 * 60 * 24 * daysInYear) / 12, - }, - yr: { - name: 'unit.year', - tags: ["time","duration","interval","yr"], - to_anchor: 60 * 60 * 24 * daysInYear, - }, +const METRIC: TbMeasureUnits = { + units: { + ns: { + name: 'unit.nanosecond', + tags: ['time', 'duration', 'interval', 'ns'], + to_anchor: 1 / 1000000000 + }, + 'μs': { + name: 'unit.microsecond', + tags: ['time', 'duration', 'interval', 'h'], + to_anchor: 1 / 1000000 + }, + ms: { + name: 'unit.millisecond', + tags: ['time', 'duration', 'interval', 'ms'], + to_anchor: 1 / 1000 + }, + s: { + name: 'unit.second', + tags: ['time', 'duration', 'interval', 'second', 'sec'], + to_anchor: 1, + }, + min: { + name: 'unit.minute', + tags: ['time', 'duration', 'interval', 'minute', 'min'], + to_anchor: 60, + }, + h: { + name: 'unit.hour', + tags: ['time', 'duration', 'interval', 'h'], + to_anchor: 60 * 60, + }, + d: { + name: 'unit.day', + tags: ['time', 'duration', 'interval', 'd'], + to_anchor: 60 * 60 * 24, + }, + wk: { + name: 'unit.week', + tags: ['time', 'duration', 'interval', 'wk'], + to_anchor: 60 * 60 * 24 * 7, + }, + mo: { + name: 'unit.month', + tags: ['time', 'duration', 'interval', 'mo'], + to_anchor: (60 * 60 * 24 * daysInYear) / 12, + }, + yr: { + name: 'unit.year', + tags: ['time', 'duration', 'interval', 'yr'], + to_anchor: 60 * 60 * 24 * daysInYear, + }, + } }; -const measure: TbMeasure = { - systems: { - METRIC, - }, +const measure: TbMeasure = { + METRIC, }; export default measure; diff --git a/ui-ngx/src/app/core/services/unit/unit.service.ts b/ui-ngx/src/app/core/services/unit/unit.service.ts index 4013e71ced..9a977de9e7 100644 --- a/ui-ngx/src/app/core/services/unit/unit.service.ts +++ b/ui-ngx/src/app/core/services/unit/unit.service.ts @@ -31,14 +31,14 @@ import { AppState } from '@core/core.state'; export class UnitService { private currentUnitSystem: UnitSystem = UnitSystem.METRIC; - private converter: Converter; + private converter: Converter; constructor(private store: Store, private translate: TranslateService) { this.translate.onLangChange.pipe( takeUntilDestroyed() ).subscribe(() => { - this.converter = configureMeasurements(allMeasures, this.translate); + this.converter = configureMeasurements(allMeasures, this.translate); console.warn(this.converter?.list()); console.warn(this.converter?.list('temperature')); console.warn(this.converter?.list('temperature', UnitSystem.METRIC)); diff --git a/ui-ngx/src/app/shared/models/unit.models.ts b/ui-ngx/src/app/shared/models/unit.models.ts index c6df79f23e..c5322d99e0 100644 --- a/ui-ngx/src/app/shared/models/unit.models.ts +++ b/ui-ngx/src/app/shared/models/unit.models.ts @@ -57,14 +57,12 @@ export interface TbUnitMapping { HYBRID: string; } -export interface TbAnchor { +export type TbMeasure = Partial>>; + +export interface TbMeasureUnits { ratio?: number; transform?: (value: number) => number; -} - -export interface TbMeasure { - systems: Partial>>>; - anchors?: Partial>>>; + units?: Partial>; } const searchUnitTags = (unit: UnitDescription, searchText: string): boolean => diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index d5e227408d..fb3de537cf 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6160,6 +6160,9 @@ "millibars": "Millibars", "inch-of-mercury": "One inch of mercury", "richter-scale": "Richter Scale", + "nanosecond": "Nanosecond", + "microsecond": "Microsecond", + "millisecond": "Millisecond", "second": "Second", "minute": "Minute", "hour": "Hour", @@ -6197,6 +6200,8 @@ "degree": "Degree", "radian": "Radian", "gradian": "Gradian", + "arcminute": "Arcminute", + "arcsecond": "Arcsecond", "mil": "Mil", "revolution": "Revolution", "siemens": "Siemens", @@ -6267,7 +6272,6 @@ "radian-per-second": "Radian per second", "radian-per-second-squared": "Radian per second squared", "revolutions-per-minute-per-second": "Angular acceleration", - "revolutions-per-minute-per-second-squared": "Angular Acceleration", "deg-per-second": "deg/s", "degrees-brix": "Degrees Brix", "katal": "Katal",