ScaleUtilities 2.0.4

dotnet add package ScaleUtilities --version 2.0.4
                    
NuGet\Install-Package ScaleUtilities -Version 2.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ScaleUtilities" Version="2.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ScaleUtilities" Version="2.0.4" />
                    
Directory.Packages.props
<PackageReference Include="ScaleUtilities" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ScaleUtilities --version 2.0.4
                    
#r "nuget: ScaleUtilities, 2.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ScaleUtilities@2.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ScaleUtilities&version=2.0.4
                    
Install as a Cake Addin
#tool nuget:?package=ScaleUtilities&version=2.0.4
                    
Install as a Cake Tool

ScaleUtilities

A comprehensive .NET library for unit conversions across multiple scale types including Weight, Length, Volume, Temperature, Speed, Velocity, Angle, Voltage, Illuminance, Concentration, and Volumetric Flow Rate. Features formula-based conversions using NCalc, extensive unit support, and validation utilities.

I. Overview

ScaleUtilities is a powerful .NET 9 library designed for converting values between units of the same measurement type. The library provides:

  • 🔄 Universal Unit Conversion: Convert between units within the same scale type (e.g., kilograms to pounds, meters to feet)
  • 📏 13 Scale Types Supported: Weight, Length, Volume, Temperature, Speed, Velocity, Angle, Voltage, Illuminance, Concentration, Volumetric Flow Rate, Wireless Signal Strength, and Electrical Conductivity
  • 🧮 Formula-Based Conversions: Uses NCalc for mathematical expression evaluation, supporting complex conversion formulas
  • ✅ Validation Tools: Built-in validation utilities to ensure unit and scale type combinations are valid
  • 🎯 Type-Safe: Strongly typed with comprehensive C# models and enums
  • ⚡ High Performance: Optimized conversion trees for fast lookups and calculations
  • 🌐 Multi-Language Support: Conversion formulas available for C#, JavaScript, Python, Java, and TypeScript

Key Features

  • Extensive Unit Support: Over 100+ units across all scale types
  • International Standards: Follows SI, Imperial, US Customary, and specialized measurement systems
  • Error Handling: Comprehensive exception handling with detailed error messages
  • Async Support: Asynchronous methods for formula evaluation
  • Documentation: Full XML documentation for IntelliSense support

II. Installation

From MyGet Feed

The ScaleUtilities library is available from our MyGet feed:

# Add the MyGet feed to your NuGet sources
dotnet nuget add source https://www.myget.org/F/cms-tool/api/v3/index.json -n "CMS Tools"

# Install the package
dotnet add package ScaleUtilities --version 1.0.1 --source "CMS Tools"

Or visit the MyGet package page directly: https://www.myget.org/feed/cms-tool/package/nuget/ScaleUtilities

Package Manager Console

Install-Package ScaleUtilities -Version 1.0.1 -Source "https://www.myget.org/F/cms-tool/api/v3/index.json"

PackageReference (csproj)

<PackageReference Include="ScaleUtilities" Version="1.0.1" />

III. Supported Types and Their Units

🏋️ Weight (25 units)

Metric Units: Microgram, Milligram, Centigram, Decigram, Gram, Decagram, Hectogram, Kilogram, Metric Ton, Quintal
Imperial/US: Ounce, Pound, Stone, Short Ton, Long Ton
Troy System: Troy Ounce, Troy Pound, Pennyweight
Apothecary: Grain, Dram, Apothecary Ounce
Specialty: Carat, Atomic Mass Unit

📏 Length (8 units)

Metric: Millimeter, Centimeter, Meter, Kilometer
Imperial: Inch, Foot, Yard, Mile

🫗 Volume (9 units)

Metric: Milliliter, Liter, Cubic Meter
US Customary: Fluid Ounce, Cup, Pint, Quart, Gallon

🌡️ Temperature (5 units)

Celsius, Fahrenheit, Kelvin, Rankine, Réaumur

🏃 Speed (11 units)

Metric: Meters/Second, Kilometers/Hour, Centimeters/Second, Millimeters/Second
Imperial: Miles/Hour, Feet/Second, Inches/Second, Yards/Second
Nautical: Knots
Scientific: Speed of Light, Mach

🎯 Velocity (11 units)

Same units as Speed with directional components

📐 Angle (11 units)

Standard: Degrees, Radians, Gradians
Subdivisions: Arc Minutes, Arc Seconds
Military: Mils, NATO Mils
Fractional: Turns, Right Angles
Historical: Compass Points, Binary Degrees

⚡ Voltage (10 units)

SI Units: Nanovolts, Microvolts, Millivolts, Volts, Kilovolts, Megavolts, Gigavolts
Electrical: Statvolts, Abvolts
Scientific: Planck Voltage

💡 Illuminance (9 units)

SI: Millilux, Lux, Kilolux, Lumen/Square Meter
Imperial: Foot-candle, Lumen/Square Foot, Lumen/Square Inch
CGS: Phot, Nox

🧪 Concentration (23 units)

Mass/Volume: Grams/Liter, Milligrams/Liter, Micrograms/Liter, Kilograms/Cubic Meter, etc.
Imperial: Pounds/Gallon, Ounces/Gallon, Grains/Gallon, Pounds/Cubic Foot
Molar: Molar, Millimolar, Micromolar, Nanomolar
Percentage: Percent by Weight, Percent by Volume, Percent Weight by Volume
Parts Per: Parts per Million, Parts per Billion, Parts per Trillion

💧 Volumetric Flow Rate (15 units)

Metric - Milliliter: Milliliter/Second, Milliliter/Minute, Milliliter/Hour
Metric - Liter: Liter/Second, Liter/Minute, Liter/Hour
Metric - Cubic Meter: Cubic Meter/Second, Cubic Meter/Minute, Cubic Meter/Hour
US Customary - Fluid Ounce: Fluid Ounce/Second, Fluid Ounce/Minute, Fluid Ounce/Hour
US Customary - Gallon: Gallon/Second, Gallon/Minute (GPM), Gallon/Hour

Common Applications: HVAC systems, plumbing, irrigation, industrial pipelines, medical IV drips, fuel injection systems, water pumps, fire sprinkler systems

IV. Utility Methods

ScaleUnitValidationUtilities

Located in ScaleUtilities.Utilities namespace

Methods

Validate(ScaleUnit scaleUnit)

  • Parameters: ScaleUnit scaleUnit - The ScaleUnit object to validate
  • Return Type: void
  • Exceptions:
    • ArgumentNullException - When scaleUnit is null
    • InvalidScaleUnitException - When the ScaleUnit has invalid type/code combination
  • Description: Validates a ScaleUnit and throws an exception if invalid

IsValid(ScaleUnit scaleUnit)

  • Parameters: ScaleUnit scaleUnit - The ScaleUnit object to check
  • Return Type: bool
  • Description: Returns true if the ScaleUnit has a valid type and code combination

IsValid(ScaleTypes type, string code)

  • Parameters:
    • ScaleTypes type - The scale type enum
    • string code - The unit code to validate
  • Return Type: bool
  • Description: Returns true if the scale type and unit code combination is valid

Conversion Tree Utilities

Each scale type has its own conversion utility class:

WeightConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters:
    • decimal value - Value to convert
    • string sourceUnit - Source unit code (e.g., "KILOGRAM")
    • string targetUnit - Target unit code (e.g., "POUND")
  • Return Type: decimal
  • Description: Converts weight values between different units
LengthConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts length values between different units
VolumeConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts volume values between different units
TemperatureConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts temperature values between different units (handles offset-based conversions)
SpeedConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts speed values between different units
VelocityConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts velocity values between different units
AngleConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts angle values between different units
VoltageConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts voltage values between different units
IlluminanceConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts illuminance values between different units
ConcentrationConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts concentration values between different units
VolumetricFlowRateConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts volumetric flow rate values between different units (e.g., liters per second to gallons per minute)

Unit Code Constants

Each scale type provides constants for unit codes:

  • WeightUnitCodes - All weight unit codes and validation methods
  • LengthUnitCodes - All length unit codes
  • VolumeUnitCodes - All volume unit codes
  • TemperatureUnitCodes - All temperature unit codes and validation methods
  • SpeedUnitCodes - All speed unit codes and validation methods
  • VelocityUnitCodes - All velocity unit codes and validation methods
  • AngleUnitCodes - All angle unit codes and validation methods
  • VoltageUnitCodes - All voltage unit codes and validation methods
  • IlluminanceUnitCodes - All illuminance unit codes and validation methods
  • ConcentrationUnitCodes - All concentration unit codes and validation methods
  • VolumetricFlowRateUnitCodes - All volumetric flow rate unit codes and symbol retrieval methods

Usage Examples

Basic Unit Conversion

using ScaleUtilities.Utilities;
using ScaleUtilities.Constants;

// Convert 1 kilogram to pounds
decimal result = WeightConversionTreeUtilities.Convert(1m, WeightUnitCodes.Kilogram, WeightUnitCodes.Pound);
// Result: 2.20462262184878

// Convert 100 degrees Celsius to Fahrenheit
decimal tempResult = TemperatureConversionTreeUtilities.Convert(100m, TemperatureUnitCodes.Celsius, TemperatureUnitCodes.Fahrenheit);
// Result: 212

// Convert 15.85 gallons per minute to liters per second
decimal flowResult = VolumetricFlowRateConversionTreeUtilities.Convert(15.85m, VolumetricFlowRateUnitCodes.GallonPerMinute, VolumetricFlowRateUnitCodes.LiterPerSecond);
// Result: 1.0 (approximately)

Unit Validation

using ScaleUtilities.Utilities;
using ScaleUtilities.Models;
using ScaleUtilities.Constants;

// Create a weight unit
var weightUnit = new WeightUnit(WeightUnitCodes.Kilogram);

// Validate the unit
bool isValid = ScaleUnitValidationUtilities.IsValid(weightUnit);
// Result: true

// Validate type/code combination
bool isValidCombo = ScaleUnitValidationUtilities.IsValid(ScaleTypes.Weight, WeightUnitCodes.Kilogram);
// Result: true

// Validate with exception throwing
try 
{
    ScaleUnitValidationUtilities.Validate(weightUnit);
    Console.WriteLine("Unit is valid!");
}
catch (InvalidScaleUnitException ex)
{
    Console.WriteLine($"Invalid unit: {ex.Message}");
}

Working with Unit Codes

using ScaleUtilities.Constants;

// Check if a unit code is valid
bool isValidWeight = WeightUnitCodes.IsValidWeightUnit("KILOGRAM");
// Result: true

// Get unit system category
string system = WeightUnitCodes.GetUnitSystem("KILOGRAM");
// Result: "Metric"

// Get all available units
string[] allWeightUnits = WeightUnitCodes.AllUnits;
// Result: Array of all weight unit codes

Volumetric Flow Rate Conversions

using ScaleUtilities.Utilities;
using ScaleUtilities.Constants;

// Convert water pump flow rate from liters per second to GPM
decimal pumpFlow = 5m; // 5 L/s
decimal gpm = VolumetricFlowRateConversionTreeUtilities.Convert(
    pumpFlow, 
    VolumetricFlowRateUnitCodes.LiterPerSecond, 
    VolumetricFlowRateUnitCodes.GallonPerMinute);
// Result: 79.25 GPM (approximately)

// Convert medical IV drip rate
decimal ivRate = 125m; // 125 mL/h
decimal mlPerMin = VolumetricFlowRateConversionTreeUtilities.Convert(
    ivRate,
    VolumetricFlowRateUnitCodes.MilliliterPerHour,
    VolumetricFlowRateUnitCodes.MilliliterPerMinute);
// Result: 2.083 mL/min (approximately)

// Get all available volumetric flow rate units
var availableUnits = VolumetricFlowRateConversionTreeUtilities.GetAvailableUnits();
// Returns array of VolumetricFlowRateUnit instances

// Get unit symbol
string symbol = VolumetricFlowRateUnitCodes.GetSymbol(VolumetricFlowRateUnitCodes.GallonPerMinute);
// Result: "gal/min"

Requirements

  • .NET 9.0 or higher
  • NCalc.NetCore 1.0.1 (automatically installed)

License

This library is licensed under the MIT License.

Support

For issues, questions, or contributions, please visit our GitLab repository: https://gitlab.com/iot93/back-end/commons/uom


© 2024 Linh Nguyen. All rights reserved.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on ScaleUtilities:

Package Downloads
IotVn.Measurements.Cores

Package Description

ApiFeatures.Uom.Apis

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.4 86 5/7/2026
1.0.0 300 9/27/2025

Version 2.0.2: Validation Support for Electrical Conductivity and Wireless Signal Strength

✨ NEW FEATURES:
- **Enhanced ScaleUnitValidationUtilities**: Added comprehensive validation support for two additional scale types
 * ElectricalConductivity: Validates all electrical conductivity units (S/m, mS/cm, µS/cm, mho/cm, Ω⁻¹·m⁻¹, etc.)
 * WirelessSignalStrength: Validates all wireless signal strength units (dBm, dBW, dBµW, RSSI, W, %, etc.)
- **Type-Safe Validation**: ScaleUnitValidationUtilities.IsValid() now supports all 12 scale types
- **Comprehensive Test Coverage**: Added extensive unit tests for both new validation types
 * Tests for valid and invalid unit codes
 * Tests for type/code mismatch scenarios
 * Tests for null and empty code handling

🔧 IMPROVEMENTS:
- Complete validation coverage across all scale types in the library
- Better error handling with InvalidScaleUnitException for invalid units
- Improved API consistency for validation methods

📖 USAGE EXAMPLES:

**Electrical Conductivity Validation:**
```csharp
// Using IsValid with ScaleUnit object
var ecUnit = new ElectricalConductivityUnit(ScaleTypes.ElectricalConductivity, "SIEMENS_PER_METER");
bool isValid = ScaleUnitValidationUtilities.IsValid(ecUnit); // Returns true

// Using IsValid with type and code
bool isValid = ScaleUnitValidationUtilities.IsValid(
   ScaleTypes.ElectricalConductivity,
   ElectricalConductivityUnitCodes.MillisiemensPerCentimeter
); // Returns true

// Using Validate (throws exception if invalid)
ScaleUnitValidationUtilities.Validate(ecUnit); // Does not throw
```

**Wireless Signal Strength Validation:**
```csharp
// Using IsValid with ScaleUnit object
var wirelessUnit = new WirelessSignalStrengthUnit(ScaleTypes.WirelessSignalStrength, "DBM");
bool isValid = ScaleUnitValidationUtilities.IsValid(wirelessUnit); // Returns true

// Using IsValid with type and code
bool isValid = ScaleUnitValidationUtilities.IsValid(
   ScaleTypes.WirelessSignalStrength,
   WirelessSignalStrengthUnitCodes.RSSI
); // Returns true

// Using Validate (throws exception if invalid)
ScaleUnitValidationUtilities.Validate(wirelessUnit); // Does not throw
```

**Error Handling:**
```csharp
var invalidUnit = new ElectricalConductivityUnit(ScaleTypes.ElectricalConductivity, "INVALID_CODE");
try
{
   ScaleUnitValidationUtilities.Validate(invalidUnit);
}
catch (InvalidScaleUnitException ex)
{
   Console.WriteLine($"Invalid unit: {ex.Type} - {ex.Code}");
   // Output: "Invalid unit: ElectricalConductivity - INVALID_CODE"
}
```

---

Version 2.0.1: GenericScaleUnit for JSON Serialization/Deserialization

✨ NEW FEATURES:
- **GenericScaleUnit Class**: Introduced new GenericScaleUnit class for improved JSON serialization and deserialization
 * Enables dynamic unit type handling in JSON scenarios
 * Supports all scale types (Weight, Length, Volume, Temperature, Speed, Velocity, Angle, Voltage, Illuminance, Concentration, WirelessSignalStrength, ElectricalConductivity)
 * Seamless integration with existing ScaleUnit hierarchy
 * Ideal for API responses and data transfer objects requiring flexible unit representation

🔧 IMPROVEMENTS:
- Enhanced JSON compatibility across the library
- Better support for dynamic unit type scenarios

---

Version 2.0.0: MAJOR RELEASE - Breaking Changes and Symbol Display Enhancements
   
⚠️ BREAKING CHANGES - MAJOR VERSION UPDATE:
- **API Method Renamed**: GetAvailableUnits() → GetAvailableUnitCodes() in all *ConversionTreeUtilities classes
 * Old method name is no longer available
 * GetAvailableUnitCodes() returns string[] (unit codes only)
 * New GetAvailableUnits() returns strongly-typed ScaleUnit arrays with metadata
- **Return Type Changed**: GetAvailableUnits() now returns ScaleUnit-derived types instead of string[]
 * Migration required for existing code using GetAvailableUnits()
 * See Migration Guide below for step-by-step instructions

✨ NEW FEATURES:
- **Rich Unit Objects**: New GetAvailableUnits() method returns strongly-typed unit classes:
 * WeightUnit[], LengthUnit[], VolumeUnit[], TemperatureUnit[]
 * SpeedUnit[], VelocityUnit[], AngleUnit[], VoltageUnit[]
 * IlluminanceUnit[], ConcentrationUnit[], WirelessSignalStrengthUnit[], ElectricalConductivityUnit[]
- **Enhanced Metadata**: Each unit object includes Type, Code, and Symbol properties
- **Symbol Support**: Added ScaleUnitDto.Symbol property for API responses with proper Unicode encoding
- **ConversionTree.Code Property**: Added missing Code property for better API consistency

🐛 BUG FIXES - Unicode Symbol Display:
- Fixed all Unicode character encoding issues across the library:
 * µ (micro): Microgram, Microvolt, Microwatt, Microsiemens, etc.
 * ℥ (apothecary ounce): Weight units
 * ℧ (mho): Electrical conductivity units
 * Ω (omega/ohm): Electrical conductivity units
 * ° (degree): Angle units
 * π (pi): Angle units (radians)
 * ∟ (right angle): Angle units (was showing as ?)
 * ² (superscript 2): Square units (m², ft², in²)
 * ³ (superscript 3): Cubic units (m³, ft³, in³)
- Fixed missing symbols in IlluminanceUnitCodes: mlx, klx, lm/m², lm/ft², lm/in²
- Fixed missing symbols in VelocityUnitCodes: cm/s, mm/s, in/s, yd/s, c, M
- Fixed typo: Footcandle → FootCandle in IlluminanceUnitCodes
- All source files re-saved with UTF-8 BOM encoding

🔧 IMPROVEMENTS:
- Enhanced web application UTF-8 encoding in Program.cs and _Layout.cshtml
- Added JavaScriptEncoder.UnsafeRelaxedJsonEscaping for proper JSON serialization
- Comprehensive XML documentation for all GetSymbol() methods
- Improved IntelliSense support with rich unit metadata
- Better type safety throughout the library
- Consistent API patterns across all conversion utilities

📖 MIGRATION GUIDE - Upgrading from 1.x to 2.0:

**Before (1.x):**
```csharp
string[] units = WeightConversionTreeUtilities.GetAvailableUnits();
// Returns: ["KILOGRAM", "GRAM", "POUND", ...]
```

**After (2.0):**
```csharp
// Option 1: Get unit codes (same as before)
string[] unitCodes = WeightConversionTreeUtilities.GetAvailableUnitCodes();
// Returns: ["KILOGRAM", "GRAM", "POUND", ...]

// Option 2: Get rich unit objects (NEW!)
WeightUnit[] units = WeightConversionTreeUtilities.GetAvailableUnits();
// Each unit has: Type (ScaleTypes.Weight), Code ("KILOGRAM"), Symbol ("kg")

// Access unit properties:
foreach (var unit in units)
{
   Console.WriteLine($"{unit.Code}: {unit.Symbol} ({unit.Type})");
}
```

**Quick Migration Steps:**
1. Find all calls to `GetAvailableUnits()` in your code
2. If you only need unit codes (strings), rename to `GetAvailableUnitCodes()`
3. If you want unit metadata, keep `GetAvailableUnits()` and update variable types
4. Recompile and test your application

**Web Application Note:**
- Restart your application after updating
- Clear browser cache (Ctrl+Shift+Delete) for proper symbol display
- Unicode symbols (µ, ℥, ℧, Ω, °, ², ³, ∟) now display correctly

For detailed upgrade assistance, visit: https://gitlab.com/iot93/back-end/commons/uom