feat: multi-customer architecture + Z-Park support + Gitea migration scripts

Multi-customer config system:
- CUSTOMER env var selects customer (tianpu/zpark)
- customers/tianpu/config.yaml — Tianpu branding, collectors, features
- customers/zpark/config.yaml — Z-Park branding, Sungrow collector
- GET /api/v1/branding endpoint for customer-specific branding
- main.py loads customer config for app title, CORS, logging
- Collector manager filters by customer's enabled collectors

Z-Park (中关村医疗器械园) support:
- Sungrow iSolarCloud API collector (sungrow_collector.py)
- Z-Park device definitions (10 inverters, 8 combiner boxes, 22+ buildings)
- Z-Park TOU pricing config (Beijing 2026 rates)
- Z-Park seed script (seed_zpark.py)

Gitea migration scripts (Mac Studio → labmac3):
- 5 migration scripts + README in scripts/gitea-migration/
- Creates 3-repo structure: ems-core, tp-ems, zpark-ems

Version: v1.0.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Du Wenbo
2026-04-04 16:23:33 +08:00
parent b31817b68b
commit 02c4698b59
19 changed files with 1109 additions and 7 deletions

View File

@@ -0,0 +1,17 @@
# 天普大兴园区 - 客户配置
customer_name: "天普新能源"
platform_name: "天普零碳园区智慧能源管理平台"
platform_name_en: "Tianpu Zero-Carbon Park Smart EMS"
logo_url: "/static/logo-tianpu.png"
theme_color: "#1890ff"
cors_origins:
- "http://localhost:3000"
- "http://localhost:5173"
collectors:
- modbus_tcp
- mqtt
- http_api
features:
charging: true
carbon: true
bigscreen_3d: true

View File

@@ -0,0 +1,15 @@
# 中关村医疗器械园 - 客户配置
customer_name: "中关村医疗器械园"
platform_name: "中关村医疗器械园智慧能源管理平台"
platform_name_en: "Z-Park Medical Device Smart EMS"
logo_url: "/static/logo-zpark.png"
theme_color: "#52c41a"
cors_origins:
- "http://localhost:3000"
- "http://localhost:5173"
collectors:
- sungrow_api
features:
charging: false
carbon: true
bigscreen_3d: false

View File

@@ -0,0 +1,338 @@
{
"customer": {
"name": "中关村医疗器械园",
"code": "zpark",
"location": "北京市海淀区"
},
"device_types": [
{
"code": "sungrow_inverter",
"name": "阳光电源组串式逆变器",
"icon": "solar-panel",
"data_fields": ["power", "daily_energy", "total_energy", "voltage", "current", "frequency", "temperature"]
},
{
"code": "dc_combiner",
"name": "直流汇流箱",
"icon": "combiner-box",
"data_fields": ["voltage", "current", "power", "string_current"]
},
{
"code": "pv_panel_group",
"name": "光伏组件组",
"icon": "pv-panel",
"data_fields": ["power", "energy"]
}
],
"device_groups": [
{
"name": "中关村医疗器械园",
"location": "北京市海淀区",
"description": "中关村医疗器械园光伏项目总节点",
"children": [
{
"name": "一期-26号楼",
"location": "26号楼屋顶",
"description": "一期项目26号楼屋顶光伏"
},
{
"name": "二期-69号",
"location": "69号区域",
"description": "二期项目69号区域多栋楼屋顶光伏",
"children": [
{"name": "1#楼", "location": "1#楼屋顶"},
{"name": "2#楼", "location": "2#楼屋顶"},
{"name": "4#楼", "location": "4#楼屋顶"},
{"name": "5#楼", "location": "5#楼屋顶"},
{"name": "7#楼", "location": "7#楼屋顶"},
{"name": "12#楼", "location": "12#楼屋顶"}
]
}
]
}
],
"devices": [
{
"name": "AP101组串式逆变器",
"code": "ZP-INV-AP101",
"device_type": "sungrow_inverter",
"group": "一期-26号楼",
"rated_power": 40,
"model": "SG40KTL-M",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP101"
}
},
{
"name": "AP102组串式逆变器",
"code": "ZP-INV-AP102",
"device_type": "sungrow_inverter",
"group": "一期-26号楼",
"rated_power": 50,
"model": "SG50KTL-M",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP102"
}
},
{
"name": "AP201组串式逆变器",
"code": "ZP-INV-AP201",
"device_type": "sungrow_inverter",
"group": "1#楼",
"rated_power": 130,
"model": "SG125HV",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP201"
}
},
{
"name": "AP202组串式逆变器",
"code": "ZP-INV-AP202",
"device_type": "sungrow_inverter",
"group": "2#楼",
"rated_power": 260,
"model": "SG250HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP202"
}
},
{
"name": "AP203组串式逆变器",
"code": "ZP-INV-AP203",
"device_type": "sungrow_inverter",
"group": "4#楼",
"rated_power": 160,
"model": "SG160HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP203"
}
},
{
"name": "AP204组串式逆变器",
"code": "ZP-INV-AP204",
"device_type": "sungrow_inverter",
"group": "5#楼",
"rated_power": 400,
"model": "SG350HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP204"
}
},
{
"name": "AP205组串式逆变器",
"code": "ZP-INV-AP205",
"device_type": "sungrow_inverter",
"group": "7#楼",
"rated_power": 290,
"model": "SG250HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP205"
}
},
{
"name": "AP206组串式逆变器",
"code": "ZP-INV-AP206",
"device_type": "sungrow_inverter",
"group": "7#楼",
"rated_power": 300,
"model": "SG300HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP206"
}
},
{
"name": "AP207组串式逆变器",
"code": "ZP-INV-AP207",
"device_type": "sungrow_inverter",
"group": "12#楼",
"rated_power": 280,
"model": "SG250HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP207"
}
},
{
"name": "AP208组串式逆变器",
"code": "ZP-INV-AP208",
"device_type": "sungrow_inverter",
"group": "12#楼",
"rated_power": 290,
"model": "SG250HX",
"manufacturer": "阳光电源",
"protocol": "http_api",
"collect_interval": 900,
"connection_params": {
"api_base": "https://gateway.isolarcloud.com",
"app_key": "1BF313B6A9F919A6FB6A90BD43D23395",
"sys_code": "901",
"x_access_key": "qpthtsf287zvtmr6t3q9hsc0k70f3tay",
"user_account": "13911211695",
"user_password": "123456#ABC",
"ps_id": "",
"device_sn": "AP208"
}
},
{
"name": "26号楼1#汇流箱",
"code": "ZP-CB-2601",
"device_type": "dc_combiner",
"group": "一期-26号楼",
"rated_power": 20,
"model": "PVS-16M",
"manufacturer": "阳光电源"
},
{
"name": "26号楼2#汇流箱",
"code": "ZP-CB-2602",
"device_type": "dc_combiner",
"group": "一期-26号楼",
"rated_power": 20,
"model": "PVS-16M",
"manufacturer": "阳光电源"
},
{
"name": "1#楼1#汇流箱",
"code": "ZP-CB-0101",
"device_type": "dc_combiner",
"group": "1#楼",
"rated_power": 30,
"model": "PVS-24M",
"manufacturer": "阳光电源"
},
{
"name": "2#楼1#汇流箱",
"code": "ZP-CB-0201",
"device_type": "dc_combiner",
"group": "2#楼",
"rated_power": 50,
"model": "PVS-24M",
"manufacturer": "阳光电源"
},
{
"name": "5#楼1#汇流箱",
"code": "ZP-CB-0501",
"device_type": "dc_combiner",
"group": "5#楼",
"rated_power": 60,
"model": "PVS-24M",
"manufacturer": "阳光电源"
},
{
"name": "7#楼1#汇流箱",
"code": "ZP-CB-0701",
"device_type": "dc_combiner",
"group": "7#楼",
"rated_power": 50,
"model": "PVS-24M",
"manufacturer": "阳光电源"
},
{
"name": "12#楼1#汇流箱",
"code": "ZP-CB-1201",
"device_type": "dc_combiner",
"group": "12#楼",
"rated_power": 50,
"model": "PVS-24M",
"manufacturer": "阳光电源"
},
{
"name": "12#楼2#汇流箱",
"code": "ZP-CB-1202",
"device_type": "dc_combiner",
"group": "12#楼",
"rated_power": 50,
"model": "PVS-24M",
"manufacturer": "阳光电源"
}
]
}

View File

@@ -0,0 +1,13 @@
{
"name": "2026年北京工商业分时电价",
"energy_type": "electricity",
"pricing_type": "tou",
"periods": [
{"name": "peak", "start": "10:00", "end": "15:00", "price": 1.35},
{"name": "peak", "start": "18:00", "end": "21:00", "price": 1.35},
{"name": "flat", "start": "07:00", "end": "10:00", "price": 0.85},
{"name": "flat", "start": "15:00", "end": "18:00", "price": 0.85},
{"name": "valley", "start": "23:00", "end": "07:00", "price": 0.35},
{"name": "shoulder", "start": "21:00", "end": "23:00", "price": 0.95}
]
}