# solargis **Repository Path**: milletes/solargis ## Basic Information - **Project Name**: solargis - **Description**: 使用go语言对接solargis光功率预测 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-11 - **Last Updated**: 2026-06-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 1. requestXml 参数配置在配置文件中yaml 2. 有对应的模块接受配置文件中的参数 3. 有对应的模块读取配置文件参数,发送给接受模块 4. 形成最终xml,并访问API 5. 接收API,元数据输出为xml文件,输出数据集为csv文件 6. 完善周期调用 7. 完善当前和1-14天的预测数据的处理 8. 完善文件工具类 9. 完善异常处理 10. 完善日志处理 11. 完善配置文件动态加载 12. 增加ui用于用户读取和写入参数到配置文件中 增加读取yaml的依赖 增加生成xml的依赖 🎯 项目概述 这是一个 SolarGIS 数据获取与管理系统,用于定时从 SolarGIS API 获取太阳能气象数据,并将数据保存为 XML 和 CSV 格式,同时支持文件自动转移和 Windows 服务部署。 📁 项目结构 plainText solargis/ ├── main.go # 主程序入口(支持Windows服务) ├── config/ │ ├── config.go # 配置管理模块 │ ├── config.yaml # 主配置文件 │ ├── config_init.yaml # 初始化配置模板 │ └── templates/ # XML请求模板目录 │ ├── a.xml │ └── b.xml ├── task/ │ ├── RequtesTools.go # API请求工具(请求、解析、写入文件) │ └── FileTransferScheduler.go # 文件定时转移调度器 ├── model/ │ ├── requestModel/RequestData.go # 请求数据构建(模板加载、日期填充) │ └── responseModel/ResponseData.go # 响应数据模型 ├── logging/ │ └── Logger.go # 日志系统(文件+控制台) ├── build.bat # 编译脚本 ├── install-service.bat # Windows服务安装脚本 └── uninstall-service.bat # Windows服务卸载脚本 🔧 核心功能模块 1. API 数据请求 (RequtesTools.go) 当日数据请求:获取当天的太阳能气象数据 未来数据请求:获取未来 N 天的预测数据(默认14天) 支持 XML 模板动态填充日期 响应数据保存为 XML 和 CSV 格式 2. 定时任务调度 (main.go) 使用 cron 调度器,三个定时任务: 当日请求:每15分钟执行一次(0 */15 * * * *) 未来请求:每天4次(00:00, 06:00, 12:00, 18:00) 文件转移:每天凌晨1点执行(0 0 1 * * *) 3. 文件转移 (FileTransferScheduler.go) 自动将数据从 solargis 目录转移到 solargis2 目录 支持配置多个源目录和目标目录 4. 配置管理 (config.go) YAML 格式配置文件 支持环境变量 SOLARGIS_CONFIG_PATH 指定配置路径 线程安全的配置读取 5. 日志系统 (Logger.go) 四级日志:DEBUG、INFO、WARNING、ERROR 同时输出到文件和控制台 日志文件位置:可执行文件同级 logs/app.log 6. Windows 服务支持 (main.go) 支持作为 Windows 服务运行 使用 WinSW 包装 支持自动启动、停止、重启 🔄 工作流程 plainText 1. 程序启动 ↓ 2. 加载配置文件 (config.yaml) ↓ 3. 初始化日志系统 ↓ 4. 注册定时任务 ├─ 当日请求 (每15分钟) ├─ 未来请求 (每天4次) └─ 文件转移 (每天凌晨1点) ↓ 5. 定时任务触发 ├─ 读取XML模板 ├─ 填充日期参数 ├─ 发送HTTP请求到SolarGIS API ├─ 解析XML响应 └─ 保存为XML和CSV文件 ↓ 6. 文件转移任务 └─ 将数据文件转移到目标目录 📦 技术栈 组件 技术 语言 Go 1.24 定时任务 github.com/robfig/cron/v3 配置解析 gopkg.in/yaml.v3 Windows服务 golang.org/x/sys/windows/svc 数据格式 XML、CSV、YAML ⚠️ 发现的问题 死代码:ExtractTemplateName 函数未被使用,可以删除 拼写错误:文件名 RequtesTools.go 应为 RequestsTools.go 文档拼写:redme.md 应为 README.md 配置文件不一致:config_init.yaml 和 config.yaml 结构有差异 📝 配置文件示例 主要配置项: API密钥:当日/未来请求的授权密钥 存储路径:数据文件保存位置 Cron表达式:定时任务执行时间 模板目录:XML请求模板位置 文件转移:源目录和目标目录映射

Parameters processing 中key的说明

The following table lists available parameters for use in the attribute of . [//]: # (These parameters define which data will be included in the response.@key) | Parameter | Description | Tier | |----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------| | GHI | Global Horizontal Irradiation [kWh/m2, Wh/m2, W/m2]. Regarding units see below note. | Basic | | GHI_C | Clear-sky Global Horizontal Irradiation [kWh/m2, Wh/m2, W/m2] | Professional | | GHI_UNC_HIGH | GHI high estimate (10 % probability of exceedance) [kWh/m2, Wh/m2, W/m2] | Professional | | GHI_UNC_LOW | GHI low estimate (90 % probability of exceedance) [kWh/m2, Wh/m2, W/m2] | Professional | | DNI | Direct Normal Irradiation [kWh/m2, Wh/m2, W/m2] | Basic | | DNI_C | Clear-sky Direct Normal Irradiation [kWh/m2, Wh/m2, W/m2] | Professional | | DIF | Diffuse Horizontal Irradiation [kWh/m2, Wh/m2, W/m2] | Basic | | GTI | Global Tilted Irradiation [kWh/m2, Wh/m2, W/m2] | Basic | | GTI_UNC_HIGH | GTI high estimate (10 % probability of exceedance) [kWh/m2, Wh/m2, W/m2] | Professional | | GTI_UNC_LOW | GTI low estimate (90 % probability of exceedance) [kWh/m2, Wh/m2, W/m2] | Professional | | GTI_C | Global tilted clear-sky irradiance [W/m2] | Professional | | CI_FLAG | Cloud identification quality flag [categories] | Basic | | FLAG_R | deprecated alias for CI_FLAG | | | KTM | Deprecated alias of KC. Can be discontinued in future versions. | Professional | | KC | Clear-sky index [unitless] | Professional | | KT | clearness index, values range (0, 1.1), during the night -9 | Professional | | PAR | Photo-synthetically Active Irradiation [kWh/m2, Wh/m2, W/m2] | Professional | | SE | Sun Altitude (Elevation) Angle [deg.] | Basic | | SA | Sun Azimuth Angle [deg.] | Basic | | TEMP | Air Temperature at 2m [deg. C] | Basic | | TD | Dew Point Temperature [deg. C] | Professional | | WBT | Wet Bulb Temperature [deg. C] | Professional | | AP | Atmospheric Pressure [hPa] | Professional | | RH | Relative Humidity [%] | Professional | | WS | Wind Speed [m/s] | Basic | | WD | Wind Direction [deg.] | Basic | | PREC | Precipitation Rate [kg/m2] | Professional | | PWAT | Precipitable Water [kg/m2] | Professional | | PVOUT | Photovoltaic Output [kW, kWh]. Regarding units see below note. | Basic | | PVOUT_UNC_HIGH | PVOUT high estimate (10 % probability of exceedance) [kW, kWh] | Professional | | PVOUT_UNC_LOW | PVOUT low estimate (90 % probability of exceedance) [kW, kWh] | Professional | | SDWE | Water equivalent of accumulated snow depth [kg/m2] | Professional | | SWE | Deprecated alias of SDWE. Can be discontinued in future versions. SDWE will be returned in a response. | Professional | | TMOD | Module temperature [deg. C]. This parameter needs a PV system defined in the request, at least in a mimimal setup like: <pv:system installedPower="1"><pv:module type="CSI"/><pv:inverter/><pv:losses/></pv:system> | Professional | | WG | Wind Gust [m/s] | Professional | | WS100 | Wind speed at 100 m [m/s] | Professional | | WD100 | Wind direction at 100 m [deg.] | Professional | | SFWE | Water equivalent of fresh snowfall rate [kg/m2/hour] - source ERA5 , the latest data available is approx. one month backward (no data for very recent or forecast period) | Professional | | INC | Incidence angle of direct irradiance [deg.], this parameter needs GTI or PVOUT in the request | Professional | | TILT | Tilt of inclined surface [deg.], this parameter needs GTI or PVOUT in the request | Basic | | ASPECT | Aspect of inclined surface [deg.], this parameter needs GTI or PVOUT in the request | Basic | 中文版本 | 参数 |描述 | 层级 | |:-----------------|---------------------------------------------------------------------------------------------------------------------------------|--------------| | GHI | 全球水平辐照度 [kWh/m², Wh/m², W/m²](单位说明见下方注释) | 基础级 | | GHI_C | 晴空全球水平辐照度 [kWh/m², Wh/m², W/m²] | 专业级 | | GHI_UNC_HIGH | GHI 高估值(10% 超越概率)[kWh/m², Wh/m², W/m²] | 专业级 | | GHI_UNC_LOW | GHI 低估值(90% 超越概率)[kWh/m², Wh/m², W/m²] | 专业级 | | DNI | 直接法向辐照度 [kWh/m², Wh/m², W/m²] | 基础级 | | DNI_C | 晴空直接法向辐照度 [kWh/m², Wh/m², W/m²] | 专业级 | | DIF | 散射水平辐照度 [kWh/m², Wh/m², W/m²] | 基础级 | | GTI | 全球倾斜辐照度 [kWh/m², Wh/m², W/m²] | 基础级 | | GTI_UNC_HIGH | GTI 高估值(10% 超越概率)[kWh/m², Wh/m², W/m²] | 专业级 | | GTI_UNC_LOW | GTI 低估值(90% 超越概率)[kWh/m², Wh/m², W/m²] | 专业级 | | GTI_C | 晴空全球倾斜辐照度 [W/m²] | 专业级 | | CI_FLAG | 云识别质量标志 [类别] | 基础级 | | FLAG_R | CI_FLAG 的弃用别名 | - | | KTM | KC 的弃用别名(未来版本可能停用) | 专业级 | | KC | 晴空指数 [无量纲] | 专业级 | | KT | 晴朗指数,取值范围 (0, 1.1),夜间为 -9 | 专业级 | | PAR | 光合有效辐照度 [kWh/m², Wh/m², W/m²] | 专业级 | | SE | 太阳高度角 [度] | 基础级 | | SA | 太阳方位角 [度] | 基础级 | | TEMP | 2米高度气温 [摄氏度] | 基础级 | | TD | 露点温度 [摄氏度] | 专业级 | | WBT | 湿球温度 [摄氏度] | 专业级 | | AP | 大气压 [hPa] | 专业级 | | RH | 相对湿度 [%] | 专业级 | | WS | 风速 [米/秒] | 基础级 | | WD | 风向 [度] | 基础级 | | PREC | 降水率 [千克/平方米] | 专业级 | | PWAT | 可降水量 [千克/平方米] | 专业级 | | PVOUT | 光伏输出 [kW, kWh](单位说明见下方注释) | 基础级 | | PVOUT_UNC_HIGH | PVOUT 高估值(10% 超越概率)[kW, kWh] | 专业级 | | PVOUT_UNC_LOW | PVOUT 低估值(90% 超越概率)[kW, kWh] | 专业级 | | SDWE | 积雪深度水当量 [千克/平方米] | 专业级 | | SWE | SDWE 的弃用别名(未来版本可能停用,响应中返回 SDWE) | 专业级 | | TMOD | 组件温度 [摄氏度](需在请求中定义光伏系统,最小配置示例:``) | 专业级 | | WG | 阵风风速 [米/秒] | 专业级 | [//]: # (

PV array geometry

) [//]: # (Element: "") Namespace: http://solargis.info/schema/common-pv.xsd Description: The element specifies the mounting type of the PV system, which is used for calculating GTI (Global Tilted Irradiation) and PVOUT (Photovoltaic Output). If this element is omitted and GTI/PVOUT is requested, flat-lying PV panels are assumed (GTI = GHI). Content: None (attributes only). | Attribute | Required | Description | Default/Example | |--------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------| | @type | Yes | Specifies the mounting geometry type. Accepted values are: GeometryFixedOneAngle, GeometryOneAxisHorizontalNS, GeometryOneAxisInclinedNS, GeometryOneAxisVertical, GeometryTwoAxisAstronomical. | Example: pv:GeometryFixedOneAngle | | @azimuth | No | True geographical azimuth in degrees (0° = North, 90° = East, 180° = South, 270° = West). Required for GeometryFixedOneAngle. Defaults to 180° for trackers. | Example: 180 | | @tilt | No | Tilt of the panel surface in degrees (0° = horizontal, 90° = vertical). Required for GeometryFixedOneAngle and GeometryOneAxisVertical. | Example: 25 | | @axisTilt | No | Tilt of the inclined rotating axis in degrees (0° = horizontal, 90° = vertical). Applicable only to GeometryOneAxisInclinedNS. Defaults to 30°. | Example: 30 | | @rotationLimitEast | No | Rotation limit for trackers on the east side. Defaults vary by tracker type. Must be less than or equal to @rotationLimitWest. | Example: -90 | | @rotationLimitWest | No | Rotation limit for trackers on the west side. Defaults vary by tracker type. Must be greater than or equal to @rotationLimitEast. | Example: 90 | | @tiltLimitMin | No | Minimum tilt limit for trackers with a horizontal axis (GeometryTwoAxisAstronomical). Default is 0°. Must be less than or equal to @tiltLimitMax. | Example: 0 | | @tiltLimitMax | No | Maximum tilt limit for trackers with a horizontal axis (GeometryTwoAxisAstronomical). Default is 90°. Must be greater than or equal to @tiltLimitMin. | Example: 60 | | @backTracking | No | Boolean value indicating whether the tracker avoids shading from neighboring structures (true) or moves freely (false). Default is false. | Example: "true" | 中文翻译 | attribute | required | description | default/example | |---------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------| | @type | yes | 指定安装几何类型。允许的值为:geometryfixedoneangle, geometryoneaxishorizontalns, geometryoneaxisinclinedns, geometryoneaxisvertical, geometrytwoaxisastronomical。 | 示例:pv:geometryfixedoneangle | | @azimuth | no | 真实地理方位角(单位:度,0° = 北,90° = 东,180° = 南,270° = 西)。对 geometryfixedoneangle 类型为必填项。对于跟踪器默认为 180°。 | 示例:180 | | @tilt | no | 面板表面倾斜角(单位:度,0° = 水平,90° = 垂直)。对 geometryfixedoneangle 和 geometryoneaxisvertical 类型为必填项。 | 示例:25 | | @axistilt | no | 倾斜旋转轴的倾斜角(单位:度,0° = 水平,90° = 垂直)。仅适用于 geometryoneaxisinclinedns 类型。默认值为 30°。 | 示例:30 | | @rotationlimiteast | no | 东侧跟踪器的旋转限制。默认值因跟踪器类型而异。必须小于或等于 @rotationlimitwest。 | 示例:-90 | | @rotationlimitwest | no | 西侧跟踪器的旋转限制。默认值因跟踪器类型而异。必须大于或等于 @rotationlimiteast。 | 示例:90 | | @tiltlimitmin | no | 具有水平轴的跟踪器(geometrytwoaxisastronomical)的最小倾斜限制。默认值为 0°。必须小于或等于 @tiltlimitmax。 | 示例:0 | | @tiltlimitmax | no | 具有水平轴的跟踪器(geometrytwoaxisastronomical)的最大倾斜限制。默认值为 90°。必须大于或等于 @tiltlimitmin。 | 示例:60 | | @backtracking | no | 布尔值,表示跟踪器是否启用避让(true)以避免相邻结构的遮挡,或自由移动(false)。默认值为 false。 | 示例:"true" | 要将当前项目打包为Windows服务,推荐使用WinSW工具。以下是详细步骤: ## 1. 下载并准备WinSW 1. 从 https://github.com/winsw/winsw 下载 `WinSW.NET461.exe` 2. 将其重命名为 `solargis-service.exe` ## 2. 创建服务配置文件 创建 `solargis-service.xml` 配置文件: ```xml SolarGIS SolarGIS Service SolarGIS数据采集服务 %BASE%\solargis.exe rotate %BASE%\logs %BASE% 1 hour ``` ## 3. 修改程序代码支持服务模式 修改 [main.go](file://D:\ProjectWork\go\goWork\xunda\solargis\main.go) 文件,添加Windows服务支持: ``` package main import ( "log" "os" "solargis/config" "solargis/logging" "solargis/model/requestModel" "solargis/task" // 添加Windows服务支持包 "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/debug" ) const defaultConfigPath = "config/config.yaml" func init() { // 初始化日志系统 if err := logging.Init(); err != nil { log.Printf("日志系统初始化失败: %v", err) } configPath := getConfigPath() _, err := config.LoadConfig(configPath) if err != nil { log.Printf("加载配置失败: %v", err) } } func getConfigPath() string { // 从环境变量中获取配置文件路径 path := os.Getenv("SOLARGIS_CONFIG_PATH") if path == "" { return defaultConfigPath } return path } // 主函数修改为支持服务模式 func main() { isIntSrv, err := svc.IsWindowsService() if err != nil { log.Fatalf("failed to determine if we are running in service mode: %v", err) } if isIntSrv { // 作为Windows服务运行 logging.Info.Println("作为Windows服务运行") runService() } else { // 作为普通程序运行 logging.Info.Println("作为普通程序运行") runApplication() } } func runService() { // 使用debug包运行服务 debug.Run("SolarGIS", &solargisService{}) } func runApplication() { getConfig := config.GetConfig() if getConfig == nil { logging.Error.Fatal("配置获取失败,程序退出") return } // 启动定时任务 startTimers(getConfig) } // Windows服务结构体 type solargisService struct{} func (m *solargisService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown changes <- svc.Status{State: svc.StartPending} // 启动应用程序逻辑 go func() { getConfig := config.GetConfig() if getConfig != nil { startTimers(getConfig) } }() changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} loop: for { select { case c := <-r: switch c.Cmd { case svc.Interrogate: changes <- c.CurrentStatus case svc.Stop, svc.Shutdown: // 服务停止逻辑 logging.Info.Println("服务正在停止") break loop default: continue loop } } } changes <- svc.Status{State: svc.StopPending} return } func currentRequest(getConfig *config.Config) { data, err := requestModel.BuildDailyRequest(getConfig, getConfig.API.Today.Value) if err != nil { logging.Error.Printf("构建每日请求失败: %v", err) } logging.Info.Printf("生成的请求数据:%v", string(data)) task.Request(string(data), getConfig.API.Today.Key, getConfig.File.Path, getConfig.API.Today.Value) } func futureRequest(getConfig *config.Config) { data, err := requestModel.BuildDailyRequest(getConfig, getConfig.API.FutureDay.Value) if err != nil { logging.Error.Printf("构建未来请求失败: %v", err) } logging.Info.Printf("%v", string(data)) task.Request(string(data), getConfig.API.FutureDay.Key, getConfig.File.Path, getConfig.API.FutureDay.Value) } func startTimers(getConfig *config.Config) { // currentRequest 定时器:每10分钟执行一次 go func() { currentRequest(getConfig) ticker := time.NewTicker(10 * time.Minute) defer ticker.Stop() for { select { case <-ticker.C: currentRequest(getConfig) } } }() // futureRequest 定时器:每天4次(00:00, 06:00, 12:00, 18:00) go func() { for { now := time.Now() nextRun := getNextRunTime(now) duration := nextRun.Sub(now) logging.Info.Printf("下次 futureRequest 执行时间: %v", nextRun) <-time.After(duration) futureRequest(getConfig) } }() // 阻塞主程序,保持定时器运行 select {} } func getNextRunTime(now time.Time) time.Time { // 设定今天的起始时间 today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) // 定义执行时间点(小时) runHours := []int{0, 6, 12, 18} // 查找下一个执行时间 for _, hour := range runHours { runTime := today.Add(time.Duration(hour) * time.Hour) if runTime.After(now) { return runTime } } // 如果今天的时间点都已过,则返回明天的第一个时间点 return today.Add(24 * time.Hour) } ``` ## 4. 安装和运行服务 创建安装脚本 `install-service.bat`: ```batch @echo off echo 安装SolarGIS服务... solargis-service.exe install echo 启动SolarGIS服务... solargis-service.exe start echo 服务安装完成 pause ``` 创建卸载脚本 `uninstall-service.bat`: ```batch @echo off echo 停止SolarGIS服务... solargis-service.exe stop echo 卸载SolarGIS服务... solargis-service.exe uninstall echo 服务卸载完成 pause ``` ## 5. 打包文件结构 确保以下文件在同一目录下: ``` solargis.exe # 主程序 solargis-service.exe # WinSW服务包装器 solargis-service.xml # 服务配置文件 install-service.bat # 安装脚本 uninstall-service.bat # 卸载脚本 config/ # 配置文件目录 config.yaml # 配置文件 ``` ## 6. 安装服务 以管理员身份运行 `install-service.bat` 即可安装并启动服务。 通过以上步骤,您的程序就可以作为Windows服务运行,支持自动启动、自动重启等服务特性。 如果配置文件再其他位置,可以配置环境变量SOLARGIS_CONFIG_PATH 指定配置文件路径。