labor-rate

Calculate construction labor rates with overhead, benefits, and productivity factors. Regional rate databases and crew composition.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "labor-rate" with this command: npx skills add datadrivenconstruction/labor-rate

Labor Rate Calculator

Overview

Labor costs account for 30-50% of construction costs. This skill calculates all-in labor rates including wages, benefits, overhead, and regional adjustments.

Python Implementation

import pandas as pd
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from enum import Enum


class LaborCategory(Enum):
    """Labor skill categories."""
    LABORER = "laborer"
    CARPENTER = "carpenter"
    ELECTRICIAN = "electrician"
    PLUMBER = "plumber"
    IRONWORKER = "ironworker"
    MASON = "mason"
    OPERATOR = "equipment_operator"
    FOREMAN = "foreman"
    SUPERINTENDENT = "superintendent"


class WorkType(Enum):
    """Work type for productivity."""
    NEW_CONSTRUCTION = "new"
    RENOVATION = "renovation"
    DEMOLITION = "demolition"
    MAINTENANCE = "maintenance"


@dataclass
class LaborRate:
    """Complete labor rate breakdown."""
    category: str
    base_wage: float
    benefits: float
    taxes: float
    insurance: float
    overhead: float
    profit: float
    total_rate: float
    unit: str = "hour"


@dataclass
class CrewComposition:
    """Crew composition for work."""
    name: str
    workers: List[Dict[str, Any]]
    total_hourly_cost: float
    output_per_hour: float
    unit: str


class LaborRateCalculator:
    """Calculate construction labor rates."""

    # Default burden rates (percent of base wage)
    DEFAULT_BURDENS = {
        'benefits': 0.30,        # Health, pension, vacation
        'taxes': 0.10,           # FICA, unemployment
        'insurance': 0.08,       # Workers comp, liability
        'overhead': 0.15,        # General conditions
        'profit': 0.10           # Contractor profit
    }

    # Base wages by category (USD/hour, US average)
    BASE_WAGES = {
        LaborCategory.LABORER: 22,
        LaborCategory.CARPENTER: 32,
        LaborCategory.ELECTRICIAN: 38,
        LaborCategory.PLUMBER: 36,
        LaborCategory.IRONWORKER: 35,
        LaborCategory.MASON: 34,
        LaborCategory.OPERATOR: 40,
        LaborCategory.FOREMAN: 45,
        LaborCategory.SUPERINTENDENT: 55
    }

    # Regional factors
    REGIONAL_FACTORS = {
        'US_National': 1.00,
        'New_York': 1.45,
        'San_Francisco': 1.40,
        'Chicago': 1.15,
        'Houston': 0.95,
        'Atlanta': 0.90,
        'Germany_Berlin': 1.20,
        'UK_London': 1.35
    }

    def __init__(self, burden_rates: Dict[str, float] = None):
        self.burdens = burden_rates or self.DEFAULT_BURDENS

    def calculate_rate(self, category: LaborCategory,
                       region: str = 'US_National',
                       custom_wage: float = None) -> LaborRate:
        """Calculate all-in labor rate."""

        # Get base wage
        base = custom_wage or self.BASE_WAGES.get(category, 25)

        # Apply regional factor
        regional_factor = self.REGIONAL_FACTORS.get(region, 1.0)
        base *= regional_factor

        # Calculate burden components
        benefits = base * self.burdens['benefits']
        taxes = base * self.burdens['taxes']
        insurance = base * self.burdens['insurance']

        # Subtotal before markup
        subtotal = base + benefits + taxes + insurance

        # Overhead and profit
        overhead = subtotal * self.burdens['overhead']
        profit = (subtotal + overhead) * self.burdens['profit']

        total = subtotal + overhead + profit

        return LaborRate(
            category=category.value,
            base_wage=round(base, 2),
            benefits=round(benefits, 2),
            taxes=round(taxes, 2),
            insurance=round(insurance, 2),
            overhead=round(overhead, 2),
            profit=round(profit, 2),
            total_rate=round(total, 2)
        )

    def calculate_crew_cost(self, composition: Dict[LaborCategory, int],
                            region: str = 'US_National') -> float:
        """Calculate hourly cost for crew composition."""

        total = 0
        for category, count in composition.items():
            rate = self.calculate_rate(category, region)
            total += rate.total_rate * count

        return round(total, 2)

    def get_rate_table(self, region: str = 'US_National') -> pd.DataFrame:
        """Generate rate table for all categories."""

        rates = []
        for category in LaborCategory:
            rate = self.calculate_rate(category, region)
            rates.append({
                'category': rate.category,
                'base_wage': rate.base_wage,
                'benefits': rate.benefits,
                'taxes': rate.taxes,
                'insurance': rate.insurance,
                'overhead': rate.overhead,
                'profit': rate.profit,
                'total_rate': rate.total_rate
            })

        return pd.DataFrame(rates)


class ProductivityFactor:
    """Calculate productivity factors for labor."""

    # Base productivity factors
    WORK_TYPE_FACTORS = {
        WorkType.NEW_CONSTRUCTION: 1.0,
        WorkType.RENOVATION: 0.75,
        WorkType.DEMOLITION: 0.90,
        WorkType.MAINTENANCE: 0.65
    }

    # Condition factors
    CONDITION_FACTORS = {
        'ideal': 1.0,
        'normal': 0.90,
        'difficult': 0.75,
        'hazardous': 0.60,
        'confined_space': 0.50
    }

    # Weather factors
    WEATHER_FACTORS = {
        'clear': 1.0,
        'hot': 0.85,
        'cold': 0.80,
        'rain': 0.60,
        'wind': 0.75
    }

    def calculate_factor(self, work_type: WorkType,
                         condition: str = 'normal',
                         weather: str = 'clear',
                         overtime_hours: int = 0) -> float:
        """Calculate combined productivity factor."""

        base = self.WORK_TYPE_FACTORS.get(work_type, 1.0)
        cond = self.CONDITION_FACTORS.get(condition, 0.9)
        weath = self.WEATHER_FACTORS.get(weather, 1.0)

        # Overtime degradation (productivity drops after 8 hours)
        overtime_factor = 1.0
        if overtime_hours > 0:
            # Each OT hour is ~15% less productive
            overtime_factor = 1 - (overtime_hours * 0.015)

        combined = base * cond * weath * overtime_factor
        return round(max(combined, 0.3), 2)  # Minimum 30% productivity

    def adjust_labor_hours(self, base_hours: float,
                           work_type: WorkType,
                           condition: str = 'normal',
                           weather: str = 'clear') -> float:
        """Adjust labor hours for conditions."""

        factor = self.calculate_factor(work_type, condition, weather)
        return round(base_hours / factor, 1)


class CrewBuilder:
    """Build and optimize crew compositions."""

    # Standard crew compositions
    STANDARD_CREWS = {
        'concrete_pour': {
            LaborCategory.FOREMAN: 1,
            LaborCategory.CARPENTER: 2,
            LaborCategory.LABORER: 4,
            LaborCategory.OPERATOR: 1
        },
        'framing': {
            LaborCategory.FOREMAN: 1,
            LaborCategory.CARPENTER: 4,
            LaborCategory.LABORER: 2
        },
        'electrical_rough': {
            LaborCategory.FOREMAN: 1,
            LaborCategory.ELECTRICIAN: 3,
            LaborCategory.LABORER: 1
        },
        'plumbing_rough': {
            LaborCategory.FOREMAN: 1,
            LaborCategory.PLUMBER: 2,
            LaborCategory.LABORER: 1
        },
        'masonry': {
            LaborCategory.FOREMAN: 1,
            LaborCategory.MASON: 4,
            LaborCategory.LABORER: 4
        }
    }

    def __init__(self, rate_calculator: LaborRateCalculator):
        self.calc = rate_calculator

    def get_crew(self, work_type: str,
                 region: str = 'US_National') -> CrewComposition:
        """Get standard crew composition with costs."""

        if work_type not in self.STANDARD_CREWS:
            raise ValueError(f"Unknown work type: {work_type}")

        composition = self.STANDARD_CREWS[work_type]
        total_cost = self.calc.calculate_crew_cost(composition, region)

        workers = []
        for category, count in composition.items():
            rate = self.calc.calculate_rate(category, region)
            workers.append({
                'category': category.value,
                'count': count,
                'hourly_rate': rate.total_rate,
                'subtotal': rate.total_rate * count
            })

        return CrewComposition(
            name=work_type,
            workers=workers,
            total_hourly_cost=total_cost,
            output_per_hour=1.0,  # Placeholder
            unit='hour'
        )

    def custom_crew(self, workers: Dict[LaborCategory, int],
                    region: str = 'US_National') -> CrewComposition:
        """Build custom crew composition."""

        total_cost = self.calc.calculate_crew_cost(workers, region)

        worker_list = []
        for category, count in workers.items():
            rate = self.calc.calculate_rate(category, region)
            worker_list.append({
                'category': category.value,
                'count': count,
                'hourly_rate': rate.total_rate,
                'subtotal': rate.total_rate * count
            })

        return CrewComposition(
            name='custom',
            workers=worker_list,
            total_hourly_cost=total_cost,
            output_per_hour=1.0,
            unit='hour'
        )

Quick Start

calc = LaborRateCalculator()

# Get single rate
rate = calc.calculate_rate(LaborCategory.CARPENTER, region='New_York')
print(f"Carpenter rate NYC: ${rate.total_rate}/hr")

# Rate table
rates = calc.get_rate_table('US_National')
print(rates)

Common Use Cases

1. Crew Cost

builder = CrewBuilder(calc)
concrete_crew = builder.get_crew('concrete_pour', 'Chicago')
print(f"Crew cost: ${concrete_crew.total_hourly_cost}/hr")

2. Productivity Adjustment

productivity = ProductivityFactor()
factor = productivity.calculate_factor(
    WorkType.RENOVATION,
    condition='difficult',
    weather='hot'
)
adjusted_hours = productivity.adjust_labor_hours(100, WorkType.RENOVATION)

Resources

  • DDC Book: Chapter 3.1 - Resource-Based Costing

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Shareone

发布本地生成的 HTML 网页、PDF 或 PPTX 到 ShareOne 平台,生成公网分享短链接(Capability URL)。当用户要求“发布”、“分享”、“生成链接”或“上线”某个生成的页面/文档时使用此技能。

Registry SourceRecently Updated
General

魔搭图片生成

魔搭(ModelScope)AI 图片生成。支持多种模型、LoRA 微调。触发词:生成图片、AI绘画、文生图、image generation、generate image。当用户要求生成图片、画图、AI 作画,或提到魔搭、ModelScope时使用。

Registry SourceRecently Updated
General

Google Drive Setup

Configure Google Drive mount on Linux via rclone + gog OAuth. Use when user wants to mount Google Drive as local filesystem, set up auto-mount on boot, or co...

Registry SourceRecently Updated
General

Meeting Notes Generator

智能会议纪要整理专家,保证信息100%不遗漏且字数至少2000字。当用户要求整理会议记录、生成会议纪要、提取会议要点、总结会议内容、将录音转文字文档转换为结构化纪要时使用此技能。特别适用于需要保证信息完整性和详细程度的场景。触发短语包括但不限于:帮我整理会议记录、会议纪要怎么写、生成会议纪要、整理会议要点、会议总...

Registry SourceRecently Updated