| """Convert the solar system electrical plan HTML to a Word document.""" |
| from docx import Document |
| from docx.shared import Pt, Inches, Cm, RGBColor |
| from docx.enum.text import WD_ALIGN_PARAGRAPH |
| from docx.enum.table import WD_TABLE_ALIGNMENT |
| from docx.oxml.ns import qn |
| from docx.oxml import OxmlElement |
| import os |
|
|
| doc = Document() |
|
|
| |
| def set_rtl(paragraph): |
| """Set paragraph to RTL.""" |
| pPr = paragraph._p.get_or_add_pPr() |
| bidi = OxmlElement('w:bidi') |
| bidi.set(qn('w:val'), '1') |
| pPr.append(bidi) |
| paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT |
|
|
| def set_cell_rtl(cell): |
| for p in cell.paragraphs: |
| set_rtl(p) |
|
|
| def add_heading_rtl(text, level=1): |
| h = doc.add_heading(text, level=level) |
| set_rtl(h) |
| return h |
|
|
| def add_para_rtl(text, bold=False, size=None, color=None): |
| p = doc.add_paragraph() |
| set_rtl(p) |
| run = p.add_run(text) |
| if bold: |
| run.bold = True |
| if size: |
| run.font.size = Pt(size) |
| if color: |
| run.font.color.rgb = color |
| return p |
|
|
| def add_table_rtl(rows, cols, header_row=None): |
| table = doc.add_table(rows=rows, cols=cols, style='Table Grid') |
| table.alignment = WD_TABLE_ALIGNMENT.CENTER |
| for row in table.rows: |
| for cell in row.cells: |
| set_cell_rtl(cell) |
| return table |
|
|
| def shade_cells(row, color_hex): |
| """Shade all cells in a row.""" |
| for cell in row.cells: |
| shading = OxmlElement('w:shd') |
| shading.set(qn('w:fill'), color_hex) |
| shading.set(qn('w:val'), 'clear') |
| cell._tc.get_or_add_tcPr().append(shading) |
|
|
| def bold_cell(cell, text): |
| cell.text = '' |
| p = cell.paragraphs[0] |
| set_rtl(p) |
| run = p.add_run(text) |
| run.bold = True |
|
|
| |
| style = doc.styles['Normal'] |
| font = style.font |
| font.name = 'Arial' |
| font.size = Pt(11) |
|
|
| |
| add_heading_rtl('ืชืื ืืช ืืฉืืืืช โ ืืขืจืืช ืกืืืืจืืช ืืืืจืืืืช', level=0) |
| add_para_rtl('ืืืืช ืืืืจ โ ืืื ืกืคืจื', bold=True, size=16) |
| add_para_rtl('ืืจืฅ 2026 | ืืืืจ: Solis S6-EH3P20K-H | ืกืืืื: CNTE 18.8kWh HV | ืคืื ืืื: 18x620W = 11.16kWp | ืืฆืขื: ืขืืฆื (ืื ืืื) #4027', size=10, color=RGBColor(0x55, 0x55, 0x55)) |
|
|
| |
| add_heading_rtl('ืืืืจืืช ืงืจืืืืืช โ ืืืื ืืืคื ืืคื ื ืืืฆืืข', level=1) |
| warnings = [ |
| 'ืืคืกืง C40 ืงืื ืืื ืืฆื ืืจืฉืช: ืืกืืืืก 20K ืืืฉื ืขื 45.6A ืืืจืฉืช. ืืคืกืง C40 (40A) ืืงืคืืฅ ืืขืืืก ืืื. ื ืืจืฉ ืืคืืืช C50 ืืฆื ืืจืฉืช (Grid side).', |
| 'ืืืจืจ ืืฆืืื Hager 40A: ืื ืืืืจืจ ืฆืจืื ืืืชืืื ืืืจื ืืืงืกืืืื โ 40A ืขืืื ืืืืืช ืฆืจ ืืื. ืืฉ ืืฉืงืื 63A.', |
| 'DC Isolators ืืืื: ืื ืชืงื DC ืืืขืืืืื (ืื MCB ืฉื AC). ืืฆื PV: ืืืืจื 1000Vdc/32A. ืืฆื ืกืืืื: ืืืืจื 800Vdc/63A.', |
| 'ืืขืจื PV ืงืื ืืืืก ืืืืืจ: 11.16kWp ืื ืจืง 35% ืืืืืืืฅ ื-20K (32kWp). ืืืืืจ ืืขืืื, ืืื ืื ืื ืฆื ืืช ืืืื ืืคืืื ืฆืืื ืฉืื.', |
| 'ืืืฆืขื ืื ืืืืืช ืืชืงื ืช ืคืื ืืื ืขื ืืื โ ืืืืจืืืช ืืืงืื. ื ืืจืฉ ืงืื ืกืืจืืงืฆืื ืืืืกืืก.', |
| ] |
| for w in warnings: |
| add_para_rtl(f'โ {w}') |
|
|
| |
| add_heading_rtl('1. ืกืงืืจืช ืืืขืจืืช', level=1) |
| add_para_rtl('ืืขืจืืช ืกืืืืจืืช ืืืืจืืืืช ืชืืช-ืคืืืืช ืขื ืืืืื ืกืืืื, ืืืืคืฉืจืช ืฆืจืืื ืขืฆืืืช, ืืืืจืช ืื ืจืืื ืืืขืืจ ืืืืืืื ืืืฆื ืืืืื (UPS) ืชืื ืคืืืช ื-10ms ืืขืช ืืคืกืงืช ืืฉืื.') |
|
|
| |
| add_heading_rtl('ืืืืจ ืืืืจืืื โ Solis S6-EH3P20K-H', level=2) |
| add_para_rtl( |
| 'ืืกืคืง: 20kW ืชืืช-ืคืืื\n' |
| 'ืืชื ืืฆืืจ: 120โ800V (High Voltage)\n' |
| 'MPPT: 4 ืื ืืกืืช, 200โ850V, ืขื 20A ืืื ืืกื\n' |
| 'PV ืืืืืฅ: ืขื 32kWp\n' |
| 'ืืขืืืืช: 98.5% ืืงืกืืืื, 97.5% EU\n' |
| 'Backup: 20kW, 200% surge ื-10 ืฉื ืืืช\n' |
| 'ืืื ืช ืื ืืกื: IP66\n' |
| 'ืืืจืืืช: 10 ืฉื ืื (RCS Solar ืืข"ื)\n' |
| 'ืืืืจ: โช9,360 (ืืคื ื ืืข"ื)' |
| ) |
|
|
| |
| add_heading_rtl('ืืขืจืืช ืืืืจื โ CNTE 18.8kWh HV', level=2) |
| add_para_rtl( |
| 'ืงืืืืืช: 18.8kWh\n' |
| 'ืกืื: LiFePO4 โ High Voltage\n' |
| 'ืืชื ื ืืืื ืื: ืืืื 120โ800V\n' |
| 'ืืจื ืืขืื ื/ืคืจืืงื ืืงืกืืืื: 50A\n' |
| 'ืืื ืช ืื ืืกื: IP66 โ ืืชืืื ืืืืฅ\n' |
| 'ืชืงืฉืืจืช: CAN / RS485 ืื ืืืืืจ\n' |
| 'ืืืจืืืช: 10 ืฉื ืื\n' |
| 'ืืืืจ: โช15,080 (ืืคื ื ืืข"ื)' |
| ) |
|
|
| |
| add_heading_rtl('ืคืื ืืื ืกืืืืจืืื โ 18 x 620W', level=2) |
| add_para_rtl( |
| 'ืืกืคืง ืืืื: 11,160Wp (11.16kWp)\n' |
| 'ืืืืงื: 2 ืกืืจืื ืืื x 9 ืคืื ืืื\n' |
| 'Voc ืืกืืจืื ื: ~396V (ืืืืื MPPT)\n' |
| 'Isc ืืกืืจืื ื: ~18A (ืืชืืช ื-20A ืืงืกืืืื)\n' |
| 'ืืืืืจ: MC4\n' |
| 'ืืืืจ ืืืืืื: โช345\n' |
| 'ืืืืจ ืืืื: โช6,210 (ืืคื ื ืืข"ื)' |
| ) |
|
|
| |
| add_heading_rtl('2. ืชืจืฉืื ืื-ืงืืื (Single Line Diagram)', level=1) |
| add_para_rtl('ืืื ื ืืืขืจืืช ืืืคืื ืืื ืืขื ืืืื ืืืฉืืื:') |
| add_para_rtl('[ืืชืจืฉืื ืืืจืคื SVG ืื ื ืืชื ืืืืจื ื-Word โ ืจืื ืงืืืฅ HTML ืืืงืืจื ืืชืจืฉืื ืืืื]', size=10, color=RGBColor(0x99, 0x99, 0x99)) |
| add_para_rtl( |
| 'String 1: 9x620W = 5,580Wp (Vocโ396V, Iscโ18A, MPPT1)\n' |
| 'String 2: 9x620W = 5,580Wp (Vocโ396V, Iscโ18A, MPPT2)\n' |
| 'โ DC Isolator 1000Vdc/32A (x2)\n' |
| 'โ DC PV Input\n' |
| 'โ Solis S6-EH3P20K-H (Hybrid Inverter, 20kW, 3ฯ, IP66)\n' |
| ' โ DC HV โ DC Isolator 800Vdc/63A โ CNTE 18.8kWh Battery (CAN/BMS)\n' |
| ' โ Backup AC (UPS <10ms) โ ABB C40 3P โ ืขืืืกืื ืืืื ืืื\n' |
| 'โ AC Grid Out\n' |
| 'โ CT Sensor โ SPD Type 2 (3P+N, 40kA) โ MCB ABB C50 4P\n' |
| 'โ Hager 4P 40A (ืืืจืจ ืืฆืืื)\n' |
| ' โโ MCB ABB C50 4P (Grid) โ ืืื ื ืืืฉืื โ ืจืฉืช ืืฉืื โ ืืืจืงื\n' |
| ' โโ MCB ABB C40 4P (Load) โ ืืื ืืฉืืื (ืขืืืกื ืืืืช)' |
| ) |
|
|
| |
| add_heading_rtl('3. ืจืฉืืืช ืจืืืืื ืืคืืจืืช', level=1) |
|
|
| components = [ |
| ('1', 'ืคืื ืืื ืกืืืืจืืื', '620W โ ืืง"ื s620', '18', 'ืื', '2 ืกืืจืื ืืื x 9'), |
| ('2', 'DC Isolator โ PV', '1000Vdc / 32A, 2-pole', '2', 'ืืื ืืคืื ืืื / ืื ืืกืช ืืืืจ', 'ืืื ืืื ืกืืจืื ื'), |
| ('3', 'ืืืืจ ืืืืจืืื', 'Solis S6-EH3P20K-H', '1', 'ืงืืจ ืืืฆืื ื ืืืฆื', 'IP66 โ ืืืื ืืืฉื. ืืืื ืืฉืืฉ ืืฉืืจื'), |
| ('4', 'DC Isolator โ ืกืืืื', '800Vdc / 63A, 2-pole', '1', 'ืืื ืืืืจ ืืกืืืื', 'ืืืืจื DC!'), |
| ('5', 'ืกืืืื', 'CNTE 18.8kWh HV (cnte18.8)', '1', 'ืืื ืืืืืจ, ืงืืจ ืืืฆื', 'IP66 โ ืืืฆืื ื. ืชืงืฉืืจืช CAN'), |
| ('6', 'ืืืืฉื ืืจื CT', 'Split-core CT, 3-ืคืืื', '1', 'ืืืฆืืืช AC ืฉื ืืืืืจ', 'ืื ืืืืจ ื-zero export'), |
| ('7', 'ืืื ืืจืงืื SPD', 'Type 2, 3P+N, 40kA', '1', 'ืืืจื CT, ืืคื ื ืืคืกืง ืจืืฉื', 'ืืื ื ืขื ืงื ืืฆืืืช ืืืืจ'), |
| ('8', 'ืืคืกืง ืืฆืืืช ืืืืจ', 'ABB C50 4-Pole โ ', '1', 'ืืืจื SPD', 'ืืงืืจื ืืืฆืขื C40 โ ืื ืืกืคืืง!'), |
| ('9', 'ืืืจืจ ืืฆืืื', 'Hager 4P 40A', '1', 'ืืคื ื ืืืชืคืฆืืืช', 'Grid / Solar / Off'), |
| ('10', 'ืืคืกืง ืจืฉืช', 'ABB C50 4-Pole โ ', '1', 'ืขื ืฃ ืจืฉืช', 'ืฆืจืื C50 ืืืจื 45.6A'), |
| ('11', 'ืืคืกืง ืขืืืกืื', 'ABB C40 4-Pole', '1', 'ืขื ืฃ ืขืืืกื ืืืืช', 'C40 ืืกืคืืง ืืื'), |
| ('12', 'ืืคืกืง ืืืืื', 'ABB C40 3-Pole', '1', 'ืืฆืืืช Backup ืฉื ืืืืจ', '3P โ ืขืืืกืื ืืืื ืืื ืืืื'), |
| ('13', 'ืืื ื ืืืฉืื', 'ืืื ื ืื-ืืืืื ื (ืืกืืคืง ืข"ื ืืืืฉืื)', '1', 'ืืคื ื ืืจืฉืช', 'โ'), |
| ] |
|
|
| table = add_table_rtl(len(components) + 1, 6) |
| headers = ['#', 'ืจืืื', 'ืืื / ืืคืจื', 'ืืืืช', 'ืืืงืื ืืชืจืฉืื', 'ืืขืจืืช'] |
| for i, h in enumerate(headers): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
|
|
| for row_idx, comp in enumerate(components): |
| for col_idx, val in enumerate(comp): |
| table.rows[row_idx + 1].cells[col_idx].text = val |
| set_cell_rtl(table.rows[row_idx + 1].cells[col_idx]) |
|
|
| |
| add_heading_rtl('4. ืืคืจื ืืืืื', level=1) |
|
|
| cables = [ |
| ('PV String โ DC Isolator', 'ืืื ืกืืืืจื H1Z2Z2-K', '6mmยฒ (ืื 4mmยฒ)', 'ืืคื ืืืงืื ืื', 'UV-resistant, DC rated, MC4'), |
| ('DC Isolator โ Inverter (PV)', 'ืืื ืกืืืืจื H1Z2Z2-K', '6mmยฒ', '~5m', '+ / โ ืืื ืกืืจืื ื'), |
| ('Inverter โ Battery', 'ืืื DC ืืืืฉ', '16mmยฒ', '~3m', '50A ืืงืกืืืื. ืืจื ืืืขืช ืืื ืืืช x 2 ืืืคืืคืื'), |
| ('Inverter โ CT โ SPD โ MCB', 'ืืื AC NYY-J 5G', '10mmยฒ', '~5m', '3L + N + PE, ืชืืช-ืคืืื'), |
| ('MCB โ Changeover โ Grid/Load', 'ืืื AC NYY-J 5G', '10mmยฒ', '~10m', 'ืืคื ืืจืืง ืืืื'), |
| ('Backup Output โ MCB โ Essential', 'ืืื AC NYY-J 5G', '6mmยฒ', '~8m', '3P ืืืื ืขืืืกืื ืืืื ืืื'), |
| ('ืืืจืงื', 'ืืจืืง-ืฆืืื', '16mmยฒ (ื ืืืฉืช)', 'โ', 'ืืืื โ ืืืืจ + ืกืืืื + ืืื ื'), |
| ('BMS Communication', 'ืืื CAN ืืกืืื', 'ืฉืืืจ', '~3m', 'ืืจื ืืืขืช ืืื ืืืช x 4 ืืืคืืคืื'), |
| ] |
|
|
| table = add_table_rtl(len(cables) + 1, 5) |
| cable_headers = ['ืงืืข', 'ืกืื ืืื', 'ืืชื', 'ืืืจื ืืืขืจื', 'ืืขืจืืช'] |
| for i, h in enumerate(cable_headers): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
|
|
| for row_idx, cable in enumerate(cables): |
| for col_idx, val in enumerate(cable): |
| table.rows[row_idx + 1].cells[col_idx].text = val |
| set_cell_rtl(table.rows[row_idx + 1].cells[col_idx]) |
|
|
| add_para_rtl('ืฉืื ืื: ืืื ืืกืืืื ืืชืงืฉืืจืช BMS ืืืืืื ืืขืืืจ ืืจื ืืืขืืช ืืื ืืืืช (ferrite rings) ืืคื ืฉืืืคืืข ืืืคืจื ืืกืืืืก โ 2 ืืืคืืคืื ืืืื ืืฉืื, 4 ืืืคืืคืื ืืืื ืชืงืฉืืจืช.', bold=True) |
|
|
| |
| add_heading_rtl('5. ืชืืืืจ ืืกืืื ืืืจื', level=1) |
|
|
| add_heading_rtl('ืืฆื ืืื โ ืืืฆืืจ ืกืืืืจื', level=2) |
| day_flow = [ |
| ('โ ืคืื ืืื ืกืืืืจืืื (2 x 9 = 18 ืคืื ืืื)', 'ืืืืฆืจืื ืืจื DC ืืืชื ~360V ืืื ืกืืจืื ื, ืืจื ืืืืืจื MC4'), |
| ('๐ DC Isolators (2 ืื\')', 'ืื ืชืงื ืืืืืืช DC โ ืืืคืฉืจืื ื ืืชืืง ืื ืกืืจืื ื ืื ืคืจื ืืชืืืืงื'), |
| ('INV โ Solis 20K โ ืืืจื DCโAC', '4 ืื ืืกืืช MPPT (200-850V). ืืืืจ ืืช ืืืจื ื-AC ืชืืช-ืคืืื 400V/50Hz. ืืืงืืื ืืืขื ืืช ืืกืืืื ืืขืืืคื ืืืฆืืจ'), |
| ('CT ืืืืฉื ืืจื', 'ืืืื ืืช ืืืจื ืืืฆืืื ืืฆืืจื ื ืืืืจ, ืืืืื ืคืืืืช ืืื ืืขืช ืืืจืื ืืจืฉืช (zero export ืื ื ืืจืฉ)'), |
| ('โก SPD ืืื ืืจืงืื Type 2', 'ืืื ืช ื ืืฉืืื ืืชื (surge) ืขื ืงื AC ืืืืฆื ืืืืืืจ. 3P+N, ืขื 40kA'), |
| ('๐ ืืืจืจ ืืฆืืื Hager 4P 40A', 'ืืืคืฉืจ ืืขืืจ ืืื ื ืืื: ืจืฉืช + ืกืืืืจื | ืกืืืืจื ืืืื | ื ืืชืืง ืืื'), |
| ('๐ ืืื ืืฉืืื ืืืืช', 'ืขืืืกื ืืืืช ืืงืืืื ืืฉืื ืืืกืืืืจื. ืขืืืคืื โ ืกืืืื โ ืจืฉืช (ืืคื ืืืืจื)'), |
| ] |
| for title, desc in day_flow: |
| p = doc.add_paragraph() |
| set_rtl(p) |
| run = p.add_run(f'{title}: ') |
| run.bold = True |
| p.add_run(desc) |
|
|
| add_heading_rtl('ืืฆื ืืืื / ืืคืกืงืช ืืฉืื', level=2) |
| night_flow = [ |
| ('๐ CNTE 18.8kWh', 'ืืกืืืื ืืกืคืงืช ืืจื DC HV ืืืืืจ'), |
| ('INV โ Solis 20K โ ืืืจื DCโAC', 'ืืืืจ ื-AC ืืืกืคืง ืืขืืืกืื. ืืขืืจ UPS ืืืืืืื ืชืื <10ms'), |
| ('๐ ืขืืืกืื ืืืื ืืื (Backup port)', 'ืืงืจืจ, ืชืืืจื, ืจืืืืจ โ ืืืืื ืื ืืฉืืจืืช ืืืฆืืืช ื-Backup ืืื ืืคืกืงื'), |
| ] |
| for title, desc in night_flow: |
| p = doc.add_paragraph() |
| set_rtl(p) |
| run = p.add_run(f'{title}: ') |
| run.bold = True |
| p.add_run(desc) |
|
|
| |
| add_heading_rtl('6. ืืคืจื ืืืืจ Solis S6-EH3P20K-H', level=1) |
|
|
| specs_sections = [ |
| ('ืื ืืกืช DC โ ืคืืื-ืืืืืื', [ |
| ('PV ืืืืืฅ ืืงืกืืืื', '32kWp'), |
| ('ืืชื ืืงืกืืืื', '1000V'), |
| ('ืืืื MPPT', '200โ850V'), |
| ('ืืจื ืืงืกืืืื ืืื ืืกื', '20A x 4'), |
| ('ืืกืคืจ MPPT / ืกืืจืื ืืื', '4/4'), |
| ('ืืกืคืง ืืงืกืืืื ื-MPPT', '9kW'), |
| ]), |
| ('ืื ืืกืช / ืืฆืืืช ืกืืืื', [ |
| ('ืกืื', 'Li-ion (High Voltage)'), |
| ('ืืืื ืืชื', '120โ800V'), |
| ('ืืกืคืง ืืขืื ื/ืคืจืืงื ืืงืกืืืื', '20kW'), |
| ('ืืจื ืืงืกืืืื', '50A'), |
| ('ืชืงืฉืืจืช', 'CAN / RS485'), |
| ]), |
| ('ืืฆืืืช AC โ ืจืฉืช', [ |
| ('ืืกืคืง ืืฆืืื', '20kW / 20kVA'), |
| ('ืืชื', '3/N/PE, 380V/400V'), |
| ('ืืจื ืืฆืืื ืืงืกืืืื', '30.4A / 28.9A'), |
| ('Power Factor', '>0.99'), |
| ('THDi', '<3%'), |
| ]), |
| ('ืื ืืกืช AC โ ืจืฉืช', [ |
| ('ืืกืคืง ืื ืืกื ืืงืกืืืื', '30kW'), |
| ('ืืจื ืื ืืกื', '45.6A โ '), |
| ('ืืชื', '3/N/PE, 380V/400V'), |
| ('ืชืืจ', '50Hz / 60Hz'), |
| ]), |
| ('ืืฆืืืช Backup', [ |
| ('ืืกืคืง', '20kW'), |
| ('Surge', '200% ืืืฉื 10 ืฉื ืืืช (40kW!)'), |
| ('ืืื ืืขืืจ', '<10ms'), |
| ('ืืชื', '3/N/PE, 380V/400V'), |
| ]), |
| ('ืืืื', [ |
| ('ืืขืืืืช ืืงืกืืืืืช', '98.5%'), |
| ('ืืขืืืืช EU', '97.5%'), |
| ('ืืื ืช ืื ืืกื', 'IP66'), |
| ('ืืืคืจืืืจืช ืขืืืื', '-25ยฐC ืขื +60ยฐC'), |
| ('ืืืืืช', '563x546x235 ื"ื'), |
| ('ืงืืจืืจ', 'ืืืืืจืจ ืืื ืืืืื ืื ืืคืื'), |
| ]), |
| ] |
|
|
| for section_title, specs in specs_sections: |
| add_heading_rtl(section_title, level=2) |
| table = add_table_rtl(len(specs), 2) |
| for row_idx, (key, val) in enumerate(specs): |
| bold_cell(table.rows[row_idx].cells[0], key) |
| table.rows[row_idx].cells[1].text = val |
| set_cell_rtl(table.rows[row_idx].cells[1]) |
|
|
| |
| add_heading_rtl('7. ืคืืจืื ืขืืืืืช โ ืืฆืขืช ืขืืฆื (ืื ืืื) #4027', level=1) |
|
|
| pricing = [ |
| ('ืืืืจ Solis 20kW', 'solis20k', '1', 'โช9,360', 'โช9,360'), |
| ('ืงืื ืืืจืืืช CNTE 18.8kWh', 'cnte18.8', '1', 'โช15,080', 'โช15,080'), |
| ('ืืื ืกืืืืจื 620W', 's620', '18', 'โช345', 'โช6,210'), |
| ('ืืชืงื ื ืืืืืจ ืืืฆืืจืื', 'โ', '1', 'โช5,800', 'โช5,800'), |
| ] |
|
|
| table = add_table_rtl(len(pricing) + 4, 5) |
| price_headers = ['ืคืจืื', 'ืืง"ื', 'ืืืืช', 'ืืืืจ ืืืืื', 'ืกื"ื'] |
| for i, h in enumerate(price_headers): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
|
|
| for row_idx, item in enumerate(pricing): |
| for col_idx, val in enumerate(item): |
| table.rows[row_idx + 1].cells[col_idx].text = val |
| set_cell_rtl(table.rows[row_idx + 1].cells[col_idx]) |
|
|
| |
| subtotal_row = len(pricing) + 1 |
| bold_cell(table.rows[subtotal_row].cells[0], 'ืกื"ื ืืคื ื ืืข"ื') |
| table.rows[subtotal_row].cells[0].merge(table.rows[subtotal_row].cells[3]) |
| bold_cell(table.rows[subtotal_row].cells[4], 'โช36,450') |
| shade_cells(table.rows[subtotal_row], 'F0F4FF') |
|
|
| |
| vat_row = subtotal_row + 1 |
| table.rows[vat_row].cells[0].text = 'ืืข"ื 18%' |
| set_cell_rtl(table.rows[vat_row].cells[0]) |
| table.rows[vat_row].cells[0].merge(table.rows[vat_row].cells[3]) |
| table.rows[vat_row].cells[4].text = 'โช6,561' |
| set_cell_rtl(table.rows[vat_row].cells[4]) |
|
|
| |
| total_row = vat_row + 1 |
| bold_cell(table.rows[total_row].cells[0], 'ืกื"ื ืืืื ืืข"ื') |
| table.rows[total_row].cells[0].merge(table.rows[total_row].cells[3]) |
| bold_cell(table.rows[total_row].cells[4], 'โช43,011') |
| shade_cells(table.rows[total_row], '0C2340') |
| for cell in [table.rows[total_row].cells[0], table.rows[total_row].cells[4]]: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| run.font.size = Pt(14) |
|
|
| add_para_rtl('ืื ืืืื ืืืฆืขื: ืืชืงื ื ืคืืืืช ืฉื ืืคืื ืืื ืขื ืืื (ืงืื ืกืืจืืงืฆืื, ืืืืืืช, ืืืกืืก) โ ืืืืจืืืช ืืืงืื ืื ืงืืื ื ืืกืฃ.', bold=True, color=RGBColor(0xC6, 0x28, 0x28)) |
|
|
| |
| add_heading_rtl('8. ืื ืืืืช ืืชืงื ื', level=1) |
|
|
| add_heading_rtl('ืืืงืื ืืืืจ ืืกืืืื', level=2) |
| add_para_rtl('ืฉื ื ืืจืืืืื (Solis + CNTE) ืืขืื ืืืจืื IP66 ืืืชืืืืื ืืืชืงื ื ืืืฆืื ืืช. ืืฉ ืืืงื ืืืชื:') |
| for item in [ |
| 'ืขื ืงืืจ ืืืฆื โ ืืืืจืืืช ืืืงืื ืืืื ืืคื ื ืฉืืฉ ืืฉืืจื (ืืคื ืฉืืฆืืื ืืืฆืขื)', |
| 'ืืืื ืืื ืืืื 60 ืก"ื ืืืงืจืงืข (ืืฆืคื, ืืืืงืื)', |
| 'ืืจืืื ืืืืจืืจ: ืืคืืืช 30 ืก"ื ืืื ืฆื, 50 ืก"ื ืืืืขืื', |
| 'ื ืืืฉ ืืชืืืืงื โ DC Isolators ืืืืฉื ืื', |
| ]: |
| add_para_rtl(f'โข {item}') |
|
|
| add_heading_rtl('ืืืจืงื', level=2) |
| add_para_rtl('ืืืื ืืืฆืข ืืืจืงื ืชืงื ืืช ืืื ืืจืืืืื: ืืืฃ ืืืืืจ, ืืืฃ ืืกืืืื, ืืื ื ืืงืื ืกืืจืืงืฆืื ืฉื ืืคืื ืืื, ืืืกืืจืืช ืืคืื ืืื ืขืฆืื. ืืชื ืืื ืืืื: 16mmยฒ ื ืืืฉืช.') |
|
|
| add_heading_rtl('ืืืืืจ ืกืืืื', level=2) |
| add_para_rtl('ืืื DC ืืกืืืื ืืืื ืืขืืืจ ืืจื ืืืขืช ืืื ืืืช (ferrite ring) ืขื 2 ืืืคืืคืื. ืืื ืชืงืฉืืจืช CAN/BMS โ ืืจื ืืืขืช ืืื ืืืช ืขื 4 ืืืคืืคืื. ืืืื ื ืืืืืง ืืืืืจ: 24.5 Nยทm.') |
|
|
| add_heading_rtl('ืืืจืืืช ืืฉืืจืืช', level=2) |
| add_para_rtl('ืืคื ืืฆืขืช ืขืืฆื (ืื ืืื):') |
| for item in [ |
| 'Solis โ ืฉืืจืืช ืืืืจืืืช: ืืจ ืกื ืืก ืกืืืืจ ืืข"ื (RCS Solar)', |
| 'CNTE / Yoshopo โ ืฉืืจืืช ืืืืจืืืช: ืืจ ืกื ืืก ืกืืืืจ ืืข"ื', |
| 'ืืืจืืืช: 10 ืฉื ืื ืขื ืืืืจ ืืกืืืื', |
| ]: |
| add_para_rtl(f'โข {item}') |
|
|
| |
| add_heading_rtl('9. ืืงืจืช ืืืืืช โ ืืืฆืืื ืืชืืงืื ืื', level=1) |
| add_para_rtl('ืกืงืืจื ืืงืฆืืขืืช ืฉื ืืชืื ืืช ืืืืชื ืืช ืื ืงืืืืช ืืืืืช. ืืฉ ืืืคื ืืืืื ืืคื ื ืชืืืืช ืืืฆืืข:') |
|
|
| |
| add_heading_rtl('ืืืฆืืื ืงืจืืืืื (ืืืื ืืชืงื)', level=2) |
|
|
| critical = [ |
| ('Q1', 'ืืืจืื ืืคืกืงื AC', 'Solis 20K โ ืืจื ืื ืืกื ืืจืฉืช ืขื 45.6A. ืืคืกืง C40 (40A) ืืงืคืืฅ ืืขืืืก ืืื. ืืื ื ืื ืชืงืื ื', 'ืืืืืืฃ ื-C50 (50A) ืืฆื ืืฆืืืช ืืืืจ ืืืฆื ืืจืฉืช. ืืคืกืง ืขืืืกืื (C40) โ ืชืงืื'), |
| ('Q2', 'ืืืจืจ ืืฆืืื โ ืืืจืื ืืจื', 'Hager 40A ืขืืื ืืืืืช ืงืื ืืื. ืืจื ืืงืกืืืื ืขืืืจ ืืจืื (ืขื 45.6A ืืจืฉืช + ืืืฆืืจ ืกืืืืจื)', 'ืืฉืงืื ืฉืืจืื ื-Hager 63A 4P, ืื ืืืืื ืฉืชืจืืืฉ ืืขืืืก ืืืงืกืืืื ืื ืืืจื ื-40A'), |
| ('Q3', 'ืืื ืช ืคืืช (RCD/RCBO) ืืกืจื', 'ืืชืื ืืช ืื ืืืืืช ืืื ืช ืคืืช โ ืืืืืช ืืจื ืืืืฃ ืืื ืื ืชืืจืื ืื ืืชืืง', 'ืืืืกืืฃ RCD Type A ืืืืจืื 30mA ืืฆื AC, ืืคื ื ืืื ืืขืืืกืื. ืืืง ืืืืืืจืื Transformerless ืืืจืฉืื RCD Type B โ ืืืืื ืืื ืืคืจื ืืกืืืืก'), |
| ('Q4', 'ืืคืกืง Backup โ ืืกืคืจ ืงืืืื', 'ืืคืกืง 3P (3 ืงืืืื) ืื ืืื ืขื Neutral. ืืฆืืืช Backup ืฉื ืืกืืืืก ืืื 3/N/PE', 'ืืืืืืฃ ื-ABB C40 4P (4 ืงืืืื) ืื ืืขื ืฃ ื-Backup'), |
| ] |
|
|
| table = add_table_rtl(len(critical) + 1, 4) |
| for i, h in enumerate(['#', 'ืืืฆื', 'ืืขืื', 'ืชืืงืื ื ืืจืฉ']): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| for row_idx, item in enumerate(critical): |
| for col_idx, val in enumerate(item): |
| table.rows[row_idx + 1].cells[col_idx].text = val |
| set_cell_rtl(table.rows[row_idx + 1].cells[col_idx]) |
| shade_cells(table.rows[row_idx + 1], 'FFF8E1') |
|
|
| |
| add_heading_rtl('ืืืฆืืื ืืฉืืืื (ืืืืืฅ ืืชืงื)', level=2) |
|
|
| important = [ |
| ('Q5', 'AFCI โ ืืื ืช ืงืฉืช ืืฉืืืืช', 'ืืกืืืืก ืืืื AFCI ืืืื ื ืืฆื DC, ืื ืืืจืฉ ืืคืขืื ืืื ืืช (activation required)', 'ืืืืื ืฉืืืฉืืืื ืืคืขืื ืืช AFCI ืืืืืจืืช ืืืืืจ ืืขืช ืืืชืงื ื'), |
| ('Q6', 'SPD ืืฆื DC ืืกืจ', 'ืืชืื ืืช ืืืืืช SPD ืืฆื AC ืืืื. ืคืื ืืื ืขื ืืื ืืฉืืคืื ืืคืืืขืช ืืจืง ืืฉืืจื ืืฆื DC', 'ืืืืกืืฃ SPD Type 2 DC ืืืืจื 1000Vdc ืืื ืืคืื ืืื ื-DC Isolator, ืื ืืื ืื ืืกืช PV ืืืืืจ'), |
| ('Q7', 'ืืชื ืืื AC โ ืืจืืื ืฆืจ', 'ืืื NYY-J 5G10 ืืืืจื ื-~57A ืืืืืืจ. ืขืืืจ 45.6A ืืื ื ืืฆืื ืฉื 80% โ ืชืงืื, ืื ืืื ืืจืืื ืืขืืืืช ืืืคืจืืืจื', 'ืื ืืกืืื ืืืื ืื (ืฆืื ืืจ ืืฉืืฉ, ืจืืืื ืืืืื) โ ืืฉืงืื ืฉืืจืื ื-5G16. ืืืจืช, 5G10 ืืกืคืืง'), |
| ('Q8', 'ืืืขืืช ืืื ืืืืช (Ferrite) ืืกืจืืช ืืจืฉืืืช ืจืืืืื', 'ืืืืืจืืช ืืื ืืืืช ืืืืื ืื ืื ืืจืฉืืืช ืืจืืืืื โ ืขืืืืืช ืืืืฉืื ืืจืืฉ', 'ืืืืกืืฃ ืืจืฉืืื: 2 ืืืขืืช ืืื ืืืืช โ ืืืช ืืืื DC ืกืืืื, ืืืช ืืืื BMS'), |
| ('Q9', 'ืืกืจ: ืืืืจืช ืืฆื ืขืืืื โ net metering / zero export', 'ืืชืื ืืช ืื ืืฆืืื ืช ืื ืืืขืจืืช ืขืืืืช ืืืฆื net metering (ืืืจืื ืืจืฉืช) ืื zero export. ืื ืืฉืคืืข ืขื ืชืฆืืจืช CT', 'ืืืืืืจ ืืื ืืืืฉืื: ืืื ืืืชืจ ืืืืืจ ืืฉืื ืืจืฉืช? ืื ืื โ ืืืืืืจ CT ืืืฆื zero export ืืืืืจ'), |
| ] |
|
|
| table = add_table_rtl(len(important) + 1, 4) |
| for i, h in enumerate(['#', 'ืืืฆื', 'ืืขืื', 'ืชืืงืื ื ืืจืฉ']): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| for row_idx, item in enumerate(important): |
| for col_idx, val in enumerate(item): |
| table.rows[row_idx + 1].cells[col_idx].text = val |
| set_cell_rtl(table.rows[row_idx + 1].cells[col_idx]) |
|
|
| |
| add_heading_rtl('ืชืงืื โ ืืืืช', level=2) |
|
|
| verified = [ |
| ('Voc ืกืืจืื ื', '9 x ~44V = 396V < 1000V (ืืงืกืืืื), ืืชืื 200โ850V (MPPT)', 'ืชืงืื โ'), |
| ('Isc ืกืืจืื ื', '~18A < 20A (ืืงืกืืืื ืืื ืืกืช MPPT), < 30A (ืงืฆืจ)', 'ืชืงืื โ'), |
| ('ืืชืืืช ืกืืืื', 'CNTE HV โ ืืืื 120โ800V ืชืืื ืืกืืืืก (120โ800V)', 'ืชืงืื โ'), |
| ('ืืจื ืกืืืื', '50A ืืงืกืืืื โ ืชืืื ืืกืืืืก (50A max charge/discharge)', 'ืชืงืื โ'), |
| ('IP Rating', 'ืืืืจ IP66 + ืกืืืื IP66 โ ืืชืืื ืืืชืงื ื ืืืฆืื ืืช ืืืืืช ืืืืจ', 'ืชืงืื โ'), |
| ('ืชืงืฉืืจืช BMS', 'CAN/RS485 โ ืชืืื ืืื CNTE ืืกืืืืก', 'ืชืงืื โ'), |
| ('ืืคืกืง ืขืืืกืื', 'C40 ืืขื ืฃ ืขืืืกื ืืืืช โ ืชืงืื (ืืจื ืืฆืืืช ืืืืจ 30.4A)', 'ืชืงืื โ'), |
| ('DC Switch ืืืื ื', 'ืืกืืืืก ืืืื DC Switch ืืืื ื (integrated) โ ืชืืื ืืชืงื', 'ืชืงืื โ'), |
| ('ืืืื ื ืืืืืง ืกืืืื', '24.5 Nยทm โ ืชืืื ืืคืจื (M8)', 'ืชืงืื โ'), |
| ('ืืืฉืื ืขืืืืืช', 'โช36,450 + 18% = โช43,011', 'ืชืงืื โ'), |
| ] |
|
|
| table = add_table_rtl(len(verified) + 1, 3) |
| for i, h in enumerate(['ืคืจืื', 'ืืืืงื', 'ืชืืฆืื']): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| for row_idx, item in enumerate(verified): |
| for col_idx, val in enumerate(item): |
| table.rows[row_idx + 1].cells[col_idx].text = val |
| set_cell_rtl(table.rows[row_idx + 1].cells[col_idx]) |
|
|
| |
| add_heading_rtl('10. ืื ืืืืช ืืืฆืืข โ ืฉืื ืืืจ ืฉืื', level=1) |
| add_para_rtl('ืืื ืืจืื: ืื ืืขืืืื ืืืฉืืืืช ืืืืืช ืืืชืืฆืข ืขื ืืื ืืฉืืืื ืืืกืื ืืขื ืจืืฉืืื ืืชืืงืฃ. ืขืืืื ืขื ืืชื DC ืืืื (ืขื 800V) ืืกืืื ืช โ ืื ืืืขืช ืืื ืฆืืื ืืื ืืชืืื.', bold=True, color=RGBColor(0xC6, 0x28, 0x28)) |
|
|
| |
| def add_checklist_table(title, items): |
| add_heading_rtl(title, level=2) |
| table = add_table_rtl(len(items) + 1, 3) |
| for i, h in enumerate(['โ', 'ืืฉืืื', 'ืคืืจืื']): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| for row_idx, (task, detail) in enumerate(items): |
| table.rows[row_idx + 1].cells[0].text = 'โ' |
| set_cell_rtl(table.rows[row_idx + 1].cells[0]) |
| bold_cell(table.rows[row_idx + 1].cells[1], task) |
| table.rows[row_idx + 1].cells[2].text = detail |
| set_cell_rtl(table.rows[row_idx + 1].cells[2]) |
|
|
| add_checklist_table('ืฉืื ื\' โ ืืื ื ืืจืืฉ (ืืคื ื ืชืืืืช ืขืืืื)', [ |
| ('ืืืฉืืจ ืชืื ืืช ืืื ืืฉืืืื', 'ืืืขืืืจ ืชืื ืืช ืื ืืืฉืืืื ืืืกืื ืืืืฉืืจ. ืืืืื ืืชืืื ืืชืงื ืืช ืืฉืื ืืฉืจืืืืืช ืืืืจืืฉืืช ืืืืฉืื'), |
| ('ืืืจืืจ ืืื ืืืืฉืื', 'ืืื ืืืชืจ net metering (ืืืืจืช ืืฉืื)? ืืื ืืจืืฉืืช ืืืืืืจ? ืืื ื ืืจืฉ ืืืฉืืจ ืืขืืช ืชืื ืื?'), |
| ('ืจืืฉ ืจืืืืื ืืกืจืื', 'ืืคืกืงื ABB C50 4P (x2), ABB C40 4P (x2 โ ืขืืืกืื + backup), SPD AC Type 2, SPD DC Type 2, DC Isolators (x3), RCD Type A 30mA, ืืืขืืช ืืื ืืืืช (x2), ืืืจืจ ืืฆืืื Hager 63A 4P'), |
| ('ืจืืฉ ืืืืื', 'ืืื ืกืืืืจื H1Z2Z2-K 6mmยฒ (ืืคื ืืืืืช ืืืจื), NYY-J 5G10 (ืื 5G16), ืืื DC 16mmยฒ ืืกืืืื, ืืื CAN ืืกืืื, ืืื ืืืจืงื 16mmยฒ ืืจืืง-ืฆืืื'), |
| ('ืืื ืช ืชืฉืชืืช ืื', 'ืงืื ืกืืจืืงืฆืื, ืืืกืืก, ืืืืืืช โ ืืชืืืื ืขื ืงืืื ืฉืื (ืื ืืืื ืืืฆืขืช ืื ืืื)'), |
| ('ืกืืืื ืืืงืื ืืืืจ ืืกืืืื', 'ืงืืจ ืืืฆืื ื ืืืฆื, ืืืื 60+ ืก"ื, ืืจืืื ืืืืจืืจ 30 ืก"ื ืืฆืืืื, 50 ืก"ื ืืืืขืื. ื ืืืฉ ืืชืืืืงื'), |
| ]) |
|
|
| add_checklist_table('ืฉืื ื\' โ ืืชืงื ื ืืื ืืช', [ |
| ('ืืชืงื ืช ืงืื ืกืืจืืงืฆืื ืขื ืืื', 'ืืืกืืก ืืกืืืืช ืืคื ืชืื ืืช ืื. ืืืืื ืืฆืืืืช ืจืืืืช, ืฉืืคืืข ื ืืงืื, ืืืืืืช ืืืืจืืช ืื'), |
| ('ืืจืืืช ืคืื ืืื', '18 ืคืื ืืื x 620W. ืืืืงื: ืกืืจืื ื 1 (9 ืื\') ืืกืืจืื ื 2 (9 ืื\'). ืืืืืจ ืืืจื ืืื ืกืืจืื ื. ืืืจืงืช ืืกืืจืืช'), |
| ('ืืชืงื ืช ืืืืจ ืขื ืืงืืจ', 'Solis S6-EH3P20K-H โ ืชืืืื ืขื ืืืจืื ืืจืืื ืืชืืืืื. ืืืืื ืืคืืก'), |
| ('ืืชืงื ืช ืกืืืื', 'CNTE 18.8kWh โ ืืื ืืืืืจ. ืืืืื ืืฆืืืืช, ืืืืืง ืืงืืจ ืื ื ืืจืฉ (ืืฉืงื ~100 ืง"ื)'), |
| ('ืืชืงื ืช ืืื ืืคืกืงืื', 'ืืื ืืืขืืื ืื ืชืืกืคืช ืืืื ืงืืื: ืืคืกืงืื, SPD, ืืืจืจ ืืฆืืื, RCD. ืกืืืื ืืจืืจ ืขื ืื ืืคืกืง'), |
| ]) |
|
|
| add_checklist_table('ืฉืื ื\' โ ืืืืื ืืืืืืจืื ืืฉืืืืื', [ |
| ('ืืืืืช DC โ ืคืื ืืื ืืืืืจ', 'H1Z2Z2-K 6mmยฒ, MC4 connectors. ืกืืจืื ื 1 โ MPPT1, ืกืืจืื ื 2 โ MPPT2. ืืืืื ืงืืืืืืช! + ื-+, โ ื-โ'), |
| ('DC Isolators โ PV', 'ืืชืงื ืช 2 DC Isolators (1000Vdc/32A) โ ืืื ืืื ืกืืจืื ื. ืืื ืื ืืกืช ืืืืืจ ืื ืืื ืืคืื ืืื'), |
| ('ืืืืืช DC โ ืกืืืื', 'ืืื 16mmยฒ ืืจื DC Isolator (800Vdc/63A). ืืืขืืืจ ืืจื ืืืขืช ืืื ืืืช x 2 ืืืคืืคืื. ืืืื ื ืืืืืง: 24.5 Nยทm. ืืืืงืช ืงืืืืืืช ืืคื ื ืืืืืจ!'), |
| ('ืืื BMS/CAN', 'ืืื CAN ืืกืืื ืืืกืืืื ืืืืืจ. ืืืขืืืจ ืืจื ืืืขืช ืืื ืืืช x 4 ืืืคืืคืื.'), |
| ('ืืืืืช AC โ ืืฆืืืช Grid', 'NYY-J 5G10 (3L+N+PE) ืืืฆืืืช Grid ืฉื ืืืืืจ โ CT โ SPD AC โ MCB C50 โ ืืืจืจ ืืฆืืื โ ืืชืคืฆืืืช'), |
| ('ืืืืืช AC โ Backup', 'NYY-J 5G6 ืืืฆืืืช Backup ืฉื ืืืืืจ โ MCB C40 4P โ ืืื ืขืืืกืื ืืืื ืืื'), |
| ('ืืืืืจ ืืจืฉืช ืืืืฉืื', 'ืืขื ืฃ ืืจืฉืช ืืืืจืจ โ MCB C50 โ ืืื ื ืืืฉืื โ ืจืฉืช'), |
| ('ืืืจืงื', 'ืืื 16mmยฒ ื ืืืฉืช ืืจืืง-ืฆืืื: ืืืืจ + ืกืืืื + ืงืื ืกืืจืืงืฆืื + ืืกืืจืืช ืคืื ืืื โ ืคืก ืืืจืงื โ ืืืงืืจืืื'), |
| ]) |
|
|
| |
| add_heading_rtl('ืฉืื ื\' โ ืืืืงืืช ืืคื ื ืืคืขืื', level=2) |
| tests = [ |
| ('ืืืืืช Voc ืืื ืกืืจืื ื', '~396V (ยฑ5%). ืืคืจืฉ ืืื ืกืืจืื ืืื: ืื ืืืชืจ ื-5%'), |
| ('ืืืืืช Isc ืืื ืกืืจืื ื', '~18A ืืฉืืฉ ืืืื. ืืืืืง ืขื ืืืื DC rated'), |
| ('ืืืืงืช ืงืืืืืืช DC', '+ ื-+ ื-โ ื-โ ืืื ื ืงืืืช ืืืืืจ. ืืืืืจ ืืคืื ืืืจืก ืืช ืืืืืจ!'), |
| ('ืืืืงืช ืืืืื DC', 'ืืืจ: >1Mฮฉ ืืื + ืืืืื, ืืืื โ ืืืืื'), |
| ('ืืืืงืช ืจืฆืืคืืช ืืืจืงื', '<0.5ฮฉ ืืื ืื ืืกืืจืช ืคืื ื / ืืืฃ ืืืืจ ืืคืก ืืืจืงื'), |
| ('ืืืืงืช ืืชื ืกืืืื', 'ืืชื ืชืงืื ืืืืื 120โ800V. SOC ืืื ืืืื ~20% ืืคื ื ืืคืขืื ืจืืฉืื ื'), |
| ('ืืืืงืช ืชืงืฉืืจืช BMS', 'ืืืืื ืฉืืืืืจ ืืืื ืืช ืืกืืืื ืืืฆืื SOC, ืืชื, ืืืคืจืืืจื'), |
| ('ืืืืงืช ืืคืกืงืื ื-RCD', 'ืืคืขืื ืื ืืชืืง ืืื ื ืฉื ืื ืืคืกืง. ืืืืงืช RCD ืขื ืืคืชืืจ TEST'), |
| ('ืืืืงืช AC โ ืืชื ืืื ืคืืืืช', '~400V ืืื ืคืืืืช, ~230V ืืื ืคืืื ืื ืืืืจื'), |
| ] |
| table = add_table_rtl(len(tests) + 1, 3) |
| for i, h in enumerate(['โ', 'ืืืืงื', 'ืขืจื ืฆืคืื / ืงืจืืืจืืื']): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], '0C2340') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| for row_idx, (test, expected) in enumerate(tests): |
| table.rows[row_idx + 1].cells[0].text = 'โ' |
| set_cell_rtl(table.rows[row_idx + 1].cells[0]) |
| bold_cell(table.rows[row_idx + 1].cells[1], test) |
| table.rows[row_idx + 1].cells[2].text = expected |
| set_cell_rtl(table.rows[row_idx + 1].cells[2]) |
|
|
| |
| add_checklist_table('ืฉืื ื\' โ ืืคืขืื ืจืืฉืื ื (Commissioning)', [ |
| ('ืืคืขืื ืืคื ืกืืจ', '1. ืกืืืจ DC Isolator ืฉื ืกืืืื โ 2. ืกืืืจ DC Isolators ืฉื PV โ 3. ืกืืืจ ืืคืกืง AC โ 4. ืืคืขื ืืืืจ'), |
| ('ืืืืจืืช ืืืืจ', 'ืืจื Bluetooth + APP: ืืืืจืช ืกืื ืกืืืื (Lithium/CAN), ืืฆื ืขืืืื (Self-use / Feed-in / Zero Export), ืฉืขืืช ืืขืื ื/ืคืจืืงื, ืชืืจ ืจืฉืช (50Hz), ืืชื ืจืฉืช (400V)'), |
| ('ืืคืขืืช AFCI', 'ืืืืืจืืช ืืืืืจ โ activation required. ืืื ืช ืงืฉืช ืืฉืืืืช ืืฆื DC'), |
| ('ืืืืจืช CT', 'ืืืืื CT (ืืฅ ืืืืืื ืืจืฉืช). ืืืืจืช zero export ืื ื ืืจืฉ. ืืืืงื: ืืฉืืืขืจืืช ืืืืฆืจืช, CT ืฆืจืื ืืืจืืืช ืขืจื ืฉืืืื (ืืืฆืื)'), |
| ('ืืืืงืช Backup', 'ื ืืชืืง ืืคืกืง ืจืฉืช ืืื ืืช โ ืืืืื ืฉืขืืืกืื ืืืื ืืื ืืืฉืืืื ืืขืืื ืชืื <10ms โ ืืืืืจ ืืืืฉ'), |
| ('ืืืืืจ WiFi/Ethernet', 'ืืืืืจ ืืืืืจ ืืจืฉืช ืืฆืืจื ื ืืืืจ ืืจืืืง ืืจื ืืคืืืงืฆืืืช Solis. ืืืืจืช ืืฉืืื ื-SolisCloud'), |
| ('ื ืืืืจ 24 ืฉืขืืช', 'ืืขืงื ืืืื ืืจืืฉืื: ืืืฆืืจ PV, ืืขืื ืช ืกืืืื, ืฆืจืืื, ืืืฆืื/ืืืืื ืืจืฉืช. ืืืืื ืฉืืื ืฉืืืืืช'), |
| ]) |
|
|
| |
| add_checklist_table('ืฉืื ื\' โ ืกืืืื ืืชืืขืื', [ |
| ('ืกืืืื ืืคืกืงืื', 'ืชืืืืช ืืจืืจื ืขื ืื ืืคืกืง: "PV String 1", "PV String 2", "ืกืืืื DC", "AC ืืืืจ", "ืจืฉืช", "ืขืืืกืื", "Backup", "SPD"'), |
| ('ืกืืืื DC Isolators', 'ืชืืืืช ืืืืื: "ืืืืจืืช โ ืืชื DC ืืืื ืขื 800V" ืขื ืื DC Isolator'), |
| ('ืฉืื ืืืืื ืืืจืื', 'ืฉืื ืืื ืืืืืจ: "ืืืืื ืืืจืื โ 1. ื ืชืง DC Isolators (PV + ืกืืืื) 2. ื ืชืง ืืคืกืง AC"'), |
| ('ืชืืขืื', 'ืืฉืืืจ ืขืืชืง ืฉื: ืชืื ืืช ืืฉืืืืช, ืืืฉืืจื ืืืืงื, ืืกืคืจืื ืกืืืืจืืื (ืืืืจ + ืกืืืื + ืคืื ืืื), ืชืืื ืืช ืืชืงื ื'), |
| ('ืืกืืจื ืืืงืื', 'ืืืจืืช ืฉืืืืฉ: ืืคืืืงืฆืื, ืืฆืื ืขืืืื, ืืืืื ืืืจืื, ืชืืืืงื ืฉืืืคืช (ื ืืงืื ืคืื ืืื ืื 3 ืืืืฉืื)'), |
| ]) |
|
|
| |
| add_heading_rtl('11. ื ืืื ืืืืื ืืืจืื', level=1) |
| add_para_rtl('ืืืงืจื ืฉื ืฉืจืืคื, ืืฆืคื, ื ืืง ืคืืื ืืฆืืื, ืื ืื ืืฆื ืืืจืื:') |
|
|
| emergency_steps = [ |
| ('1', 'ื ืชืง DC โ ืกืืืื', 'DC Isolator ืฉื ืืกืืืื โ ืืฆื OFF'), |
| ('2', 'ื ืชืง DC โ ืคืื ืืื', 'ืฉื ื DC Isolators ืฉื PV โ ืืฆื OFF'), |
| ('3', 'ื ืชืง AC โ ืืืืจ', 'ืืคืกืง ืืฆืืืช ืืืืจ (C50) โ ืืฆื OFF'), |
| ('4', 'ื ืชืง ืจืฉืช', 'ืืคืกืง ืจืฉืช (C50) โ ืืฆื OFF'), |
| ] |
|
|
| table = add_table_rtl(len(emergency_steps) + 1, 3) |
| for i, h in enumerate(['ืฉืื', 'ืคืขืืื', 'ืคืืจืื']): |
| bold_cell(table.rows[0].cells[i], h) |
| shade_cells(table.rows[0], 'C62828') |
| for cell in table.rows[0].cells: |
| for p in cell.paragraphs: |
| for run in p.runs: |
| run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) |
| for row_idx, (step, action, detail) in enumerate(emergency_steps): |
| bold_cell(table.rows[row_idx + 1].cells[0], step) |
| bold_cell(table.rows[row_idx + 1].cells[1], action) |
| table.rows[row_idx + 1].cells[2].text = detail |
| set_cell_rtl(table.rows[row_idx + 1].cells[2]) |
| shade_cells(table.rows[row_idx + 1], 'FFEBEE') |
|
|
| add_para_rtl('') |
| add_para_rtl('โ ืืืืจืืช: ืื ืืืืจ ื ืืชืืง ืื ืืืคืกืงืื, ืืคืื ืืื ืขืฆืื ืืืฉืืืื ืืืืฆืจ ืืชื ืื ืขืื ืืฉ ืืืจ. ืืชื ืืขืื ืคืชืื: ~396V ืืกืืจืื ื. ืืื ืืืขืช ืืืืืืจื MC4 ืื ืืืืื DC ืืื ืฆืืื ืืื ืืชืืื ืืืืืงื ืขื ืืืื.', bold=True, color=RGBColor(0xC6, 0x28, 0x28)) |
|
|
| |
| add_para_rtl('') |
| p = add_para_rtl('ืืกืื ืื ืืืื ืืฆืจืื ืชืื ืื ืืืื ืืืื ื ืืืืื ืชืื ืืช ืืฉืืืืช ืจืฉืืืช. ืืฉ ืืืืื ืขื ืืฉืืืื ืืืกืื ืืคื ื ืืืฆืืข.', size=10, color=RGBColor(0x99, 0x99, 0x99)) |
| add_para_rtl('ืืืืช ืืืืจ โ ืืื ืกืคืจื | ืืจืฅ 2026', size=10, color=RGBColor(0x99, 0x99, 0x99)) |
|
|
| |
| output_path = os.path.expanduser('~/Documents/GitHub/Baseline/ืชืื ืืช_ืืฉืืืืช_ืืืืช_ืืืืจ.docx') |
| doc.save(output_path) |
| print(f'Saved to: {output_path}') |
|
|