SkillAgentSearch skills...

cwicr-unit-converter

Convert between construction measurement units. Handle metric/imperial conversion, area/volume calculations, and unit normalization for CWICR data.

Install / Use

npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill cwicr-unit-converter

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

91/100

Supported Platforms

Universal

Our assessment of cwicr-unit-converter

cwicr-unit-converter scores 91/100 on our quality scale, 1219th of 4,644 Development & Engineering skills we index (top 27%).

Its SKILL.md is 17 KB long, well organised into 19 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.

It has 333 GitHub stars, a meaningful sign that others use it.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
11/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 44 days ago, so cwicr-unit-converter is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

cwicr-unit-converter compared with similar skills

All 4 of these similar skills score higher than cwicr-unit-converter; compare them before choosing.

SkillScoreStarsUpdatedFormat
cwicr-unit-converter (this skill)by datadrivenconstruction9133344d agoSKILL.md
Agent-Reachby Panniantong10091.2k19d agoCLAUDE.md
headroomby headroomlabs-ai10074.4ktodayCLAUDE.md
ai-job-searchby MadsLorentzen10045.0k1d agoCLAUDE.md
claude-howtoby luongnv8910041.7k5d agoCLAUDE.md

Frequently asked questions

How do I install cwicr-unit-converter?
Run npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill cwicr-unit-converter. The install tabs above show the steps for each supported agent.
Which AI agents does cwicr-unit-converter work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is cwicr-unit-converter safe to use?
It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is cwicr-unit-converter still maintained?
The repository was last updated 44 days ago, so cwicr-unit-converter is actively maintained.

name: "cwicr-unit-converter" description: "Convert between construction measurement units. Handle metric/imperial conversion, area/volume calculations, and unit normalization for CWICR data." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "🗄️", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}

CWICR Unit Converter

Business Case

Problem Statement

Construction data comes in various unit systems:

  • Metric vs Imperial measurements
  • Different unit conventions by trade
  • BIM quantities need normalization
  • Regional standards differ

Solution

Comprehensive unit conversion for construction quantities, normalizing data for CWICR integration and analysis.

Business Value

  • Accuracy - Eliminate unit conversion errors
  • Consistency - Standardize across projects
  • Integration - BIM to cost data alignment
  • Global - Support international projects

Technical Implementation

import pandas as pd
import numpy as np
from typing import Dict, Any, List, Optional, Tuple, Union
from dataclasses import dataclass
from enum import Enum


class UnitCategory(Enum):
    """Categories of measurement units."""
    LENGTH = "length"
    AREA = "area"
    VOLUME = "volume"
    WEIGHT = "weight"
    TIME = "time"
    QUANTITY = "quantity"


class UnitSystem(Enum):
    """Unit systems."""
    METRIC = "metric"
    IMPERIAL = "imperial"
    MIXED = "mixed"


@dataclass
class UnitConversion:
    """Unit conversion result."""
    original_value: float
    original_unit: str
    converted_value: float
    target_unit: str
    conversion_factor: float
    category: UnitCategory


# Conversion factors to base units
# Base units: meter (length), m² (area), m³ (volume), kg (weight), hour (time)

CONVERSIONS = {
    # Length to meters
    'm': {'factor': 1.0, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'meter': {'factor': 1.0, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'meters': {'factor': 1.0, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'cm': {'factor': 0.01, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'mm': {'factor': 0.001, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'km': {'factor': 1000.0, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'ft': {'factor': 0.3048, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'feet': {'factor': 0.3048, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'foot': {'factor': 0.3048, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'in': {'factor': 0.0254, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'inch': {'factor': 0.0254, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'inches': {'factor': 0.0254, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'yd': {'factor': 0.9144, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'yard': {'factor': 0.9144, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'yards': {'factor': 0.9144, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'mi': {'factor': 1609.344, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'mile': {'factor': 1609.344, 'category': UnitCategory.LENGTH, 'base': 'm'},
    'lf': {'factor': 0.3048, 'category': UnitCategory.LENGTH, 'base': 'm'},  # Linear foot

    # Area to m²
    'm2': {'factor': 1.0, 'category': UnitCategory.AREA, 'base': 'm2'},
    'm²': {'factor': 1.0, 'category': UnitCategory.AREA, 'base': 'm2'},
    'sqm': {'factor': 1.0, 'category': UnitCategory.AREA, 'base': 'm2'},
    'cm2': {'factor': 0.0001, 'category': UnitCategory.AREA, 'base': 'm2'},
    'mm2': {'factor': 0.000001, 'category': UnitCategory.AREA, 'base': 'm2'},
    'ha': {'factor': 10000.0, 'category': UnitCategory.AREA, 'base': 'm2'},
    'hectare': {'factor': 10000.0, 'category': UnitCategory.AREA, 'base': 'm2'},
    'ft2': {'factor': 0.092903, 'category': UnitCategory.AREA, 'base': 'm2'},
    'sf': {'factor': 0.092903, 'category': UnitCategory.AREA, 'base': 'm2'},
    'sqft': {'factor': 0.092903, 'category': UnitCategory.AREA, 'base': 'm2'},
    'yd2': {'factor': 0.836127, 'category': UnitCategory.AREA, 'base': 'm2'},
    'sy': {'factor': 0.836127, 'category': UnitCategory.AREA, 'base': 'm2'},  # Square yard
    'acre': {'factor': 4046.86, 'category': UnitCategory.AREA, 'base': 'm2'},

    # Volume to m³
    'm3': {'factor': 1.0, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'm³': {'factor': 1.0, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'cbm': {'factor': 1.0, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'l': {'factor': 0.001, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'liter': {'factor': 0.001, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'litre': {'factor': 0.001, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'ml': {'factor': 0.000001, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'ft3': {'factor': 0.0283168, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'cf': {'factor': 0.0283168, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'cuft': {'factor': 0.0283168, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'yd3': {'factor': 0.764555, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'cy': {'factor': 0.764555, 'category': UnitCategory.VOLUME, 'base': 'm3'},  # Cubic yard
    'cuyd': {'factor': 0.764555, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'gal': {'factor': 0.00378541, 'category': UnitCategory.VOLUME, 'base': 'm3'},
    'gallon': {'factor': 0.00378541, 'category': UnitCategory.VOLUME, 'base': 'm3'},

    # Weight to kg
    'kg': {'factor': 1.0, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'kilogram': {'factor': 1.0, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'g': {'factor': 0.001, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'gram': {'factor': 0.001, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'mg': {'factor': 0.000001, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    't': {'factor': 1000.0, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'ton': {'factor': 1000.0, 'category': UnitCategory.WEIGHT, 'base': 'kg'},  # Metric ton
    'tonne': {'factor': 1000.0, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'mt': {'factor': 1000.0, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'lb': {'factor': 0.453592, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'lbs': {'factor': 0.453592, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'pound': {'factor': 0.453592, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'oz': {'factor': 0.0283495, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'ounce': {'factor': 0.0283495, 'category': UnitCategory.WEIGHT, 'base': 'kg'},
    'st': {'factor': 907.185, 'category': UnitCategory.WEIGHT, 'base': 'kg'},  # Short ton (US)

    # Time to hours
    'hr': {'factor': 1.0, 'category': UnitCategory.TIME, 'base': 'hr'},
    'hour': {'factor': 1.0, 'category': UnitCategory.TIME, 'base': 'hr'},
    'hours': {'factor': 1.0, 'category': UnitCategory.TIME, 'base': 'hr'},
    'h': {'factor': 1.0, 'category': UnitCategory.TIME, 'base': 'hr'},
    'min': {'factor': 1/60, 'category': UnitCategory.TIME, 'base': 'hr'},
    'minute': {'factor': 1/60, 'category': UnitCategory.TIME, 'base': 'hr'},
    'day': {'factor': 8.0, 'category': UnitCategory.TIME, 'base': 'hr'},  # 8-hour workday
    'days': {'factor': 8.0, 'category': UnitCategory.TIME, 'base': 'hr'},
    'week': {'factor': 40.0, 'category': UnitCategory.TIME, 'base': 'hr'},  # 40-hour week

    # Quantity (no conversion, just counting)
    'ea': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'each': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'pc': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'pcs': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'piece': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'pieces': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'no': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'nr': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'set': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'lot': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},
    'ls': {'factor': 1.0, 'category': UnitCategory.QUANTITY, 'base': 'ea'},  # Lump sum
}


class CWICRUnitConverter:
    """Convert between construction units."""

    def __init__(self):
        self.conversions = CONVERSIONS

    def normalize_unit(self, unit: str) -> str:
        """Normalize unit string for lookup."""
        return str(unit).lower().strip().replace(' ', '').replace('.', '')

    def get_unit_info(self, unit: str) -> Optional[Dict[str, Any]]:
        """Get conversion info for unit."""
        normalized = self.normalize_unit(unit)
        return self.conversions.get(normalized)

    def convert(self,
                value: float,
                from_unit: str,
                to_unit: str) -> UnitConversion:
        """Convert value between units."""

        from_info = self.get_unit_info(from_unit)
        to_info = self.get_unit_info(to_unit)

        if not from_info:
            raise ValueError(f"Unknown source unit: {from_unit}")
        if not to_info:
            raise ValueError(f"Unknown target unit: {to_unit}")

        if from_info['category'] != to_info['category']:
            raise ValueError(
                f"Cannot convert between {from_info['category'].value} and {to_info['category'].value}"
            )

        # Convert: source -> base -> target
        base_value = value * from_info['factor']
        converted_value = base_value / to_info['factor']
        conversion_factor = from_info['factor'] / to_info['factor']

        return UnitConversion(
            original_value=value,
            original_unit=from_unit,
            converted_value=round(converted_value, 6),
            target_unit=to_unit,
            conversion_factor=conversion_factor,
            category=from_info['category']
        )

    def to_metric(self, value: float, from_unit: str) -> UnitConversion:
        """Convert to standard metric unit."""

        info = self.get_unit_info(from_unit)
        if not info:
            raise ValueError(f"Unknown unit: {from_unit}")

        base_unit = info['base']
        return self.convert(value, from_unit, base_unit)

    def to_imperial(self, value: float, from_unit: str) -> UnitConversion:
        """Convert to common imperial unit."""

        info = self.get_unit_info(from_unit)
        if not info:
            raise ValueError(f"Unknown unit: {from_unit}")

        imperial_map = {
            'm': 'ft',
            'm2': 'sf',
            'm3': 'cy',
            'kg': 'lb',
            'hr': 'hr'
        }

        base = info['base']
        imperial_unit = imperial_map.get(base, base)

        return self.convert(value, from_unit, imperial_unit)

    def convert_dataframe(self,
                          df: pd.DataFrame,
                          value_column: str,
                          unit_column: str,
                          target_unit: str,
                          output_column: str = None) -> pd.DataFrame:
        """Convert units in DataFrame column."""

        result = df.copy()
        if output_column is None:
            output_column = f"{value_column}_converted"

        converted_values = []
        for _, row in df.iterrows():
            try:
                conversion = self.convert(
                    row[value_column],
                    row[unit_column],
                    target_unit
                )
                converted_values.append(conversion.converted_value)
            except ValueError:
                converted_values.append(None)

        result[output_column] = converted_values
        result[f'{output_column}_unit'] = target_unit

        return result

    def normalize_units(self,
                        df: pd.D

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars333
CategoryDevelopment
Updated1mo ago
Forks82

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions