Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Added "roof_report_pdf_file", "roof_report_pdf_start" and "roof_report_pdf_status"; changed the definition of "edit_roof", "plan_roof" and "roof_report_pdf" (14 tools before, 17 now)
⟨98 unchanged words⟩ Falzblech, Trapezblech, rack tilt 5/10/15°, flat-roof racks; on a flat dormer roof it decides racks or flush), dormer_modules, fill_dormer and clear_dormer (one dormer's roof full of modules, or none), modules (arrangement as the page names it: „Ästhetisch“ ⟨77 unchanged words⟩ eave height) and delete_face, turn_racks (flat roofs and racked dormer roofs), find_similar („Ähnliche finden“ on the aerial ⟨22 unchanged words⟩ turn_field; also on dormer roofs from "dormer_roofs"; on flat roofs the modules keep standing on their racks), the modules in an area together as the page selects them (move_modules, turn_modules, set_module_type for a module type of their own; remove_modules takes an area too) and household (incl. offer_eur, the price ⟨149 unchanged words⟩
before
{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"answers":{"description":"The person's answers to the last answer's \"questions\".","items":{"additionalProperties":false,"properties":{"id":{"description":"The id of a question from the last answer.","maxLength":80,"minLength":1,"type":"string"},"obstacle":{"description":"true: there is an obstacle there; false: there is none.","type":"boolean"}},"required":["id","obstacle"],"type":"object"},"maxItems":20,"type":"array"},"edits":{"items":{"oneOf":[{"additionalProperties":false,"properties":{"direction_deg":{"description":"Compass direction the face looks to: 0 north, 90 east, 180 south, 270 west.","maximum":360,"minimum":0,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"tilt_deg":{"description":"Tilt, degrees (0 flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"slope","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"edge":{"description":"Which edge moves: the eave, or the left or right end seen from below.","enum":["eave","left","right"],"type":"string"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"metres":{"description":"Or a change: metres out from where the edge is now (negative: in), horizontal.","maximum":1.5,"minimum":-1.5,"type":"number"},"to_m":{"description":"Eave only: how far the eave should reach past the wall, horizontal metres (\"Dachüberstand 50 cm\" → 0.5). The face list shows the current eave_overhang_m.","maximum":1.5,"minimum":0,"type":"number"},"type":{"const":"overhang","type":"string"}},"required":["type","face","edge"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A cut along the eave, this far up from it.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"A cut up the slope, this far from the left end.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"split","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"corners_m":{"description":"Any shape instead: its corners as [east, north] metres in the same frame as \"house.footprint_m\" (from a building plan).","items":{"items":false,"maxItems":2,"minItems":2,"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array"},"maxItems":24,"minItems":3,"type":"array"},"depth_m":{"description":"Out from the wall, metres.","maximum":20,"minimum":1,"type":"number"},"direction_deg":{"description":"Way the roof slopes down to (default: away from the wall).","maximum":360,"minimum":0,"type":"number"},"eave_height_m":{"description":"Height of the roof's lowest edge above the ground, metres.","maximum":15,"minimum":1.5,"type":"number"},"offset_m":{"description":"From the middle of the wall: positive to the east (north and south walls) or north (east and west walls).","maximum":30,"minimum":-30,"type":"number"},"tilt_deg":{"description":"Roof tilt, degrees (default 0, flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"add_face","type":"string"},"wall":{"description":"The house wall the new part stands against (an extension, a garage, a porch). With width_m and depth_m; or give corners_m instead.","enum":["north","east","south","west"],"type":"string"},"width_m":{"description":"Along the wall, metres.","maximum":30,"minimum":1,"type":"number"}},"required":["type","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"Horizontal metres up from the eave (as on a drawing seen from above).","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a dormer: its front wall; default: the kind's usual height).","maximum":4,"minimum":0.1,"type":"number"},"kind":{"description":"What it is: chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall, or block (anything else, 60 cm square).","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (e.g. a dormer the scan found).","maxLength":80,"minLength":1,"type":"string"},"kind":{"description":"The new kind. Dormers: dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall (a dormer stays its size). Or chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, block.","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id","kind"],"type":"object"},{"additionalProperties":false,"properties":{"colour":{"description":"A colour id. metal: anthracite, aluminium, zinc, copper, brown; dormerBarrel: tiles, anthracite, aluminium, zinc, copper, brown; dormerShed: tiles, anthracite, aluminium, zinc, copper, brown; block: wall, grey, anthracite, red, brown; window: silver, anthracite, white, brown; chimney: render, brick, slate, steel, copper; flue: steel, anthracite, red; vent: anthracite, red, brown, grey; dish: light, anthracite, red; antenna: silver, anthracite; ladder: anthracite, red, brown, galvanised; snowWood: natural, dark, weathered; snowGrid: anthracite, red, brown, galvanised; steps: anthracite, red, brown, galvanised; solarThermal: silver, black; pv: silver, black; dome: opal, clear","maxLength":30,"minLength":1,"type":"string"},"face":{"description":"With item \"metal\": only this face's sheet (a copper garage beside a zinc roof).","maxLength":80,"minLength":1,"type":"string"},"item":{"description":"What gets the colour: roof (a tiled roof, for the building part of face, the house without face; colours: photo, clay, red, darkRed, copper, brown, black, anthracite, slate, grey), metal (sheet-metal dormer tops and Falz- or Trapezblech roofs), or a kind of item.","enum":["roof","metal","dormerBarrel","dormerShed","block","window","chimney","flue","vent","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome"],"type":"string"},"type":{"const":"colour","type":"string"}},"required":["type","item","colour"],"type":"object"},{"additionalProperties":false,"properties":{"covering":{"description":"The roof's covering: tiles, biber (Biberschwanz plain tiles), flach (flat tiles such as Tegalit), falz (standing-seam sheet, modules flush) or trapez (trapezoidal sheet).","enum":["tiles","biber","flach","falz","trapez"],"type":"string"},"face":{"description":"Only this face (a garage in Falzblech, say); without it the whole roof.","maxLength":80,"minLength":1,"type":"string"},"flat_rack":{"description":"Racks on flat roofs: ew (east-west pairs back to back, default), south (rows facing south), ns (along the roof).","enum":["ew","south","ns"],"type":"string"},"rack_tilt_deg":{"anyOf":[{"const":5,"type":"number"},{"const":10,"type":"number"},{"const":15,"type":"number"}],"description":"Tilt of the racks on flat roofs and racked trapezoidal sheet: 5, 10 (default) or 15 degrees."},"trapez_racks":{"description":"Trapezoidal sheet sloping 15° or less: modules on racks instead of flush.","type":"boolean"},"type":{"const":"covering","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\". Its modules stay exactly where they are from now on (the other module edits do this by themselves).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"lay_by_hand","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's lower left corner: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The field's lower left corner: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"Default portrait (landscape if the plan is set to landscape).","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"type":{"const":"add_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on the module to take off, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner (every module whose centre lies inside goes).","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"remove_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Put modules taken out of the automatic layout back.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on a module taken out before, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"restore_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field: the modules joined to the nearest one move together.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"type":{"const":"move_field","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id (\"u:<n>\" for one added before).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"maxLength":80,"minLength":1,"type":"string"},"type":{"const":"confirm_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"on":{"description":"Modules on flat and shed dormers too (gable dormers always carry them).","type":"boolean"},"type":{"const":"dormer_modules","type":"string"}},"required":["type","on"],"type":"object"},{"additionalProperties":false,"properties":{"arrange":{"description":"As the solar roof check names them: design = „Ästhetisch“ (whole rectangles only, the same height, left and right the same width), tidy = „Ordentlich“ (rows in one line, no small single fields; default), most = „Maximal“ (as many as fit, landscape in gaps too).","enum":["tidy","most","design"],"type":"string"},"module":{"description":"The module type: m470 = 470 W · 1.762 × 1.134 mm; m490 = 490 W · 1.800 × 1.134 mm; m520 = 520 W · 1.960 × 1.134 mm.","enum":["m470","m490","m520"],"type":"string"},"orientation":{"description":"auto (default): portrait, or landscape where that fits 2+ more modules; mixed: portrait and landscape on one roof, wherever each fits.","enum":["auto","portrait","landscape","mixed"],"type":"string"},"type":{"const":"modules","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" (an extension, a garage, the other half of a semi-detached house) to plan with the house.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"add_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" to plan without again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id (\"t:…\") from \"shade\": felled, or wrong in the data; its shade no longer counts.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id taken out before.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"change_m":{"description":"Metres higher (positive) or lower (negative) than the laser scan measured it (the scan is from earlier years).","maximum":20,"minimum":-20,"type":"number"},"id":{"description":"A tree id (\"t:…\") from \"shade\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"tree_height","type":"string"}},"required":["type","id","change_m"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"A free four-cornered outline instead of a rectangle (as the solar roof check's corner handles): its corners on its face, the front (eave side) first.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":4,"minItems":4,"type":"array"},"depth_m":{"description":"New depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a chimney taller than measured casts more shade).","maximum":8,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" (found by scan or photo) or \"your_obstacles\".","maxLength":80,"minLength":1,"type":"string"},"right_m":{"description":"Move it to the right seen from below (negative: left), metres.","maximum":10,"minimum":-10,"type":"number"},"turn_deg":{"description":"Turn it round its centre, degrees (positive: clockwise seen from above), as „Drehen“ in the solar roof check.","maximum":180,"minimum":-180,"type":"number"},"type":{"const":"edit_obstacle","type":"string"},"up_m":{"description":"Move it up the roof (negative: down), horizontal metres.","maximum":10,"minimum":-10,"type":"number"},"width_m":{"description":"New width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"The face's new outline, corner by corner (as the solar roof check's editor drags them); \"faces[].corners\" gives the present ones.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":30,"minItems":3,"type":"array"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"face_outline","type":"string"}},"required":["type","face","corners"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face back to the measured roof („Wie gemessen“): its outline, slope, turned racks and hand-laid modules go.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"reset_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A piece of a split face (\"<id>|1\" or \"|2\"): both pieces become one face again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"unsplit","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"eave_height_m":{"description":"Its lowest edge above the ground, metres.","maximum":30,"minimum":1.5,"type":"number"},"face":{"description":"A face added with add_face (\"d:<n>\").","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"drawn_face","type":"string"}},"required":["type","face","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face added with add_face (\"d:<n>\"): deleted; later ones move down by one.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"delete_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (a chimney, a skylight dome, a vent …): the aerial photo is searched for more of the same on this roof (as „Ähnliche finden“), and what it finds is added as your obstacles. One AI call each; at most 3 a call.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"find_similar","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"description":"The AI outline check (as „Umriss passt nicht?“): the roof's edges are compared with the aerial photo and moved where they clearly lie elsewhere. One AI call; use it when a note says the photo shows more roof.","properties":{"type":{"const":"check_outline","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"Ask the aerial photo again for chimneys and roof windows when \"obstacles_checked\" was false (as „Nochmal suchen“).","properties":{"type":{"const":"search_again","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"degrees":{"description":"Turn the module racks from the roof's own edges by this much (0: along the edges again; positive: clockwise).","maximum":45,"minimum":-45,"type":"number"},"face":{"description":"A flat face.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"turn_racks","type":"string"}},"required":["type","face","degrees"],"type":"object"},{"additionalProperties":false,"properties":{"battery_kwh":{"description":"Battery size, kWh: one of 0, 5, 8, 10, 15 (default 8).","type":"number"},"consumption_kwh":{"description":"The household's electricity use a year, kWh, without car or heat pump (default 4,500).","maximum":30000,"minimum":1000,"type":"number"},"ev":{"description":"An electric car is (or will be) charged at home: about 2,700 kWh a year more.","type":"boolean"},"heat_pump":{"description":"A heat pump heats the house: about 4,500 kWh a year more.","type":"boolean"},"offer_eur":{"description":"The total price on an offer the person already has, euros before any subsidy (0 clears it): the solar roof check link then shows the payback. Never a price of Sky Solar's.","maximum":300000,"minimum":0,"type":"number"},"type":{"const":"household","type":"string"}},"required":["type"],"type":"object"}]},"maxItems":20,"type":"array"},"link":{"description":"A solar roof check link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or the solar roof check page gave it.","maxLength":12000,"minLength":10,"type":"string"}},"required":["link"],"type":"object"}⟨60 unchanged words⟩ public rates (own use and feed-in) foreverya choice of batterysizesizes (none, or 4 to 20 kWh; any whole kWh in between on request), the municipal subsidy and, with an offer ⟨101 unchanged words⟩
⟨63 unchanged words⟩ ":{"description":"Battery size, kWh:one0offor0none,5,or8,a10,whole15
⟨86 unchanged words⟩ the server and no download link is made. This one-shot call waits at most 55 seconds for the page's own report and otherwise answers with a drawn version (same modules; the answer's page_report says why and where the time went); for the page's own report with more time use roof_report_pdf_start. An example, not a quote; no prices.
Get the finished roof plan PDF (solar roof check) — The finished PDF of a roof_report_pdf_start job, inside this answer as an embedded resource (application/pdf, base64); save it as a file. Only when the status says done.
Start the roof plan PDF as a job (solar roof check) — The same PDF as roof_report_pdf, made as a background job so a slow render cannot time out your call: this answers at once with a job_id. The page's own report with its 3D picture takes 30 to 150 seconds to draw on the server. Then call roof_report_pdf_status with the job_id every 10 seconds until it says done (or failed, with the reason), and roof_report_pdf_file to get the file. If the page's report cannot be made in time you get the drawn version, and the status says so. The finished PDF is kept for 15 minutes under the random job_id; nothing else is stored.
Status of a roof plan PDF job (solar roof check) — Where a roof_report_pdf_start job is: rendering (poll again in 10 seconds), done (summary and which PDF it is), failed (with a reason code: plan_error, render_error, render_lost) or unknown (wrong or expired job_id). A tool error here means the call itself failed, not the job.
Changed the definition of "edit_roof", "find_house", "plan_roof" and 2 more
Improve a roof plan (Dachchecksolar roof check)
Improve aDachchecksolar roof check plan from what the person knows: a ⟨376 unchanged words⟩
before
{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"answers":{"description":"The person's answers to the last answer's \"questions\".","items":{"additionalProperties":false,"properties":{"id":{"description":"The id of a question from the last answer.","maxLength":80,"minLength":1,"type":"string"},"obstacle":{"description":"true: there is an obstacle there; false: there is none.","type":"boolean"}},"required":["id","obstacle"],"type":"object"},"maxItems":20,"type":"array"},"edits":{"items":{"oneOf":[{"additionalProperties":false,"properties":{"direction_deg":{"description":"Compass direction the face looks to: 0 north, 90 east, 180 south, 270 west.","maximum":360,"minimum":0,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"tilt_deg":{"description":"Tilt, degrees (0 flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"slope","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"edge":{"description":"Which edge moves: the eave, or the left or right end seen from below.","enum":["eave","left","right"],"type":"string"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"metres":{"description":"Or a change: metres out from where the edge is now (negative: in), horizontal.","maximum":1.5,"minimum":-1.5,"type":"number"},"to_m":{"description":"Eave only: how far the eave should reach past the wall, horizontal metres (\"Dachüberstand 50 cm\" → 0.5). The face list shows the current eave_overhang_m.","maximum":1.5,"minimum":0,"type":"number"},"type":{"const":"overhang","type":"string"}},"required":["type","face","edge"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A cut along the eave, this far up from it.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"A cut up the slope, this far from the left end.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"split","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"corners_m":{"description":"Any shape instead: its corners as [east, north] metres in the same frame as \"house.footprint_m\" (from a building plan).","items":{"items":false,"maxItems":2,"minItems":2,"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array"},"maxItems":24,"minItems":3,"type":"array"},"depth_m":{"description":"Out from the wall, metres.","maximum":20,"minimum":1,"type":"number"},"direction_deg":{"description":"Way the roof slopes down to (default: away from the wall).","maximum":360,"minimum":0,"type":"number"},"eave_height_m":{"description":"Height of the roof's lowest edge above the ground, metres.","maximum":15,"minimum":1.5,"type":"number"},"offset_m":{"description":"From the middle of the wall: positive to the east (north and south walls) or north (east and west walls).","maximum":30,"minimum":-30,"type":"number"},"tilt_deg":{"description":"Roof tilt, degrees (default 0, flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"add_face","type":"string"},"wall":{"description":"The house wall the new part stands against (an extension, a garage, a porch). With width_m and depth_m; or give corners_m instead.","enum":["north","east","south","west"],"type":"string"},"width_m":{"description":"Along the wall, metres.","maximum":30,"minimum":1,"type":"number"}},"required":["type","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"Horizontal metres up from the eave (as on a drawing seen from above).","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a dormer: its front wall; default: the kind's usual height).","maximum":4,"minimum":0.1,"type":"number"},"kind":{"description":"What it is: chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall, or block (anything else, 60 cm square).","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (e.g. a dormer the scan found).","maxLength":80,"minLength":1,"type":"string"},"kind":{"description":"The new kind. Dormers: dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall (a dormer stays its size). Or chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, block.","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id","kind"],"type":"object"},{"additionalProperties":false,"properties":{"colour":{"description":"A colour id. metal: anthracite, aluminium, zinc, copper, brown; dormerBarrel: tiles, anthracite, aluminium, zinc, copper, brown; dormerShed: tiles, anthracite, aluminium, zinc, copper, brown; block: wall, grey, anthracite, red, brown; window: silver, anthracite, white, brown; chimney: render, brick, slate, steel, copper; flue: steel, anthracite, red; vent: anthracite, red, brown, grey; dish: light, anthracite, red; antenna: silver, anthracite; ladder: anthracite, red, brown, galvanised; snowWood: natural, dark, weathered; snowGrid: anthracite, red, brown, galvanised; steps: anthracite, red, brown, galvanised; solarThermal: silver, black; pv: silver, black; dome: opal, clear","maxLength":30,"minLength":1,"type":"string"},"face":{"description":"With item \"metal\": only this face's sheet (a copper garage beside a zinc roof).","maxLength":80,"minLength":1,"type":"string"},"item":{"description":"What gets the colour: roof (a tiled roof, for the building part of face, the house without face; colours: photo, clay, red, darkRed, copper, brown, black, anthracite, slate, grey), metal (sheet-metal dormer tops and Falz- or Trapezblech roofs), or a kind of item.","enum":["roof","metal","dormerBarrel","dormerShed","block","window","chimney","flue","vent","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome"],"type":"string"},"type":{"const":"colour","type":"string"}},"required":["type","item","colour"],"type":"object"},{"additionalProperties":false,"properties":{"covering":{"description":"The roof's covering: tiles, biber (Biberschwanz plain tiles), flach (flat tiles such as Tegalit), falz (standing-seam sheet, modules flush) or trapez (trapezoidal sheet).","enum":["tiles","biber","flach","falz","trapez"],"type":"string"},"face":{"description":"Only this face (a garage in Falzblech, say); without it the whole roof.","maxLength":80,"minLength":1,"type":"string"},"flat_rack":{"description":"Racks on flat roofs: ew (east-west pairs back to back, default), south (rows facing south), ns (along the roof).","enum":["ew","south","ns"],"type":"string"},"rack_tilt_deg":{"anyOf":[{"const":5,"type":"number"},{"const":10,"type":"number"},{"const":15,"type":"number"}],"description":"Tilt of the racks on flat roofs and racked trapezoidal sheet: 5, 10 (default) or 15 degrees."},"trapez_racks":{"description":"Trapezoidal sheet sloping 15° or less: modules on racks instead of flush.","type":"boolean"},"type":{"const":"covering","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\". Its modules stay exactly where they are from now on (the other module edits do this by themselves).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"lay_by_hand","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's lower left corner: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The field's lower left corner: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"Default portrait (landscape if the plan is set to landscape).","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"type":{"const":"add_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on the module to take off, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner (every module whose centre lies inside goes).","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"remove_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Put modules taken out of the automatic layout back.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on a module taken out before, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"restore_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field: the modules joined to the nearest one move together.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"type":{"const":"move_field","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id (\"u:<n>\" for one added before).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"maxLength":80,"minLength":1,"type":"string"},"type":{"const":"confirm_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"on":{"description":"Modules on flat and shed dormers too (gable dormers always carry them).","type":"boolean"},"type":{"const":"dormer_modules","type":"string"}},"required":["type","on"],"type":"object"},{"additionalProperties":false,"properties":{"arrange":{"description":"As the Dachcheck names them: design = „Ästhetisch“ (whole rectangles only, the same height, left and right the same width), tidy = „Ordentlich“ (rows in one line, no small single fields; default), most = „Maximal“ (as many as fit, landscape in gaps too).","enum":["tidy","most","design"],"type":"string"},"module":{"description":"The module type: m470 = 470 W · 1.762 × 1.134 mm; m490 = 490 W · 1.800 × 1.134 mm; m520 = 520 W · 1.960 × 1.134 mm.","enum":["m470","m490","m520"],"type":"string"},"orientation":{"description":"auto (default): portrait, or landscape where that fits 2+ more modules; mixed: portrait and landscape on one roof, wherever each fits.","enum":["auto","portrait","landscape","mixed"],"type":"string"},"type":{"const":"modules","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" (an extension, a garage, the other half of a semi-detached house) to plan with the house.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"add_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" to plan without again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id (\"t:…\") from \"shade\": felled, or wrong in the data; its shade no longer counts.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id taken out before.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"change_m":{"description":"Metres higher (positive) or lower (negative) than the laser scan measured it (the scan is from earlier years).","maximum":20,"minimum":-20,"type":"number"},"id":{"description":"A tree id (\"t:…\") from \"shade\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"tree_height","type":"string"}},"required":["type","id","change_m"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"A free four-cornered outline instead of a rectangle (as the Dachcheck's corner handles): its corners on its face, the front (eave side) first.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":4,"minItems":4,"type":"array"},"depth_m":{"description":"New depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a chimney taller than measured casts more shade).","maximum":8,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" (found by scan or photo) or \"your_obstacles\".","maxLength":80,"minLength":1,"type":"string"},"right_m":{"description":"Move it to the right seen from below (negative: left), metres.","maximum":10,"minimum":-10,"type":"number"},"turn_deg":{"description":"Turn it round its centre, degrees (positive: clockwise seen from above), as „Drehen“ in the Dachcheck.","maximum":180,"minimum":-180,"type":"number"},"type":{"const":"edit_obstacle","type":"string"},"up_m":{"description":"Move it up the roof (negative: down), horizontal metres.","maximum":10,"minimum":-10,"type":"number"},"width_m":{"description":"New width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"The face's new outline, corner by corner (as the Dachcheck's editor drags them); \"faces[].corners\" gives the present ones.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":30,"minItems":3,"type":"array"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"face_outline","type":"string"}},"required":["type","face","corners"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face back to the measured roof („Wie gemessen“): its outline, slope, turned racks and hand-laid modules go.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"reset_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A piece of a split face (\"<id>|1\" or \"|2\"): both pieces become one face again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"unsplit","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"eave_height_m":{"description":"Its lowest edge above the ground, metres.","maximum":30,"minimum":1.5,"type":"number"},"face":{"description":"A face added with add_face (\"d:<n>\").","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"drawn_face","type":"string"}},"required":["type","face","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face added with add_face (\"d:<n>\"): deleted; later ones move down by one.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"delete_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (a chimney, a skylight dome, a vent …): the aerial photo is searched for more of the same on this roof (as „Ähnliche finden“), and what it finds is added as your obstacles. One AI call each; at most 3 a call.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"find_similar","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"description":"The AI outline check (as „Umriss passt nicht?“): the roof's edges are compared with the aerial photo and moved where they clearly lie elsewhere. One AI call; use it when a note says the photo shows more roof.","properties":{"type":{"const":"check_outline","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"Ask the aerial photo again for chimneys and roof windows when \"obstacles_checked\" was false (as „Nochmal suchen“).","properties":{"type":{"const":"search_again","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"degrees":{"description":"Turn the module racks from the roof's own edges by this much (0: along the edges again; positive: clockwise).","maximum":45,"minimum":-45,"type":"number"},"face":{"description":"A flat face.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"turn_racks","type":"string"}},"required":["type","face","degrees"],"type":"object"},{"additionalProperties":false,"properties":{"battery_kwh":{"description":"Battery size, kWh: one of 0, 5, 8, 10, 15 (default 8).","type":"number"},"consumption_kwh":{"description":"The household's electricity use a year, kWh, without car or heat pump (default 4,500).","maximum":30000,"minimum":1000,"type":"number"},"ev":{"description":"An electric car is (or will be) charged at home: about 2,700 kWh a year more.","type":"boolean"},"heat_pump":{"description":"A heat pump heats the house: about 4,500 kWh a year more.","type":"boolean"},"offer_eur":{"description":"The total price on an offer the person already has, euros before any subsidy (0 clears it): the Dachcheck link then shows the payback. Never a price of Sky Solar's.","maximum":300000,"minimum":0,"type":"number"},"type":{"const":"household","type":"string"}},"required":["type"],"type":"object"}]},"maxItems":20,"type":"array"},"link":{"description":"A Dachcheck link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or the Dachcheck page gave it.","maxLength":12000,"minLength":10,"type":"string"}},"required":["link"],"type":"object"}Added "roof_dxf" and "roof_report_pdf"; changed the definition of "edit_roof" and "plan_roof" (12 tools before, 14 now)
⟨100 unchanged words⟩ 5/10/15°, flat-roof racks), dormer_modules, modules (arrangement as the page names it: „Ästhetisch“ design, „Ordentlich“ tidy, „Maximal“ most; orientation incl. mixed; module type), add_part or remove_part (an attached building part from "building_parts", e.g. the other half of a semi-detached house), remove_tree, restore_tree or tree_height (trees from "shade", the worst shade casters first), edit_obstacle (move, resize, raise, turn or give a free four-cornered outline to any obstacle, found or own), face_outline (any outline by corners, as the editor drags them), reset_face („Wie gemessen“), unsplit, add_face also with corners_m (any shape), drawn_face (eave height) and delete_face, turn_racks (flat roofs), find_similar („Ähnliche finden“ on the aerial photo), check_outline (the AI outline check), search_again, module fields by hand (lay_by_hand, add_modules as ⟨10 unchanged words⟩ on dormer roofs from "dormer_roofs") andhousehold.household (incl. offer_eur, the price on an offer the person has, for the payback the link shows). Own obstacle ids (u:<n>) keep their numbers for the whole call. To rebuild a layout the person drew,
Changed the definition of "edit_roof"
⟨519 unchanged words⟩ "},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from ⟨142 unchanged words⟩ "const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind ⟨4 unchanged words⟩ "},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from ⟨83 unchanged words⟩ "const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}}
Added "edit_roof", "find_house" and "plan_roof" (9 tools before, 12 now)
Improve a roof plan (Dachcheck) — Improve a Dachcheck plan from what the person knows: a building plan, photos, measurements or answers. Read the numbers yourself (tilt, overhang, sizes, where a chimney is) and pass them as edits: slope (tilt and direction of a face), overhang (move an eave or end in or out), split a face, remove or restore a face, add_face (an extension or garage against a wall), add, remove or confirm obstacles (with height_m), change_kind (e.g. a found dormer to a flat-roofed or hipped one, or a chimney to a vent), colour (sheet metal, window frames, …), covering (tiles, Falzblech, Trapezblech, rack tilt 5…
Find a house (Dachcheck) — Find a building in Bavaria by its address, for the Dachcheck (roof check). Returns up to 5 matches with a house id. If several match, ask the person which one before planning.
Plan a roof (Dachcheck) — Plan solar modules on a house's roof from the Bavarian 3D building model, the aerial photo and the laser scan, exactly as Sky Solar's Dachcheck page does: modules, kWp, kWh a year with measured weather, shade loss and self-use with and without a battery, each roof face with tilt and direction, the obstacles found, questions about unsure spots for the person, notes on likely model errors, and a Dachcheck link that opens this plan in 3D for the person to check, change and send an enquiry from. Give house (from find_house) for a new plan, or link to read and explain a plan the person already has…
Certificate recorded, valid to 2027-01-21
Authorization not required
Unknown → Live
First tool surface recorded: 9 tools (server version 1.0.0)
https://pv.skysolar.de/mcp (mcp_streamable_http) — from mcp_registry, with the record
Showing the latest 10 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
after
{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"answers":{"description":"The person's answers to the last answer's \"questions\".","items":{"additionalProperties":false,"properties":{"id":{"description":"The id of a question from the last answer.","maxLength":80,"minLength":1,"type":"string"},"obstacle":{"description":"true: there is an obstacle there; false: there is none.","type":"boolean"}},"required":["id","obstacle"],"type":"object"},"maxItems":20,"type":"array"},"edits":{"items":{"oneOf":[{"additionalProperties":false,"properties":{"direction_deg":{"description":"Compass direction the face looks to: 0 north, 90 east, 180 south, 270 west.","maximum":360,"minimum":0,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"tilt_deg":{"description":"Tilt, degrees (0 flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"slope","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"edge":{"description":"Which edge moves: the eave, or the left or right end seen from below.","enum":["eave","left","right"],"type":"string"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"metres":{"description":"Or a change: metres out from where the edge is now (negative: in), horizontal.","maximum":1.5,"minimum":-1.5,"type":"number"},"to_m":{"description":"Eave only: how far the eave should reach past the wall, horizontal metres (\"Dachüberstand 50 cm\" → 0.5). The face list shows the current eave_overhang_m.","maximum":1.5,"minimum":0,"type":"number"},"type":{"const":"overhang","type":"string"}},"required":["type","face","edge"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A cut along the eave, this far up from it.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"A cut up the slope, this far from the left end.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"split","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"corners_m":{"description":"Any shape instead: its corners as [east, north] metres in the same frame as \"house.footprint_m\" (from a building plan).","items":{"items":false,"maxItems":2,"minItems":2,"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array"},"maxItems":24,"minItems":3,"type":"array"},"depth_m":{"description":"Out from the wall, metres.","maximum":20,"minimum":1,"type":"number"},"direction_deg":{"description":"Way the roof slopes down to (default: away from the wall).","maximum":360,"minimum":0,"type":"number"},"eave_height_m":{"description":"Height of the roof's lowest edge above the ground, metres.","maximum":15,"minimum":1.5,"type":"number"},"offset_m":{"description":"From the middle of the wall: positive to the east (north and south walls) or north (east and west walls).","maximum":30,"minimum":-30,"type":"number"},"tilt_deg":{"description":"Roof tilt, degrees (default 0, flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"add_face","type":"string"},"wall":{"description":"The house wall the new part stands against (an extension, a garage, a porch). With width_m and depth_m; or give corners_m instead.","enum":["north","east","south","west"],"type":"string"},"width_m":{"description":"Along the wall, metres.","maximum":30,"minimum":1,"type":"number"}},"required":["type","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"Horizontal metres up from the eave (as on a drawing seen from above).","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a dormer: its front wall; default: the kind's usual height).","maximum":4,"minimum":0.1,"type":"number"},"kind":{"description":"What it is: chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall, or block (anything else, 60 cm square).","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (e.g. a dormer the scan found). A found one becomes one of your obstacles (u:<n>), but its id keeps working: later edits that name it (edit_obstacle, change_kind, fill_dormer, clear_dormer, find_similar, remove_obstacle, confirm_obstacle) and its dormer roofs (g:<id>:<n>) reach the new one, in this call and later ones, while it stays on the found one's spot; the answer's \"id_map\" lists them ({ found id: u:<n> }). A dormer's modules and roof settings move to its new roofs where they are the same, and the answer says what did not.","maxLength":80,"minLength":1,"type":"string"},"kind":{"description":"The new kind. Dormers: dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall (a dormer stays its size). Or chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, block.","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id","kind"],"type":"object"},{"additionalProperties":false,"properties":{"colour":{"description":"A colour id. metal: anthracite, aluminium, zinc, copper, brown; dormerBarrel: tiles, anthracite, aluminium, zinc, copper, brown; dormerShed: tiles, anthracite, aluminium, zinc, copper, brown; block: wall, grey, anthracite, red, brown; window: silver, anthracite, white, brown; chimney: render, brick, slate, steel, copper; flue: steel, anthracite, red; vent: anthracite, red, brown, grey; dish: light, anthracite, red; antenna: silver, anthracite; ladder: anthracite, red, brown, galvanised; snowWood: natural, dark, weathered; snowGrid: anthracite, red, brown, galvanised; steps: anthracite, red, brown, galvanised; solarThermal: silver, black; pv: silver, black; dome: opal, clear","maxLength":30,"minLength":1,"type":"string"},"face":{"description":"With item \"metal\": only this face's sheet (a copper garage beside a zinc roof).","maxLength":80,"minLength":1,"type":"string"},"item":{"description":"What gets the colour: roof (a tiled roof, for the building part of face, the house without face; colours: photo, clay, red, darkRed, copper, brown, black, anthracite, slate, grey), metal (sheet-metal dormer tops and Falz- or Trapezblech roofs), or a kind of item.","enum":["roof","metal","dormerBarrel","dormerShed","block","window","chimney","flue","vent","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome"],"type":"string"},"type":{"const":"colour","type":"string"}},"required":["type","item","colour"],"type":"object"},{"additionalProperties":false,"properties":{"covering":{"description":"The roof's covering: tiles, biber (Biberschwanz plain tiles), flach (flat tiles such as Tegalit), falz (standing-seam sheet, modules flush) or trapez (trapezoidal sheet).","enum":["tiles","biber","flach","falz","trapez"],"type":"string"},"face":{"description":"Only this face (a garage in Falzblech, say), from \"faces\" or \"dormer_roofs\"; without it the whole roof. On a flat dormer roof it decides the mounting: tiles (a plain flat roof) or trapez puts the modules on racks, falz lays them flush (without a choice: racks where it stands on a flat roof or measures 20 m² or more; see its \"mounting\").","maxLength":80,"minLength":1,"type":"string"},"flat_rack":{"description":"Racks on flat roofs: ew (east-west pairs back to back, default), south (rows facing south), ns (along the roof).","enum":["ew","south","ns"],"type":"string"},"rack_tilt_deg":{"anyOf":[{"const":5,"type":"number"},{"const":10,"type":"number"},{"const":15,"type":"number"}],"description":"Tilt of the racks on flat roofs and racked trapezoidal sheet: 5, 10 (default) or 15 degrees."},"trapez_racks":{"description":"Trapezoidal sheet sloping 15° or less: modules on racks instead of flush.","type":"boolean"},"type":{"const":"covering","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"Place an R × C field of modules exactly where the person's drawing shows it, in the face's own metres. Use dry_run first when unsure.","properties":{"anchor":{"description":"What from_eave_m and from_left_m name: the field's lower left corner (default) or its middle.","enum":["lower_left","centre"],"type":"string"},"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"dry_run":{"description":"true: change nothing; the answer's \"dry_run\" lists the modules that would be placed (row, column, centre, orientation) and every collision with its reason.","type":"boolean"},"exact":{"description":"Default true: all or nothing. If any module of the R × C field would collide (an obstacle, the edge margin, another module) nothing is placed and every collision is listed. false: place the ones that fit (as add_modules).","type":"boolean"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's anchor: horizontal metres up from the eave (the lower left corner, or the middle with anchor \"centre\").","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The anchor: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"portrait: the module's long side up the slope (across the eave); landscape: long side along the eave. The same on every face, house roof or dormer roof: \"up the slope\" and \"along the eave\" are the face's own axes (geometry.faces[].slope_axis / eave_axis; on a flat face its longest edge). On racks every module stands landscape and this does not apply.","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"snap_to_grid":{"description":"true: the field's first module is moved onto the module grid of the nearest module on this face (same pitch, same rows and columns, its orientation unless given), so a new field lines up with an existing one. The answer says by how many cm it moved.","type":"boolean"},"type":{"const":"place_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Continue a row (or column) of modules in a direction, on the row's own grid: the same pitch, orientation, type and line, one clamp gap on from its last module. A neighbouring field on the same grid is met exactly.","properties":{"count":{"description":"How many modules to add. Without it: as many as fit, up to the next obstacle, module or edge (the answer says what stopped the row).","maximum":20,"minimum":1,"type":"integer"},"direction":{"description":"Which way: right or left seen from below along the eave; up or down the slope.","enum":["right","left","up","down"],"type":"string"},"dry_run":{"description":"true: change nothing; \"dry_run\" lists what would be added.","type":"boolean"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on a module of the row (or column) to continue.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"continue_row","type":"string"}},"required":["type","face","from_eave_m","from_left_m","direction"],"type":"object"},{"additionalProperties":false,"description":"Move a dormer and keep its modules: the dormer moves as with edit_obstacle, its automatically laid modules follow, and the modules laid by hand on its roofs are carried the same distance.","properties":{"id":{"description":"A dormer's obstacle id (\"obstacles\" or \"your_obstacles\"; a replaced dormer's old id works).","maxLength":80,"minLength":1,"type":"string"},"right_m":{"description":"Move it to the right seen from below (negative: left), metres.","maximum":10,"minimum":-10,"type":"number"},"type":{"const":"move_dormer","type":"string"},"up_m":{"description":"Move it up the roof (negative: down), horizontal metres.","maximum":10,"minimum":-10,"type":"number"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\". Its modules stay exactly where they are from now on (the other module edits do this by themselves).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"lay_by_hand","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's lower left corner: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The field's lower left corner: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"Default portrait (landscape if the plan is set to landscape). portrait: the module's long side up the slope (across the eave); landscape: long side along the eave. The same on every face, house roof or dormer roof: \"up the slope\" and \"along the eave\" are the face's own axes (geometry.faces[].slope_axis / eave_axis; on a flat face its longest edge). On racks every module stands landscape and this does not apply.","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"type":{"const":"add_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on the module to take off, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner (every module whose centre lies inside goes).","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"remove_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Put modules taken out of the automatic layout back.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on a module taken out before, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"restore_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field: the modules joined to the nearest one move together.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"type":{"const":"move_field","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Move the modules in an area together, as the solar roof check moves a selection (press, hold and drag over them, then drag the middle). All or none: blocked by the face's edge, another module or an obstacle.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"One corner of the area (horizontal metres up from the eave), or a spot on one module.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"to_eave_m":{"description":"The area's other corner: every module whose middle lies in the area is picked.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"move_modules","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Turn the modules in an area portrait ↔ landscape, as the page's selection does: laid afresh from their corner at the eave, as wide as they were, at most as many as there were. Modules on racks always stand landscape.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"One corner of the area (horizontal metres up from the eave), or a spot on one module.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner: every module whose middle lies in the area is picked.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Another module type for the modules in an area (the page's selection, \"Modultyp\"): each keeps its row and column from the group's corner; one that no longer fits goes.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"One corner of the area (horizontal metres up from the eave), or a spot on one module.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"module":{"description":"The module type for these modules: m470 = 470 W · 1.762 × 1.134 mm; m490 = 490 W · 1.800 × 1.134 mm; m520 = 520 W · 1.960 × 1.134 mm. The plan's own type (edit \"modules\") stays for the rest.","enum":["m470","m490","m520"],"type":"string"},"to_eave_m":{"description":"The area's other corner: every module whose middle lies in the area is picked.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"set_module_type","type":"string"}},"required":["type","face","from_eave_m","from_left_m","module"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id (\"u:<n>\" for one added before).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"maxLength":80,"minLength":1,"type":"string"},"type":{"const":"confirm_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"on":{"description":"Modules on flat and shed dormers too (gable dormers always carry them).","type":"boolean"},"type":{"const":"dormer_modules","type":"string"}},"required":["type","on"],"type":"object"},{"additionalProperties":false,"description":"„Gaube ganz belegen“: as many modules as fit on the dormer's roof, laid as any roof (on racks where its flat top is big enough or stands on a flat roof). A flat or shed dormer is switched on alone.","properties":{"id":{"description":"A dormer's obstacle id (from \"obstacles\", \"u:<n>\" for one added).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"fill_dormer","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"description":"„Alle Module von der Gaube nehmen“: the dormer's roof switched off (fill_dormer lays it again).","properties":{"id":{"description":"A dormer's obstacle id.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"clear_dormer","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"arrange":{"description":"As the solar roof check names them: design = „Ästhetisch“ (whole rectangles only, the same height, left and right the same width), tidy = „Ordentlich“ (rows in one line, no small single fields; default), most = „Maximal“ (as many as fit, landscape in gaps too).","enum":["tidy","most","design"],"type":"string"},"module":{"description":"The module type: m470 = 470 W · 1.762 × 1.134 mm; m490 = 490 W · 1.800 × 1.134 mm; m520 = 520 W · 1.960 × 1.134 mm.","enum":["m470","m490","m520"],"type":"string"},"orientation":{"description":"auto (default): portrait, or landscape where that fits 2+ more modules; mixed: portrait and landscape on one roof, wherever each fits.","enum":["auto","portrait","landscape","mixed"],"type":"string"},"type":{"const":"modules","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" (an extension, a garage, the other half of a semi-detached house) to plan with the house.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"add_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" to plan without again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id (\"t:…\") from \"shade\": felled, or wrong in the data; its shade no longer counts.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id taken out before.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"change_m":{"description":"Metres higher (positive) or lower (negative) than the laser scan measured it (the scan is from earlier years).","maximum":20,"minimum":-20,"type":"number"},"id":{"description":"A tree id (\"t:…\") from \"shade\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"tree_height","type":"string"}},"required":["type","id","change_m"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"A free four-cornered outline instead of a rectangle (as the solar roof check's corner handles): its corners on its face, the front (eave side) first.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":4,"minItems":4,"type":"array"},"depth_m":{"description":"New depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a chimney taller than measured casts more shade).","maximum":8,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" (found by scan or photo) or \"your_obstacles\".","maxLength":80,"minLength":1,"type":"string"},"right_m":{"description":"Move it to the right seen from below (negative: left), metres.","maximum":10,"minimum":-10,"type":"number"},"turn_deg":{"description":"Turn it round its centre, degrees (positive: clockwise seen from above), as „Drehen“ in the solar roof check.","maximum":180,"minimum":-180,"type":"number"},"type":{"const":"edit_obstacle","type":"string"},"up_m":{"description":"Move it up the roof (negative: down), horizontal metres.","maximum":10,"minimum":-10,"type":"number"},"width_m":{"description":"New width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"The face's new outline, corner by corner (as the solar roof check's editor drags them); \"faces[].corners\" gives the present ones.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":30,"minItems":3,"type":"array"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"face_outline","type":"string"}},"required":["type","face","corners"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face back to the measured roof („Wie gemessen“): its outline, slope, turned racks and hand-laid modules go.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"reset_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A piece of a split face (\"<id>|1\" or \"|2\"): both pieces become one face again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"unsplit","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"eave_height_m":{"description":"Its lowest edge above the ground, metres.","maximum":30,"minimum":1.5,"type":"number"},"face":{"description":"A face added with add_face (\"d:<n>\").","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"drawn_face","type":"string"}},"required":["type","face","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face added with add_face (\"d:<n>\"): deleted; later ones move down by one.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"delete_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (a chimney, a skylight dome, a vent …): the aerial photo is searched for more of the same on this roof (as „Ähnliche finden“), and what it finds is added as your obstacles. One AI call each; at most 3 a call.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"find_similar","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"description":"The AI outline check (as „Umriss passt nicht?“): the roof's edges are compared with the aerial photo and moved where they clearly lie elsewhere. One AI call; use it when a note says the photo shows more roof.","properties":{"type":{"const":"check_outline","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"Ask the aerial photo again for chimneys and roof windows when \"obstacles_checked\" was false (as „Nochmal suchen“).","properties":{"type":{"const":"search_again","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"degrees":{"description":"Turn the module racks from the roof's own edges by this much (0: along the edges again; positive: anticlockwise, seen from above).","maximum":45,"minimum":-45,"type":"number"},"face":{"description":"A flat face, or a flat dormer roof from \"dormer_roofs\" whose \"mounting\" is racks.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"turn_racks","type":"string"}},"required":["type","face","degrees"],"type":"object"},{"additionalProperties":false,"properties":{"battery_kwh":{"description":"Battery size, kWh: 0 for none, or a whole number from 4 to 20 (default 8).","maximum":20,"minimum":0,"type":"integer"},"consumption_kwh":{"description":"The household's electricity use a year, kWh, without car or heat pump (default 4,500).","maximum":30000,"minimum":1000,"type":"number"},"ev":{"description":"An electric car is (or will be) charged at home: about 2,700 kWh a year more.","type":"boolean"},"heat_pump":{"description":"A heat pump heats the house: about 4,500 kWh a year more.","type":"boolean"},"offer_eur":{"description":"The total price on an offer the person already has, euros before any subsidy (0 clears it): the solar roof check link then shows the payback. Never a price of Sky Solar's.","maximum":300000,"minimum":0,"type":"number"},"type":{"const":"household","type":"string"}},"required":["type"],"type":"object"}]},"maxItems":20,"type":"array"},"geometry":{"description":"true: add a complete geometry snapshot to the answer (the default stays short): for every face and dormer roof its outline, size, usable box and the eave and slope axes (with compass bearings), every module with its face, position in the face's own metres and orientation, the module fields (rows × columns), and the obstacles with their outlines and clearances. Everything in the same metres the edits take.","type":"boolean"},"link":{"description":"A solar roof check link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or the solar roof check page gave it.","maxLength":12000,"minLength":10,"type":"string"}},"required":["link"],"type":"object"}after
{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"answers":{"description":"The person's answers to the last answer's \"questions\".","items":{"additionalProperties":false,"properties":{"id":{"description":"The id of a question from the last answer.","maxLength":80,"minLength":1,"type":"string"},"obstacle":{"description":"true: there is an obstacle there; false: there is none.","type":"boolean"}},"required":["id","obstacle"],"type":"object"},"maxItems":20,"type":"array"},"edits":{"items":{"oneOf":[{"additionalProperties":false,"properties":{"direction_deg":{"description":"Compass direction the face looks to: 0 north, 90 east, 180 south, 270 west.","maximum":360,"minimum":0,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"tilt_deg":{"description":"Tilt, degrees (0 flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"slope","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"edge":{"description":"Which edge moves: the eave, or the left or right end seen from below.","enum":["eave","left","right"],"type":"string"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"metres":{"description":"Or a change: metres out from where the edge is now (negative: in), horizontal.","maximum":1.5,"minimum":-1.5,"type":"number"},"to_m":{"description":"Eave only: how far the eave should reach past the wall, horizontal metres (\"Dachüberstand 50 cm\" → 0.5). The face list shows the current eave_overhang_m.","maximum":1.5,"minimum":0,"type":"number"},"type":{"const":"overhang","type":"string"}},"required":["type","face","edge"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A cut along the eave, this far up from it.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"A cut up the slope, this far from the left end.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"split","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"corners_m":{"description":"Any shape instead: its corners as [east, north] metres in the same frame as \"house.footprint_m\" (from a building plan).","items":{"items":false,"maxItems":2,"minItems":2,"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array"},"maxItems":24,"minItems":3,"type":"array"},"depth_m":{"description":"Out from the wall, metres.","maximum":20,"minimum":1,"type":"number"},"direction_deg":{"description":"Way the roof slopes down to (default: away from the wall).","maximum":360,"minimum":0,"type":"number"},"eave_height_m":{"description":"Height of the roof's lowest edge above the ground, metres.","maximum":15,"minimum":1.5,"type":"number"},"offset_m":{"description":"From the middle of the wall: positive to the east (north and south walls) or north (east and west walls).","maximum":30,"minimum":-30,"type":"number"},"tilt_deg":{"description":"Roof tilt, degrees (default 0, flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"add_face","type":"string"},"wall":{"description":"The house wall the new part stands against (an extension, a garage, a porch). With width_m and depth_m; or give corners_m instead.","enum":["north","east","south","west"],"type":"string"},"width_m":{"description":"Along the wall, metres.","maximum":30,"minimum":1,"type":"number"}},"required":["type","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"Horizontal metres up from the eave (as on a drawing seen from above).","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a dormer: its front wall; default: the kind's usual height).","maximum":4,"minimum":0.1,"type":"number"},"kind":{"description":"What it is: chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall, or block (anything else, 60 cm square).","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (e.g. a dormer the scan found).","maxLength":80,"minLength":1,"type":"string"},"kind":{"description":"The new kind. Dormers: dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall (a dormer stays its size). Or chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, block.","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id","kind"],"type":"object"},{"additionalProperties":false,"properties":{"colour":{"description":"A colour id. metal: anthracite, aluminium, zinc, copper, brown; dormerBarrel: tiles, anthracite, aluminium, zinc, copper, brown; dormerShed: tiles, anthracite, aluminium, zinc, copper, brown; block: wall, grey, anthracite, red, brown; window: silver, anthracite, white, brown; chimney: render, brick, slate, steel, copper; flue: steel, anthracite, red; vent: anthracite, red, brown, grey; dish: light, anthracite, red; antenna: silver, anthracite; ladder: anthracite, red, brown, galvanised; snowWood: natural, dark, weathered; snowGrid: anthracite, red, brown, galvanised; steps: anthracite, red, brown, galvanised; solarThermal: silver, black; pv: silver, black; dome: opal, clear","maxLength":30,"minLength":1,"type":"string"},"face":{"description":"With item \"metal\": only this face's sheet (a copper garage beside a zinc roof).","maxLength":80,"minLength":1,"type":"string"},"item":{"description":"What gets the colour: roof (a tiled roof, for the building part of face, the house without face; colours: photo, clay, red, darkRed, copper, brown, black, anthracite, slate, grey), metal (sheet-metal dormer tops and Falz- or Trapezblech roofs), or a kind of item.","enum":["roof","metal","dormerBarrel","dormerShed","block","window","chimney","flue","vent","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome"],"type":"string"},"type":{"const":"colour","type":"string"}},"required":["type","item","colour"],"type":"object"},{"additionalProperties":false,"properties":{"covering":{"description":"The roof's covering: tiles, biber (Biberschwanz plain tiles), flach (flat tiles such as Tegalit), falz (standing-seam sheet, modules flush) or trapez (trapezoidal sheet).","enum":["tiles","biber","flach","falz","trapez"],"type":"string"},"face":{"description":"Only this face (a garage in Falzblech, say); without it the whole roof.","maxLength":80,"minLength":1,"type":"string"},"flat_rack":{"description":"Racks on flat roofs: ew (east-west pairs back to back, default), south (rows facing south), ns (along the roof).","enum":["ew","south","ns"],"type":"string"},"rack_tilt_deg":{"anyOf":[{"const":5,"type":"number"},{"const":10,"type":"number"},{"const":15,"type":"number"}],"description":"Tilt of the racks on flat roofs and racked trapezoidal sheet: 5, 10 (default) or 15 degrees."},"trapez_racks":{"description":"Trapezoidal sheet sloping 15° or less: modules on racks instead of flush.","type":"boolean"},"type":{"const":"covering","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\". Its modules stay exactly where they are from now on (the other module edits do this by themselves).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"lay_by_hand","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's lower left corner: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The field's lower left corner: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"Default portrait (landscape if the plan is set to landscape).","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"type":{"const":"add_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on the module to take off, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner (every module whose centre lies inside goes).","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"remove_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Put modules taken out of the automatic layout back.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on a module taken out before, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"restore_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field: the modules joined to the nearest one move together.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"type":{"const":"move_field","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id (\"u:<n>\" for one added before).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"maxLength":80,"minLength":1,"type":"string"},"type":{"const":"confirm_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"on":{"description":"Modules on flat and shed dormers too (gable dormers always carry them).","type":"boolean"},"type":{"const":"dormer_modules","type":"string"}},"required":["type","on"],"type":"object"},{"additionalProperties":false,"properties":{"arrange":{"description":"As the solar roof check names them: design = „Ästhetisch“ (whole rectangles only, the same height, left and right the same width), tidy = „Ordentlich“ (rows in one line, no small single fields; default), most = „Maximal“ (as many as fit, landscape in gaps too).","enum":["tidy","most","design"],"type":"string"},"module":{"description":"The module type: m470 = 470 W · 1.762 × 1.134 mm; m490 = 490 W · 1.800 × 1.134 mm; m520 = 520 W · 1.960 × 1.134 mm.","enum":["m470","m490","m520"],"type":"string"},"orientation":{"description":"auto (default): portrait, or landscape where that fits 2+ more modules; mixed: portrait and landscape on one roof, wherever each fits.","enum":["auto","portrait","landscape","mixed"],"type":"string"},"type":{"const":"modules","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" (an extension, a garage, the other half of a semi-detached house) to plan with the house.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"add_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" to plan without again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id (\"t:…\") from \"shade\": felled, or wrong in the data; its shade no longer counts.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id taken out before.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"change_m":{"description":"Metres higher (positive) or lower (negative) than the laser scan measured it (the scan is from earlier years).","maximum":20,"minimum":-20,"type":"number"},"id":{"description":"A tree id (\"t:…\") from \"shade\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"tree_height","type":"string"}},"required":["type","id","change_m"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"A free four-cornered outline instead of a rectangle (as the solar roof check's corner handles): its corners on its face, the front (eave side) first.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":4,"minItems":4,"type":"array"},"depth_m":{"description":"New depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a chimney taller than measured casts more shade).","maximum":8,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" (found by scan or photo) or \"your_obstacles\".","maxLength":80,"minLength":1,"type":"string"},"right_m":{"description":"Move it to the right seen from below (negative: left), metres.","maximum":10,"minimum":-10,"type":"number"},"turn_deg":{"description":"Turn it round its centre, degrees (positive: clockwise seen from above), as „Drehen“ in the solar roof check.","maximum":180,"minimum":-180,"type":"number"},"type":{"const":"edit_obstacle","type":"string"},"up_m":{"description":"Move it up the roof (negative: down), horizontal metres.","maximum":10,"minimum":-10,"type":"number"},"width_m":{"description":"New width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"The face's new outline, corner by corner (as the solar roof check's editor drags them); \"faces[].corners\" gives the present ones.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":30,"minItems":3,"type":"array"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"face_outline","type":"string"}},"required":["type","face","corners"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face back to the measured roof („Wie gemessen“): its outline, slope, turned racks and hand-laid modules go.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"reset_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A piece of a split face (\"<id>|1\" or \"|2\"): both pieces become one face again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"unsplit","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"eave_height_m":{"description":"Its lowest edge above the ground, metres.","maximum":30,"minimum":1.5,"type":"number"},"face":{"description":"A face added with add_face (\"d:<n>\").","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"drawn_face","type":"string"}},"required":["type","face","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face added with add_face (\"d:<n>\"): deleted; later ones move down by one.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"delete_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (a chimney, a skylight dome, a vent …): the aerial photo is searched for more of the same on this roof (as „Ähnliche finden“), and what it finds is added as your obstacles. One AI call each; at most 3 a call.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"find_similar","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"description":"The AI outline check (as „Umriss passt nicht?“): the roof's edges are compared with the aerial photo and moved where they clearly lie elsewhere. One AI call; use it when a note says the photo shows more roof.","properties":{"type":{"const":"check_outline","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"Ask the aerial photo again for chimneys and roof windows when \"obstacles_checked\" was false (as „Nochmal suchen“).","properties":{"type":{"const":"search_again","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"degrees":{"description":"Turn the module racks from the roof's own edges by this much (0: along the edges again; positive: clockwise).","maximum":45,"minimum":-45,"type":"number"},"face":{"description":"A flat face.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"turn_racks","type":"string"}},"required":["type","face","degrees"],"type":"object"},{"additionalProperties":false,"properties":{"battery_kwh":{"description":"Battery size, kWh: one of 0, 5, 8, 10, 15 (default 8).","type":"number"},"consumption_kwh":{"description":"The household's electricity use a year, kWh, without car or heat pump (default 4,500).","maximum":30000,"minimum":1000,"type":"number"},"ev":{"description":"An electric car is (or will be) charged at home: about 2,700 kWh a year more.","type":"boolean"},"heat_pump":{"description":"A heat pump heats the house: about 4,500 kWh a year more.","type":"boolean"},"offer_eur":{"description":"The total price on an offer the person already has, euros before any subsidy (0 clears it): the solar roof check link then shows the payback. Never a price of Sky Solar's.","maximum":300000,"minimum":0,"type":"number"},"type":{"const":"household","type":"string"}},"required":["type"],"type":"object"}]},"maxItems":20,"type":"array"},"link":{"description":"A solar roof check link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or the solar roof check page gave it.","maxLength":12000,"minLength":10,"type":"string"}},"required":["link"],"type":"object"}⟨7 unchanged words⟩ true,"title":"Improve a roof plan (Dachchecksolar roof check)"}
Find a house (Dachchecksolar roof check)
Find a building in Bavaria by its address, for theDachchecksolar(roofcheck).check. Returns up to 5 matches with a house ⟨11 unchanged words⟩
⟨7 unchanged words⟩ ":true,"title":"Find a house (Dachchecksolar roof check)"}
Plan a roof (Dachchecksolar roof check)
⟨17 unchanged words⟩ the laser scan, exactly as Sky Solar'sDachchecksolar roof check page does: modules, kWp, kWh a year ⟨70 unchanged words⟩ notes on likely model errors, and aDachchecksolar roof check link that opens this plan in 3D for ⟨56 unchanged words⟩
⟨165 unchanged words⟩ string"},"link":{"description":"ADachchecksolar roof check link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or theDachchecksolar roof check page gave it.","maxLength":12000,"minLength" ⟨17 unchanged words⟩ any subsidy (0 clears it): theDachchecksolar roof check link then shows the payback. Never a price ⟨11 unchanged words⟩
⟨7 unchanged words⟩ ":true,"title":"Plan a roof (Dachchecksolar roof check)"}
Roof plan as a DXF drawing (Dachchecksolar roof check)
The plan behind aDachchecksolar roof check link as a DXF drawing (R12, metres ⟨49 unchanged words⟩
⟨5 unchanged words⟩ properties":{"link":{"description":"ADachchecksolar roof check link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or theDachchecksolar roof check page gave it.","maxLength":12000,"minLength ⟨7 unchanged words⟩
⟨9 unchanged words⟩ ":"Roof plan as a DXF drawing (Dachchecksolar roof check)"}
Roof plan as a PDF (Dachchecksolar roof check)
The plan behind aDachchecksolar roof check link as the one-page PDF report theDachchecksolar roof check page prints, in German, for the person ⟨77 unchanged words⟩
⟨5 unchanged words⟩ properties":{"link":{"description":"ADachchecksolar roof check link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or theDachchecksolar roof check page gave it.","maxLength":12000,"minLength ⟨7 unchanged words⟩
⟨8 unchanged words⟩ "title":"Roof plan as a PDF (Dachchecksolar roof check)"}
before
{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"answers":{"description":"The person's answers to the last answer's \"questions\".","items":{"additionalProperties":false,"properties":{"id":{"description":"The id of a question from the last answer.","maxLength":80,"minLength":1,"type":"string"},"obstacle":{"description":"true: there is an obstacle there; false: there is none.","type":"boolean"}},"required":["id","obstacle"],"type":"object"},"maxItems":20,"type":"array"},"edits":{"items":{"oneOf":[{"additionalProperties":false,"properties":{"direction_deg":{"description":"Compass direction the face looks to: 0 north, 90 east, 180 south, 270 west.","maximum":360,"minimum":0,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"tilt_deg":{"description":"Tilt, degrees (0 flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"slope","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"edge":{"description":"Which edge moves: the eave, or the left or right end seen from below.","enum":["eave","left","right"],"type":"string"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"metres":{"description":"Or a change: metres out from where the edge is now (negative: in), horizontal.","maximum":1.5,"minimum":-1.5,"type":"number"},"to_m":{"description":"Eave only: how far the eave should reach past the wall, horizontal metres (\"Dachüberstand 50 cm\" → 0.5). The face list shows the current eave_overhang_m.","maximum":1.5,"minimum":0,"type":"number"},"type":{"const":"overhang","type":"string"}},"required":["type","face","edge"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A cut along the eave, this far up from it.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"A cut up the slope, this far from the left end.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"split","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Out from the wall, metres.","maximum":20,"minimum":1,"type":"number"},"direction_deg":{"description":"Way the roof slopes down to (default: away from the wall).","maximum":360,"minimum":0,"type":"number"},"eave_height_m":{"description":"Height of the roof's lowest edge above the ground, metres.","maximum":15,"minimum":1.5,"type":"number"},"offset_m":{"description":"From the middle of the wall: positive to the east (north and south walls) or north (east and west walls).","maximum":30,"minimum":-30,"type":"number"},"tilt_deg":{"description":"Roof tilt, degrees (default 0, flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"add_face","type":"string"},"wall":{"description":"The house wall the new part stands against (an extension, a garage, a porch).","enum":["north","east","south","west"],"type":"string"},"width_m":{"description":"Along the wall, metres.","maximum":30,"minimum":1,"type":"number"}},"required":["type","wall","width_m","depth_m","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"Horizontal metres up from the eave (as on a drawing seen from above).","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a dormer: its front wall; default: the kind's usual height).","maximum":4,"minimum":0.1,"type":"number"},"kind":{"description":"What it is: chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall, or block (anything else, 60 cm square).","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (e.g. a dormer the scan found).","maxLength":80,"minLength":1,"type":"string"},"kind":{"description":"The new kind. Dormers: dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall (a dormer stays its size). Or chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, block.","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id","kind"],"type":"object"},{"additionalProperties":false,"properties":{"colour":{"description":"A colour id. metal: anthracite, aluminium, zinc, copper, brown; block: wall, grey, anthracite, red, brown; window: silver, anthracite, white, brown; chimney: render, brick, slate, steel, copper; flue: steel, anthracite, red; vent: anthracite, red, brown, grey; dish: light, anthracite, red; antenna: silver, anthracite; ladder: anthracite, red, brown, galvanised; snowWood: natural, dark, weathered; snowGrid: anthracite, red, brown, galvanised; steps: anthracite, red, brown, galvanised; solarThermal: silver, black; pv: silver, black; dome: opal, clear","maxLength":30,"minLength":1,"type":"string"},"face":{"description":"With item \"metal\": only this face's sheet (a copper garage beside a zinc roof).","maxLength":80,"minLength":1,"type":"string"},"item":{"description":"What gets the colour: metal (sheet-metal dormer tops and Falz- or Trapezblech roofs), or a kind of item.","enum":["metal","block","window","chimney","flue","vent","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome"],"type":"string"},"type":{"const":"colour","type":"string"}},"required":["type","item","colour"],"type":"object"},{"additionalProperties":false,"properties":{"covering":{"description":"The roof's covering: tiles, biber (Biberschwanz plain tiles), flach (flat tiles such as Tegalit), falz (standing-seam sheet, modules flush) or trapez (trapezoidal sheet).","enum":["tiles","biber","flach","falz","trapez"],"type":"string"},"face":{"description":"Only this face (a garage in Falzblech, say); without it the whole roof.","maxLength":80,"minLength":1,"type":"string"},"flat_rack":{"description":"Racks on flat roofs: ew (east-west pairs back to back, default), south (rows facing south), ns (along the roof).","enum":["ew","south","ns"],"type":"string"},"rack_tilt_deg":{"anyOf":[{"const":5,"type":"number"},{"const":10,"type":"number"},{"const":15,"type":"number"}],"description":"Tilt of the racks on flat roofs and racked trapezoidal sheet: 5, 10 (default) or 15 degrees."},"trapez_racks":{"description":"Trapezoidal sheet sloping 15° or less: modules on racks instead of flush.","type":"boolean"},"type":{"const":"covering","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\". Its modules stay exactly where they are from now on (the other module edits do this by themselves).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"lay_by_hand","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's lower left corner: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The field's lower left corner: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"Default portrait (landscape if the plan is set to landscape).","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"type":{"const":"add_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on the module to take off, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner (every module whose centre lies inside goes).","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"remove_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field: the modules joined to the nearest one move together.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"type":{"const":"move_field","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id (\"u:<n>\" for one added before).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"maxLength":80,"minLength":1,"type":"string"},"type":{"const":"confirm_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"on":{"description":"Modules on flat and shed dormers too (gable dormers always carry them).","type":"boolean"},"type":{"const":"dormer_modules","type":"string"}},"required":["type","on"],"type":"object"},{"additionalProperties":false,"properties":{"arrange":{"description":"tidy: even fields (default); most: as many as fit; design: clean rectangles only.","enum":["tidy","most","design"],"type":"string"},"orientation":{"enum":["auto","portrait","landscape"],"type":"string"},"type":{"const":"modules","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"battery_kwh":{"description":"Battery size, kWh: one of 0, 5, 8, 10, 15 (default 8).","type":"number"},"consumption_kwh":{"description":"The household's electricity use a year, kWh, without car or heat pump (default 4,500).","maximum":30000,"minimum":1000,"type":"number"},"ev":{"description":"An electric car is (or will be) charged at home: about 2,700 kWh a year more.","type":"boolean"},"heat_pump":{"description":"A heat pump heats the house: about 4,500 kWh a year more.","type":"boolean"},"type":{"const":"household","type":"string"}},"required":["type"],"type":"object"}]},"maxItems":20,"type":"array"},"link":{"description":"A Dachcheck link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or the Dachcheck page gave it.","maxLength":12000,"minLength":10,"type":"string"}},"required":["link"],"type":"object"}after
{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"answers":{"description":"The person's answers to the last answer's \"questions\".","items":{"additionalProperties":false,"properties":{"id":{"description":"The id of a question from the last answer.","maxLength":80,"minLength":1,"type":"string"},"obstacle":{"description":"true: there is an obstacle there; false: there is none.","type":"boolean"}},"required":["id","obstacle"],"type":"object"},"maxItems":20,"type":"array"},"edits":{"items":{"oneOf":[{"additionalProperties":false,"properties":{"direction_deg":{"description":"Compass direction the face looks to: 0 north, 90 east, 180 south, 270 west.","maximum":360,"minimum":0,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"tilt_deg":{"description":"Tilt, degrees (0 flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"slope","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"edge":{"description":"Which edge moves: the eave, or the left or right end seen from below.","enum":["eave","left","right"],"type":"string"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"metres":{"description":"Or a change: metres out from where the edge is now (negative: in), horizontal.","maximum":1.5,"minimum":-1.5,"type":"number"},"to_m":{"description":"Eave only: how far the eave should reach past the wall, horizontal metres (\"Dachüberstand 50 cm\" → 0.5). The face list shows the current eave_overhang_m.","maximum":1.5,"minimum":0,"type":"number"},"type":{"const":"overhang","type":"string"}},"required":["type","face","edge"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A cut along the eave, this far up from it.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"A cut up the slope, this far from the left end.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"split","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"corners_m":{"description":"Any shape instead: its corners as [east, north] metres in the same frame as \"house.footprint_m\" (from a building plan).","items":{"items":false,"maxItems":2,"minItems":2,"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array"},"maxItems":24,"minItems":3,"type":"array"},"depth_m":{"description":"Out from the wall, metres.","maximum":20,"minimum":1,"type":"number"},"direction_deg":{"description":"Way the roof slopes down to (default: away from the wall).","maximum":360,"minimum":0,"type":"number"},"eave_height_m":{"description":"Height of the roof's lowest edge above the ground, metres.","maximum":15,"minimum":1.5,"type":"number"},"offset_m":{"description":"From the middle of the wall: positive to the east (north and south walls) or north (east and west walls).","maximum":30,"minimum":-30,"type":"number"},"tilt_deg":{"description":"Roof tilt, degrees (default 0, flat).","maximum":60,"minimum":0,"type":"number"},"type":{"const":"add_face","type":"string"},"wall":{"description":"The house wall the new part stands against (an extension, a garage, a porch). With width_m and depth_m; or give corners_m instead.","enum":["north","east","south","west"],"type":"string"},"width_m":{"description":"Along the wall, metres.","maximum":30,"minimum":1,"type":"number"}},"required":["type","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"Its depth up the roof, metres in the slope (a roof window \"78 × 140\": 1.4); a dormer's horizontally, as on a drawing from above. A ladder starts at from_eave_m and runs this far up; without it a ladder runs from the eave to the ridge.","maximum":12,"minimum":0.1,"type":"number"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"Horizontal metres up from the eave (as on a drawing seen from above).","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a dormer: its front wall; default: the kind's usual height).","maximum":4,"minimum":0.1,"type":"number"},"kind":{"description":"What it is: chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall, or block (anything else, 60 cm square).","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"add_obstacle","type":"string"},"width_m":{"description":"Its width along the eave, metres in the roof's slope (a dormer, a roof window \"78 × 140\": 0.78). Default: the kind's usual size.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","face","kind","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"depth_m":{"description":"A new depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (e.g. a dormer the scan found).","maxLength":80,"minLength":1,"type":"string"},"kind":{"description":"The new kind. Dormers: dormerShed, dormerFlat, dormerGable, dormerTwin, dormerHip, dormerPoint, dormerTrapez, dormerBarrel, dormerBat, dormerWall (a dormer stays its size). Or chimney, window, vent, flue, dish, antenna, ladder, snowWood, snowGrid, steps, solarThermal, pv, dome, block.","enum":["chimney","window","vent","flue","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome","dormerShed","dormerFlat","dormerGable","dormerTwin","dormerHip","dormerPoint","dormerTrapez","dormerBarrel","dormerBat","dormerWall","block"],"type":"string"},"type":{"const":"change_kind","type":"string"},"width_m":{"description":"A new width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id","kind"],"type":"object"},{"additionalProperties":false,"properties":{"colour":{"description":"A colour id. metal: anthracite, aluminium, zinc, copper, brown; dormerBarrel: tiles, anthracite, aluminium, zinc, copper, brown; dormerShed: tiles, anthracite, aluminium, zinc, copper, brown; block: wall, grey, anthracite, red, brown; window: silver, anthracite, white, brown; chimney: render, brick, slate, steel, copper; flue: steel, anthracite, red; vent: anthracite, red, brown, grey; dish: light, anthracite, red; antenna: silver, anthracite; ladder: anthracite, red, brown, galvanised; snowWood: natural, dark, weathered; snowGrid: anthracite, red, brown, galvanised; steps: anthracite, red, brown, galvanised; solarThermal: silver, black; pv: silver, black; dome: opal, clear","maxLength":30,"minLength":1,"type":"string"},"face":{"description":"With item \"metal\": only this face's sheet (a copper garage beside a zinc roof).","maxLength":80,"minLength":1,"type":"string"},"item":{"description":"What gets the colour: roof (a tiled roof, for the building part of face, the house without face; colours: photo, clay, red, darkRed, copper, brown, black, anthracite, slate, grey), metal (sheet-metal dormer tops and Falz- or Trapezblech roofs), or a kind of item.","enum":["roof","metal","dormerBarrel","dormerShed","block","window","chimney","flue","vent","dish","antenna","ladder","snowWood","snowGrid","steps","solarThermal","pv","dome"],"type":"string"},"type":{"const":"colour","type":"string"}},"required":["type","item","colour"],"type":"object"},{"additionalProperties":false,"properties":{"covering":{"description":"The roof's covering: tiles, biber (Biberschwanz plain tiles), flach (flat tiles such as Tegalit), falz (standing-seam sheet, modules flush) or trapez (trapezoidal sheet).","enum":["tiles","biber","flach","falz","trapez"],"type":"string"},"face":{"description":"Only this face (a garage in Falzblech, say); without it the whole roof.","maxLength":80,"minLength":1,"type":"string"},"flat_rack":{"description":"Racks on flat roofs: ew (east-west pairs back to back, default), south (rows facing south), ns (along the roof).","enum":["ew","south","ns"],"type":"string"},"rack_tilt_deg":{"anyOf":[{"const":5,"type":"number"},{"const":10,"type":"number"},{"const":15,"type":"number"}],"description":"Tilt of the racks on flat roofs and racked trapezoidal sheet: 5, 10 (default) or 15 degrees."},"trapez_racks":{"description":"Trapezoidal sheet sloping 15° or less: modules on racks instead of flush.","type":"boolean"},"type":{"const":"covering","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\". Its modules stay exactly where they are from now on (the other module edits do this by themselves).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"lay_by_hand","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"description":"Modules side by side (default 1).","maximum":20,"minimum":1,"type":"number"},"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"The field's lower left corner: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"The field's lower left corner: metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"orientation":{"description":"Default portrait (landscape if the plan is set to landscape).","enum":["portrait","landscape"],"type":"string"},"rows":{"description":"Rows up the roof (default 1).","maximum":10,"minimum":1,"type":"number"},"type":{"const":"add_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on the module to take off, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner (every module whose centre lies inside goes).","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"remove_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"description":"Put modules taken out of the automatic layout back.","properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on a module taken out before, or one corner of an area: horizontal metres up from the eave.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"to_eave_m":{"description":"The area's other corner.","maximum":30,"minimum":0,"type":"number"},"to_left_m":{"description":"The area's other corner.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"restore_modules","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field: the modules joined to the nearest one move together.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"right_m":{"description":"Metres to the right seen from below (negative: left).","maximum":40,"minimum":-40,"type":"number"},"type":{"const":"move_field","type":"string"},"up_m":{"description":"Metres up the roof, in its slope (negative: down).","maximum":20,"minimum":-20,"type":"number"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face id from \"faces\" or \"dormer_roofs\".","maxLength":80,"minLength":1,"type":"string"},"from_eave_m":{"description":"A spot on (or next to) the field.","maximum":30,"minimum":0,"type":"number"},"from_left_m":{"description":"Metres from the face's left end, seen from below.","maximum":40,"minimum":0,"type":"number"},"type":{"const":"turn_field","type":"string"}},"required":["type","face","from_eave_m","from_left_m"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id (\"u:<n>\" for one added before).","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"maxLength":80,"minLength":1,"type":"string"},"type":{"const":"confirm_obstacle","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"on":{"description":"Modules on flat and shed dormers too (gable dormers always carry them).","type":"boolean"},"type":{"const":"dormer_modules","type":"string"}},"required":["type","on"],"type":"object"},{"additionalProperties":false,"properties":{"arrange":{"description":"As the Dachcheck names them: design = „Ästhetisch“ (whole rectangles only, the same height, left and right the same width), tidy = „Ordentlich“ (rows in one line, no small single fields; default), most = „Maximal“ (as many as fit, landscape in gaps too).","enum":["tidy","most","design"],"type":"string"},"module":{"description":"The module type: m470 = 470 W · 1.762 × 1.134 mm; m490 = 490 W · 1.800 × 1.134 mm; m520 = 520 W · 1.960 × 1.134 mm.","enum":["m470","m490","m520"],"type":"string"},"orientation":{"description":"auto (default): portrait, or landscape where that fits 2+ more modules; mixed: portrait and landscape on one roof, wherever each fits.","enum":["auto","portrait","landscape","mixed"],"type":"string"},"type":{"const":"modules","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" (an extension, a garage, the other half of a semi-detached house) to plan with the house.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"add_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A building part from \"building_parts\" to plan without again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_part","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id (\"t:…\") from \"shade\": felled, or wrong in the data; its shade no longer counts.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"remove_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"A tree id taken out before.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"restore_tree","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"change_m":{"description":"Metres higher (positive) or lower (negative) than the laser scan measured it (the scan is from earlier years).","maximum":20,"minimum":-20,"type":"number"},"id":{"description":"A tree id (\"t:…\") from \"shade\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"tree_height","type":"string"}},"required":["type","id","change_m"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"A free four-cornered outline instead of a rectangle (as the Dachcheck's corner handles): its corners on its face, the front (eave side) first.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":4,"minItems":4,"type":"array"},"depth_m":{"description":"New depth up the roof, metres in the slope (a dormer's horizontally).","maximum":12,"minimum":0.1,"type":"number"},"height_m":{"description":"How high it stands above the roof, metres (a chimney taller than measured casts more shade).","maximum":8,"minimum":0.1,"type":"number"},"id":{"description":"An obstacle id from \"obstacles\" (found by scan or photo) or \"your_obstacles\".","maxLength":80,"minLength":1,"type":"string"},"right_m":{"description":"Move it to the right seen from below (negative: left), metres.","maximum":10,"minimum":-10,"type":"number"},"turn_deg":{"description":"Turn it round its centre, degrees (positive: clockwise seen from above), as „Drehen“ in the Dachcheck.","maximum":180,"minimum":-180,"type":"number"},"type":{"const":"edit_obstacle","type":"string"},"up_m":{"description":"Move it up the roof (negative: down), horizontal metres.","maximum":10,"minimum":-10,"type":"number"},"width_m":{"description":"New width along the eave, metres in the slope.","maximum":12,"minimum":0.1,"type":"number"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"properties":{"corners":{"description":"The face's new outline, corner by corner (as the Dachcheck's editor drags them); \"faces[].corners\" gives the present ones.","items":{"additionalProperties":false,"description":"A corner on the face: horizontal metres up from the eave and from the left end seen from below.","properties":{"from_eave_m":{"maximum":40,"minimum":-40,"type":"number"},"from_left_m":{"maximum":50,"minimum":-50,"type":"number"}},"required":["from_eave_m","from_left_m"],"type":"object"},"maxItems":30,"minItems":3,"type":"array"},"face":{"description":"A face id from the last answer's \"faces\".","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"face_outline","type":"string"}},"required":["type","face","corners"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face back to the measured roof („Wie gemessen“): its outline, slope, turned racks and hand-laid modules go.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"reset_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A piece of a split face (\"<id>|1\" or \"|2\"): both pieces become one face again.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"unsplit","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"eave_height_m":{"description":"Its lowest edge above the ground, metres.","maximum":30,"minimum":1.5,"type":"number"},"face":{"description":"A face added with add_face (\"d:<n>\").","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"drawn_face","type":"string"}},"required":["type","face","eave_height_m"],"type":"object"},{"additionalProperties":false,"properties":{"face":{"description":"A face added with add_face (\"d:<n>\"): deleted; later ones move down by one.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"delete_face","type":"string"}},"required":["type","face"],"type":"object"},{"additionalProperties":false,"properties":{"id":{"description":"An obstacle id from \"obstacles\" or \"your_obstacles\" (a chimney, a skylight dome, a vent …): the aerial photo is searched for more of the same on this roof (as „Ähnliche finden“), and what it finds is added as your obstacles. One AI call each; at most 3 a call.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"find_similar","type":"string"}},"required":["type","id"],"type":"object"},{"additionalProperties":false,"description":"The AI outline check (as „Umriss passt nicht?“): the roof's edges are compared with the aerial photo and moved where they clearly lie elsewhere. One AI call; use it when a note says the photo shows more roof.","properties":{"type":{"const":"check_outline","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"Ask the aerial photo again for chimneys and roof windows when \"obstacles_checked\" was false (as „Nochmal suchen“).","properties":{"type":{"const":"search_again","type":"string"}},"required":["type"],"type":"object"},{"additionalProperties":false,"properties":{"degrees":{"description":"Turn the module racks from the roof's own edges by this much (0: along the edges again; positive: clockwise).","maximum":45,"minimum":-45,"type":"number"},"face":{"description":"A flat face.","maxLength":80,"minLength":1,"type":"string"},"type":{"const":"turn_racks","type":"string"}},"required":["type","face","degrees"],"type":"object"},{"additionalProperties":false,"properties":{"battery_kwh":{"description":"Battery size, kWh: one of 0, 5, 8, 10, 15 (default 8).","type":"number"},"consumption_kwh":{"description":"The household's electricity use a year, kWh, without car or heat pump (default 4,500).","maximum":30000,"minimum":1000,"type":"number"},"ev":{"description":"An electric car is (or will be) charged at home: about 2,700 kWh a year more.","type":"boolean"},"heat_pump":{"description":"A heat pump heats the house: about 4,500 kWh a year more.","type":"boolean"},"offer_eur":{"description":"The total price on an offer the person already has, euros before any subsidy (0 clears it): the Dachcheck link then shows the payback. Never a price of Sky Solar's.","maximum":300000,"minimum":0,"type":"number"},"type":{"const":"household","type":"string"}},"required":["type"],"type":"object"}]},"maxItems":20,"type":"array"},"link":{"description":"A Dachcheck link (https://pv.skysolar.de/dachcheck/#d=…), as plan_roof, edit_roof or the Dachcheck page gave it.","maxLength":12000,"minLength":10,"type":"string"}},"required":["link"],"type":"object"}⟨47 unchanged words⟩ with tilt and direction, the obstacles found, money a year at public rates (own use and feed-in) for every battery size, the municipal subsidy and, with an offer price, the payback, kWh month by month and per face, the worst shade casters, questions about unsure spots for the person and what else to ask them, notes on likely model errors, and a ⟨65 unchanged words⟩
⟨183 unchanged words⟩ 12000,"minLength":10,"type":"string"},"offer_eur":{"description":"The total price on an offer the person already has, euros before any subsidy (0 clears it): the Dachcheck link then shows the payback. Never a price of Sky Solar's.","maximum":300000,"minimum":0,"type":"number"}},"type":"object"}
Roof plan as a DXF drawing (Dachcheck) — The plan behind a Dachcheck link as a DXF drawing (R12, metres) for CAD or a mounting planner: the roof from above, and below it each face unfolded at its true size, with modules, obstacles and dormers on their own layers. Comes back inside this answer as an embedded resource (application/dxf, base64); save it as a file. Nothing is stored.
Roof plan as a PDF (Dachcheck) — The plan behind a Dachcheck link as the one-page PDF report the Dachcheck page prints, in German, for the person to keep or print: the 3D picture, key figures, the roof from above with its modules, the faces, kWh month by month, self-use with and without battery, the worst shade casters, and a QR code that opens the plan. The PDF comes back inside this answer as an embedded resource (application/pdf, base64); save it as a file. Nothing is stored on the server and no download link is made. An example, not a quote; no prices.