<< All versions
Skill v1.0.1
currentAutomated scan100/100datadrivenconstruction/ddc_skills_for_ai_agents_in_construction/daily-progress-report
1 files
──Details
PublishedSeptember 29, 2026 at 05:59 AM
Content Hashsha256:5177524190bf7cd6...
Git SHAce45bbfbdd63
Bump Typepatch
──Files
Files (1 file, 11.6 KB)
SKILL.md11.6 KBactive
SKILL.md · 388 lines · 11.6 KB
version: "1.0.1" name: "daily-progress-report" description: "Generate automated daily progress reports from site data. Track work completed, labor hours, equipment usage, and weather conditions." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "📊", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
Daily Progress Report Generator
Business Case
Problem Statement
Site managers spend hours creating daily reports:
- Manual data collection
- Inconsistent formats
- Delayed submissions
- Missing information
Solution
Automated daily progress report generation from structured site data inputs.
Technical Implementation
python
import pandas as pdfrom datetime import datetime, datefrom typing import Dict, Any, Listfrom dataclasses import dataclassfrom enum import Enumclass WeatherCondition(Enum):CLEAR = "clear"CLOUDY = "cloudy"RAIN = "rain"SNOW = "snow"WIND = "wind"EXTREME = "extreme"class WorkStatus(Enum):COMPLETED = "completed"IN_PROGRESS = "in_progress"DELAYED = "delayed"NOT_STARTED = "not_started"@dataclassclass WorkActivity:activity_id: strdescription: strlocation: strplanned_qty: floatactual_qty: floatunit: strstatus: WorkStatuscrew_size: inthours_worked: floatnotes: str = ""@dataclassclass LaborEntry:trade: strcompany: strworkers: inthours: floatovertime_hours: float = 0@dataclassclass EquipmentEntry:equipment_type: strequipment_id: strhours_used: floatstatus: str # active, idle, maintenanceoperator: str = ""@dataclassclass DailyReport:report_date: dateproject_name: strproject_number: strweather: WeatherConditiontemperature_high: floattemperature_low: floatwork_activities: List[WorkActivity]labor: List[LaborEntry]equipment: List[EquipmentEntry]delays: List[str]safety_incidents: intvisitors: List[str]deliveries: List[str]prepared_by: strclass DailyProgressReporter:"""Generate daily progress reports."""def __init__(self, project_name: str, project_number: str):self.project_name = project_nameself.project_number = project_numberdef create_report(self,report_date: date,weather: WeatherCondition,temp_high: float,temp_low: float,prepared_by: str) -> DailyReport:"""Create new daily report."""return DailyReport(report_date=report_date,project_name=self.project_name,project_number=self.project_number,weather=weather,temperature_high=temp_high,temperature_low=temp_low,work_activities=[],labor=[],equipment=[],delays=[],safety_incidents=0,visitors=[],deliveries=[],prepared_by=prepared_by)def add_work_activity(self,report: DailyReport,activity_id: str,description: str,location: str,planned_qty: float,actual_qty: float,unit: str,crew_size: int,hours_worked: float,notes: str = ""):"""Add work activity to report."""# Determine statusif actual_qty >= planned_qty:status = WorkStatus.COMPLETEDelif actual_qty > 0:status = WorkStatus.IN_PROGRESSelif actual_qty == 0 and planned_qty > 0:status = WorkStatus.DELAYEDelse:status = WorkStatus.NOT_STARTEDactivity = WorkActivity(activity_id=activity_id,description=description,location=location,planned_qty=planned_qty,actual_qty=actual_qty,unit=unit,status=status,crew_size=crew_size,hours_worked=hours_worked,notes=notes)report.work_activities.append(activity)def add_labor(self,report: DailyReport,trade: str,company: str,workers: int,hours: float,overtime_hours: float = 0):"""Add labor entry."""report.labor.append(LaborEntry(trade=trade,company=company,workers=workers,hours=hours,overtime_hours=overtime_hours))def add_equipment(self,report: DailyReport,equipment_type: str,equipment_id: str,hours_used: float,status: str,operator: str = ""):"""Add equipment entry."""report.equipment.append(EquipmentEntry(equipment_type=equipment_type,equipment_id=equipment_id,hours_used=hours_used,status=status,operator=operator))def calculate_summary(self, report: DailyReport) -> Dict[str, Any]:"""Calculate report summary metrics."""total_workers = sum(l.workers for l in report.labor)total_manhours = sum(l.workers * l.hours for l in report.labor)total_overtime = sum(l.workers * l.overtime_hours for l in report.labor)equipment_hours = sum(e.hours_used for e in report.equipment)completed = sum(1 for a in report.work_activities if a.status == WorkStatus.COMPLETED)in_progress = sum(1 for a in report.work_activities if a.status == WorkStatus.IN_PROGRESS)delayed = sum(1 for a in report.work_activities if a.status == WorkStatus.DELAYED)return {'total_workers': total_workers,'total_manhours': round(total_manhours, 1),'total_overtime': round(total_overtime, 1),'equipment_hours': round(equipment_hours, 1),'activities_completed': completed,'activities_in_progress': in_progress,'activities_delayed': delayed,'safety_incidents': report.safety_incidents,'deliveries_count': len(report.deliveries)}def export_to_excel(self, report: DailyReport, output_path: str) -> str:"""Export report to Excel."""with pd.ExcelWriter(output_path, engine='openpyxl') as writer:# Headerheader_df = pd.DataFrame([{'Project': report.project_name,'Project #': report.project_number,'Date': report.report_date,'Weather': report.weather.value,'High Temp': report.temperature_high,'Low Temp': report.temperature_low,'Prepared By': report.prepared_by}])header_df.to_excel(writer, sheet_name='Summary', index=False)# Work Activitiesif report.work_activities:activities_df = pd.DataFrame([{'Activity ID': a.activity_id,'Description': a.description,'Location': a.location,'Planned': a.planned_qty,'Actual': a.actual_qty,'Unit': a.unit,'Status': a.status.value,'Crew': a.crew_size,'Hours': a.hours_worked,'Notes': a.notes}for a in report.work_activities])activities_df.to_excel(writer, sheet_name='Work Activities', index=False)# Laborif report.labor:labor_df = pd.DataFrame([{'Trade': l.trade,'Company': l.company,'Workers': l.workers,'Hours': l.hours,'Overtime': l.overtime_hours,'Total Hours': l.workers * (l.hours + l.overtime_hours)}for l in report.labor])labor_df.to_excel(writer, sheet_name='Labor', index=False)# Equipmentif report.equipment:equip_df = pd.DataFrame([{'Type': e.equipment_type,'ID': e.equipment_id,'Hours': e.hours_used,'Status': e.status,'Operator': e.operator}for e in report.equipment])equip_df.to_excel(writer, sheet_name='Equipment', index=False)return output_pathdef generate_text_report(self, report: DailyReport) -> str:"""Generate text version of report."""summary = self.calculate_summary(report)lines = [f"DAILY PROGRESS REPORT",f"=" * 50,f"Project: {report.project_name}",f"Project #: {report.project_number}",f"Date: {report.report_date}",f"Prepared by: {report.prepared_by}",f"",f"WEATHER CONDITIONS",f"-" * 30,f"Conditions: {report.weather.value}",f"Temperature: {report.temperature_low}°C - {report.temperature_high}°C",f"",f"SUMMARY",f"-" * 30,f"Total Workers: {summary['total_workers']}",f"Total Man-hours: {summary['total_manhours']}",f"Equipment Hours: {summary['equipment_hours']}",f"Activities Completed: {summary['activities_completed']}",f"Activities In Progress: {summary['activities_in_progress']}",f"Activities Delayed: {summary['activities_delayed']}",f"Safety Incidents: {summary['safety_incidents']}",]if report.delays:lines.extend([f"", f"DELAYS", f"-" * 30])for delay in report.delays:lines.append(f"• {delay}")return "\n".join(lines)
Quick Start
python
from datetime import date# Initialize reporterreporter = DailyProgressReporter("Office Tower A", "PRJ-2024-001")# Create reportreport = reporter.create_report(report_date=date.today(),weather=WeatherCondition.CLEAR,temp_high=28,temp_low=18,prepared_by="John Smith")# Add activitiesreporter.add_work_activity(report,activity_id="A-101",description="Pour concrete slab Level 3",location="Level 3, Zone A",planned_qty=150,actual_qty=150,unit="m3",crew_size=8,hours_worked=10)# Add laborreporter.add_labor(report, "Concrete", "ABC Concrete Co", 8, 10, 2)# Exportreporter.export_to_excel(report, "daily_report.xlsx")
Common Use Cases
1. Generate Text Summary
python
text = reporter.generate_text_report(report)print(text)
2. Track Delays
python
report.delays.append("Weather delay - rain from 14:00-16:00")report.delays.append("Material delivery late by 2 hours")
3. Calculate Metrics
python
summary = reporter.calculate_summary(report)print(f"Productivity: {summary['total_manhours']} man-hours")
Resources
- DDC Book: Chapter 4.1 - Site Data Collection