← 返回 Skills 市场
datadrivenconstruction

Cwicr Cost Calculator

作者 datadrivenconstruction · GitHub ↗ · v2.1.0
darwinlinuxwin32 ⚠ suspicious
1220
总下载
0
收藏
1
当前安装
3
版本数
在 OpenClaw 中安装
/install cwicr-cost-calculator
功能描述
Calculate construction costs using DDC CWICR resource-based methodology. Break down costs into labor, materials, equipment with transparent pricing.
使用说明 (SKILL.md)

\r \r

CWICR Cost Calculator\r

\r

Business Case\r

\r

Problem Statement\r

Traditional cost estimation often produces "black box" estimates with hidden markups. Stakeholders need:\r

  • Transparent cost breakdowns\r
  • Traceable pricing logic\r
  • Auditable calculations\r
  • Resource-level detail\r \r

Solution\r

Resource-based cost calculation using CWICR methodology that separates physical norms (labor hours, material quantities) from volatile prices, enabling transparent and auditable estimates.\r \r

Business Value\r

  • Full transparency - Every cost component visible\r
  • Auditable - Traceable calculation logic\r
  • Flexible - Update prices without changing norms\r
  • Accurate - Based on 55,000+ validated work items\r \r

Technical Implementation\r

\r

Prerequisites\r

pip install pandas numpy\r
```\r
\r
### Python Implementation\r
\r
```python\r
import pandas as pd\r
import numpy as np\r
from typing import Dict, Any, List, Optional, Tuple\r
from dataclasses import dataclass, field\r
from enum import Enum\r
from datetime import datetime\r
\r
\r
class CostComponent(Enum):\r
    """Cost breakdown components."""\r
    LABOR = "labor"\r
    MATERIAL = "material"\r
    EQUIPMENT = "equipment"\r
    OVERHEAD = "overhead"\r
    PROFIT = "profit"\r
    TOTAL = "total"\r
\r
\r
class CostStatus(Enum):\r
    """Cost calculation status."""\r
    CALCULATED = "calculated"\r
    ESTIMATED = "estimated"\r
    MISSING_DATA = "missing_data"\r
    ERROR = "error"\r
\r
\r
@dataclass\r
class CostBreakdown:\r
    """Detailed cost breakdown for a work item."""\r
    work_item_code: str\r
    description: str\r
    unit: str\r
    quantity: float\r
\r
    labor_cost: float = 0.0\r
    material_cost: float = 0.0\r
    equipment_cost: float = 0.0\r
    overhead_cost: float = 0.0\r
    profit_cost: float = 0.0\r
\r
    unit_price: float = 0.0\r
    total_cost: float = 0.0\r
\r
    labor_hours: float = 0.0\r
    labor_rate: float = 0.0\r
\r
    resources: List[Dict[str, Any]] = field(default_factory=list)\r
    status: CostStatus = CostStatus.CALCULATED\r
\r
    def to_dict(self) -> Dict[str, Any]:\r
        return {\r
            'work_item_code': self.work_item_code,\r
            'description': self.description,\r
            'unit': self.unit,\r
            'quantity': self.quantity,\r
            'labor_cost': self.labor_cost,\r
            'material_cost': self.material_cost,\r
            'equipment_cost': self.equipment_cost,\r
            'overhead_cost': self.overhead_cost,\r
            'profit_cost': self.profit_cost,\r
            'total_cost': self.total_cost,\r
            'status': self.status.value\r
        }\r
\r
\r
@dataclass\r
class CostSummary:\r
    """Summary of cost estimate."""\r
    total_cost: float\r
    labor_total: float\r
    material_total: float\r
    equipment_total: float\r
    overhead_total: float\r
    profit_total: float\r
\r
    item_count: int\r
    currency: str\r
    calculated_at: datetime\r
\r
    breakdown_by_category: Dict[str, float] = field(default_factory=dict)\r
\r
\r
class CWICRCostCalculator:\r
    """Resource-based cost calculator using CWICR methodology."""\r
\r
    DEFAULT_OVERHEAD_RATE = 0.15  # 15% overhead\r
    DEFAULT_PROFIT_RATE = 0.10   # 10% profit\r
\r
    def __init__(self, cwicr_data: pd.DataFrame,\r
                 overhead_rate: float = None,\r
                 profit_rate: float = None,\r
                 currency: str = "USD"):\r
        """Initialize calculator with CWICR data."""\r
        self.data = cwicr_data\r
        self.overhead_rate = overhead_rate or self.DEFAULT_OVERHEAD_RATE\r
        self.profit_rate = profit_rate or self.DEFAULT_PROFIT_RATE\r
        self.currency = currency\r
\r
        # Index data for fast lookup\r
        self._index_data()\r
\r
    def _index_data(self):\r
        """Create index for fast work item lookup."""\r
        if 'work_item_code' in self.data.columns:\r
            self._code_index = self.data.set_index('work_item_code')\r
        else:\r
            self._code_index = None\r
\r
    def calculate_item_cost(self, work_item_code: str,\r
                            quantity: float,\r
                            price_overrides: Dict[str, float] = None) -> CostBreakdown:\r
        """Calculate cost for single work item."""\r
\r
        # Find work item in database\r
        if self._code_index is not None and work_item_code in self._code_index.index:\r
            item = self._code_index.loc[work_item_code]\r
        else:\r
            # Try partial match\r
            matches = self.data[\r
                self.data['work_item_code'].str.contains(work_item_code, case=False, na=False)\r
            ]\r
            if matches.empty:\r
                return CostBreakdown(\r
                    work_item_code=work_item_code,\r
                    description="NOT FOUND",\r
                    unit="",\r
                    quantity=quantity,\r
                    status=CostStatus.MISSING_DATA\r
                )\r
            item = matches.iloc[0]\r
\r
        # Get base costs\r
        labor_unit = float(item.get('labor_cost', 0) or 0)\r
        material_unit = float(item.get('material_cost', 0) or 0)\r
        equipment_unit = float(item.get('equipment_cost', 0) or 0)\r
\r
        # Apply price overrides if provided\r
        if price_overrides:\r
            if 'labor_rate' in price_overrides:\r
                labor_norm = float(item.get('labor_norm', 0) or 0)\r
                labor_unit = labor_norm * price_overrides['labor_rate']\r
            if 'material_factor' in price_overrides:\r
                material_unit *= price_overrides['material_factor']\r
            if 'equipment_factor' in price_overrides:\r
                equipment_unit *= price_overrides['equipment_factor']\r
\r
        # Calculate component costs\r
        labor_cost = labor_unit * quantity\r
        material_cost = material_unit * quantity\r
        equipment_cost = equipment_unit * quantity\r
\r
        # Direct costs\r
        direct_cost = labor_cost + material_cost + equipment_cost\r
\r
        # Overhead and profit\r
        overhead_cost = direct_cost * self.overhead_rate\r
        profit_cost = (direct_cost + overhead_cost) * self.profit_rate\r
\r
        # Total\r
        total_cost = direct_cost + overhead_cost + profit_cost\r
\r
        # Unit price\r
        unit_price = total_cost / quantity if quantity > 0 else 0\r
\r
        return CostBreakdown(\r
            work_item_code=work_item_code,\r
            description=str(item.get('description', '')),\r
            unit=str(item.get('unit', '')),\r
            quantity=quantity,\r
            labor_cost=labor_cost,\r
            material_cost=material_cost,\r
            equipment_cost=equipment_cost,\r
            overhead_cost=overhead_cost,\r
            profit_cost=profit_cost,\r
            unit_price=unit_price,\r
            total_cost=total_cost,\r
            labor_hours=float(item.get('labor_norm', 0) or 0) * quantity,\r
            labor_rate=float(item.get('labor_rate', 0) or 0),\r
            status=CostStatus.CALCULATED\r
        )\r
\r
    def calculate_estimate(self, items: List[Dict[str, Any]],\r
                          group_by_category: bool = True) -> CostSummary:\r
        """Calculate cost estimate for multiple items."""\r
\r
        breakdowns = []\r
        for item in items:\r
            code = item.get('work_item_code') or item.get('code')\r
            qty = item.get('quantity', 0)\r
            overrides = item.get('price_overrides')\r
\r
            breakdown = self.calculate_item_cost(code, qty, overrides)\r
            breakdowns.append(breakdown)\r
\r
        # Aggregate totals\r
        labor_total = sum(b.labor_cost for b in breakdowns)\r
        material_total = sum(b.material_cost for b in breakdowns)\r
        equipment_total = sum(b.equipment_cost for b in breakdowns)\r
        overhead_total = sum(b.overhead_cost for b in breakdowns)\r
        profit_total = sum(b.profit_cost for b in breakdowns)\r
        total_cost = sum(b.total_cost for b in breakdowns)\r
\r
        # Group by category if requested\r
        breakdown_by_category = {}\r
        if group_by_category:\r
            for b in breakdowns:\r
                # Extract category from work item code prefix\r
                category = b.work_item_code.split('-')[0] if '-' in b.work_item_code else 'Other'\r
                if category not in breakdown_by_category:\r
                    breakdown_by_category[category] = 0\r
                breakdown_by_category[category] += b.total_cost\r
\r
        return CostSummary(\r
            total_cost=total_cost,\r
            labor_total=labor_total,\r
            material_total=material_total,\r
            equipment_total=equipment_total,\r
            overhead_total=overhead_total,\r
            profit_total=profit_total,\r
            item_count=len(breakdowns),\r
            currency=self.currency,\r
            calculated_at=datetime.now(),\r
            breakdown_by_category=breakdown_by_category\r
        )\r
\r
    def calculate_from_qto(self, qto_df: pd.DataFrame,\r
                          code_column: str = 'work_item_code',\r
                          quantity_column: str = 'quantity') -> pd.DataFrame:\r
        """Calculate costs from Quantity Takeoff DataFrame."""\r
\r
        results = []\r
        for _, row in qto_df.iterrows():\r
            code = row[code_column]\r
            qty = row[quantity_column]\r
\r
            breakdown = self.calculate_item_cost(code, qty)\r
            result = breakdown.to_dict()\r
\r
            # Add original QTO columns\r
            for col in qto_df.columns:\r
                if col not in result:\r
                    result[f'qto_{col}'] = row[col]\r
\r
            results.append(result)\r
\r
        return pd.DataFrame(results)\r
\r
    def apply_regional_factors(self, base_costs: pd.DataFrame,\r
                               region_factors: Dict[str, float]) -> pd.DataFrame:\r
        """Apply regional adjustment factors."""\r
        adjusted = base_costs.copy()\r
\r
        if 'labor_cost' in adjusted.columns and 'labor' in region_factors:\r
            adjusted['labor_cost'] *= region_factors['labor']\r
\r
        if 'material_cost' in adjusted.columns and 'material' in region_factors:\r
            adjusted['material_cost'] *= region_factors['material']\r
\r
        if 'equipment_cost' in adjusted.columns and 'equipment' in region_factors:\r
            adjusted['equipment_cost'] *= region_factors['equipment']\r
\r
        # Recalculate totals\r
        adjusted['direct_cost'] = (\r
            adjusted.get('labor_cost', 0) +\r
            adjusted.get('material_cost', 0) +\r
            adjusted.get('equipment_cost', 0)\r
        )\r
        adjusted['total_cost'] = adjusted['direct_cost'] * (1 + self.overhead_rate) * (1 + self.profit_rate)\r
\r
        return adjusted\r
\r
    def compare_estimates(self, estimate1: CostSummary,\r
                         estimate2: CostSummary) -> Dict[str, Any]:\r
        """Compare two cost estimates."""\r
        return {\r
            'total_difference': estimate2.total_cost - estimate1.total_cost,\r
            'total_percent_change': (\r
                (estimate2.total_cost - estimate1.total_cost) /\r
                estimate1.total_cost * 100 if estimate1.total_cost > 0 else 0\r
            ),\r
            'labor_difference': estimate2.labor_total - estimate1.labor_total,\r
            'material_difference': estimate2.material_total - estimate1.material_total,\r
            'equipment_difference': estimate2.equipment_total - estimate1.equipment_total,\r
            'item_count_difference': estimate2.item_count - estimate1.item_count\r
        }\r
\r
\r
class CostReportGenerator:\r
    """Generate cost reports from calculations."""\r
\r
    def __init__(self, calculator: CWICRCostCalculator):\r
        self.calculator = calculator\r
\r
    def generate_summary_report(self, items: List[Dict[str, Any]]) -> Dict[str, Any]:\r
        """Generate summary cost report."""\r
        summary = self.calculator.calculate_estimate(items)\r
\r
        return {\r
            'report_date': datetime.now().isoformat(),\r
            'currency': summary.currency,\r
            'total_cost': round(summary.total_cost, 2),\r
            'breakdown': {\r
                'labor': round(summary.labor_total, 2),\r
                'material': round(summary.material_total, 2),\r
                'equipment': round(summary.equipment_total, 2),\r
                'overhead': round(summary.overhead_total, 2),\r
                'profit': round(summary.profit_total, 2)\r
            },\r
            'percentages': {\r
                'labor': round(summary.labor_total / summary.total_cost * 100, 1) if summary.total_cost > 0 else 0,\r
                'material': round(summary.material_total / summary.total_cost * 100, 1) if summary.total_cost > 0 else 0,\r
                'equipment': round(summary.equipment_total / summary.total_cost * 100, 1) if summary.total_cost > 0 else 0,\r
            },\r
            'item_count': summary.item_count,\r
            'by_category': summary.breakdown_by_category\r
        }\r
\r
    def generate_detailed_report(self, items: List[Dict[str, Any]]) -> pd.DataFrame:\r
        """Generate detailed line-item report."""\r
        results = []\r
\r
        for item in items:\r
            code = item.get('work_item_code') or item.get('code')\r
            qty = item.get('quantity', 0)\r
\r
            breakdown = self.calculator.calculate_item_cost(code, qty)\r
            results.append(breakdown.to_dict())\r
\r
        df = pd.DataFrame(results)\r
\r
        # Add totals row\r
        totals = df[['labor_cost', 'material_cost', 'equipment_cost',\r
                     'overhead_cost', 'profit_cost', 'total_cost']].sum()\r
        totals['description'] = 'TOTAL'\r
        totals['work_item_code'] = ''\r
\r
        df = pd.concat([df, pd.DataFrame([totals])], ignore_index=True)\r
\r
        return df\r
\r
\r
# Convenience functions\r
def calculate_cost(cwicr_data: pd.DataFrame,\r
                   work_item_code: str,\r
                   quantity: float) -> float:\r
    """Quick cost calculation."""\r
    calc = CWICRCostCalculator(cwicr_data)\r
    breakdown = calc.calculate_item_cost(work_item_code, quantity)\r
    return breakdown.total_cost\r
\r
\r
def estimate_project_cost(cwicr_data: pd.DataFrame,\r
                         items: List[Dict[str, Any]]) -> Dict[str, Any]:\r
    """Quick project cost estimate."""\r
    calc = CWICRCostCalculator(cwicr_data)\r
    report = CostReportGenerator(calc)\r
    return report.generate_summary_report(items)\r
```\r
\r
## Quick Start\r
\r
```python\r
import pandas as pd\r
from cwicr_data_loader import CWICRDataLoader\r
\r
# Load CWICR data\r
loader = CWICRDataLoader()\r
cwicr = loader.load("ddc_cwicr_en.parquet")\r
\r
# Initialize calculator\r
calc = CWICRCostCalculator(cwicr)\r
\r
# Calculate single item\r
breakdown = calc.calculate_item_cost("CONC-001", quantity=150)\r
print(f"Total: ${breakdown.total_cost:,.2f}")\r
print(f"  Labor: ${breakdown.labor_cost:,.2f}")\r
print(f"  Material: ${breakdown.material_cost:,.2f}")\r
print(f"  Equipment: ${breakdown.equipment_cost:,.2f}")\r
```\r
\r
## Common Use Cases\r
\r
### 1. Project Estimate\r
```python\r
items = [\r
    {'work_item_code': 'CONC-001', 'quantity': 150},\r
    {'work_item_code': 'EXCV-002', 'quantity': 200},\r
    {'work_item_code': 'REBAR-003', 'quantity': 15000}  # kg\r
]\r
\r
summary = calc.calculate_estimate(items)\r
print(f"Project Total: ${summary.total_cost:,.2f}")\r
```\r
\r
### 2. QTO Integration\r
```python\r
# Load BIM quantities\r
qto = pd.read_excel("quantities.xlsx")\r
\r
# Calculate costs\r
costs = calc.calculate_from_qto(qto,\r
    code_column='work_item',\r
    quantity_column='quantity'\r
)\r
print(costs[['description', 'quantity', 'total_cost']])\r
```\r
\r
### 3. Regional Adjustment\r
```python\r
# Apply Berlin pricing\r
berlin_factors = {\r
    'labor': 1.15,      # 15% higher labor\r
    'material': 0.95,   # 5% lower materials\r
    'equipment': 1.0\r
}\r
\r
adjusted = calc.apply_regional_factors(costs, berlin_factors)\r
```\r
\r
## Resources\r
\r
- **GitHub**: [OpenConstructionEstimate-DDC-CWICR](https://github.com/datadrivenconstruction/OpenConstructionEstimate-DDC-CWICR)\r
- **DDC Book**: Chapter 3.1 - Construction Cost Estimation\r
安全使用建议
What to check before installing or using this skill: - Ask the publisher where the CWICR dataset (the 55k work items) is expected to come from. If you must supply the dataset, confirm the exact file path and format before allowing filesystem access. - Confirm whether your runtime will actually execute the provided pip install commands; if so, run them in a controlled environment (virtualenv/container) rather than your main system. - Verify claw.json's filesystem permission scope with your platform: ensure the skill can only read the intended dataset and not arbitrary files. - Because the skill has no declared install spec or packaged dataset, expect some manual setup (installing pandas/numpy, supplying the CWICR CSV/DB). If you do not trust the source (owner ID unknown), avoid giving it access to sensitive files. - Note there are no credentials requested (good). If the skill later asks for external endpoints, API keys, or uploads data, treat that as a significant change and re-evaluate. - If you need higher assurance, request the dataset source, a formal install script, or a signed release from the publisher before running the skill in production.
功能分析
Type: OpenClaw Skill Name: cwicr-cost-calculator Version: 2.1.0 The OpenClaw skill 'cwicr-cost-calculator' is classified as benign. The Python code implements a construction cost calculator using standard libraries (pandas, numpy) without any direct calls to risky functions like os.system, subprocess, eval, or network operations. The `filesystem` permission requested in `claw.json` is justified by the skill's need to load local data files (e.g., .parquet, .xlsx) as demonstrated in the `SKILL.md` examples. There is no evidence of prompt injection attempts in `SKILL.md` or `instructions.md`, nor any signs of data exfiltration, malicious execution, persistence mechanisms, or obfuscation.
能力评估
Purpose & Capability
Name/description, instructions, and embedded Python implementation all describe a resource-based CWICR cost calculator — that is coherent. However the SKILL references a large CWICR database (55k+ items) but provides no dataset, no config path, and no guidance where the data is stored. claw.json declares filesystem permission which suggests the skill expects to read local files; this capability is plausible for the stated purpose but the relationship is underspecified.
Instruction Scope
The runtime instructions focus on identifying work items, looking up norms, applying prices, and producing breakdowns — all within scope. The SKILL.md also includes Python code and explicitly instructs installing packages (pip install pandas numpy). The instructions do not attempt to read unrelated system files or request secrets, but they are open-ended about where to obtain the CWICR database and 'current unit prices', giving the agent broad discretion to ask the user or load local files.
Install Mechanism
There is no formal install spec (instruction-only), yet SKILL.md tells the user to run pip install pandas numpy. That is common for Python snippets but is an unstated side-effect: it requires network access and package installation if the environment lacks them. No URLs or external installers are embedded in the skill itself.
Credentials
The skill requests no environment variables, no credentials, and declares no required config paths. That is proportionate for a calculation tool. The only permission in claw.json is 'filesystem', which is reasonable if the skill needs to read a local CWICR dataset — but the dataset path is not declared.
Persistence & Privilege
always:false and default autonomous invocation are set (normal). The skill does not request persistent elevated privileges. The one notable privilege is claw.json's 'filesystem' permission; combined with lack of explicit data-path declarations, this could allow the agent to read arbitrary files if the runtime enforces that permission broadly. This is not definitive malicious behavior but it is a scope gap to clarify.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install cwicr-cost-calculator
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /cwicr-cost-calculator 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v2.1.0
- Added homepage and metadata fields to SKILL.md for improved documentation and platform compatibility. - Metadata includes supported OS platforms, required binaries (python3), and an emoji icon for better discoverability. - No code or functional changes to the skill itself.
v2.0.0
cwicr-cost-calculator 2.0.0 - Major rewrite: Adds a robust, transparent construction cost calculator using the DDC CWICR resource-based methodology. - Breaks down estimates into labor, materials, equipment, overhead, and profit with full pricing transparency. - Includes Python implementation with detailed dataclasses (CostBreakdown, CostSummary) for structured cost reporting. - Supports customizable resource price overrides and group category summaries. - Enhances auditability and flexibility compared to traditional “black box” estimates.
v1.0.0
CWICR Cost Calculator 1.0.0 initial release: - Enables transparent construction cost calculation using DDC CWICR resource-based methodology. - Provides detailed breakdowns of labor, materials, equipment, overhead, and profit per work item. - Supports price and rate overrides for flexible, auditable estimates. - Returns both itemized cost breakdowns and project summaries, exportable via dictionary structures. - Built with Python using pandas and numpy; easy integration into estimation workflows.
元数据
Slug cwicr-cost-calculator
版本 2.1.0
许可证
累计安装 1
当前安装数 1
历史版本数 3
常见问题

Cwicr Cost Calculator 是什么?

Calculate construction costs using DDC CWICR resource-based methodology. Break down costs into labor, materials, equipment with transparent pricing. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 1220 次。

如何安装 Cwicr Cost Calculator?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install cwicr-cost-calculator」即可一键安装,无需额外配置。

Cwicr Cost Calculator 是免费的吗?

是的,Cwicr Cost Calculator 完全免费(开源免费),可自由下载、安装和使用。

Cwicr Cost Calculator 支持哪些平台?

Cwicr Cost Calculator 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(darwin, linux, win32)。

谁开发了 Cwicr Cost Calculator?

由 datadrivenconstruction(@datadrivenconstruction)开发并维护,当前版本 v2.1.0。

💬 留言讨论