BESS installation labour estimator
A takeoff and man-hour model for the electrical scope of a grid-scale battery site — DC and AC cable pulling, terminations, conduit, and the BESS-specific work that no general electrical labour book has a line for. It ships the structure. You bring the labour units.
What this is, and is not. An estimating aid, not a bid and not a compliance document. It computes man-hours from quantities and the labour units you supply; it does not tell you what those units should be. Check the result against your own history before it leaves your desk.
01Block specification
Twenty 5 MWh enclosures on one conversion block. Row spacing assumed typical for a utility-scale site.
Cable schedule
Each line becomes a pull and its terminations. Conductors per run is asked rather than assumed: a DC pull carrying + and − is ONE run with TWO conductors, and the units are per conductor-foot — getting it backwards doubles or halves the largest line on the sheet.
| Scope | Runs | Length (ft) | Conductors / run | Size | Remove |
|---|---|---|---|---|---|
Enclosure internals — cabinets to a connection box (off)
For a block where the run from each cabinet to its connection box differs enough to be worth stating separately. Each cabinet adds its own pull and terminations to the takeoff.
Conversion scope, derived: 1 PCS skid · 1 transformer · 4 MV runs · 900 tray-ft. Change the enclosure count and these follow it.
MV collection and comms — the values the schedule does not carry
Polarity is a conductor, not a run. A DC pull carrying + and − is one pull with two conductors, and the cable rows are priced per conductor-foot. Getting this backwards doubles or halves the biggest line on the sheet.
02Labour units
This tool ships the structure of a BESS electrical takeoff — 316 unit records across 25 categories — and no labour values. That is deliberate. Published labour-unit manuals are commercial products and their tables are not ours to redistribute, and inventing numbers for a page whose stated use is checking a contractor’s bid would be worse than shipping none. So you bring the units: from your own licensed source, or from what your own crews actually book.
Values stay in this browser. Nothing you enter is transmitted or stored on a server. The blank template never contains a value. Your filled sheet and the estimate export do — they are your numbers, in a file only you have.
Enter them here — 0 of 28 doneman-hours per unit, at Normal · 3 of these do not vary by condition and are stored once
- Enclosure DC output to conversion block — 500 kcmilmh / 1,000 ft
- Enclosure DC output to conversion block — lugs, Compression lug, two hole, 500 kcmilmh / each
- DC equipment grounding conductor — #4/0mh / 1,000 ft
- DC equipment grounding conductor — lugs, Compression lug, two hole, #4/0mh / each
- Underground DC duct — enclosures to combiner — PVC Sch 40, 3"mh / 100 ft
- Underground DC duct — combiner to PCS — PVC Sch 40, 4"mh / 100 ft
- Stub-ups / risers at battery enclosures — GRC / RMC steel, 3"mh / 100 ft
- Stub-ups / risers at PCS skid — GRC / RMC steel, 4"mh / 100 ft
- BMS / comms raceway — EMT, 1"mh / 100 ft
- Riser elbows at battery enclosures — GRC factory elbow, 3"mh / each
- Riser elbows at PCS skid — GRC factory elbow, 4"mh / each
- Enclosure conduit entries — GRC locknut and bushing set, 3"mh / each
- Underground duct bends — PVC Sch 40 elbow, 3"mh / each
- Comms raceway elbows — EMT factory elbow, 1"mh / each
- Comms raceway terminations — EMT set-screw box connector, 1"mh / each
- Battery enclosure - hoist, set, level and shim, anchor with torque recordmh / each
- PCS skid - set, level, anchormh / each
- MV transformer - set, level, anchormh / each
- Maintenance service disconnect installmh / each
- OEM harness route, dress and landmh / each
- Coolant loop connect, fill, bleedmh / each
- CAN / RS-485 daisy chain per rackmh / each
- Insulation resistance test per DC circuitmh / each
- Pack voltage and SoC balance verification before series connectionmh / each
- HV elbow or deadbreak landingmh / each
- LV bushing landingmh / each
- Ground-grid bondingmh / each
- Ladder tray, 18 inmh / 100 ft
Fill missing sizes from my own size step — 4 size families in this takeoff
Type your value for one size, then your own multiplier per size step. Larger sizes without a value follow upward from your nearest typed size; sizes below it stay open rather than dividing down. We ship no ladder — the anchor and the step are both yours, and a derived value always shows as a placeholder marked derived.
Bring them as a file instead — download the sheet, fill it, re-import
03Takeoff and hours
28 rows have no labour unit, so what you see below is the sum of the rows that do. It is not the scope. Per-MWh and per-enclosure figures are withheld until every row prices, because a normalised number computed over an incomplete scope is the most quotable wrong answer this tool could give you.
Scope: this takeoff covers the DC block and the MV collection. It does not include AC LV collection, MV collection, MV terminations, enclosure bonding, station service, protection and relaying, fire and gas detection, SCADA checkout. The per-MWh and per-enclosure figures are therefore for the scope above, not for a whole site — add the rest before comparing them to a contractor’s number.
| Scope | Quantity | Unit | Man-hours | Actions |
|---|---|---|---|---|
| Enclosure DC output to conversion block — 500 kcmilDC cable pulling | runs22680 conductor-ft | needs a value | ||
| Enclosure DC output to conversion block — lugs, Compression lug, two hole, 500 kcmilTerminations | count480 each | needs a value | ||
| DC equipment grounding conductor — #4/0DC cable pulling | runs1890 conductor-ft | needs a value | ||
| DC equipment grounding conductor — lugs, Compression lug, two hole, #4/0Terminations | count40 each | needs a value | ||
| Underground DC duct — enclosures to combiner — PVC Sch 40, 3"Conduit | ft2400 raceway-ft | needs a value | ||
| Underground DC duct — combiner to PCS — PVC Sch 40, 4"Conduit | ft7830 raceway-ft | needs a value | ||
| Stub-ups / risers at battery enclosures — GRC / RMC steel, 3"Conduit | ft240 raceway-ft | needs a value | ||
| Stub-ups / risers at PCS skid — GRC / RMC steel, 4"Conduit | ft100 raceway-ft | needs a value | ||
| BMS / comms raceway — EMT, 1"Conduit | ft600 raceway-ft | needs a value | ||
| Riser elbows at battery enclosures — GRC factory elbow, 3"Conduit fittings | count160 each | needs a value | ||
| Riser elbows at PCS skid — GRC factory elbow, 4"Conduit fittings | count80 each | needs a value | ||
| Enclosure conduit entries — GRC locknut and bushing set, 3"Conduit fittings | count160 each | needs a value | ||
| Underground duct bends — PVC Sch 40 elbow, 3"Conduit fittings | count240 each | needs a value | ||
| Comms raceway elbows — EMT factory elbow, 1"Conduit fittings | count280 each | needs a value | ||
| Comms raceway terminations — EMT set-screw box connector, 1"Conduit fittings | count400 each | needs a value | ||
| Battery enclosure - hoist, set, level and shim, anchor with torque recordEquipment setting | count20 each | needs a value | ||
| PCS skid - set, level, anchorEquipment setting | count1 each | needs a value | ||
| MV transformer - set, level, anchorEquipment setting | count1 each | needs a value | ||
| Maintenance service disconnect installBESS internal wiring | count20 each | needs a value | ||
| OEM harness route, dress and landBESS internal wiring | count20 each | needs a value | ||
| Coolant loop connect, fill, bleedThermal management | count20 each | needs a value | ||
| CAN / RS-485 daisy chain per rackComms and controls | count40 each | needs a value | ||
| Insulation resistance test per DC circuitTest and turnover | count140 each | needs a value | ||
| Pack voltage and SoC balance verification before series connectionTest and turnover | count20 each | needs a value | ||
| HV elbow or deadbreak landingTransformer connections | count3 each | needs a value | ||
| LV bushing landingTransformer connections | count3 each | needs a value | ||
| Ground-grid bondingTransformer connections | count1 each | needs a value | ||
| Ladder tray, 18 inTray and supports | ft900 raceway-ft | needs a value |
Edit a quantity, remove a row, or add one from any of the 316 unit records — including the scopes this preset does not generate. Changing the block specification re-derives the generated rows and leaves your edits and additions alone.
04Site factors
Material and method — 7 factors, applied only where the unit allows
1.0 is no change. These multiply hours on the units that declare them eligible and are ignored everywhere else — an aluminium deduct on a termination is not harmless, it is wrong in direction.
Crew size converts man-days into calendar days, which is what equipment rental, temporary facilities and travel are charged against. Leave it blank and those three cannot be priced: man-days are calendar days multiplied by the crew, so charging a daily rate against them overstates it by the crew size.
Scheduled week, derived: 4 × 10 = 40 hours. Hours above the straight-time week set in 05 carry the overtime premium.
There is one clock. Attended hours per shift is the only divisor for duration and man-days — the efficiency factors multiply hours once and never take a second haircut off the same schedule.
05Rates and cost
No wage rates ship. Inventing a metro number is the same mistake as inventing a labour unit — it reads as authoritative and nobody can tell where it came from. Enter the rates from your own agreement or determination, and cost appears.
Rate fields appear here for each craft the takeoff uses — they follow from the hours, and no row carries hours yet. Enter unit values in 02 — Labour units and the wage fields arrive with the crafts.
Cost details — overtime split, prevailing wage, travel and site costs
Payroll tax and workers’ compensation ride the base wage, not the wage-plus-fringe package. Bona fide fringe paid into a plan is not taxable wages and is not payroll for comp rating, and burdening it overstates the largest number here by roughly 4% on a typical rate — more on a determination carrying a large fringe. Overtime premium rides the base wage only.
The estimate is partial, so a cost would be computed over an incomplete scope. Hours above are unaffected.
| Craft | Man-hours |
|---|---|
| Total | 0.0 |
Of the total, 0.0 man-hours are indirect — supervision and attendants, already inside the craft rows above. They ride in cost and in the total, and never in crew-days: supervision does not shorten the job.
Why it ships without labour units
The obvious way to build this is to load a published labour manual into the page. That is not available to us, and the reason is worth stating plainly rather than hiding behind a disclaimer.
Manuals like NECA’s are commercial publications, and their labour-unit tables are the product being sold. Owning a copy licenses you to use it — including in your own estimating, on your own machine. It does not license anyone to republish the tables on a free web page. And the numbers are not raw facts that copyright leaves alone: they are predicted values reflecting editorial judgement, which courts have treated as protectable in exactly this shape.
The alternative — inventing plausible-looking units so the tool shows a total on landing — is worse. The stated use of this page is checking a contractor’s number. A confident total built on made-up productivity would be the most damaging thing it could do.
So the page ships 316 unit records with their structure fully defined — category, size, install method, unit basis, assumed crew, whether condition changes them, whether the termination already includes torque — and no values. An unpriced row says not priced. It never contributes a zero.
Getting to a number
- Pick a block and write the cable schedule. Enclosure count and power, then a line per scope: how many runs, how far, how many conductors, what size. The takeoff follows the schedule, so every cable row on the sheet is one you wrote and can correct — and the per-enclosure scopes (equipment setting, comms, conduit, tray) re-derive from the enclosure count.
- The schedule does not multiply itself. Runs and lengths are what you measured, so changing the enclosure count leaves them alone. If a bigger block means more cable, that is a number only you can state.
- Type the unit values, in the panel under “Labour units”. This takeoff needs 28 of the 316 records — not all 316 — and they are listed in the takeoff’s own order, each showing the basis, the assumed crew and whether the value is man-hours or crew-elapsed hours. Values come from a source you are entitled to use: your licensed manual, your estimating database, or the hours your own crews book against these tasks. The last of those is the best input anyone has.
- Or bring them as a file. Download the 28 units this takeoff needs (or all 316), fill the sheet, and paste or upload it back. Values stay in your browser and are remembered between visits. They are not transmitted to us, and clearing them is one button.
- Enter one wage rate. Cost needs a base and a fringe for each craft the takeoff uses; one composite rate can fill them all, and each field it fills says so. Until a rate exists the ledger returns nothing rather than guessing.
The sheet records each unit’s basis and crew. If a unit’s definition changes after you exported the sheet, the import refuses that value rather than applying it — the same number under a different basis is a different number.
The four things this gets right that spreadsheets usually do not
- Polarity is a conductor, not a runA DC pull carrying + and − is one pull with two conductors. Cable units are per conductor-foot, so treating the pair as two runs doubles the largest line on the sheet. The generator decides this once and the row echoes the basis it resolved.
- Condition selects a column, it does not multiplyNormal, Difficult and Very difficult are three independent values. Nothing here derives the harder tiers from the easy one by a fixed ladder. If you only have a Normal value, you can apply your own step — and it is labelled as yours.
- Torque is a property of the termination, not a separate multiplierIf a termination unit already contains torque-to-spec and witness marking, no separate torque row is generated for those joints. Put both in and you have counted the joint twice; the engine refuses that outright and names both rows.
- One clockAttended hours per shift is the only divisor for duration and man-days. Site efficiency multiplies hours, once. Dividing paid hours by a net-of-breaks figure and then also applying an efficiency factor takes the same haircut twice, and it is a common way per-diem estimates come out 50% high.
Limits worth knowing before you rely on it
It prices direct installation man-hours first, then adds indirect supervision — foreman by ratio with a minimum-foreman floor, and general foreman by percentage. Those ride in cost and in the total and never in crew-days, because supervision does not shorten a job. The ledger also carries a safety attendant on any row marked as an energised work front, but nothing on this page can mark one yet — no shipped record is flagged and the unit sheet has no column for it — so that term is always zero today.
Cost is optional, and it is withheld rather than guessed. No wage rates ship, for the same reason no labour units ship: you enter your own, and until every craft carrying hours has one the ledger returns nothing. It is withheld while any row is unpriced, and while prevailing wage is switched on without a multiplier — there is no safe default for that number, so the ledger refuses rather than assuming one. The switch lives under “Cost details” in the rates section.
What it still does not model: escalation to a construction midpoint, shift differential, a detailed equipment schedule, per-craft workers’-comp rates, cash-in-lieu fringe, or anything below the line — bonding, insurance, permits, sales tax on materials. Per diem, mobilisation and demobilisation, travel, temporary facilities, the overtime and double-time split and the OEM field-service day rate have inputs in the rates section, most under “Cost details”; anything left at zero is listed as zero rather than hidden.
Per-MWh and per-enclosure figures are withheld whenever any row is unpriced. A normalised number computed over an incomplete scope is precise, quotable and wrong, and it is the failure mode most likely to end up in somebody’s board pack.
The learning curve is implemented and structurally gated: it applies only to units that are first-unit values, and no record in this dataset is one — so it could take no repetition saving even if it were switched on, and no control offers it. That is the safe direction to be wrong in: applying a cumulative-average curve to a unit that is already an average takes roughly 28% off at a hundred repetitions, which is a large and entirely fictional saving.