diff --git a/bin/Release/EES.exe b/bin/Release/EES.exe deleted file mode 100644 index 6208d1e..0000000 Binary files a/bin/Release/EES.exe and /dev/null differ diff --git a/bin/Release/ESS.exe b/bin/Release/ESS.exe new file mode 100644 index 0000000..cfe7f54 Binary files /dev/null and b/bin/Release/ESS.exe differ diff --git a/bin/Release/assets/config/BCU电池簇遥信.txt b/bin/Release/assets/config/BCU电池簇遥信.txt new file mode 100644 index 0000000..a798b1e --- /dev/null +++ b/bin/Release/assets/config/BCU电池簇遥信.txt @@ -0,0 +1,114 @@ +所属通道号 R uint16 1~4 0xA001 +所属BCU号 R uint16 1~40 0xA002 +蓄电池充放电状态 R uint16 "0x11开路 +0x22待机 +0x33充电 +0x44放电" 0xA003 +电池组运行状态 R uint16 "0x11跳机 +0x22待机 +0x33放空 +0x44充满 +0x55预警 +0x66正常" 0xA004 +簇DO1状态 R uint16 1:断开 2:闭合 0xA005 +簇DO2状态 R uint16 1:断开 2:闭合 0xA006 +继电器总正 R uint16 0:断开 1:闭合 2:粘连 0xA007 +继电器总负 R uint16 0:断开 1:闭合 2:粘连 0xA008 +继电器预充 R uint16 0:断开 1:闭合 2:粘连 0xA009 +继电器bmu供电 R uint16 0:断开 1:闭合 2:粘连 0xA00A +整簇总电压过高告警 R uint16 0:正常 1:告警 0xA00B +整簇总电压过低告警 R uint16 0:正常 1:告警 0xA00C +整簇中单体电压过高告警 R uint16 0:正常 1:告警 0xA00D +整簇中单体电压过低告警 R uint16 0:正常 1:告警 0xA00E +整簇中单体电压偏差过大告警 R uint16 0:正常 1:告警 0xA00F +整簇中单体温度偏差过大告警 R uint16 0:正常 1:告警 0xA010 +整簇中单体温度过高告警 R uint16 0:正常 1:告警 0xA011 +整簇中单体温度过低告警 R uint16 0:正常 1:告警 0xA012 +整簇总充电电流过高告警 R uint16 0:正常 1:告警 0xA013 +整簇总放电电流过高告警 R uint16 0:正常 1:告警 0xA014 +整簇总SOC过高告警 R uint16 0:正常 1:告警 0xA015 +整簇总SOC过低告警 R uint16 0:正常 1:告警 0xA016 +高压盒主正接触器粘连告警 R uint16 0:正常 1:告警 0xA017 +高压盒主正接触器不能吸合告警 R uint16 0:正常 1:告警 0xA018 +高压盒主负接触器粘连告警 R uint16 0:正常 1:告警 0xA019 +高压盒主负接触器不能吸合告警 R uint16 0:正常 1:告警 0xA01A +高压盒预充接触器粘连告警 R uint16 0:正常 1:告警 0xA01B +高压盒预充接触器不能吸合告警 R uint16 0:正常 1:告警 0xA01C +预充失败告警 R uint16 0:正常 1:告警 0xA01D +BCU电压检测模块出现问题告警 R uint16 0:正常 1:告警 0xA01E +BCU温度检测模块出现问题告警 R uint16 0:正常 1:告警 0xA01F +BCU电流检测模块出现问题告警 R uint16 0:正常 1:告警 0xA020 +BCU绝缘检测模块出现问题告警 R uint16 0:正常 1:告警 0xA021 +高压盒内总压检测模块出现问题告警 R uint16 0:正常 1:告警 0xA022 +高压盒外总压检测模块出现问题告警 R uint16 0:正常 1:告警 0xA023 +PCS-CAN通信故障告警 R uint16 0:正常 1:告警 0xA024 +高压盒供电电压过高告警 R uint16 0:正常 1:告警 0xA025 +绝缘正极故障告警 R uint16 0:正常 1:告警 0xA026 +绝缘负极故障告警 R uint16 0:正常 1:告警 0xA027 +绝缘中间侧故障告警 R uint16 0:正常 1:告警 0xA028 +绝缘故障告警 R uint16 0:正常 1:告警 0xA029 +BMU中电压采样线开路告警 R uint16 0:正常 1:告警 0xA02A +BMU中NTC采样线短开路告警 R uint16 0:正常 1:告警 0xA02B +BMU中采样芯片故障告警 R uint16 0:正常 1:告警 0xA02C +BMU中电池温度升高过快告警 R uint16 0:正常 1:告警 0xA02D +BMU中电池内部短路告警 R uint16 0:正常 1:告警 0xA02E +BMU充电均衡模块出现故障告警 R uint16 0:正常 1:告警 0xA02F +BMU放电均衡模块出现故障告警 R uint16 0:正常 1:告警 0xA030 +BMU通信故障告警 R uint16 0:正常 1:告警 0xA031 +单体内阻过大告警 R uint16 0:正常 1:告警 0xA032 +单体内阻过小告警 R uint16 0:正常 1:告警 0xA033 +单体内阻阻差过大告警 R uint16 0:正常 1:告警 0xA034 +簇内阻过大告警 R uint16 0:正常 1:告警 0xA035 +簇内阻过小告警 R uint16 0:正常 1:告警 0xA036 +SOC初始化无效告警 R uint16 0:正常 1:告警 0xA037 +充电时soc降低故障告警 R uint16 0:正常 1:告警 0xA038 +放电时soc升高告警 R uint16 0:正常 1:告警 0xA039 +静止时SOC跳变告警 R uint16 0:正常 1:告警 0xA03A +整簇总电压过高保护 R uint16 0:正常 1:保护 0xA03B +整簇总电压过低保护 R uint16 0:正常 1:保护 0xA03C +整簇中单体电压过高保护 R uint16 0:正常 1:保护 0xA03D +整簇中单体电压过低保护 R uint16 0:正常 1:保护 0xA03E +整簇中单体电压偏差过大保护 R uint16 0:正常 1:保护 0xA03F +整簇中单体温度偏差过大保护 R uint16 0:正常 1:保护 0xA040 +整簇中单体温度过高保护 R uint16 0:正常 1:保护 0xA041 +整簇中单体温度过低保护 R uint16 0:正常 1:保护 0xA042 +整簇总充电电流过高保护 R uint16 0:正常 1:保护 0xA043 +整簇总放电电流过高保护 R uint16 0:正常 1:保护 0xA044 +整簇总SOC过高保护 R uint16 0:正常 1:保护 0xA045 +整簇总SOC过低保护 R uint16 0:正常 1:保护 0xA046 +高压盒主正接触器粘连保护 R uint16 0:正常 1:保护 0xA047 +高压盒主正接触器不能吸合保护 R uint16 0:正常 1:保护 0xA048 +高压盒主负接触器粘连保护 R uint16 0:正常 1:保护 0xA049 +高压盒主负接触器不能吸合保护 R uint16 0:正常 1:保护 0xA04A +高压盒预充接触器粘连保护 R uint16 0:正常 1:保护 0xA04B +高压盒预充接触器不能吸合保护 R uint16 0:正常 1:保护 0xA04C +预充失败保护 R uint16 0:正常 1:保护 0xA04D +BCU电压检测模块出现问题保护 R uint16 0:正常 1:保护 0xA04E +BCU温度检测模块出现问题保护 R uint16 0:正常 1:保护 0xA04F +BCU电流检测模块出现问题保护 R uint16 0:正常 1:保护 0xA050 +BCU绝缘检测模块出现问题保护 R uint16 0:正常 1:保护 0xA051 +高压盒内总压检测模块出现问题保护 R uint16 0:正常 1:保护 0xA052 +高压盒外总压检测模块出现问题保护 R uint16 0:正常 1:保护 0xA053 +PCS-CAN通信故障保护 R uint16 0:正常 1:保护 0xA054 +高压盒供电电压过高保护 R uint16 0:正常 1:保护 0xA055 +绝缘正极故障保护 R uint16 0:正常 1:保护 0xA056 +绝缘负极故障保护 R uint16 0:正常 1:保护 0xA057 +绝缘中间侧故障保护 R uint16 0:正常 1:保护 0xA058 +绝缘故障保护 R uint16 0:正常 1:保护 0xA059 +BMU中电压采样线开路保护 R uint16 0:正常 1:保护 0xA05A +BMU中NTC采样线短开路保护 R uint16 0:正常 1:保护 0xA05B +BMU中采样芯片故障保护 R uint16 0:正常 1:保护 0xA05C +BMU中电池温度升高过快保护 R uint16 0:正常 1:保护 0xA05D +BMU中电池内部短路保护 R uint16 0:正常 1:保护 0xA05E +BMU充电均衡模块出现故障保护 R uint16 0:正常 1:保护 0xA05F +BMU放电均衡模块出现故障保护 R uint16 0:正常 1:保护 0xA060 +BMU通信故障保护 R uint16 0:正常 1:保护 0xA061 +单体内阻过大保护 R uint16 0:正常 1:保护 0xA062 +单体内阻过小保护 R uint16 0:正常 1:保护 0xA063 +单体内阻阻差过大保护 R uint16 0:正常 1:保护 0xA064 +簇内阻过大保护 R uint16 0:正常 1:保护 0xA065 +簇内阻过小保护 R uint16 0:正常 1:保护 0xA066 +SOC初始化无效保护 R uint16 0:正常 1:保护 0xA067 +充电时soc降低故障保护 R uint16 0:正常 1:保护 0xA068 +放电时soc升高保护 R uint16 0:正常 1:保护 0xA069 +静止时SOC跳变保护 R uint16 0:正常 1:保护 0xA06A \ No newline at end of file diff --git a/bin/Release/assets/config/BCU电池簇遥测.txt b/bin/Release/assets/config/BCU电池簇遥测.txt new file mode 100644 index 0000000..717d0d5 --- /dev/null +++ b/bin/Release/assets/config/BCU电池簇遥测.txt @@ -0,0 +1,65 @@ +所属通道号 R uint16 1~4 0x0001 +所属BCU号 R uint16 1~40 0x0002 +簇电压 R uint32 0.1V 0x0003 +簇电流 R int32 0.1A 0x0005 +簇温度 R int32 0.1℃ 0x0007 +簇电阻 R uint32 1mΩ 0x0009 +簇SOC R uint16 0.1 0x000B +簇SOH R uint16 0.1 0x000C +簇正绝缘电阻 R uint32 1kΩ 0x000D +簇负绝缘电阻 R uint32 1kΩ 0x000F +簇允许最大充电电流 R int32 0.1A 0x0011 +簇允许最大放电电流 R int32 0.1A 0x0013 +簇允许最大充电功率 R uint32 1kW 0x0015 +簇允许最大放电功率 R uint32 1kW 0x0017 +簇可充容量 R uint32 0.1Ah 0x0019 +簇可放容量 R uint32 0.1Ah 0x001B +簇单次累计充容量 R uint32 0.1Ah 0x001D +簇单次累计放容量 R uint32 0.1Ah 0x001F +簇总累计充容量 R uint32 0.1Ah 0x0021 +簇总累计放容量 R uint32 0.1Ah 0x0023 +簇可充电量 R uint32 1kWh 0x0025 +簇可放电量 R uint32 1kWh 0x0027 +簇单次充电量 R uint32 1kWh 0x0029 +簇单次放电量 R uint32 1kWh 0x002B +簇累计充电量 R uint32 1kWh 0x002D +簇累计放电量 R uint32 1kWh 0x002F +pack累计簇总压 R uint32 0.1V 0x0031 +簇与pack压差 R uint32 0.1V 0x0033 +簇与PCS压差 R uint32 0.1V 0x0035 +簇中BMU个数 R uint16 0x0037 +簇中BMU中单体个数 R uint16 0x0038 +簇中BMU中温度个数 R uint16 0x0039 +簇中单体个数 R uint16 0x003A +簇中温度个数 R uint16 0x003B +单体最高SOC节号 R uint16 0x003C +单体最高SOC R uint16 0.1 0x003D +单体最低SOC节号 R uint16 0x003E +单体最低SOC R uint16 0.1 0x003F +单体最高SOH节号 R uint16 0x0040 +单体最高SOH R uint16 0.1 0x0041 +单体最低SOH节号 R uint16 0x0042 +单体最低SOH R uint16 0.1 0x0043 +单体最高电压节号 R uint16 0x0044 +单体最高电压 R uint16 mV 0x0045 +单体最低电压节号 R uint16 0x0046 +单体最低电压 R uint16 mV 0x0047 +单体电压差 R uint16 mV 0x0048 +单体平均电压 R uint16 mV 0x0049 +单体最高温度节号 R uint16 0x004A +单体最高温度 R int16 0.1℃ 0x004B +单体最低温度节号 R uint16 0x004C +单体最低温度 R int16 0.1℃ 0x004D +单体温度差 R int16 0.1℃ 0x004E +单体平均温度 R int16 0.1℃ 0x004F +单体最高内阻节号 R uint16 0x0050 +单体最高内阻 R uint16 mΩ 0x0051 +单体最低内阻节号 R uint16 0x0052 +单体最低内阻 R uint16 mΩ 0x0053 +单体内阻差 R uint16 mΩ 0x0054 +单体平均内阻 R uint16 mΩ 0x0055 +单体SOC R uint16[1000] 0.1 0x0056~0x043D +单体SOH R uint16[1000] 0.1 0x043E~0x0825 +单体电压 R uint16[1000] mV 0x0826~0x0C0D +单体温度 R int16[1000] 0.01℃ 0x0C0E~0x0FF5 +单体内阻 R uint16[1000] mΩ 0x0FF6~0x13DD \ No newline at end of file diff --git a/bin/Release/assets/config/BMS电池堆遥测.txt b/bin/Release/assets/config/BMS电池堆遥测.txt new file mode 100644 index 0000000..4621f17 --- /dev/null +++ b/bin/Release/assets/config/BMS电池堆遥测.txt @@ -0,0 +1,63 @@ +SOC R uint16 0.1 0x0001 +SOH R uint16 0.1 0x0002 +电压 R uint32 0.1V 0x0003 +电流 R int32 0.1A 0x0005 +可充电量 R uint32 1kWh 0x0007 +可放电量 R uint32 1kWh 0x0009 +单次可充电量 R uint32 1kWh 0x000B +单次可放电量 R uint32 1kWh 0x000D +堆功率 R int32 1kW 0x000F +充电量累加 R uint32 1kWh 0x0011 +放电量累加 R uint32 1kWh 0x0013 +簇最大SOC R uint16 0.1 0x0015 +簇最小SOC R uint16 0.1 0x0016 +簇最大SOC号 R uint16 0x0017 +簇最小SOC号 R uint16 0x0018 +簇SOC差值 R uint16 0.1 0x0019 +簇最大电压 R uint16 0.1V 0x001A +簇最小电压 R uint16 0.1V 0x001B +簇最大电压号 R uint16 0x001C +簇最小电压号 R uint16 0x001D +簇电压差值 R uint16 0.1V 0x001E +单体最大电压簇号 R uint16 0x001F +单体最大电压节号 R uint16 0x0020 +单体最大电压 R uint16 mV 0x0021 +单体最小电压簇号 R uint16 0x0022 +单体最小电压节号 R uint16 0x0023 +单体最小电压 R uint16 mV 0x0024 +单体平均电压 R uint16 mV 0x0025 +单体电压差 R uint16 mV 0x0026 +单体最大温度簇号 R uint16 0x0027 +单体最大温度节号 R uint16 0x0028 +单体最大温度 R int16 0.1℃ 0x0029 +单体最小温度簇号 R uint16 0x002A +单体最小温度节号 R uint16 0x002B +单体最小温度 R int16 0.1℃ 0x002C +单体平均温度 R int16 0.1℃ 0x002D +单体温度差 R int16 0.1℃ 0x002E +最大内阻簇号 R uint16 0x002F +最大内阻节号 R uint16 0x0030 +最大内阻 R uint16 mΩ 0x0031 +最小内阻簇号 R uint16 0x0032 +最小内阻节号 R uint16 0x0033 +最小内阻 R uint16 mΩ 0x0034 +单体平均内阻 R uint16 mΩ 0x0035 +单体内阻差 R uint16 mΩ 0x0036 +单体最大SOH簇号 R uint16 0x0037 +单体最大SOH节号 R uint16 0x0038 +单体最大SOH R uint16 0.10% 0x0039 +单体最小SOH簇号 R uint16 0x003A +单体最小SOH节号 R uint16 0x003B +单体最小SOH R uint16 0.10% 0x003C +单体最大SOc簇号 R uint16 0x003D +单体最大SOc节号 R uint16 0x003E +单体最大Soc R uint16 0.10% 0x0040 +单体最小SOc簇号 R uint16 0x0041 +单体最小SOc节号 R uint16 0x0042 +单体最小SOc R uint16 0.10% 0x0043 +系统剩余最大可充电功率 R uint32 1KW 0x0043 +系统剩余最大可放电功率 R uint32 1KW 0x0045 +可充电状态 R uint16 1:可充电;0:不可充电 0x0047 +可放电状态 R uint16 1:可放电;0:不可放电 0x0048 +运行状态 R uint16 运行状态 0-正常 1-告警 2-保护 0x0049 +充放电状态 R uint16 0-待机 1-充电 2-放电 0x004A \ No newline at end of file diff --git a/bin/Release/assets/config/EMS遥信.txt b/bin/Release/assets/config/EMS遥信.txt new file mode 100644 index 0000000..52773f8 --- /dev/null +++ b/bin/Release/assets/config/EMS遥信.txt @@ -0,0 +1,44 @@ +BMS(电池堆)通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x2001 +BCU(电池簇)通信状态 R uint64 "0:正常 +1:故障" bit位从低到高分别对应1~64 0x2002 +PCU(主控)通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x2006 +PCS(模块)通信状态 R uint64 "0:正常 +1:故障" bit位从低到高分别对应1~64 0x2007 +电表总接点通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x200B +电表通信状态 R uint32 "0:正常 +1:故障" bit位从低到高分别对应1~32 0x200C +消防通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x200E +UPS通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x200F +温湿度总接点通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x2010 +温湿度通信状态 R uint32 "0:正常 +1:故障" bit位从低到高分别对应1~32 0x2011 +空调总接点通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x2013 +空调通信状态 R uint32 "0:正常 +1:故障" bit位从低到高分别对应1~32 0x2014 +控制干接点(配电系统)状态 R uint16 "0:开路 +1:闭合" bit位从低到高分别对应1~16 0x2016 +状态干接点(配电系统)状态 R uint16 "0:开路 +1:闭合" bit位从低到高分别对应1~16 0x2017 +BCU总通信状态 R uint16 0:正常 1:告警 2:故障 0x2018 +PCU总通信状态 R uint16 0:正常 1:告警 2:故障 0x2019 +电表总通信状态 R uint16 0:正常 1:告警 2:故障 0x201A +消防总通信状态 R uint16 0:正常 1:告警 2:故障 0x201B +UPS总通信状态 R uint16 0:正常 1:告警 2:故障 0x201C +温湿度总通信状态 R uint16 0:正常 1:告警 2:故障 0x201D +空调总通信状态 R uint16 0:正常 1:告警 2:故障 0x201E +EMU通信状态 R uint16 0:正常 1:告警 2:故障 0x201F +冷机总通信状态 R uint16 0:正常 1:告警 2:故障 0x2020 +冷机总接点通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x2021 +冷机通信状态 R uint16 "0:正常 +1:故障" bit位从低到高分别对应1~16 0x2022 +预留 0x2023~0x2079 +预留 +判断总表的三相总有功 < -5.0fkW 充电 >5.0fkW放电 否则停机 R uint16 0:充电 1:放电 2:停机 储能状态 0x207A \ No newline at end of file diff --git a/bin/Release/assets/config/EMS遥测.txt b/bin/Release/assets/config/EMS遥测.txt new file mode 100644 index 0000000..ce7fdc0 --- /dev/null +++ b/bin/Release/assets/config/EMS遥测.txt @@ -0,0 +1,111 @@ +BMS(电池堆)个数 R uint16 1 0x1001 +BCU通道个数 R uint16 1~2 0x1002 +BCU(电池簇)个数 R uint16 1~40 0x1003 +PCU(主控)个数 R uint16 1~4 0x1004 +PCU通道个数 R uint16 1~4 0x1005 +PCS(模块)个数 R uint16 1~40 0x1006 +电表通道个数 R uint16 1 0x1007 +电表个数 R uint16 1~10 0x1008 +消防通道个数 R uint16 1~10 0x1009 +消防个数 R uint16 1~10 0x100A +UPS通道个数 R uint16 1~10 0x100B +UPS个数 R uint16 1~10 0x100C +温湿度通道个数 R uint16 1 0x100D +温湿度个数 R uint16 1~10 0x100E +空调通道个数 R uint16 1 0x100F +空调个数 R uint16 1~10 0x1010 +控制干接点(配电系统)个数 R uint16 16 0x1011 +状态干接点(配电系统)个数 R uint16 16 0x1012 +预留 0x1013~0x1071 +预留 +预留 +预留 +预留 +预留 +预留 +预留 +预留 +系统最大可充电功率 R uint32 1KW Pcu数据 0x1072 +系统最大可放电功率 R uint32 1KW 0x1074 +储能母线电压 R uint32 0.1V 堆数据 0x1076 +储能母线电流 R int32 0.1A 0x1078 +储能系统SOC R uint16 0.1 0x107A +储能系统SOH R uint16 0.1 0x107B +电流变比 R uint16 电表总表数据 0x107C +电压变比 R uint16 0x107D +A相电压 R uint32 1V 0x107E +B相电压 R uint32 1V 0x1080 +C相电压 R uint32 1V 0x1082 +A相电流 R int32 1A 0x1084 +B相电流 R int32 1A 0x1086 +C相电流 R int32 1A 0x1088 +AB相电压 R uint32 1V 0x108A +BC相电压 R uint32 1V 0x108C +CA相电压 R uint32 1V 0x108E +A相有功功率 R int32 1kW 0x1090 +B相有功功率 R int32 1kW 0x1092 +C相有功功率 R int32 1kW 0x1094 +三相总有功功率 R int32 1kW 0x1096 +当前控制功率 R int32 0.1kW 堆数据 0x1098 +负荷率 R uint32 1% 台区控制策略数据 0不拿 大于0 默认拿第一个 0x109A +三相不平衡度  R uint32 1% 0x109C + 功率因素比率  R uint32 1% 0x109E +进线开关柜功率 R int32 1kW 并网口电表 0x10A0 +用户关口表功率 R int32 1kW 并网口电表 0x10A2 +预留 0x10A4~0x1103 +预留 +正向总有功总需量 R int32 1kW 0x1104 +尖段电价 R uint32 1RMB 0x1106 +峰段电价 R uint32 1RMB 0x1108 +平段电价 R uint32 1RMB 0x110A +谷段电价 R uint32 1RMB 0x110C +日充电电量 R uint32 1kWh 0x110E +日放电电量 R uint32 1kWh 0x1110 +日充电费用 R uint32 1RMB 0x1112 +日放电费用 R uint32 1RMB 0x1114 +日收益 R int32 1RMB 0x1116 +日正向尖有功电能 R uint32 1kWh 0x1118 +日正向峰有功电能 R uint32 1kWh 0x111A +日正向平有功电能 R uint32 1kWh 0x111C +日正向谷有功电能 R uint32 1kWh 0x111E +日正向总有功电能 R uint32 1kWh 0x1120 +日反向尖有功电能 R uint32 1kWh 0x1122 +日反向峰有功电能 R uint32 1kWh 0x1124 +日反向平有功电能 R uint32 1kWh 0x1126 +日反向谷有功电能 R uint32 1kWh 0x1128 +日反向总有功电能 R uint32 1kWh 0x112A +总充电电量 R uint32 1kWh 0x112C +总放电电量 R uint32 1kWh 0x112E +总充电费用 R uint32 1RMB 0x1130 +总放电费用 R uint32 1RMB 0x1132 +总收益 R int32 1RMB 0x1134 +总正向尖有功电能 R uint32 1kWh 0x1136 +总正向峰有功电能 R uint32 1kWh 0x1138 +总正向平有功电能 R uint32 1kWh 0x113A +总正向谷有功电能 R uint32 1kWh 0x113C +总正向总有功电能 R uint32 1kWh 0x113E +总反向尖有功电能 R uint32 1kWh 0x1140 +总反向峰有功电能 R uint32 1kWh 0x1142 +总反向平有功电能 R uint32 1kWh 0x1144 +总反向谷有功电能 R uint32 1kWh 0x1146 +总反向总有功电能 R uint32 1kWh 0x1148 +预留 0x114A~0x11AD +预留 +预留 +交流A相电压 R int16 1V 0x11AE +交流B相电压 R int16 1V 0x11AF +交流C相电压 R int16 1V 0x11B0 +交流A相频率 R int16 1Hz 0x11B1 +交流B相频率 R int16 1Hz 0x11B2 +交流C相频率 R int16 1Hz 0x11B3 +总直流功率 R int32 1kW 0x11B4 +总直流电压 R uint32 0.1V 0x11B6 +总直流电流 R int32 0.1A 0x11B8 +预留 0x11B9~0x121A +预留 +预留 +储能系统温度 R int16 0.1℃ 堆里面单体温度最高 0x121B +储能充放电时段hh R uint16 时 0x01 0x121C +储能充放电时段mm R uint16 分 0x01 0x121D +储能充放电时段ss R uint16 秒 0x01 0x121E +储能系统各时段功率 R int16 1kW 0x01 0x121F \ No newline at end of file diff --git a/bin/Release/assets/config/EMS遥调.txt b/bin/Release/assets/config/EMS遥调.txt new file mode 100644 index 0000000..65f34c7 --- /dev/null +++ b/bin/Release/assets/config/EMS遥调.txt @@ -0,0 +1,53 @@ +EMS工作模式 RW uint16 - "0:无效 +1:本地控制模式, EMS不接受平台调控 +2:平台控制模式, EMS接收平台调控指令" 0x0001 +有功功率 RW int16 kW "并网恒功率模式下交流侧功率值: +<0: 充电功率 +0: 静置 +>0: 放电功率" 0x0002 +PCS开关机 RW uint16 - "0: 关机 +1: 开机" 软件开关机 0x0003 +主控对象 RW uint16 "储能遥控对象: +0:无效 +1:华云 +2:轻舟" 0x0004 +A相有功功率 RW int16 1kW 0x0005 +B相有功功率 RW int16 1kW 0x0006 +C相有功功率 RW int16 1kW 0x0007 +三相总有功功率 RW int16 1kW 0x0008 +A相无功功率 RW int16 1kVar 0x0009 +B相无功功率 RW int16 1kVar 0x000A +C相无功功率 RW int16 1kVar 0x000B +三相总无功功率 RW int16 1kVar 0x000C +A相电流 RW int16 0.01A 在使用的时候除以100转float 0x000D +B相电流 RW int16 0.01A 0x000E +C相电流 RW int16 0.01A 0x000F +A相电压 RW uint16 1V 0x0010 +B相电压 RW uint16 1V 0x0011 +C相电压 RW uint16 1V 0x0012 +A相交流功率因数 RW int16 0.01 在使用的时候除以100转float 0x0013 +B相交流功率因数 RW int16 0.01 0x0014 +C相交流功率因数 RW int16 0.01 0x0015 +A相视在功率 RW int16 1kVA 0x0016 +B相视在功率 RW int16 1kVA 0x0017 +C相视在功率 RW int16 1kVA 0x0018 +正向总有功总需量 RW int16 1kW 0x0019 +数据有效性 RW int16 0无效 1有效 0x001A +EMS工作模式 RW uint16 - "0:无效 +1:本地控制模式, EMS不接受平台调控 +2:平台控制模式, EMS接收平台调控指令" 2413项目需求 0x001B +有功功率 RW uint16 kW "并网恒功率模式下交流侧功率值: +功率绝对值 没有正负" 2413项目需求 0x001C +充放电类型 RW uint16 - "0: 关机 +1: 充电 +2:放电 +3:待机" "2413项目需求 +充放电类型" 0x001D +最大SOC RW uint16 2413项目需求 0x001E +最小SOC RW uint16 2413项目需求 0x001F +自动并离网 RW uint16 "0:手动 +1:自动" "2332项目需求 +(若为自动,则通过主控进行并离网切换)" 0x0020 +并网离网 RW uint16 "0:并网 +1:离网" "2332项目需求 +(该下发参数的前提为手动模式下)" 0x0021 \ No newline at end of file diff --git a/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx b/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx new file mode 100644 index 0000000..17dafac Binary files /dev/null and b/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx differ diff --git a/bin/Release/assets/config/PCS遥信.txt b/bin/Release/assets/config/PCS遥信.txt new file mode 100644 index 0000000..df3b360 --- /dev/null +++ b/bin/Release/assets/config/PCS遥信.txt @@ -0,0 +1,99 @@ +所属主控号 R uint16 1~4 0x1001 +所属PCS号 R uint16 1~40 0x1002 +故障状态 R uint16 1故障,0正常 0x1003 +告警状态 R uint16 1告警,0正常 0x1004 +设备在线 R uint16 1在线,0无效 0x1005 +禁止充电 R uint16 1禁止,0无效 0x1006 +禁止放电 R uint16 1禁止,0无效 0x1007 +运行状态 R uint16 1开机,0关机 0x1008 +充放状态 R uint16 0:待机,1:充电,2:放电,3:搁置 0x1009 +电网状态 R uint16 1离网,0并网 0x100A +逆变供电 R uint16 0禁止,1使能 0x100B +缓启动完成 R uint16 0禁止,1使能 0x100C +主机标志 R uint16 0禁止,1使能 0x100D +并离网状态 R uint16 0:并网, 1:离网 0x100E +同步请求标志 R uint16 0:无效;1:动作 0x100F +绝缘故障 R uint16 1:故障,0正常 0x1010 +漏电保护 R uint16 1:故障,0正常 0x1011 +直流过压 R uint16 1:故障,0正常 0x1012 +市电幅值异常 R uint16 1:故障,0正常 0x1013 +市电相序异常 R uint16 1:故障,0正常 0x1014 +温度开关异常 R uint16 1:故障,0正常 0x1015 +市电频率异常 R uint16 1:故障,0正常 0x1016 +IGBT过温 R uint16 1:故障,0正常 0x1017 +交流接地故障 R uint16 1:故障,0正常 0x1018 +逆变过流异常 R uint16 1:故障,0正常 0x1019 +直流缓起故障 R uint16 1:故障,0正常 0x101A +直流主继电器故障 R uint16 1:故障,0正常 0x101B +风机异常 R uint16 1:故障,0正常 0x101C +主接触器异常 R uint16 1:故障,0正常 0x101D +均浮充切换超时 R uint16 1:故障,0正常 0x101E +硬件故障 R uint16 1:故障,0正常 0x101F +机内过温 R uint16 1:故障,0正常 0x1020 +软启动故障 R uint16 1:故障,0正常 0x1021 +触摸屏通讯故障 R uint16 1:故障,0正常 0x1022 +防雷器故障 R uint16 1:故障,0正常 0x1023 +急停故障 R uint16 1:故障,0正常 0x1024 +BMS系统故障 R uint16 1:故障,0正常 0x1025 +BMS通讯故障 R uint16 1:故障,0正常 0x1026 +BMS干接点通讯故障 R uint16 1:故障,0正常 0x1027 +远程通讯故障 R uint16 1:故障,0正常 0x1028 +门禁告警 R uint16 1:故障,0正常 0x1029 +锁相异常 R uint16 1:故障,0正常 0x102A +IGBT过温告警 R uint16 1:故障,0正常 0x102B +硬件过流保护 R uint16 1:故障,0正常 0x102C +驱动故障 R uint16 1:故障,0正常 0x102D +ID冲突 R uint16 1:故障,0正常 0x102E +电池过压 R uint16 1:故障,0正常 0x102F +电池欠压 R uint16 1:故障,0正常 0x1030 +直流过流保护 R uint16 1:故障,0正常 0x1031 +输出电压异常 R uint16 1:故障,0正常 0x1032 +离网输出电压不符合 R uint16 1:故障,0正常 0x1033 +输出过载保护 R uint16 1:故障,0正常 0x1034 +输出短路保护 R uint16 1:故障,0正常 0x1035 +并机通信异常 R uint16 1:故障,0正常 0x1036 +电池保险异常 R uint16 1:故障,0正常 0x1037 +电池重载低压 R uint16 1:故障,0正常 0x1038 +电池低压告警 R uint16 1:故障,0正常 0x1039 +一拖二压差过大 R uint16 1:故障,0正常 0x103A +电池反接故障 R uint16 1:故障,0正常 0x103B +电池电压异常 R uint16 1:故障,0正常 0x103C +过载告警 R uint16 1:故障,0正常 0x103D +外部接触器异常 R uint16 1:故障,0正常 0x103E +IGBT温度传感器异常 R uint16 1:故障,0正常 0x103F +整机温度传感器异常 R uint16 1:故障,0正常 0x1040 +市电CT异常 R uint16 1:故障,0正常 0x1041 +逆变电流三相不平衡 R uint16 1:故障,0正常 0x1042 +逆变电流直流分量异常 R uint16 1:故障,0正常 0x1043 +母线不平衡 R uint16 1:故障,0正常 0x1044 +逆变电压直流分量异常 R uint16 1:故障,0正常 0x1045 +主接触器控制异常 R uint16 1:故障,0正常 0x1046 +逆变电压控制异常 R uint16 1:故障,0正常 0x1047 +直流霍尔异常 R uint16 1:故障,0正常 0x1048 +电池单体过压 R uint16 1:故障,0正常 0x1049 +电池单体欠压 R uint16 1:故障,0正常 0x104A +电网过压 R uint16 1:故障,0正常 0x104B +电网欠压 R uint16 1:故障,0正常 0x104C +电网过频 R uint16 1:故障,0正常 0x104D +电网欠频 R uint16 1:故障,0正常 0x104E +市电不平衡 R uint16 1:故障,0正常 0x104F +参数设置不匹配 R uint16 1:故障,0正常 0x1050 +SPI通信异常 R uint16 1:故障,0正常 0x1051 +SCI通信异常 R uint16 1:故障,0正常 0x1052 +IIC通信异常 R uint16 1:故障,0正常 0x1053 +Xintf通信异常 R uint16 1:故障,0正常 0x1054 +零偏校准异常 R uint16 1:故障,0正常 0x1055 +烟雾告警 R uint16 1:故障,0正常 0x1056 +无电池组故障 R uint16 1异常,0正常 0x1057 +环温降频 R uint16 1异常,0正常 0x1058 +交流过载 R uint16 1异常,0正常 0x1059 +采样异常 R uint16 1异常,0正常 0x105A +24V辅源故障 R uint16 1异常,0正常 0x105B +直流欠压异常 R uint16 1异常,0正常 0x105C +散热器过温 R uint16 1异常,0正常 0x105D +CAN配置故障 R uint16 1异常,0正常 0x105E +3.3V辅源故障 R uint16 1异常,0正常 0x105F +环境过温 R uint16 1异常,0正常 0x1060 +A相IGBT逆变过流 R uint16 1异常,0正常 0x1061 +B相IGBT逆变过流 R uint16 1异常,0正常 0x1062 +C相IGBT逆变过流 R uint16 1异常,0正常 0x1063 \ No newline at end of file diff --git a/bin/Release/assets/config/PCS遥测.txt b/bin/Release/assets/config/PCS遥测.txt new file mode 100644 index 0000000..2eea459 --- /dev/null +++ b/bin/Release/assets/config/PCS遥测.txt @@ -0,0 +1,78 @@ +所属主控号 R uint16 1~4 0x0001 +所属PCS号 R uint16 1~40 0x0002 +总充电量 R uint32 1kWh 0x0003 +总放电量 R uint32 1kWh 0x0005 +散热器温度 R int16 1℃ 0x0007 +内部温度 R int16 1℃ 0x0008 +最大允许充电功率 R int16 0.1kW 0x0009 +最大允许放电功率 R int16 0.1kW 0x000A +有功功率期望 R int16 1kWh 0x000B +无功功率期望 R int16 1kVar 0x000C +AB线电压 R int16 1V 0x000D +BC线电压 R int16 1V 0x000E +CA线电压 R int16 1V 0x000F +A相电压 R int16 1V 0x0010 +B相电压 R int16 1V 0x0011 +C相电压 R int16 1V 0x0012 +A相频率 R int16 1Hz 0x0013 +B相频率 R int16 1Hz 0x0014 +C相频率 R int16 1Hz 0x0015 +A相功率因数 R int16 1 0x0016 +B相功率因数 R int16 1 0x0017 +C相功率因数 R int16 1 0x0018 +A相电流 R int16 1A 0x0019 +B相电流 R int16 1A 0x001A +C相电流 R int16 1A 0x001B +A相有功功率 R int16 1kW 0x001C +B相有功功率 R int16 1kW 0x001D +C相有功功率 R int16 1kW 0x001E +A相无功功率 R int16 1kVar 0x001F +B相无功功率 R int16 1kVar 0x0020 +C相无功功率 R int16 1kVar 0x0021 +A相视在功率 R int16 1kVA 0x0022 +B相视在功率 R int16 1kVA 0x0023 +C相视在功率 R int16 1kVA 0x0024 +三相总有功功率 R int16 1kW 0x0025 +三相总无功功率 R int16 1kVar 0x0026 +三相总视在功率 R int16 1kVA 0x0027 +三相总功率因数 R int16 1 0x0028 +直流功率 R int16 1kW 0x0029 +直流电压 R int16 1V 0x002A +直流电流 R int16 1A 0x002B +充电功率 R int16 1kW 0x002C +放电功率 R int16 1kW 0x002D +PF值 R int16 1 0x002E +UV线/U相电网计量线电压 R int16 1V 0x002F +VW线/V相电网计量线电压 R int16 1V 0x0030 +WU线/W相电网计量线电压 R int16 1V 0x0031 +U相电网计量电流 R int16 1A 0x0032 +V相电网计量电流 R int16 1A 0x0033 +W相电网计量电流 R int16 1A 0x0034 +正母线电压 R int16 1V 0x0035 +可用功率 R int16 1kVA 0x0036 +负母线电压 R int16 1V 0x0037 +A相IGBT温度 R int16 1℃ 0x0038 +B相IGBT温度 R int16 1℃ 0x0039 +C相IGBT温度 R int16 1℃ 0x003A +逆变侧AB线电压 R int16 1V 0x003B +逆变侧BC线电压 R int16 1V 0x003C +逆变侧CA线电压 R int16 1V 0x003D +逆变侧A相电压 R int16 1V 0x003E +逆变侧B相电压 R int16 1V 0x003F +逆变侧C相电压 R int16 1V 0x0040 +逆变侧A相电流 R int16 1A 0x0041 +逆变侧B相电流 R int16 1A 0x0042 +逆变侧C相电流 R int16 1A 0x0043 +逆变侧A相电流直流分量 R int16 1A 0x0044 +逆变侧B相电流直流分量 R int16 1A 0x0045 +逆变侧C相电流直流分量 R int16 1A 0x0046 +离网频率 R int16 1Hz 0x0047 +A相负载量 R int16 1 0x0048 +B相负载量 R int16 1 0x0049 +C相负载量 R int16 1 0x004A +总负载量 R int16 1 0x004B +逆变侧AB线电压直流分量 R int16 1A 0x004C +逆变侧BC线电压直流分量 R int16 1A 0x004D +逆变侧CA线电压直流分量 R int16 1A 0x004E +在线数量 R int16 0x004F +逆变数量 R int16 0x0050 \ No newline at end of file diff --git a/bin/Release/assets/config/PCU遥信.txt b/bin/Release/assets/config/PCU遥信.txt new file mode 100644 index 0000000..4f371d9 --- /dev/null +++ b/bin/Release/assets/config/PCU遥信.txt @@ -0,0 +1,59 @@ +所属通道号 R uint16 1~4 0x1001 +故障状态 R uint16 1故障,0正常 0x1002 +告警状态 R uint16 1告警,0正常 0x1003 +设备在线 R uint16 1在线,0无效 0x1004 +本地远程 R uint16 1本地,0远程 0x1005 +启停状态 R uint16 1开机,0关机 0x1006 +电网状态 R uint16 1离网,0并网 0x1007 +模块状态 R uint16 1开机,0待机 0x1008 +EPO急停 R uint16 1故障,0正常 0x1009 +防雷器异常 R uint16 1告警,0正常 0x100A +负载电压反序 R uint16 1故障,0正常 0x100B +市电电压反序 R uint16 1故障,0正常 0x100C +输出相反序 R uint16 1故障,0正常 0x100D +过载告警 R uint16 1告警,0正常 0x100E +过载超时 R uint16 1故障,0正常 0x100F +交流过流保护 R uint16 1故障,0正常 0x1010 +逆变电压异常 R uint16 1故障,0正常 0x1011 +内部串口异常 R uint16 1故障,0正常 0x1012 +485通信故障 R uint16 1故障,0正常 0x1013 +CAN通信故障 R uint16 1故障,0正常 0x1014 +E2PROM故障 R uint16 1故障,0正常 0x1015 +电网过压 R uint16 1故障,0正常 0x1016 +电网欠压 R uint16 1故障,0正常 0x1017 +电网过频 R uint16 1故障,0正常 0x1018 +电网欠频 R uint16 1故障,0正常 0x1019 +电网快检综合异常 R uint16 1故障,0正常 0x101A +电网幅值快检异常 R uint16 1故障,0正常 0x101B +电网拖尾异常 R uint16 1故障,0正常 0x101C +消防输入信号NO R uint16 1闭合,0断开 0x101D +急停按钮信号NC R uint16 1急停,0正常 0x101E +避雷器NC R uint16 1故障,0正常 0x101F +避雷器断路器NC R uint16 1故障,0正常 0x1020 +PCS总断路器NC R uint16 1闭合,0断开 0x1021 +电操状态NO R uint16 1闭合,0断开 0x1022 +远程关机NO R uint16 1开机,0无效 0x1023 +远程开机NO R uint16 1开机,0无效 0x1024 +BA故障信号NO R uint16 1故障,0正常 0x1025 +PCS_01状态 R uint16 1在线,0掉线 0x1026 +PCS_02状态 R uint16 1在线,0掉线 0x1027 +PCS_03状态 R uint16 1在线,0掉线 0x1028 +PCS_04状态 R uint16 1在线,0掉线 0x1029 +PCS_05状态 R uint16 1在线,0掉线 0x102A +PCS_06状态 R uint16 1在线,0掉线 0x102B +PCS_07状态 R uint16 1在线,0掉线 0x102C +PCS_09状态 R uint16 1在线,0掉线 0x102D +PCS_10状态 R uint16 1在线,0掉线 0x102E +PCS_01下发设置 R uint16 1故障,0正常 0x102F +PCS_02下发设置 R uint16 1故障,0正常 0x1030 +PCS_03下发设置 R uint16 1故障,0正常 0x1031 +PCS_04下发设置 R uint16 1故障,0正常 0x1032 +PCS_05下发设置 R uint16 1故障,0正常 0x1033 +PCS_06下发设置 R uint16 1故障,0正常 0x1034 +PCS_07下发设置 R uint16 1故障,0正常 0x1035 +PCS_08下发设置 R uint16 1故障,0正常 0x1036 +PCS_09下发设置 R uint16 1故障,0正常 0x1037 +PCS_10下发设置 R uint16 1:故障,0正常 0x1038 +内部DSP通信故障 R uint16 1:故障,0正常 0x1039 +BMS CAN通信故障 R uint16 1:故障,0正常 0x103A +下发设置失败 R uint16 1:故障,0正常 0x103B \ No newline at end of file diff --git a/bin/Release/assets/config/PCU遥测.txt b/bin/Release/assets/config/PCU遥测.txt new file mode 100644 index 0000000..a2de26c --- /dev/null +++ b/bin/Release/assets/config/PCU遥测.txt @@ -0,0 +1,72 @@ +所属通道号 R uint16 1~4 0x0001 +充电功率最大许可 R uint32 1KW 0x0002 +放电功率最大许可 R uint32 1KW 0x0004 +交流日总充电量 R uint32 1KWh 0x0006 +交流日总放电量 R uint32 1KWh 0x0008 +交流总充电量 R uint32 1KWh 0x000A +交流总放电量 R uint32 1KWh 0x000C +有功功率期望值 R int16 1KW 0x000E +无功功率期望值 R int16 1kVar 0x000F +PCS侧线电压VAB R int16 1v 0x0010 +PCS侧线电压VBC R int16 1v 0x0011 +PCS侧线电压VCA R int16 1v 0x0012 +PCS侧线A相电压 R int16 1v 0x0013 +PCS侧线B相电压 R int16 1v 0x0014 +PCS侧线C相电压 R int16 1v 0x0015 +PCS侧A相频率 R int16 1Hz 0x0016 +PCS侧B相频率 R int16 1Hz 0x0017 +PCS侧C相频率 R int16 1Hz 0x0018 +PCS侧功率因数A R int16 1 0x0019 +PCS侧功率因数B R int16 1 0x001A +PCS侧功率因数C R int16 1 0x001B +PCS侧相电流A R int16 1A 0x001C +PCS侧相电流B R int16 1A 0x001D +PCS侧相电流C R int16 1A 0x001E +PCS侧有功功率A R int16 1kW 0x001F +PCS侧有功功率B R int16 1kW 0x0020 +PCS侧有功功率C R int16 1kW 0x0021 +PCS侧无功功率A R int16 1kVar 0x0022 +PCS侧无功功率B R int16 1kVar 0x0023 +PCS侧无功功率C R int16 1kVar 0x0024 +PCS侧视在功率A R int16 1kVar 0x0025 +PCS侧视在功率B R int16 1kVar 0x0026 +PCS侧视在功率C R int16 1kVar 0x0027 +PCS侧三相总有功功率 R int16 1kW 0x0028 +PCS侧三相总无功功率 R int16 1kVar 0x0029 + PCS侧三相总视在功率 R int16 1kVA 0x002A +PCS侧三相总功率因数 R int16 1 0x002B +PCU模块温度 R int16 1℃ 0x002C +外部温度NTC1 R int16 1℃ 0x002D +外部温度NTC2 R int16 1℃ 0x002E +外部温度NTC3 R int16 1℃ 0x002F +台区负载侧A相电流 R int16 1A 0x0030 +台区负载侧B相电流 R int16 1A 0x0031 +台区负载侧C相电流 R int16 1A 0x0032 +台区负载侧A相有功功率 R int16 1kW 0x0033 +台区负载侧B相有功功率 R int16 1kW 0x0034 +台区负载侧C相有功功率 R int16 1kW 0x0035 +台区负载侧总有功功率 R int16 1kW 0x0036 +台区负载侧A相无功功率 R int16 1kVar 0x0037 +台区负载侧B相无功功率 R int16 1kVar 0x0038 +台区负载侧C相无功功率 R int16 1kVar 0x0039 +台区负载侧总无功功率 R int16 1kVar 0x003A +台区负载侧A相视在功率 R int16 1kVA 0x003B +台区负载侧B相视在功率 R int16 1kVA 0x003C +台区负载侧C相视在功率 R int16 1kVA 0x003D +台区负载侧总视在功率 R int16 1kVA 0x003E +台区负载侧A相功率因数 R int16 1 0x003F +台区负载侧B相功率因数 R int16 1 0x0040 +台区负载侧C相功率因数 R int16 1 0x0041 +台区负载侧总功率因数 R int16 1 0x0042 +负载侧线电压AB R int16 1V 0x0043 +负载侧线电压BC R int16 1V 0x0044 +负载侧线电压CA R int16 1V 0x0045 +负载侧相电压AN R int16 1V 0x0046 +负载侧相电压BN R int16 1V 0x0047 +负载侧相电压CN R int16 1V 0x0048 +负载侧A功率因素 R int16 1 0x0049 +负载侧B功率因素 R int16 1 0x004A +负载侧C功率因素 R int16 1 0x004B +负载侧A视在功率 R int16 1kVA 0x004C +负载侧B视在功率 R int16 1kVA 0x004D +负载侧C视在功率 R int16 1kVA 0x004E \ No newline at end of file diff --git a/bin/Release/assets/config/app.json b/bin/Release/assets/config/app.json index 9bb99f7..bbc1ee3 100644 --- a/bin/Release/assets/config/app.json +++ b/bin/Release/assets/config/app.json @@ -2,5 +2,6 @@ "database": {"host": "localhost", "port": 3306, "user": "root", "passwd": "123456", "dbname": "ees"}, "token":"", "http": {"port": 19800}, - "mqtt": {"host":"tcp://localhost:1883","username":"","password":""} + "mqtt": {"host":"tcp://localhost:1883","username":"","password":""}, + "weburl": "https://map.baidu.com" } \ No newline at end of file diff --git a/bin/Release/assets/config/registeraddr.json b/bin/Release/assets/config/registeraddr.json new file mode 100644 index 0000000..2a55385 --- /dev/null +++ b/bin/Release/assets/config/registeraddr.json @@ -0,0 +1,40 @@ +{ + "EMS_YT": { + "count":1, + "addr":[ + {"key": "0x0001", "datatype": "int16", "remark": "EMS工作模式 RW u - 0:无效1:本地控制模式, EMS不接受平台调控2:平台控制模式, EMS接收平台调控指令"}, + {"key": "0x0002", "datatype": "int16", "remark": "有功功率 RW kW 并网恒功率模式下交流侧功率值:<0: 充电功率0: 静置>0: 放电功率"}, + {"key": "0x0003", "datatype": "int16", "remark": "PCS开关机 RW u - 0: 关机1: 开机 软件开关机"}, + {"key": "0x0004", "datatype": "int16", "remark": "主控对象 RW u 储能遥控对象:0:无效1:华云2:轻舟"}, + {"key": "0x0005", "datatype": "int16", "remark": "A相有功功率 RW 1kW"}, + {"key": "0x0006", "datatype": "int16", "remark": "B相有功功率 RW 1kW"}, + {"key": "0x0007", "datatype": "int16", "remark": "C相有功功率 RW 1kW"}, + {"key": "0x0008", "datatype": "int16", "remark": "三相总有功功率 RW 1kW"}, + {"key": "0x0009", "datatype": "int16", "remark": "A相无功功率 RW 1kVar"}, + {"key": "0x000A", "datatype": "int16", "remark": "B相无功功率 RW 1kVar"}, + {"key": "0x000B", "datatype": "int16", "remark": "C相无功功率 RW 1kVar"}, + {"key": "0x000C", "datatype": "int16", "remark": "三相总无功功率 RW 1kVar"}, + {"key": "0x000D", "datatype": "int16", "remark": "A相电流 RW 0.01A 在使用的时候除以100转float"}, + {"key": "0x000E", "datatype": "int16", "remark": "B相电流 RW 0.01A"}, + {"key": "0x000F", "datatype": "int16", "remark": "C相电流 RW 0.01A"}, + {"key": "0x0010", "datatype": "int16", "remark": "A相电压 RW u 1V"}, + {"key": "0x0011", "datatype": "int16", "remark": "B相电压 RW u 1V"}, + {"key": "0x0012", "datatype": "int16", "remark": "C相电压 RW u 1V"}, + {"key": "0x0013", "datatype": "int16", "remark": "A相交流功率因数 RW 0.01 在使用的时候除以100转float"}, + {"key": "0x0014", "datatype": "int16", "remark": "B相交流功率因数 RW 0.01"}, + {"key": "0x0015", "datatype": "int16", "remark": "C相交流功率因数 RW 0.01"}, + {"key": "0x0016", "datatype": "int16", "remark": "A相视在功率 RW 1kVA"}, + {"key": "0x0017", "datatype": "int16", "remark": "B相视在功率 RW 1kVA"}, + {"key": "0x0018", "datatype": "int16", "remark": "C相视在功率 RW 1kVA"}, + {"key": "0x0019", "datatype": "int16", "remark": "正向总有功总需量 RW 1kW"}, + {"key": "0x001A", "datatype": "int16", "remark": "数据有效性 RW 0无效 1有效"}, + {"key": "0x001B", "datatype": "int16", "remark": "EMS工作模式 RW u - 0:无效1:本地控制模式, EMS不接受平台调控2:平台控制模式, EMS接收平台调控指令 2413项目需求"}, + {"key": "0x001C", "datatype": "int16", "remark": "有功功率 RW u kW 并网恒功率模式下交流侧功率值:功率绝对值 没有正负 2413项目需求"}, + {"key": "0x001D", "datatype": "int16", "remark": "充放电类型 RW u - 0: 关机1: 充电2:放电3:待机 2413项目需求充放电类型"}, + {"key": "0x001E", "datatype": "int16", "remark": "最大SOC RW u 2413项目需求"}, + {"key": "0x001F", "datatype": "int16", "remark": "最小SOC RW u 2413项目需求"}, + {"key": "0x0020", "datatype": "int16", "remark": "自动并离网 RW u 0:手动1:自动 2332项目需求(若为自动,则通过主控进行并离网切换)"}, + {"key": "0x0021", "datatype": "int16", "remark": "并网离网 RW u 0:并网1:离网 2332项目需求(该下发参数的前提为手动模式下)"} + ] + } +} \ No newline at end of file diff --git a/bin/Release/assets/config/registeraddrs.py b/bin/Release/assets/config/registeraddrs.py new file mode 100644 index 0000000..53eebb2 --- /dev/null +++ b/bin/Release/assets/config/registeraddrs.py @@ -0,0 +1,77 @@ +import re +import json + +def parse_datatype(text): + datatypes = ["int16", "uint16", "int32", "uint32", "int64", "uint64"] + for index, datatype in enumerate(datatypes): + left, separator, right = text.partition(datatype) + if len(separator) != 0: + return datatype, left + right + return "", text + + +def parse_from_file(filename): + data = "" + with open(filename, "r", encoding='utf-8') as f: # 打开文件 + linedata = "" + for line in f: # 行遍历 + line = line.strip() + #linedata = f.readline() # 读取文件的一行 + flag = bool(re.search(r'0x[0-9A-Fa-f]{4}', line)) + linedata += line.strip() + if flag: + # print(linedata) + # left, separator, right = linedata.partition("0x") + parts = re.split(r'(0x[0-9A-Fa-f]{4})', linedata) + linedata = "" + + key = parts[1] + datatype, remark = parse_datatype(parts[0].strip()) + remark = remark.replace("\t", " ").replace("\"", "") + + item = {} + item["key"] = key + item["datatype"] = datatype + item["remark"] = remark + + if len(data) > 0: + data += ",\n" + data += ("\t\t\t" + json.dumps(item, ensure_ascii=False)) + return data + + +addritems = {} +addritems["EMS_YT"] = ["EMS遥调.txt", 1] +addritems["BCU_YX"] = ["BCU电池簇遥信.txt", 1] +addritems["BCU_YC"] = ["BCU电池簇遥测.txt", 1] +addritems["BMS_YC"] = ["BMS电池堆遥测.txt", 1] +addritems["EMS_YX"] = ["EMS遥信.txt", 1] +addritems["EMS_YC"] = ["EMS遥测.txt", 1] +addritems["EMS_YT"] = ["EMS遥调.txt", 1] +addritems["PCS_YX"] = ["PCS遥信.txt", 1] +addritems["PCS_YC"] = ["PCS遥测.txt", 1] +addritems["PCU_YX"] = ["PCU遥信.txt", 1] +addritems["PCU_YC"] = ["PCU遥测.txt", 1] +addritems["MEM_YC"] = ["多功能电表遥测.txt", 1] +addritems["TH_YC"] = ["温湿度状态遥测.txt", 1] +addritems["Fire40_YX"] = ["消防4.0遥信.txt", 1] +addritems["Cooling_YX"] = ["冷机遥信.txt", 1] +addritems["Cooling_YC"] = ["冷机遥测.txt", 1] + + +with open('registeraddr.json', 'w', encoding='utf-8') as f: + f.write("{") + index = 0 + for key in addritems: + filename = addritems[key][0] + count = addritems[key][1] + print("parse: ", key, filename) + data = parse_from_file(filename) + if len(data) > 0: + data = "\n" + data + "\n\t" + if index != 0: + f.write(",") + f.write("\n\t\"" + key + "\": {\n\t\t\"count\":" + str(count) + ",\n\t\t\"addr\":[" + data + "\t]\n\t}") + index+=1 + f.write("\n}") + diff --git a/bin/Release/assets/config/冷机遥信.txt b/bin/Release/assets/config/冷机遥信.txt new file mode 100644 index 0000000..f9416d2 --- /dev/null +++ b/bin/Release/assets/config/冷机遥信.txt @@ -0,0 +1,14 @@ +所属通道号 R uint16 1 0x1001 +所属冷机号 R uint16 1~10 0x1002 +开关 R uint16 0:关机,1:开机 0x1003 +采样模式 R uint16 0-出水温度 1-电芯温度 0x1004 +制冷状态 R uint16 0:关闭,1:启动 0x1005 +制热状态 R uint16 0:关闭,1:启动 0x1006 +高温告警 R uint16 0:正常,1:告警 0x1007 +低温告警 R uint16 0:正常,1:告警 0x1008 +高压告警 R uint16 0:正常,1:告警 0x1009 +低压告警 R uint16 0:正常,1:告警 0x100A +进水温度传感器 R uint16 0:正常,1:告警 0x100B +出水温度传感器 R uint16 0:正常,1:告警 0x100C +进水压力传感器 R uint16 0:正常,1:告警 0x100D +出水压力传感器 R uint16 0:正常,1:告警 0x100E \ No newline at end of file diff --git a/bin/Release/assets/config/冷机遥测.txt b/bin/Release/assets/config/冷机遥测.txt new file mode 100644 index 0000000..f01c347 --- /dev/null +++ b/bin/Release/assets/config/冷机遥测.txt @@ -0,0 +1,21 @@ +所属通道号 R uint16 1 0x0001 +所属冷机号 R uint16 1~10 0x0002 +制冷点 R int16 0.1℃ 0x0003 +制冷偏差 R int16 0.1℃ 0x0004 +高温告警值 R int16 0.1℃ 0x0005 +低温告警值 R int16 0.1℃ 0x0006 +制热点 R int16 0.1℃ 0x0007 +制热偏差 R int16 0.1℃ 0x0008 +电芯温度 R int16 0.1℃ 0x0009 +环境湿度 R int16 0.1℃ 0x000A +吸气温度 R int16 0.1℃ 0x000B +排气温度 R int16 0.1℃ 0x000C +进水温度/供液温度 R int16 0.1℃ 0x000D +出水温度/回液温度 R int16 0.1℃ 0x000E +进水压力/供液压力 R int16 0.1 0x000F +出水压力/回液压力 R int16 0.1 0x0010 +高压压力 R int16 0.1 0x0011 +低压压力 R int16 0.1 0x0012 +循环水泵转速 R int16 0x0013 +压缩机频率 R int16 0x0014 +室外风机转速 R int16 0x0015 \ No newline at end of file diff --git a/bin/Release/assets/config/多功能电表遥测.txt b/bin/Release/assets/config/多功能电表遥测.txt new file mode 100644 index 0000000..0e8242b --- /dev/null +++ b/bin/Release/assets/config/多功能电表遥测.txt @@ -0,0 +1,57 @@ +所属通道号 R uint16 1 0x0001 +电表地址 R uint16[6] 0x0002~0x0007 +电表类型 R uint16 "0:储能站总表 +1:逆变前侧电表 +2:逆变后侧电表 +3:配电柜电表 +4:并网口电表" 0x0008 +电流变比 R uint16 0x0009 +电压变比 R uint16 0x000A +A相电压 R uint32 1V 0x000B +B相电压 R uint32 1V 0x000D +C相电压 R uint32 1V 0x000F +A相电流 R int32 1A 0x0011 +B相电流 R int32 1A 0x0013 +C相电流 R int32 1A 0x0015 +AB相电压 R uint32 1V 0x0017 +BC相电压 R uint32 1V 0x0019 +CA相电压 R uint32 1V 0x001B +A相有功 R int32 1kW 0x001D +B相有功 R int32 1kW 0x001F +C相有功 R int32 1kW 0x0021 +三相总有功 R int32 1kW 0x0023 +正向总有功总需量 R int32 1kW 0x0025 +尖段电价 R uint32 1RMB 0x0027 +峰段电价 R uint32 1RMB 0x0029 +平段电价 R uint32 1RMB 0x002B +谷段电价 R uint32 1RMB 0x002D +日充电电量 R uint32 1kWh 0x002F +日放电电量 R uint32 1kWh 0x0031 +日充电费用 R uint32 1RMB 0x0033 +日放电费用 R uint32 1RMB 0x0035 +日收益 R int32 1RMB 0x0037 +日正向尖有功电能 R uint32 1kWh 0x0039 +日正向峰有功电能 R uint32 1kWh 0x003B +日正向平有功电能 R uint32 1kWh 0x003D +日正向谷有功电能 R uint32 1kWh 0x003F +日正向总有功电能 R uint32 1kWh 0x0041 +日反向尖有功电能 R uint32 1kWh 0x0043 +日反向峰有功电能 R uint32 1kWh 0x0045 +日反向平有功电能 R uint32 1kWh 0x0047 +日反向谷有功电能 R uint32 1kWh 0x0049 +日反向总有功电能 R uint32 1kWh 0x004B +总充电电量 R uint32 1kWh 0x004D +总放电电量 R uint32 1kWh 0x004F +总充电费用 R uint32 1RMB 0x0051 +总放电费用 R uint32 1RMB 0x0053 +总收益 R int32 1RMB 0x0055 +总正向尖有功电能 R uint32 1kWh 0x0057 +总正向峰有功电能 R uint32 1kWh 0x0059 +总正向平有功电能 R uint32 1kWh 0x005B +总正向谷有功电能 R uint32 1kWh 0x005D +总正向总有功电能 R uint32 1kWh 0x005F +总反向尖有功电能 R uint32 1kWh 0x0061 +总反向峰有功电能 R uint32 1kWh 0x0063 +总反向平有功电能 R uint32 1kWh 0x0065 +总反向谷有功电能 R uint32 1kWh 0x0067 +总反向总有功电能 R uint32 1kWh 0x0069 \ No newline at end of file diff --git a/bin/Release/assets/config/消防4.0遥信.txt b/bin/Release/assets/config/消防4.0遥信.txt new file mode 100644 index 0000000..4748a53 --- /dev/null +++ b/bin/Release/assets/config/消防4.0遥信.txt @@ -0,0 +1,24 @@ +所属通道号 R uint16 1~10 0x0001 +主控数量 R uint16 1 0x0002 +主控ID R uint16 1 0x0003 +主控状态 R uint16 0:正常 1:预警 2:火警 0x0004 +主控硬件版本 R uint16[2] 主控硬件版本 0x0005~0x0006 +主控软件版本 R uint16[2] 主控软件版本 0x0007~0x0008 +主电状态 R uint16 0:使用市电 1:使用备电 0x0009 +备电电流 R uint32 0.1A 0x000A +备电电压 R uint32 0.1V 0x000C +可用容量 R uint32 0.01Ah 0x000E +可充放容量 R uint32 0.01Ah 0x0010 +警铃是否使用 R uint16 0x0012 +警铃状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0013 +瓶头阀是否使用 R uint16 0x0014 +瓶头阀状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0015 +手报是否使用 R uint16 0x0016 +手报状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0017 +簇控制器数量 R uint16 0x0018 +复合探测器总数量 R uint16 0x0019 +烟雾探测器总数量 R uint16 0x001A +压力探测器总数量 R uint16 0x001B +吸气式探测器总数量 R uint16 0x001C +PACK探测器总数量 R uint16 0x001D +电池总数量 R uint16 0x001E \ No newline at end of file diff --git a/bin/Release/assets/config/温湿度状态遥测.txt b/bin/Release/assets/config/温湿度状态遥测.txt new file mode 100644 index 0000000..5ac203a --- /dev/null +++ b/bin/Release/assets/config/温湿度状态遥测.txt @@ -0,0 +1,4 @@ +所属通道号 R uint16 1 0x0001 +所属温湿度号 R uint16 1~10 0x0002 +温度 R int16 0.1℃ 0x0003 +湿度 R int16 0.1℃ 0x0004 \ No newline at end of file diff --git a/bin/Release/assets/config/空调遥信.txt b/bin/Release/assets/config/空调遥信.txt new file mode 100644 index 0000000..650f094 --- /dev/null +++ b/bin/Release/assets/config/空调遥信.txt @@ -0,0 +1,12 @@ +所属通道号 R uint16 1 0x1001 +所属空调号 R uint16 1~10 0x1002 +开关 R uint16 0:关机,1:开机 0x1003 +启动制冷指令 R uint16 0:关闭,1:启动 0x1004 +启动送风指令 R uint16 0:关闭,1:启动 0x1005 +启动待机指令 R uint16 0:关闭,1:启动 0x1006 +启动加热指令 R uint16 0:关闭,1:启动 0x1007 +传感器故障 R uint16 0:正常,1:告警 0x1008 +高低电压告警 R uint16 0:正常,1:告警 0x1009 +高低温告警 R uint16 0:正常,1:告警 0x100A +高低压告警 R uint16 0:正常,1:告警 0x100B +压缩机告警 R uint16 0:正常,1:告警 0x100C \ No newline at end of file diff --git a/bin/Release/assets/config/空调遥测.txt b/bin/Release/assets/config/空调遥测.txt new file mode 100644 index 0000000..4ca7e1c --- /dev/null +++ b/bin/Release/assets/config/空调遥测.txt @@ -0,0 +1,14 @@ +所属通道号 R uint16 1 0x0001 +所属空调号 R uint16 1~10 0x0002 +制冷点 R int16 0.1℃ 0x0003 +制冷偏差 R int16 0.1℃ 0x0004 +高温告警值 R int16 0.1℃ 0x0005 +低温告警值 R int16 0.1℃ 0x0006 +制热点 R int16 0.1℃ 0x0007 +制热偏差 R int16 0.1℃ 0x0008 +当前温度 R int16 0.1℃ 0x0009 +当前湿度 R int16 0.1℃ 0x000A +除湿开启温度 R int16 0.1℃ 0x000B +除湿停止温度 R int16 0.1℃ 0x000C +除湿开启湿度 R int16 0.1℃ 0x000D +除湿停止湿度 R int16 0.1℃ 0x000E \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1955f0d..37b8794 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,7 +18,7 @@ macro(ADD_SOURCE_GROUP srcpath) endmacro(ADD_SOURCE_GROUP) ############################################################################### -set(PROJECT_NAME EES) +set(PROJECT_NAME ESS) project(${PROJECT_NAME}) set(CMAKE_CXX_STANDARD 17) diff --git a/src/app/AppData.cpp b/src/app/AppData.cpp index df908d1..e8e3bc4 100644 --- a/src/app/AppData.cpp +++ b/src/app/AppData.cpp @@ -11,19 +11,19 @@ void ElectPeriod::parse(std::string jsonstr) { - NJsonNode jsonroot; - NJson::parse(jsonstr, jsonroot); + njson jsonroot; + JSON::parse(jsonstr, jsonroot); - NJson::read(jsonroot, "price_super_peak", this->priceSuperPeak); - NJson::read(jsonroot, "price_peak", this->pricePeak); - NJson::read(jsonroot, "price_shoulder", this->priceShoulder); - NJson::read(jsonroot, "price_off_peak", this->priceOffPeak); - NJson::read>>(jsonroot, "periods", this->vecPeriods); + JSON::read(jsonroot, "price_super_peak", this->priceSuperPeak); + JSON::read(jsonroot, "price_peak", this->pricePeak); + JSON::read(jsonroot, "price_shoulder", this->priceShoulder); + JSON::read(jsonroot, "price_off_peak", this->priceOffPeak); + JSON::read>>(jsonroot, "periods", this->vecPeriods); } std::string ElectPeriod::dump() { - NJsonNode jsonroot; + njson jsonroot; jsonroot["price_super_peak"] = this->priceSuperPeak; jsonroot["price_peak"] = this->pricePeak; jsonroot["price_shoulder"] = this->priceShoulder; @@ -40,7 +40,7 @@ void AppData::initFromDB() auto dao = DaoEntity::create(""); if (!dao->isConnected()) { - spdlog::info("Database connected error."); + spdlog::error("Init app data failed, database connected error."); return; } @@ -130,8 +130,6 @@ void AppData::initFromDB() if (station) { auto device = Device::create(fields); - auto deviceTypeDef = this->getDeviceTypeDef(device->type); - device->group = deviceTypeDef->group; station->addDevice(deviceId, device); } else @@ -278,6 +276,16 @@ std::shared_ptr AppData::getDevice(int stationId, int deviceId) return nullptr; } +std::shared_ptr AppData::getDeviceByType(int stationId, int deviceType, std::string code) +{ + auto station = getStation(stationId); + if (station) + { + return station->getDeviceByType(deviceType, code); + } + return nullptr; +} + std::string AppData::getDeviceNameById(int typeId) { auto iter = mapDeviceType.find(typeId); diff --git a/src/app/AppData.h b/src/app/AppData.h index ece7d57..f9a46df 100644 --- a/src/app/AppData.h +++ b/src/app/AppData.h @@ -73,6 +73,7 @@ public: std::shared_ptr getStationByCode(std::string code); std::shared_ptr getDevice(int stationId, int deviceId); + std::shared_ptr getDeviceByType(int stationId, int deviceType, std::string code); std::string getDeviceNameById(int typeId); diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 87358b2..db55822 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -16,6 +16,9 @@ void Application::init() // 初始化系统配置,读取配置文件 Config::init("assets/config/app.json"); + // MQTT 数据结构 + MqttClient::loadDataStruct("assets/config/registeraddr.json"); + // 设置数据库配置 DaoEntity::setOption(Config::option.database.host, Config::option.database.port, diff --git a/src/app/Config.cpp b/src/app/Config.cpp index da13feb..b1642fe 100644 --- a/src/app/Config.cpp +++ b/src/app/Config.cpp @@ -10,8 +10,8 @@ AppOption Config::option; bool Config::init(std::string filename) { - NJsonNode jsonroot; - bool ret = NJson::load(filename, jsonroot); + njson jsonroot; + bool ret = JSON::load(filename, jsonroot); if (!ret) { spdlog::error("[config] load config file failed, filename={}", filename); @@ -21,7 +21,7 @@ bool Config::init(std::string filename) if (jsonroot.contains("database")) { - NJsonNode json = jsonroot.at("database"); + njson json = jsonroot.at("database"); option.database.host = json.contains("host") ? json.at("host") : ""; option.database.port = json.contains("port") ? json.at("port") : 0; option.database.user = json.contains("user") ? json.at("user") : ""; @@ -37,11 +37,11 @@ bool Config::init(std::string filename) if (jsonroot.contains("http")) { - NJsonNode json = jsonroot.at("http"); + njson json = jsonroot.at("http"); std:string token; - NJson::read(json, "token", token); + JSON::read(json, "token", token); option.http.useToken = !token.empty(); - NJson::read(json, "port", option.http.port); + JSON::read(json, "port", option.http.port); } else { @@ -50,14 +50,20 @@ bool Config::init(std::string filename) if (jsonroot.contains("mqtt")) { - NJsonNode json = jsonroot.at("mqtt"); - NJson::read(json, "host", option.mqtt.host); - NJson::read(json, "username", option.mqtt.username); - NJson::read(json, "password", option.mqtt.password); + njson json = jsonroot.at("mqtt"); + JSON::read(json, "host", option.mqtt.host); + JSON::read(json, "username", option.mqtt.username); + JSON::read(json, "password", option.mqtt.password); } else { spdlog::info("[config] parse mqtt failed: not found."); } + + if (jsonroot.contains("weburl")) + { + JSON::read(jsonroot, "weburl", option.webSrvUrl); + } + return true; } \ No newline at end of file diff --git a/src/app/Config.h b/src/app/Config.h index 6da7a81..35e649a 100644 --- a/src/app/Config.h +++ b/src/app/Config.h @@ -26,6 +26,8 @@ struct AppOption std::string password; } mqtt; + std::string webSrvUrl; + }; class Config diff --git a/src/app/DataStruct.cpp b/src/app/DataStruct.cpp index e9f0c79..de57163 100644 --- a/src/app/DataStruct.cpp +++ b/src/app/DataStruct.cpp @@ -2,37 +2,37 @@ void EMSYX::fromJson(const std::string& str) { - NJsonNode jsonroot; - auto ret = NJson::parse(str, jsonroot); + njson jsonroot; + auto ret = JSON::parse(str, jsonroot); if (!ret) { return; } - NJson::read(jsonroot, "mcu", mcu); - NJson::read(jsonroot, "pcs", pcs); - NJson::read(jsonroot, "electMeterMainPoint", electMeterMainPoint); - NJson::read(jsonroot, "electMeter", electMeter); - NJson::read(jsonroot, "fireSystem", fireSystem); - NJson::read(jsonroot, "ups", ups); - NJson::read(jsonroot, "temHumMainPoint", temHumMainPoint); - NJson::read(jsonroot, "temHum", temHum); - NJson::read(jsonroot, "aircMainPoint", aircMainPoint); - NJson::read(jsonroot, "airc", airc); - NJson::read(jsonroot, "controlDryContact", controlDryContact); - NJson::read(jsonroot, "statusDryContact", statusDryContact); - NJson::read(jsonroot, "bcuMain", bcuMain); - NJson::read(jsonroot, "pcuMain", pcuMain); - NJson::read(jsonroot, "electMeterMain", electMeterMain); - NJson::read(jsonroot, "fireSystemMain", fireSystemMain); - NJson::read(jsonroot, "upsMain", upsMain); - NJson::read(jsonroot, "temHumMain", temHumMain); - NJson::read(jsonroot, "aircMain", aircMain); - NJson::read(jsonroot, "emu", emu); - NJson::read(jsonroot, "chillerMain", chillerMain); - NJson::read(jsonroot, "chillerMainPoint", chillerMainPoint); - NJson::read(jsonroot, "chiller", chiller); + JSON::read(jsonroot, "mcu", mcu); + JSON::read(jsonroot, "pcs", pcs); + JSON::read(jsonroot, "electMeterMainPoint", electMeterMainPoint); + JSON::read(jsonroot, "electMeter", electMeter); + JSON::read(jsonroot, "fireSystem", fireSystem); + JSON::read(jsonroot, "ups", ups); + JSON::read(jsonroot, "temHumMainPoint", temHumMainPoint); + JSON::read(jsonroot, "temHum", temHum); + JSON::read(jsonroot, "aircMainPoint", aircMainPoint); + JSON::read(jsonroot, "airc", airc); + JSON::read(jsonroot, "controlDryContact", controlDryContact); + JSON::read(jsonroot, "statusDryContact", statusDryContact); + JSON::read(jsonroot, "bcuMain", bcuMain); + JSON::read(jsonroot, "pcuMain", pcuMain); + JSON::read(jsonroot, "electMeterMain", electMeterMain); + JSON::read(jsonroot, "fireSystemMain", fireSystemMain); + JSON::read(jsonroot, "upsMain", upsMain); + JSON::read(jsonroot, "temHumMain", temHumMain); + JSON::read(jsonroot, "aircMain", aircMain); + JSON::read(jsonroot, "emu", emu); + JSON::read(jsonroot, "chillerMain", chillerMain); + JSON::read(jsonroot, "chillerMainPoint", chillerMainPoint); + JSON::read(jsonroot, "chiller", chiller); } std::string EMSYX::toJson() { - NJsonNode jsonroot; + njson jsonroot; jsonroot["bms"] = bms; jsonroot["bcu"] = bcu; jsonroot["mcu"] = mcu; diff --git a/src/app/DataStruct.h b/src/app/DataStruct.h index 1da35a6..2818bdf 100644 --- a/src/app/DataStruct.h +++ b/src/app/DataStruct.h @@ -3,12 +3,6 @@ #include #include "common/JsonN.h" -struct REGInfo -{ - std::string name; - int byte; - std::string remark; -}; // EMS遥信 struct EMSYX @@ -43,7 +37,7 @@ struct EMSYX uint16_t energyStatus; //判断总表的三相总有功 < -5.0fkW 充电 >5.0fkW放电 否则停机 R uint16 0:充电 1 : 放电 2 : 停机 储能状态 void fromJson(const std::string& str); - void toJson(); + std::string toJson(); }; // EMS遥测 diff --git a/src/app/Device.cpp b/src/app/Device.cpp index fec753a..88d2149 100644 --- a/src/app/Device.cpp +++ b/src/app/Device.cpp @@ -1,68 +1,10 @@ #include "Device.h" -#include "common/Logger.h" +#include "common/Spdlogger.h" #include "common/Utils.h" #include "protocol/CommEntity.h" #include "common/JsonN.h" -//int DeviceEntity::getAttrInt(std::string key) -//{ -// auto iter = mapAttrs.find(key); -// if (iter == mapAttrs.end()) { return 0; } -// return Utils::toInt(iter->second); -//} -// -//float DeviceEntity::getAttrFloat(std::string key) -//{ -// auto iter = mapAttrs.find(key); -// if (iter == mapAttrs.end()) { return 0.0f; } -// return Utils::toFloat(iter->second); -//} -// -//double DeviceEntity::getAttrDouble(std::string key) -//{ -// auto iter = mapAttrs.find(key); -// if (iter == mapAttrs.end()) { return 0.0; } -// return Utils::toDouble(iter->second); -//} -// -//std::string DeviceEntity::getAttrStr(std::string key) -//{ -// auto iter = mapAttrs.find(key); -// if (iter == mapAttrs.end()) { return ""; } -// return iter->second; -//} - -int Device::startComm() -{ - if (!isOpen) - { - if (commEntity && commEntity->alive) - { - commEntity->close(); - } - return 0; - } - - // 从属性列表中获取通讯方式和通讯地址、端口 - std::string commType = attrs.value("commType"); - - // 如果entity的通讯协议类型当前配置不一致,需要关闭连接删除通讯后创建新的通讯 - if (commEntity && commEntity->type != commType) - { - commEntity->close(); - commEntity = nullptr; - } - // 创建新的通讯 - if (!commEntity) - { - commEntity = CommEntity::create(attrs); - if (!commEntity) { return -1; } - } - - commEntity->start(); - return 0; -} std::shared_ptr Device::create(Fields& fields) { @@ -73,13 +15,14 @@ std::shared_ptr Device::create(Fields& fields) device->code = fields.value("code"); device->isOpen = fields.get("is_open"); device->attrsJson = fields.value("attrs"); + device->category = fields.get("category"); // 解析属性的JSON字符串,转换成键值对 - NJsonNode jsonroot; - bool ret = NJson::parse(device->attrsJson, jsonroot); + njson jsonroot; + bool ret = JSON::parse(device->attrsJson, jsonroot); if (!ret) // 解析错误 { - XLOGE() << "device attr json parse error, device_id=" << device->deviceId; + spdlog::error("[device] device attr json parse error, device_id={}", device->deviceId); } else { @@ -92,30 +35,143 @@ std::shared_ptr Device::create(Fields& fields) device->attrs.set(key, val.get()); } else { - XLOGE() << key << ": [" << valType << "]"; + spdlog::error("[device] device attr unknown type: key={}, valtype={}", key, valType); } } } + int step = 600; + for (int i = 0; i*600<86400; ++i) + { + double voltage = double(Utils::random(20000, 30000))*0.01; + double current = double(Utils::random(1000, 2000))*0.01; + device->mapCacheVoltage[i*step] = voltage; + device->mapCacheCurrent[i*step] = current; + device->mapCachePower[i*step] = voltage * current; + } + // 启动通讯,该函数中会自动判断isOpen状态,选择是否进行通讯连接 - device->startComm(); + //device->startComm(); return device; } +int Device::startComm() +{ + if (!isOpen) + { + if (commEntity && commEntity->alive) + { + commEntity->close(); + } + return 0; + } + //// 从属性列表中获取通讯方式和通讯地址、端口 + //std::string commType = attrs.value("commType"); + // + //// 如果entity的通讯协议类型当前配置不一致,需要关闭连接删除通讯后创建新的通讯 + //if (commEntity && commEntity->type != commType) + //{ + // commEntity->close(); + // commEntity = nullptr; + //} + //// 创建新的通讯 + //if (!commEntity) + //{ + // commEntity = CommEntity::create(attrs); + // if (!commEntity) { return -1; } + //} + //commEntity->start(); + return 0; +} -// -//std::vector> Device::getDeviceByType(int type) -//{ -// std::vector> vecDevice; -// for (auto iter = mapDevices.begin(); iter!=mapDevices.end(); ++iter) -// { -// auto device = iter->second; -// if (device && (type<=0 || device->type == type)) -// { -// vecDevice.push_back(device); -// } -// } -// return vecDevice; -//} \ No newline at end of file +void Device::getCacheVoltage(std::vector& vec) +{ + vec.resize(mapCacheVoltage.size()); + int i = 0; + for (auto iter = mapCacheVoltage.begin(); iter != mapCacheVoltage.end(); ++iter) + { + vec[i] = Utils::toStr(iter->second); + i++; + } +} +void Device::getCacheCurrent(std::vector& vec) +{ + vec.resize(mapCacheCurrent.size()); + int i = 0; + for (auto iter = mapCacheCurrent.begin(); iter != mapCacheCurrent.end(); ++iter) + { + vec[i] = Utils::toStr(iter->second); + i++; + } +} +void Device::getCachePower(std::vector& vec) +{ + vec.resize(mapCachePower.size()); + int i = 0; + for (auto iter = mapCachePower.begin(); iter != mapCachePower.end(); ++iter) + { + vec[i] = Utils::toStr(iter->second); + i++; + } +} + +void Device::setParam(std::string k, std::string v) +{ + mapParams[k] = v; +} + +std::string Device::getParam(std::string k, std::string defaultVal) +{ + auto iter = mapParams.find(k); + if (iter != mapParams.end()) + { + return iter->second; + } + return defaultVal; +} + +void Device::getRuntimeParams(std::vector>& params) +{ + // 3 电表 + // 101 EMS + // 102 PCS + // 103 PCU + // 104 BMS + // 105 BCU + // 106 充电桩 + // 109 光伏板 + + if (this->type == 3) + { + params.push_back({"A相电压", getParam("0x000B", "0.0") + "V"}); + params.push_back({"B相电压", getParam("0x000D", "0.0") + "V"}); + params.push_back({"C相电压", getParam("0x000F", "0.0") + "V"}); + params.push_back({"A相电流", getParam("0x0011", "0.0") + "A"}); + params.push_back({"B相电流", getParam("0x0013", "0.0") + "A"}); + params.push_back({"C相电流", getParam("0x0015", "0.0") + "A"}); + } + else if (this->type == 101) + { + params.push_back({"额定电压", getParam("0x0001", "0.0") + "V"}); + params.push_back({"实时电压", getParam("0x0001", "0.0") + "V"}); + params.push_back({"额定电流", getParam("0x0001", "0.0") + "A"}); + params.push_back({"实时电流", getParam("0x0001", "0.0") + "A"}); + params.push_back({"额定功率", getParam("0x0001", "0.0") + "kW"}); + params.push_back({"实时功率", getParam("0x0001", "0.0") + "A"}); + } + //else if (this->type == 101) + //{ + + //} + else + { + params.push_back({"额定电压", getParam("0x0001", "0.0") + "V"}); + params.push_back({"实时电压", getParam("0x0001", "0.0") + "V"}); + params.push_back({"额定电流", getParam("0x0001", "0.0") + "A"}); + params.push_back({"实时电流", getParam("0x0001", "0.0") + "A"}); + params.push_back({"额定功率", getParam("0x0001", "0.0") + "kW"}); + params.push_back({"实时功率", getParam("0x0001", "0.0") + "A"}); + } +} diff --git a/src/app/Device.h b/src/app/Device.h index bcaa76e..cd5ed36 100644 --- a/src/app/Device.h +++ b/src/app/Device.h @@ -9,20 +9,36 @@ class CommEntity; + class Device { +public: + static std::shared_ptr create(Fields& fields); + + + int startComm(); + + void getCacheVoltage(std::vector& vec); + void getCacheCurrent(std::vector& vec); + void getCachePower(std::vector& vec); + + void setParam(std::string k, std::string v); + std::string getParam(std::string k, std::string defaultVal = ""); + + void getRuntimeParams(std::vector>& params); + public: int deviceId = -1; int type = -1; std::string name; std::string code; - std::string group; + int category; bool isOpen = false; std::string attrsJson = ""; int err = 0; int online = 0; - int status = 0; + int running = 0; //std::map mapAttrs; Fields attrs; @@ -30,17 +46,9 @@ public: // 通讯entity std::shared_ptr commEntity; - //int getAttrInt(std::string key); - //float getAttrFloat(std::string key); - //double getAttrDouble(std::string key); - //std::string getAttrStr(std::string key); - - int64_t tsDataDate {}; - std::map mapCacheData; - - // 启动通讯 - int startComm(); - - static std::shared_ptr create(Fields& fields); + std::map mapCacheVoltage; + std::map mapCacheCurrent; + std::map mapCachePower; + std::map mapParams; }; diff --git a/src/app/Station.cpp b/src/app/Station.cpp index fa63d52..2121fde 100644 --- a/src/app/Station.cpp +++ b/src/app/Station.cpp @@ -42,7 +42,7 @@ void Station::setFields(Fields& fields) void Station::addDevice(int deviceId, std::shared_ptr device) { mapDevice[deviceId] = device; - mapDeviceGroupNum[device->group]++; + mapDeviceGroup[device->category].push_back(device); } std::shared_ptr Station::getDevice(int deviceId) @@ -55,32 +55,42 @@ std::shared_ptr Station::getDevice(int deviceId) return nullptr; } -void Station::getDeviceByType(int typeId, std::vector>& res) +std::shared_ptr Station::getDeviceByType(int deviceType, std::string code) { for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter) { auto device = iter->second; - if (device->type == typeId) + if (device->type == deviceType && device->code == code) + { + return device; + } + } + return nullptr; +} + +void Station::getDeviceByType(int deviceType, std::vector>& res) +{ + for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter) + { + auto device = iter->second; + if (device->type == deviceType) { res.push_back(device); } } } -int Station::getDeviceNumByGroup(std::string name) +int Station::getDeviceNumByGroup(int category) { - return mapDeviceGroupNum[name]; + return 0; } -void Station::getDeviceByGroup(std::string name, std::vector>& res) +void Station::getDeviceByGroup(int category, std::vector>& res) { - for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter) + auto iter = mapDeviceGroup.find(category); + if (iter != mapDeviceGroup.end()) { - auto device = iter->second; - if (device->group == name) - { - res.push_back(device); - } + res = iter->second; } } diff --git a/src/app/Station.h b/src/app/Station.h index 569a45d..7d80c33 100644 --- a/src/app/Station.h +++ b/src/app/Station.h @@ -96,10 +96,11 @@ public: void addDevice(int deviceId, std::shared_ptr device); std::shared_ptr getDevice(int deviceId); - + + std::shared_ptr getDeviceByType(int deviceType, std::string code); void getDeviceByType(int typeId, std::vector>& res); - int getDeviceNumByGroup(std::string name); - void getDeviceByGroup(std::string name, std::vector>& res); + int getDeviceNumByGroup(int category); + void getDeviceByGroup(int category, std::vector>& res); void setWorkMode(int modeId); void setPolicy(int policyId); @@ -169,8 +170,8 @@ public: /////////////////////////////////////////////////////////////////////////////////////////////// /// === 设备信息 === std::unordered_map> mapDevice; + std::map>> mapDeviceGroup; - std::map mapDeviceGroupNum; // 温湿度信息 std::map mapTempHumUnit; @@ -184,4 +185,6 @@ public: /////////////////////////////////////////////////////////////////////////////////////////////// /// === MQTT client std::shared_ptr mqttCli {nullptr}; + + }; \ No newline at end of file diff --git a/src/app/errcode.h b/src/app/errcode.h index 32e9721..07f756f 100644 --- a/src/app/errcode.h +++ b/src/app/errcode.h @@ -4,22 +4,21 @@ enum class Errcode { - OK = 0, - ERR = 1, - ERR_TOKEN, // TOKEN错误 - ERR_PARAM, // 参数错误 - ERR_PARAM_NUL, // 缺少参数 - ERR_DATA_NUL, // 数据不存在 + OK = 0, // 成功 + ERR = 1, // 系统错误 + ERR_TOKEN = 2, // TOKEN错误 + ERR_PARAM = 3, // 参数错误 + ERR_PARAM_NUL = 4, // 缺少参数 + ERR_DATA_NUL = 5, // 数据不存在 ERR_USER = 100, - ERR_LOGIN_USER_NOTEXIST, // 登入错误,用户不存在 - ERR_LOGIN_PASSWD, // 登入错误,密码不正确 + ERR_LOGIN_USER_NOTEXIST = 101, // 登入错误,用户不存在 + ERR_LOGIN_PASSWD = 102, // 登入错误,密码不正确 ERR_DEVICE = 200, - ERR_DB_CONN = 1001, // 数据库连接错误 - + ERR_DB_CONN = 1001, // 数据库连接错误 ERR_DB_DUPLICATE = 1062, // Duplicate entry for key ERR_DB_SQL = 1064, // 数据库查询SQL错误 ERR_DB_VAL = 1366, // 1366,Incorrect decimal value,通常为参数值错误,例如空值、值类型错误 diff --git a/src/common/Fields.cpp b/src/common/Fields.cpp index b580ddc..56130dd 100644 --- a/src/common/Fields.cpp +++ b/src/common/Fields.cpp @@ -57,9 +57,10 @@ void Fields::clear() void Fields::check(string key, string val, string d) { - if (mapFields.count(key) > 0 && mapFields[key] == val) + auto iter = mapFields.find(key); + if (iter != mapFields.end() && iter->second == val) { - mapFields[key] = d; + iter->second = d; } } @@ -182,8 +183,8 @@ string Fields::toSqlUpdate(string tableName, std::vector vecKeys, s void Fields::parseJson(std::string jsonstr) { - NJsonNode jsonroot; - NJson::parse(jsonstr, jsonroot); + njson jsonroot; + JSON::parse(jsonstr, jsonroot); for (auto& item : jsonroot.items()) { this->set(item.key(), item.value()); diff --git a/src/common/JsonN.cpp b/src/common/JsonN.cpp new file mode 100644 index 0000000..ee92cd7 --- /dev/null +++ b/src/common/JsonN.cpp @@ -0,0 +1,68 @@ +#include "JsonN.h" +#include "common/Utils.h" + +bool JSON::load(std::string jsonfile, njson& json) +{ + std::ifstream ifs(jsonfile); + if (!ifs.is_open()) { return false; } + try { ifs >> json; } + catch (nlohmann::json::parse_error& e) { return false; } + return true; +} + +bool JSON::parse(std::string jsonstr, njson& json) +{ + try + { + if (!jsonstr.empty()) { json = njson::parse(jsonstr); } + } + catch (nlohmann::json::parse_error& e) + { + std::cout << "JSON parse error: " << e.what() << "\n" << jsonstr << std::endl; + return false; + } + return true; +} + +std::string JSON::readStr(njson& json, std::string k) +{ + std::string v; + try + { + if (json.contains(k)) + { + switch (json[k].type()) + { + case njson::value_t::string: { v = json[k].get(); } break; + case njson::value_t::boolean: { v = Utils::toStr(json[k].get()); } break; + case njson::value_t::number_integer: { v = Utils::toStr(json[k].get()); } break; + case njson::value_t::number_unsigned: { v = Utils::toStr(json[k].get()); } break; + case njson::value_t::number_float: { v = Utils::toStr(json[k].get()); } break; + case njson::value_t::null: {} { v = "null"; } break; + case njson::value_t::object: {} break; + case njson::value_t::array: {} break; + case njson::value_t::binary: {} break; + case njson::value_t::discarded: {} break; + default: + break; + } + + if (json.is_number()) { v = json.at(k).get(); } + else if (json.is_string()) { v = json.at(k).get(); } + } + } + catch (const nlohmann::detail::exception& e) + { + std::cout << "JSON read error: k=" << k << ", err=" << e.what() << std::endl; + } + return v; +} + +void JSON::parse(std::string jsonstr, std::vector& vd) +{ + njson jsonroot; + if (JSON::parse(jsonstr, jsonroot)) + { + vd = jsonroot.get>(); + } +} \ No newline at end of file diff --git a/src/common/JsonN.h b/src/common/JsonN.h index 7b42ca2..b24485d 100644 --- a/src/common/JsonN.h +++ b/src/common/JsonN.h @@ -5,7 +5,7 @@ #include #include -using NJsonNode = nlohmann::json; +using njson = nlohmann::json; /// ============================================================================================= /// 使用说明: @@ -48,34 +48,16 @@ using NJsonNode = nlohmann::json; // std::vector v1; // v1 = j.at["data"].get>() -class NJson +class JSON { public: - static bool load(std::string jsonfile, NJsonNode& json) - { - std::ifstream ifs(jsonfile); - if (!ifs.is_open()) { return false; } - try { ifs >> json; } - catch (nlohmann::json::parse_error& e) { return false; } - return true; - } + static bool load(std::string jsonfile, njson& json); - static bool parse(std::string jsonstr, NJsonNode& json) - { - try - { - if (!jsonstr.empty()) { json = NJsonNode::parse(jsonstr); } - } - catch (nlohmann::json::parse_error& e) - { - std::cout << "JSON parse error: " << e.what() << "\n" << jsonstr << std::endl; - return false; - } - return true; - } + + static bool parse(std::string jsonstr, njson& json); template - static void read(NJsonNode& json, std::string k, T& v) + static void read(njson& json, std::string k, T& v) { try { @@ -87,14 +69,10 @@ public: } } - static void parse(std::string jsonstr, std::vector& vd) - { - NJsonNode jsonroot; - if (NJson::parse(jsonstr, jsonroot)) - { - vd = jsonroot.get>(); - } - } + static std::string readStr(njson& json, std::string k); + + static void parse(std::string jsonstr, std::vector& vd); + }; diff --git a/src/common/Utils.h b/src/common/Utils.h index c90b588..5d20ed0 100644 --- a/src/common/Utils.h +++ b/src/common/Utils.h @@ -39,11 +39,11 @@ public: memcpy_s(&dest[start], len, &src, len); } - // 获取当前时间的时间戳(毫秒) + // 获取当前时间的时间戳(秒) static int64_t time(std::string s=""); // 获取当前时间的格式字符串 static string timeStr(int64_t ts=0, std::string fmt = "%Y-%m-%d %H:%M:%S"); - // 获取当前日期的时间戳(毫秒) + // 获取当前日期的时间戳(秒) static int64_t date(); // 获取当前日期的格式字符串 static string dateStr(int64_t ts = 0, std::string fmt = "%Y-%m-%d %H:%M:%S"); diff --git a/src/database/Dao.cpp b/src/database/Dao.cpp index 46bf095..0e39fbc 100644 --- a/src/database/Dao.cpp +++ b/src/database/Dao.cpp @@ -111,6 +111,7 @@ static Errcode QueryPagination(std::string sqlFields, std::string sqlCondition, } if (page.index < 1) page.index = 1; + if (page.size <= 0) page.size = 10; page.total = count; std::string sql = "SELECT " + sqlFields + " " + sqlCondition + DAO::sqlPageLimit(page.index -1, page.size); int ret = dao.exec(sql, result); @@ -143,19 +144,21 @@ Errcode DAO::insertUser(Fields& params) params.set(DMUser::USER_ID, Snowflake::instance().getIdStr()); params.set(DMUser::CREATETIME, createTime); params.set(DMUser::PASSWD, "123456"); + std::string userRoleId = params.remove(DMRole::ROLE_ID); ret = dao->insertFields(params); if (ret != 0) { return Errcode(ret); } - std::string userRoleId = params.remove(DMRole::ROLE_ID); + if (!userRoleId.empty()) { Fields paramsUserRole; paramsUserRole.set(DMUser::USER_ID, params.value(DMUser::USER_ID)); paramsUserRole.set(DMRole::ROLE_ID, userRoleId); paramsUserRole.set(DMUser::UPDATETIME, createTime); + dao->setTableName(DMUserRole::TABLENAME); ret = dao->duplicateUpdate(paramsUserRole, {DMUser::USER_ID}); } return Errcode::OK; @@ -211,19 +214,20 @@ Errcode DAO::login(std::shared_ptr dao, std::string account, std::str Errcode DAO::queryRolePermission(std::shared_ptr dao, int roleId, vector& result) { - std::string sql = "SELECT rp.role_id, rp.permission_id, p.name FROM role_permission rp" - " LEFT JOIN permission p ON p.permission_id = rp.permission_id" - " WHERE rp.is_open='1' AND rp.role_id ='" + std::to_string(roleId) + "';"; + std::string sql = R"(SELECT rp.role_id, p.permission_id, p.parent_id, p.route, p.name, rp.is_view, rp.is_add, rp.is_edit, rp.is_del + FROM role_permission rp + LEFT JOIN permission p ON p.permission_id = rp.permission_id + WHERE rp.is_open='1' AND rp.role_id =')" + std::to_string(roleId) + "';"; return DAO::exec(dao, sql, result); } Errcode DAO::queryRolePermission(std::shared_ptr dao, vector& result) { // 查询 role 的 permission - std::string sql = "SELECT rp.role_id, rp.permission_id, rp.is_open, r.name role_name, p.name permission_name FROM role_permission rp" - " LEFT JOIN `role` r ON r.role_id = rp.role_id" - " LEFT JOIN permission p ON p.permission_id = rp.permission_id" - " WHERE rp.is_open='1';"; + std::string sql = R"(SELECT rp.role_id, r.name role_name, rp.permission_id, p.parent_id, p.route, p.name, rp.is_view, rp.is_add, rp.is_edit, rp.is_del FROM role_permission rp + LEFT JOIN `role` r ON r.role_id = rp.role_id + LEFT JOIN permission p ON p.permission_id = rp.permission_id + WHERE rp.is_open='1';)"; return DAO::exec(dao, sql, result); } @@ -317,29 +321,14 @@ Errcode DAO::queryRoleList(PageInfo& pageInfo, vector& result) return QueryPagination("*", sqlCondition, pageInfo, result); } -Errcode DAO::updateRolePermission(std::shared_ptr dao, std::string roleId, std::string permission) +Errcode DAO::updateRolePermission(std::shared_ptr dao, std::string roleId, vector& vecFields) { - NJsonNode jnode; - NJson::parse(permission, jnode); - std::vector vec; - for (auto& item: jnode) - { - std::string permissionId; - if (item.is_number()) { permissionId = std::to_string(item.get()); } - if (item.is_string()) { permissionId = item.get(); } - if (!permissionId.empty()) - { - Fields field; - field.set("role_id", roleId); - field.set("permission_id", permissionId); - vec.emplace_back(field); - } - } + if (!dao) dao = DaoEntity::create(""); dao->setTableName(DMRolePermission::TABLENAME); std::string sqlDel = "DELETE from " + DMRolePermission::TABLENAME + " WHERE role_id='" + roleId + "';"; int ret = dao->exec(sqlDel); if (ret != 0 ){ return Errcode(ret); }; - ret = dao->insertFields(vec); + ret = dao->insertFields(vecFields); if (ret != 0) { return Errcode(ret); }; return Errcode::OK; } @@ -360,29 +349,31 @@ Errcode DAO::insertRole(Fields& params) err = DAO::exec(dao, sql, res); if (err == Errcode::OK && res.size() > 0) { - std::string roleId = res[0].value("role_id"); - err = DAO::updateRolePermission(dao, roleId, permission); + //std::string roleId = res[0].value("role_id"); + //err = DAO::updateRolePermission(dao, roleId, permission); } } return err; } // 更新角色 -Errcode DAO::updateRoleById(Fields& params) +Errcode DAO::updateRoleById(std::shared_ptr dao, Fields& params) { + if (!dao) dao = DaoEntity::create(""); + dao->setTableName(DMRole::TABLENAME); + auto roleId = params.value(DMRole::ROLE_ID); if (roleId.empty()) { return Errcode::ERR_DB_SQL; } auto permission = params.remove("permission"); - - auto dao = DaoEntity::create(DMRole::TABLENAME); + auto err = DAO::update(dao, DMRole::TABLENAME, params, DMRole::ROLE_ID); - if (err == Errcode::OK && !permission.empty()) - { - err = DAO::updateRolePermission(dao, roleId, permission); - } + //if (err == Errcode::OK && !permission.empty()) + //{ + // err = DAO::updateRolePermission(dao, roleId, permission); + //} return err; } @@ -426,7 +417,7 @@ Errcode DAO::updateStationById(Fields& params) // 查询设备信息列表 Errcode DAO::queryDeviceList(std::shared_ptr dao, vector& result) { - std::string sql = "SELECT * FROM " + DMDevice::TABLENAME; + std::string sql = "SELECT d.*, ddt.category FROM device d LEFT JOIN def_device_type ddt ON d.`type`=ddt.device_type_id;"; return DAO::exec(dao, sql, result); } diff --git a/src/database/Dao.h b/src/database/Dao.h index e8ecfd0..48e24f4 100644 --- a/src/database/Dao.h +++ b/src/database/Dao.h @@ -44,7 +44,7 @@ public: static Errcode deletePermissionById(std::string userId); - static Errcode updateRolePermission(std::shared_ptr dao, std::string roleId, std::string permission); + static Errcode updateRolePermission(std::shared_ptr dao, std::string roleId, vector& vecFields); // 查询角色列表(分页) static Errcode queryRoleList(PageInfo& pageInfo, vector& result); @@ -54,7 +54,7 @@ public: // 新增角色 static Errcode insertRole(Fields& params); // 更新角色 - static Errcode updateRoleById(Fields& params); + static Errcode updateRoleById(std::shared_ptr dao, Fields& params); // 删除角色 static Errcode deleteRoleById(std::string userId); diff --git a/src/database/DaoEntity.cpp b/src/database/DaoEntity.cpp index 5fdcd27..b97959c 100644 --- a/src/database/DaoEntity.cpp +++ b/src/database/DaoEntity.cpp @@ -12,18 +12,18 @@ DaoEntity::DaoEntity(string tb_name) //opts.password = "123456"; //opts.port = 3306; //opts.dbname = "pvb"; - db_ = make_shared(DaoEntity::option); - if (!db_->isConnected()) + db = make_shared(DaoEntity::option); + if (!db->isConnected()) { //Global::data().status_msg = "数据库连接异常!"; //PvInstance::send_user_event(nullptr, EUserEvent::ALARM_DB, "数据库连接异常!"); } - tableName_ = tb_name; + tableName = tb_name; } DaoEntity::~DaoEntity() { - db_ = nullptr; + db = nullptr; } MysqlOption& DaoEntity::mysqlOption() @@ -58,34 +58,34 @@ bool DaoEntity::execOnce(string sql, vector& result) void DaoEntity::setTableName(string tb_name) { - tableName_ = tb_name; + tableName = tb_name; } bool DaoEntity::isConnected() { - return db_->isConnected(); + return db->isConnected(); } int DaoEntity::exec(string sql) { - return db_->exec(sql); + return db->exec(sql); } int DaoEntity::exec(string sql, vector& result) { - return db_->exec(sql, result); + return db->exec(sql, result); } int DaoEntity::insertFields(Fields& fields) { - string sql = fields.toSqlInsert(tableName_); - return this->db_->exec(sql); + string sql = fields.toSqlInsert(tableName); + return this->db->exec(sql); } int DaoEntity::insertFields(vector& vec_fields) { //"insert into TABLE () values ()"; - string sql = "insert into " + tableName_; + string sql = "insert into " + tableName; bool first = true; string keys; string values; @@ -100,16 +100,10 @@ int DaoEntity::insertFields(vector& vec_fields) const string& v = item.second; if (first) { - if (!keys.empty()) - { - keys += ","; - } + if (!keys.empty()) { keys += ","; } keys += k; } - if (!values.empty()) - { - values += ","; - } + if (!values.empty()) { values += ","; } values += ("'" + v + "'"); } if (first) @@ -124,7 +118,7 @@ int DaoEntity::insertFields(vector& vec_fields) } } sql += ";"; - return this->db_->exec(sql); + return this->db->exec(sql); } int DaoEntity::duplicateUpdate(Fields& fields, const vector& keys) @@ -150,8 +144,8 @@ int DaoEntity::duplicateUpdate(Fields& fields, const vector& keys) } str += (k + "='" + fields.value(k) + "'"); } - string sql = "INSERT INTO " + tableName_ + "(" + key + ") VALUES (" + val + ") ON duplicate KEY UPDATE " + str; - return this->db_->exec(sql); + string sql = "INSERT INTO " + tableName + "(" + key + ") VALUES (" + val + ") ON duplicate KEY UPDATE " + str; + return this->db->exec(sql); } //void DaoEntity::queryFields(const string& condition, DaoPageinfo& pageinfo, vector>& result) @@ -164,18 +158,18 @@ int DaoEntity::duplicateUpdate(Fields& fields, const vector& keys) int DaoEntity::queryFields(string keys, const string& condition, vector& result) { ostringstream oss; - oss << "SELECT " + keys + " FROM " << tableName_ << (" " + condition) << "; "; - return this->db_->exec(oss.str(), result); + oss << "SELECT " + keys + " FROM " << tableName << (" " + condition) << "; "; + return this->db->exec(oss.str(), result); } int DaoEntity::queryFields(string keys, const string& condition, PageInfo& page, vector& result) { int err = 0; ostringstream oss; - oss << "SELECT count(1) total FROM `" << tableName_ << "` " << condition << ";"; + oss << "SELECT count(1) total FROM `" << tableName << "` " << condition << ";"; vector res_total; - if (err = this->db_->exec(oss.str().c_str(), res_total)) + if (err = this->db->exec(oss.str().c_str(), res_total)) { return err; } @@ -192,23 +186,20 @@ int DaoEntity::queryFields(string keys, const string& condition, PageInfo& page, } oss.str(""); - if (page.index <= 0) - { - page.index = 1; - } + if (page.index <= 0) { page.index = 1; } int start = (page.index - 1) * page.size; - oss << "SELECT " << keys << " FROM `" << tableName_ << "` " << condition << " LIMIT " << start << "," << page.size << ";"; - return this->db_->exec(oss.str().c_str(), result); + oss << "SELECT " << keys << " FROM `" << tableName << "` " << condition << " LIMIT " << start << "," << page.size << ";"; + return this->db->exec(oss.str().c_str(), result); } int DaoEntity::updateFields(Fields& fields, const string& condition) { - string sql = fields.toSqlUpdate(tableName_, condition); - return this->db_->exec(sql); + string sql = fields.toSqlUpdate(tableName, condition); + return this->db->exec(sql); } int DaoEntity::updateFields(Fields& fields, vector vecKeys, const string& condition) { - string sql = fields.toSqlUpdate(tableName_, vecKeys, condition); - return this->db_->exec(sql); + string sql = fields.toSqlUpdate(tableName, vecKeys, condition); + return this->db->exec(sql); } \ No newline at end of file diff --git a/src/database/DaoEntity.h b/src/database/DaoEntity.h index 9bc208a..ec41271 100644 --- a/src/database/DaoEntity.h +++ b/src/database/DaoEntity.h @@ -103,10 +103,10 @@ protected: static MysqlOption option; // mysql 数据库操作对象 - std::shared_ptr db_ = nullptr; + std::shared_ptr db = nullptr; // 数据库表名称 - string tableName_; + string tableName; }; #endif // !!! _DaoBase_H_ diff --git a/src/main.cpp b/src/main.cpp index ffa931a..03e6fa3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,6 +30,9 @@ #include #include "DataStruct.h" +#include +#include + #define wsa rlwsa void rlSocketTest() { @@ -118,8 +121,9 @@ void memberJsonTest() //std::cout << to << std::endl; } + int main(int argc, char** argv) -{ +{ // 设置控制台输出为 UTF-8 编码 SetConsoleOutputCP(CP_UTF8); // 设置控制台输入为 UTF-8 编码(如果需要输入中文) @@ -128,6 +132,8 @@ int main(int argc, char** argv) Spdlogger::init(spdlog::level::debug, ""); spdlog::info("[main] start ... ======================================================================"); + spdlog::info(""); + std::cout << Snowflake::instance().getId() << std::endl; for (int i = 0; i<=10; ++i) { std::cout << Snowflake::instance().getId() << std::endl; @@ -136,33 +142,42 @@ int main(int argc, char** argv) // 运行后台服务 Application::instance().init(); - { - //REGInfo reg; - //std::string s = "BMS(电池堆)通信状态 R uint16 \"0:正常1:故障\" bit位从低到高分别对应1~16 0x2001"; - //int pos; - //if (std::string::npos != (pos = s.find("\t0x"))) - //{ - // reg.name = s.substr(pos+1); - // s = s.substr(0, pos); - // std::cout << reg.name << std::endl; - //} - //if (std::string::npos != (pos = s.find("\t"))) - //{ - // reg.remark = s.substr(0, pos); - // s = s.substr(pos+1); - // std::cout << reg.remark << std::endl; - //} - //if (std::string::npos != (pos = s.find("uint"))) - //{ - // std::string bytename = s.substr(pos, 6); - // std::cout << bytename << std::endl; - // s = s.substr(pos+6); - //} - //std::cout << s << std::endl; - //std::cout << s << std::endl; - - } + // 启动 PV 服务主线程 + std::thread([=]() + { + // 运行pv主流程 + PARAM p; + int s; + pvInit(argc, argv, &p); + /* here you may interpret ac,av and set p->user to your data */ + while (1) + { + s = pvAccept(&p); + if (s != -1) pvCreateThread(&p, s); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + }).detach(); + QApplication qapp(argc, argv); + + QMainWindow mainWin; + mainWin.setWindowTitle("光储充站监控与运营管理平台"); + mainWin.setGeometry(0, 0, 1920, 1080); + QWebEngineView webView; + webView.setGeometry(0, 0, 1920, 1080); + // 默认设置透明, 解决加载时的白屏闪烁 + webView.page()->setBackgroundColor(Qt::transparent); + webView.setContextMenuPolicy(Qt::NoContextMenu); + webView.load(QUrl(Config::option.webSrvUrl.c_str())); + //webView.load(QUrl("file:///assets/html/main.html")); + //connect(wWebView.get(), &QWebEngineView::loadFinished, this, &MyWidget::slotLoadFinished); + //std::string htmlContent = "HelloWorld"; + //webView->setHtml(htmlContent.c_str(), QUrl("file:///assets/html/")); + webView.show(); + mainWin.setCentralWidget(&webView); + + mainWin.show(); + qapp.exec(); // 运行QT主窗口 //QApplication qapp(argc, argv); @@ -171,16 +186,5 @@ int main(int argc, char** argv) //mainWin.resize(1920, 1080); //mainWin.show(); //qapp.exec(); - - // 运行pv主流程 - PARAM p; - int s; - pvInit(argc, argv, &p); - /* here you may interpret ac,av and set p->user to your data */ - while(1) - { - s = pvAccept(&p); - if(s != -1) pvCreateThread(&p,s); - } return 0; } \ No newline at end of file diff --git a/src/protocol/HttpEntity.cpp b/src/protocol/HttpEntity.cpp index f93f148..3de980d 100644 --- a/src/protocol/HttpEntity.cpp +++ b/src/protocol/HttpEntity.cpp @@ -7,21 +7,56 @@ #include "app/AppData.h" #include "app/Config.h" #include "app/Station.h" +#include "app/Device.h" -static void FieldsToJson(Fields& fields, NJsonNode& json) +static void FieldsToJson(Fields& fields, njson& json) { for (auto& item : fields.map()) { json[item.first] = item.second; } } - -static NJsonNode FieldsToJsonArray(std::vector& vecFields) +static void JsonToFields(njson& json, std::vector vecKeys, Fields& fields) { - NJsonNode jsonnode = NJsonNode::array(); + if (vecKeys.empty()) + { + for (auto& item: json.items()) + { + auto key = item.key(); + auto& val = json[key]; + } + } + + for (auto& key : vecKeys) + { + if (json.contains(key)) { + + switch (json[key].type()) + { + case njson::value_t::string: { fields.set(key, json[key].get()); } break; + case njson::value_t::boolean: { fields.set(key, json[key].get()); } break; + case njson::value_t::number_integer: { fields.set(key, json[key].get()); } break; + case njson::value_t::number_unsigned: { fields.set(key, json[key].get()); } break; + case njson::value_t::number_float: { fields.set(key, json[key].get()); } break; + case njson::value_t::null: {} break; + case njson::value_t::object: {} break; + case njson::value_t::array: {} break; + case njson::value_t::binary: {} break; + case njson::value_t::discarded: {} break; + default: + break; + } + + } + } +} + +static njson FieldsToJsonArray(std::vector& vecFields) +{ + njson jsonnode = njson::array(); for (auto& fields : vecFields) { - NJsonNode jnode; + njson jnode; for (auto& item : fields.map()) { jnode[item.first] = item.second; @@ -33,7 +68,6 @@ static NJsonNode FieldsToJsonArray(std::vector& vecFields) static void GetRequestParam(const httplib::Request& req, const std::vector& vecKeys, Fields& fields) { - if (req.method == "GET") { for (auto& key : vecKeys) @@ -46,32 +80,10 @@ static void GetRequestParam(const httplib::Request& req, const std::vector()); } break; - case NJsonNode::value_t::boolean: { fields.set(key, json[key].get()); } break; - case NJsonNode::value_t::number_integer: { fields.set(key, json[key].get()); } break; - case NJsonNode::value_t::number_unsigned: { fields.set(key, json[key].get()); } break; - case NJsonNode::value_t::number_float: { fields.set(key, json[key].get()); } break; - case NJsonNode::value_t::null: {} break; - case NJsonNode::value_t::object: {} break; - case NJsonNode::value_t::array: {} break; - case NJsonNode::value_t::binary: {} break; - case NJsonNode::value_t::discarded: {} break; - default: - break; - } - - } - } + njson json; + JSON::parse(req.body, json); + JsonToFields(json, vecKeys, fields); } - } class HttpHelper @@ -82,7 +94,16 @@ public: errmsg = ""; for (auto& key : vecKeys) { - if (!req.has_param(key)) + bool hasParam = false; + if (req.method == "GET") + { + hasParam = req.has_param(key); + } + else + { + hasParam = (req.body.find("\"" + key + "\"") != std::string::npos); + } + if (!hasParam) { if (!errmsg.empty()) { errmsg += ","; } errmsg += "缺少参数[" + key + "]"; @@ -94,7 +115,7 @@ public: } return true; } - static void setPagination(PageInfo& pageinfo, std::vector result, NJsonNode& json) + static void setPagination(PageInfo& pageinfo, std::vector result, njson& json) { json["count"] = pageinfo.total; json["page"] = pageinfo.index; @@ -103,20 +124,7 @@ public: } }; -using HandlerFunc = Errcode(HttpEntity::*)(const httplib::Request& req, httplib::Response& resp, NJsonNode& jnode); -struct HandlerOptions -{ - HandlerFunc func; - std::vector requiredKeys; - std::vector keys; - - - HandlerOptions(HandlerFunc func, const std::vector& requiredKeys) - : func(func), requiredKeys(requiredKeys) - { - } -}; static std::map g_mapHttpHandlerGet = { @@ -134,14 +142,18 @@ static std::map g_mapHttpHandlerGet = {"/deleteStation", HandlerOptions(&HttpEntity::deleteStation, { DMStation::STATION_ID})}, {"/queryStationInfo", HandlerOptions(&HttpEntity::queryStationInfo, { DMStation::STATION_ID})}, - {"/queryStationRuntime", HandlerOptions(&HttpEntity::queryStationRuntime, { DMStation::STATION_ID})}, + {"/queryStationData", HandlerOptions(&HttpEntity::queryStationData, { DMStation::STATION_ID})}, + {"/queryStationOverview", HandlerOptions(&HttpEntity::queryStationOverview, {DMStation::STATION_ID})}, + {"/queryDeviceList", HandlerOptions(&HttpEntity::queryDeviceList, {})}, {"/deleteDevice", HandlerOptions(&HttpEntity::deleteDevice, { DMDevice::DEVICE_ID})}, {"/queryDevicTypeDef", HandlerOptions(&HttpEntity::queryDevicTypeDef, {})}, + {"/queryDevicByCategory", HandlerOptions(&HttpEntity::queryDevicByCategory, {DMStation::STATION_ID, "category"})}, + {"/queryDevicCharts", HandlerOptions(&HttpEntity::queryDevicCharts, {DMStation::STATION_ID, "device_id"})}, - {"/queryPolicyList", HandlerOptions(&HttpEntity::queryPolicyList, {})}, + {"/queryPolicyList", HandlerOptions(&HttpEntity::queryPolicyList, {})}, {"/deletePolicy", HandlerOptions(&HttpEntity::deletePolicy, { DMPolicy::POLICY_ID})}, @@ -157,6 +169,10 @@ static std::map g_mapHttpHandlerGet = {"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})}, {"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})}, + + + {"/queryServiceApiList", HandlerOptions(&HttpEntity::queryServiceApiList, {})}, + {"/deleteServiceApi", HandlerOptions(&HttpEntity::deleteServiceApi, {"api_id"})}, //{"/insert", HandlerOptions(&HttpEntity::insert, {})}, //{"/update", HandlerOptions(&HttpEntity::update, {})}, @@ -182,6 +198,9 @@ static std::map g_mapHttpHandlerPost {"/insertPolicy", HandlerOptions(&HttpEntity::insertPolicy, { DMPolicy::NAME})}, {"/updatePolicy", HandlerOptions(&HttpEntity::updatePolicy, { DMPolicy::POLICY_ID})}, + + {"/insertServiceApi", HandlerOptions(&HttpEntity::insertServiceApi, {})}, + {"/updateServiceApi", HandlerOptions(&HttpEntity::updateServiceApi, {"api_id"})}, }; bool CheckHttpToken(const httplib::Request& req) @@ -202,70 +221,22 @@ bool CheckHttpToken(const httplib::Request& req) HttpEntity::HttpEntity() { - bool useToken = Config::option.http.useToken; for (auto& item : g_mapHttpHandlerGet) { std::string name = item.first; HandlerOptions& handler = item.second; this->httpsvr.Get(name, [=, &handler](const httplib::Request& req, httplib::Response& resp) { - spdlog::info("[http] request: {}", name); - Errcode errcode = Errcode::OK; - if (name != "/login" && useToken) - { - bool ret = CheckHttpToken(req); - errcode = ret ? Errcode::OK : Errcode::ERR_TOKEN; - } - - NJsonNode json; - std::string errmsg; - if (errcode == Errcode::OK) - { - if (!HttpHelper::CheckRequestParam(req, resp, handler.requiredKeys, errmsg)) - { - errcode = Errcode::ERR_PARAM; - } - else - { - errcode = (this->*(handler.func))(req, resp, json); - } - } - json["errcode"] = errcode; - json["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg)); - resp.set_content(json.dump(), "text/plain; charset=utf-8"); - resp.status = 200; + this->runHandler(name, handler, req, resp); }); } - for (auto& item : g_mapHttpHandlerPost) { std::string name = item.first; HandlerOptions& handler = item.second; this->httpsvr.Post(name, [=](const httplib::Request& req, httplib::Response& resp) { - Errcode errcode = Errcode::OK; - std::string errmsg; - if (name != "/login" && useToken) - { - bool ret = CheckHttpToken(req); - errcode = ret ? Errcode::OK : Errcode::ERR_TOKEN; - } - - if (errcode == Errcode::OK) - { - NJsonNode jsonparam; - bool ret = NJson::parse(req.body, jsonparam); - if (ret) - { - errcode = (this->*(handler.func))(req, resp, jsonparam); - } - } - - NJsonNode json; - json["errcode"] = errcode; - json["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg)); - resp.set_content(json.dump(), "text/plain; charset=utf-8"); - resp.status = 200; + this->runHandler(name, handler, req, resp); }); } } @@ -277,12 +248,43 @@ void HttpEntity::listen(std::string addr, int port) httpsvr.listen(addr, port); // 阻塞 } +void HttpEntity::runHandler(std::string name, const HandlerOptions& handler, const httplib::Request& req, httplib::Response& resp) +{ + spdlog::info("[http] request: {}", name); + bool useToken = Config::option.http.useToken; + Errcode errcode = Errcode::OK; + std::string errmsg; + + if (name != "/login" && useToken) + { + bool ret = CheckHttpToken(req); + errcode = ret ? Errcode::OK : Errcode::ERR_TOKEN; + } + + njson jsonresp; + if (errcode == Errcode::OK) + { + if (!HttpHelper::CheckRequestParam(req, resp, handler.requiredKeys, errmsg)) + { + errcode = Errcode::ERR_PARAM; + } + else + { + errcode = (this->*(handler.func))(req, jsonresp, errmsg); + } + } + jsonresp["errcode"] = errcode; + jsonresp["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg)); + resp.set_content(jsonresp.dump(), "text/plain; charset=utf-8"); + resp.status = 200; +} + void HttpEntity::registGet(std::string name, void (HttpEntity::* func)(const httplib::Request& req, httplib::Response& resp)) { this->httpsvr.Get(name, std::bind(func, this, std::placeholders::_1, std::placeholders::_2)); } -Errcode HttpEntity::login(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::login(const httplib::Request& req, njson& json, std::string& errmsg) { std::string userId; std::string token; @@ -302,16 +304,21 @@ Errcode HttpEntity::login(const httplib::Request& req, httplib::Response& resp, int roleId = fields.get(DMRole::ROLE_ID); DAO::queryRolePermission(dao, roleId, vecPermission); - NJsonNode jnode = NJsonNode::array(); - for (auto& item : vecPermission) { jnode.push_back(item.value("name")); } - json["permission"] = jnode; + njson nodePermission = njson::array(); + for (auto& item : vecPermission) + { + njson node; + FieldsToJson(item, node); + nodePermission.push_back(node); + } + json["permission"] = nodePermission; } DAO::insertSystemLogUser(token, "用户登录:" + ErrcodeStr(err), (err==Errcode::OK) ? 0: 1); return err; } -Errcode HttpEntity::queryUserList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryUserList(const httplib::Request& req, njson& json, std::string& errmsg) { std::string token = req.get_param_value("token"); PageInfo pageinfo; @@ -328,27 +335,27 @@ Errcode HttpEntity::queryUserList(const httplib::Request& req, httplib::Response return err; } -Errcode HttpEntity::insertUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::insertUser(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params); return DAO::insertUser(params); } -Errcode HttpEntity::updateUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updateUser(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; - GetRequestParam(req, {"user_id", "name", "gender", "age", "phone", "email", "role_id"}, params); + GetRequestParam(req, {"user_id", "account", "name", "gender", "age", "phone", "email", "role_id"}, params); return DAO::updateUserById(params); } -Errcode HttpEntity::deleteUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::deleteUser(const httplib::Request& req, njson& json, std::string& errmsg) { std::string userId = req.get_param_value("user_id"); return DAO::deleteUserById(userId); } -Errcode HttpEntity::queryPermissionList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryPermissionList(const httplib::Request& req, njson& json, std::string& errmsg) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); @@ -360,28 +367,28 @@ Errcode HttpEntity::queryPermissionList(const httplib::Request& req, httplib::Re return err; } -Errcode HttpEntity::insertPermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::insertPermission(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"name", "describe", "is_open"}, params); return DAO::insertPermission(params); } -Errcode HttpEntity::updatePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updatePermission(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"permission_id", "name", "describe", "is_open"}, params); return DAO::updatePermissionById(params); } -Errcode HttpEntity::deletePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::deletePermission(const httplib::Request& req, njson& json, std::string& errmsg) { std::string permissionId = req.get_param_value("permission_id"); return DAO::deletePermissionById(permissionId); } -Errcode HttpEntity::queryRoleList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std::string& errmsg) { std::string token = req.get_param_value("page"); PageInfo pageinfo; @@ -400,15 +407,14 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, httplib::Response return err; } - std::map> mapPermission; - for (auto& item: vecPermission) + std::map> mapPermission; + for (auto& fields: vecPermission) { - std::string roleId = item.value("role_id"); + std::string roleId = fields.value("role_id"); auto& v = mapPermission[roleId]; - NJsonNode jnode; - jnode["id"] = item.value("permission_id"); - jnode["name"] = item.value("permission_name"); - v.push_back(jnode); + njson node; + FieldsToJson(fields, node); + v.push_back(node); } HttpHelper::setPagination(pageinfo, result, json); @@ -424,25 +430,55 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, httplib::Response return err; } -Errcode HttpEntity::insertRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::insertRole(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"name", "describe", "is_open", "permission"}, params); return DAO::insertRole(params); }; -Errcode HttpEntity::updateRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updateRole(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; - GetRequestParam(req, {"role_id", "name", "describe", "is_open", "permission"}, params); - return DAO::updateRoleById(params); + //GetRequestParam(req, {"role_id", "name", "describe", "is_open", "permission"}, params); + + njson jsonparam; + if (!JSON::parse(req.body, jsonparam)) + { + return Errcode::ERR_PARAM; + } + JsonToFields(jsonparam, {"role_id", "name", "describe", "is_open"}, params); + + auto roleId = params.value("role_id"); + + auto dao = DaoEntity::create(""); + auto err = DAO::updateRoleById(dao, params); + if (err == Errcode::OK && jsonparam.contains("permission")) + { + if (jsonparam["permission"].is_array()) + { + + auto& jsonPermission = jsonparam["permission"]; + std::vector vecFields(jsonPermission.size()); + int i = 0; + for (auto& item: jsonPermission) + { + auto& fields = vecFields[i]; + i++; + JsonToFields(item, {"permission_id", "is_add", "is_del", "is_edit", "is_view"}, fields); + fields.set("role_id", roleId); + } + err = DAO::updateRolePermission(dao, roleId, vecFields); + } + } + return err; }; -Errcode HttpEntity::deleteRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::deleteRole(const httplib::Request& req, njson& json, std::string& errmsg) { std::string roleId = req.get_param_value(DMRole::ROLE_ID); return DAO::remove(NULL, DMRole::TABLENAME, DMRole::ROLE_ID, roleId); }; -Errcode HttpEntity::queryStationList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStationList(const httplib::Request& req, njson& json, std::string& errmsg) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); @@ -454,7 +490,7 @@ Errcode HttpEntity::queryStationList(const httplib::Request& req, httplib::Respo return err; }; -Errcode HttpEntity::insertStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::insertStation(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; @@ -462,20 +498,84 @@ Errcode HttpEntity::insertStation(const httplib::Request& req, httplib::Response return DAO::insertStation(params); }; -Errcode HttpEntity::updateStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updateStation(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"station_id", "name", "address", "lon", "lat", "tel", "capacity", "status"}, params); + params.check("capacity", "", "0.0"); + params.check("lon", "", "0.0"); + params.check("lat", "", "0.0"); + params.check("status", "", "1"); return DAO::updateStationById(params); }; -Errcode HttpEntity::deleteStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::deleteStation(const httplib::Request& req, njson& json, std::string& errmsg) { std::string primaryKey = DMStation::STATION_ID; return DAO::remove(NULL, DMStation::TABLENAME, primaryKey, req.get_param_value(primaryKey)); }; -Errcode HttpEntity::queryStationInfo(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStationOverview(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(req, {"station_id"}, params); + std::string stationId = params.value("station_id"); + if (stationId.empty()) + { + return Errcode::ERR_PARAM; + } + + auto dao = DaoEntity::create(""); + std::vector result; + + // 运行模式 + std::string sql = "SELECT * FROM station WHERE station_id='" + stationId + "';"; + int ret = dao->exec(sql, result); + if (ret != 0) + { + return Errcode(ret); + } + if (result.size() > 0) + { + json["data"]["work_mode"] = result[0].get("work_mode"); + } + + // 储能设备:总功率,数量 + // 充电设备:总功率,数量 + // 光伏设备:总功率,数量 + sql = R"(SELECT d.`type`, count(1) count, ddt.name typename, ddt.category FROM device d + LEFT JOIN def_device_type ddt ON ddt.device_type_id=d.`type` WHERE d.station_id=')" + stationId + "' GROUP BY `type`;"; + ret = dao->exec(sql, result); + if (ret != 0) + { + return Errcode(ret); + } + njson jsonStorage = njson::parse(R"({"category":1, "count":0, "power":0.0})"); + njson jsonCharge = njson::parse(R"({"category":2, "count":0, "power":0.0})"); + njson jsonSolar = njson::parse(R"({"category":3, "count":0, "power":0.0})"); + njson jsonSecurity = njson::parse(R"({"category":4, "count":0, "power":0.0})"); + for (auto& fields : result) + { + int category = fields.get("category"); + int count = fields.get("count"); + switch (category) + { + case 1: { jsonStorage["count"] = jsonStorage["count"].get() + count; } break; + case 2: { jsonCharge["count"] = jsonCharge["count"].get() + count; } break; + case 3: { jsonSolar["count"] = jsonSolar["count"].get() + count; } break; + case 4: { jsonSecurity["count"] = jsonSecurity["count"].get() + count; } break; + default: + break; + } + } + + // 从运行数据中读取功率信息(待补充) + + json["data"]["device_group"] = {jsonStorage, jsonCharge, jsonSolar, jsonSecurity}; + return Errcode::OK; +} + +Errcode HttpEntity::queryStationInfo(const httplib::Request& req, njson& json, std::string& errmsg) { // 查询场站的基础配置信息 std::string stationId = req.get_param_value("station_id"); @@ -497,9 +597,9 @@ Errcode HttpEntity::queryStationInfo(const httplib::Request& req, httplib::Respo } auto& fields = result[0]; - NJsonNode jsondata; + njson jsondata; std::string attr = fields.remove(DMStation::ATTR); - NJson::parse(attr, jsondata); + JSON::parse(attr, jsondata); FieldsToJson(fields, jsondata); json["data"] = jsondata; @@ -514,10 +614,10 @@ Errcode HttpEntity::queryStationInfo(const httplib::Request& req, httplib::Respo // voltage_rated: 电池额定电压: // power_rated: PCS额定功率 } -Errcode HttpEntity::queryStationData(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStationData(const httplib::Request& req, njson& json, std::string& errmsg) { // 温度, 电压、电流、功率、功率因数、 - NJsonNode jsondata; + njson jsondata; jsondata["voltage"] = Utils::toStr(200.32); jsondata["current"] = Utils::toStr(20.56); jsondata["power"] = Utils::toStr(200.32); @@ -531,7 +631,7 @@ Errcode HttpEntity::queryStationData(const httplib::Request& req, httplib::Respo return Errcode::OK; } -Errcode HttpEntity::queryDeviceList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryDeviceList(const httplib::Request& req, njson& json, std::string& errmsg) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); @@ -543,24 +643,24 @@ Errcode HttpEntity::queryDeviceList(const httplib::Request& req, httplib::Respon return err; }; -Errcode HttpEntity::insertDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params); return DAO::insertDevice(params); }; -Errcode HttpEntity::updateDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updateDevice(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params); return DAO::updateDeviceById(params); }; -Errcode HttpEntity::deleteDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::deleteDevice(const httplib::Request& req, njson& json, std::string& errmsg) { std::string primaryKey = DMDevice::DEVICE_ID; return DAO::remove(NULL, DMDevice::TABLENAME, primaryKey, req.get_param_value(primaryKey)); }; -Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, njson& json, std::string& errmsg) { std::string sql = "SELECT device_type_id, name FROM def_device_type;"; std::vector result; @@ -568,8 +668,78 @@ Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, httplib::Resp json["data"] = FieldsToJsonArray(result); return err; } +Errcode HttpEntity::queryDevicByCategory(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(req, {"station_id", "category"}, params); + if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; } + if (!params.contains("category")) { errmsg = "缺少参数[category]"; return Errcode::ERR_PARAM; } -Errcode HttpEntity::queryPolicyList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) + int stationId = params.get("station_id"); + int category = params.get("category"); + + njson jsondata = njson::array(); + auto station = Application::data().getStation(stationId); + if (station) + { + std::vector> vecDevice; + station->getDeviceByGroup(category, vecDevice); + + for(auto& device: vecDevice) + { + njson jsonnode; + jsonnode["stationId"] = stationId; + jsonnode["category"] = category; + jsonnode["device_id"] = device->deviceId; + jsonnode["name"] = device->name; + jsonnode["code"] = device->code; + jsonnode["type"] = device->type; + jsonnode["typename"] = Application::data().getDeviceNameById(device->type); + jsonnode["view"] = 1; + + jsonnode["is_online"] = device->online;// ? "在线" : "离线"; + jsonnode["is_error"] = device->err;// ? "故障" : "正常"; + jsonnode["is_running"] = device->running;// ? "工作" : "空闲"; + + njson jsonarrayParams = njson::array(); + VecPairSS vec; + device->getRuntimeParams(vec); + for (auto& item: vec) + { + jsonarrayParams.push_back({{"k", item.first}, {"v", item.second}}); + } + + jsonnode["params"] = jsonarrayParams; + jsondata.push_back(jsonnode); + } + } + json["data"] = jsondata; + return Errcode::OK; +} + +Errcode HttpEntity::queryDevicCharts(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(req, {"station_id", "device_id"}, params); + if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; } + if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; } + + int stationId = params.get("station_id"); + int deviceId = params.get("device_id"); + auto device = Application::data().getDevice(stationId, deviceId); + + std::vector vecV, vecI, vecP; + if (device) + { + device->getCacheVoltage(vecV); + device->getCacheCurrent(vecI); + device->getCachePower(vecP); + } + json["data"] = {{"V", vecV}, {"I", vecI}, {"P", vecP}}; + return Errcode::OK; +} + +Errcode HttpEntity::queryPolicyList(const httplib::Request& req, njson& json, std::string& errmsg) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); @@ -580,24 +750,26 @@ Errcode HttpEntity::queryPolicyList(const httplib::Request& req, httplib::Respon HttpHelper::setPagination(pageinfo, result, json); return err; }; -Errcode HttpEntity::insertPolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::insertPolicy(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"type", "name", "describe", "value", "is_open"}, params); return DAO::insertPolicy(params); }; -Errcode HttpEntity::updatePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updatePolicy(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"policy_id", "type", "describe", "value", "is_open"}, params); return DAO::updatePolicyById(params); }; -Errcode HttpEntity::deletePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::deletePolicy(const httplib::Request& req, njson& json, std::string& errmsg) { - return DAO::deletePolicyById(req.get_param_value("prolicy_id")); + Fields params; + GetRequestParam(req, {"policy_id"}, params); + return DAO::deletePolicyById(params.value("policy_id")); }; -Errcode HttpEntity::querySystemLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); @@ -610,14 +782,14 @@ Errcode HttpEntity::querySystemLogList(const httplib::Request& req, httplib::Res } //Errcode insertSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); -Errcode HttpEntity::updateSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updateSystemLog(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"log_id", "status"}, params); return DAO::updateSystemLogById(params); } -Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); @@ -630,37 +802,43 @@ Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, httplib::Resp } //Errcode insertAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); -Errcode HttpEntity::updateAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::updateAlertLog(const httplib::Request& req, njson& json, std::string& errmsg) { Fields params; GetRequestParam(req, {"log_id", "status"}, params); return DAO::updateAlertLogById(params); } -Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, njson& json, std::string& errmsg) { - NJsonNode jsonData = NJsonNode::array(); - for (int i = 1; i<=5; i++) + njson jsonData = njson::array(); + + std::vector vecStoreIn(144), vecStoreOut(144), vecCharge(144), vecSolar(144), vecSolarP(144); + for (int i = 0; i<144; ++i) { - NJsonNode jnode; - jnode["datatype"] = i; - NJsonNode jsonValues = NJsonNode::array(); - for (int i = 0; i<1440; ++i) - { - jsonValues.push_back(float(Utils::random(50, 100))); - } - jnode["values"] = jsonValues; - jsonData.push_back(jnode); + vecStoreIn[i] = Utils::toStr(float(Utils::random(50, 100))); + vecStoreOut[i] = Utils::toStr(float(Utils::random(50, 100))); + vecCharge[i] = Utils::toStr(float(Utils::random(50, 100))); + vecSolar[i] = Utils::toStr(float(Utils::random(50, 100))); + vecSolarP[i] = Utils::toStr(float(Utils::random(50, 100))); } + json["data"] = jsonData; + json["data"] = { + {"W_store_in", vecStoreIn}, + {"W_store_out", vecStoreOut}, + {"W_charge", vecCharge}, + {"W_solar", vecSolar}, + {"P_solar", vecSolarP } + }; return Errcode::OK; } -Errcode HttpEntity::queryStatSystem(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg) { auto& appdata = Application::data(); - NJsonNode jsondata; + njson jsondata; jsondata["launch_date"] = "2025-01-01"; //: 系统上线启用日期,格式:yyyy-mm-dd jsondata["income_total"] = std::to_string(Utils::random(100, 200)); // : 累计收益(元),精度0.01 jsondata["station_num"] = Utils::toStr(appdata.getStationCount()); // : 能源站数量 @@ -675,12 +853,12 @@ Errcode HttpEntity::queryStatSystem(const httplib::Request& req, httplib::Respon json["data"] = jsondata; return Errcode::OK; } -Errcode HttpEntity::queryStatTotal(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg) { std::string station_id = req.get_param_value("station_id"); std::string category = req.get_param_value("category"); - NJsonNode jsondata; + njson jsondata; jsondata["station_id"] = "1"; jsondata["launch_date"] = "2025-01-01"; //场站上线日期 jsondata["usage_rate"] = "12"; @@ -695,17 +873,17 @@ Errcode HttpEntity::queryStatTotal(const httplib::Request& req, httplib::Respons jsondata["charge_elect"] = "123.123"; //充电设备充电电量(kWh),精度:0.001 jsondata["charge_num"] = "1"; //充电设备充电次数 jsondata["charge_num_err"] = "1"; //充电设备故障次数 - jsondata["income_elect"] = "123.123"; //发电收益(元),精度:0.01 - jsondata["income_charge"] = "123.123"; //充电收益(元),精度:0.01 + jsondata["income_elect"] = "123.123"; //发电收益(元),精度:0.01 + jsondata["income_charge"] = "123.123"; //充电收益(元),精度:0.01 json["data"] = jsondata; return Errcode::OK; } -Errcode HttpEntity::queryStatStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStatStation(const httplib::Request& req, njson& json, std::string& errmsg) { std::string station_id = req.get_param_value("station_id"); std::string category = req.get_param_value("category"); - NJsonNode jsondata; + njson jsondata; jsondata["station_id"] = "1"; jsondata["launch_date"] = "2025-01-01"; //场站上线日期 jsondata["usage_rate"] = "12"; @@ -727,7 +905,7 @@ Errcode HttpEntity::queryStatStation(const httplib::Request& req, httplib::Respo return Errcode::OK; } -Errcode HttpEntity::queryStatDayList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg) { std::string station_id = req.get_param_value("station_id"); std::string category = req.get_param_value("category"); @@ -738,10 +916,10 @@ Errcode HttpEntity::queryStatDayList(const httplib::Request& req, httplib::Respo int64_t t2 = Utils::time(dt_end)/1000; int64_t tMax = t1+ 86400 * 30; - NJsonNode jsondata = NJsonNode::array(); + njson jsondata = njson::array(); for (int64_t t = t1; t<=t2 && t<=tMax; t += 86400) { - NJsonNode jnode; + njson jnode; jnode["station_id"] = station_id; if (!category.empty()) jnode["category"] = category; jnode["dt"] = Utils::dateStr(t*1000); //日期 @@ -765,7 +943,7 @@ Errcode HttpEntity::queryStatDayList(const httplib::Request& req, httplib::Respo return Errcode::OK; } -Errcode HttpEntity::queryEnvironment(const httplib::Request& req, httplib::Response& resp, NJsonNode& json) +Errcode HttpEntity::queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg) { std::string stationId = req.get_param_value("station_id"); auto& appdata = Application::data(); @@ -777,15 +955,15 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, httplib::Respo return Errcode::ERR_PARAM; } - NJsonNode jsondata; + njson jsondata; { // 温湿度 auto& mapTempHumUnit = station->mapTempHumUnit; - NJsonNode nodearray = NJsonNode::array(); + njson nodearray = njson::array(); for (auto iter = mapTempHumUnit.begin(); iter!=mapTempHumUnit.end(); iter++) { auto& unit = iter->second; - NJsonNode node; + njson node; node["pos"] = "#" + std::to_string(iter->first); node["temp"] = unit.temp; node["hum"] = unit.hum; @@ -797,10 +975,10 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, httplib::Respo auto& mapAircUnit = station->mapAircUnit; AircUnit unitTmp; AircUnit* unit = (mapAircUnit.size() > 0) ? &(mapAircUnit[0]) : &unitTmp; - NJsonNode nodearray = NJsonNode::array(); + njson nodearray = njson::array(); if (unit) { - NJsonNode node; + njson node; nodearray.push_back({{"pos", "开关"}, {"status", unit->powerOn == 0 ? "关机" : "开机"}}); nodearray.push_back({{"pos", "启动制冷指令"}, {"status", unit->cooling == 0 ? "启动" : "关闭"}}); nodearray.push_back({{"pos", "启动送风指令"}, {"status", unit->airSupply == 0 ? "关闭" : "启动"}}); @@ -820,10 +998,10 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, httplib::Respo static std::map mapFireStatusDef = { {0, "正常"}, {1,"预警"}, {2,"火警"} }; auto& mapFire40Unit = station->mapFire40Unit; - NJsonNode nodearray = NJsonNode::array(); + njson nodearray = njson::array(); for (auto iter = mapFire40Unit.begin(); iter!=mapFire40Unit.end(); ++iter) { - NJsonNode node; + njson node; node["pos"] = "#" + std::to_string(iter->first); node["status"] = mapFireStatusDef[iter->second]; // 0:正常 1:预警 2:火警 nodearray.push_back(node); @@ -834,10 +1012,10 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, httplib::Respo auto& mapCoolingUnit = station->mapCoolingUnit; CoolingUnit unitTmp; CoolingUnit* unit = (mapCoolingUnit.size() > 0) ? &(mapCoolingUnit[0]) : &unitTmp; - NJsonNode nodearray = NJsonNode::array(); + njson nodearray = njson::array(); if (unit) { - NJsonNode node; + njson node; nodearray.push_back({{"pos", "开关"}, {"status", unit->powerOn == 0 ? "关机" : "开机"}}); nodearray.push_back({{"pos", "采样模式"}, {"status", unit->mode == 0 ? "出水温度" : "电芯温度"}}); nodearray.push_back({{"pos", "制冷状态"}, {"status", unit->cooling == 0 ? "关闭" : "启动"}}); @@ -851,4 +1029,42 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, httplib::Respo } json["data"] = jsondata; return Errcode::OK; +} + + +Errcode HttpEntity::queryServiceApiList(const httplib::Request& req, njson& json, std::string& errmsg) +{ + PageInfo pageinfo; + pageinfo.index = Utils::toInt(req.get_param_value("page")); + pageinfo.size = Utils::toInt(req.get_param_value("page_size")); + std::vector result; + std::string sql = "SELECT * FROM serviceapi;" ; + auto err = DAO::exec(NULL, sql, result); + HttpHelper::setPagination(pageinfo, result, json); + return err; +} + +Errcode HttpEntity::insertServiceApi(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(req, {"name", "describe", "params", "is_open"}, params); + if (params.size() == 0) { return Errcode::ERR_PARAM; } + + return DAO::insert(NULL, "serviceapi", params); +} + +Errcode HttpEntity::updateServiceApi(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(req, {"api_id", "name", "describe", "params", "is_open"}, params); + if (params.size() == 0) { return Errcode::ERR_PARAM; } + + return DAO::update(NULL, "serviceapi", params, "api_id"); +} + +Errcode HttpEntity::deleteServiceApi(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(req, {"api_id"}, params); + return DAO::remove(NULL, "serviceapi", "api_id", params.value("api_id")); } \ No newline at end of file diff --git a/src/protocol/HttpEntity.h b/src/protocol/HttpEntity.h index 1f8dd44..4eff86b 100644 --- a/src/protocol/HttpEntity.h +++ b/src/protocol/HttpEntity.h @@ -1,6 +1,22 @@ -#include "httplib.h" +#include "httplib.h" #include "common/JsonN.h" #include "errcode.h" +#include + +class HttpEntity; +using HandlerFunc = Errcode(HttpEntity::*)(const httplib::Request& req, njson& jnode, std::string& errmsg); + +struct HandlerOptions +{ + HandlerFunc func; + std::vector requiredKeys; + std::vector keys; + + HandlerOptions(HandlerFunc func, const std::vector& requiredKeys) + : func(func), requiredKeys(requiredKeys) + { + } +}; class HttpEntity { @@ -8,61 +24,71 @@ public: httplib::Server httpsvr; HttpEntity(); void listen(std::string addr, int port); + void runHandler(std::string name, const HandlerOptions& handler, const httplib::Request& req, httplib::Response& resp); void registGet(std::string name, void (HttpEntity::* func)(const httplib::Request& req, httplib::Response& resp)); //void onGet(const httplib::Request& req, httplib::Response& resp); - Errcode login(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode login(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryUserList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode insertUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updateUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode deleteUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryUserList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertUser(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updateUser(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deleteUser(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryPermissionList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode insertPermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updatePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode deletePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryPermissionList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertPermission(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updatePermission(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deletePermission(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryRoleList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode insertRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updateRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode deleteRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryRoleList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertRole(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updateRole(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deleteRole(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryStationList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode insertStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updateStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode deleteStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryStationList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertStation(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updateStation(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deleteStation(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryStationInfo(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode queryStationData(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryStationOverview(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryStationInfo(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryStationData(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryDeviceList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode insertDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updateDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode deleteDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode queryDevicTypeDef(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryDeviceList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertDevice(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updateDevice(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deleteDevice(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryDevicTypeDef(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryDevicByCategory(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryDevicCharts(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryPolicyList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode insertPolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updatePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode deletePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryPolicyList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertPolicy(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updatePolicy(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deletePolicy(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode querySystemLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg); //Errcode insertSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updateSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode updateSystemLog(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryAlertLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg); //Errcode insertAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode updateAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode updateAlertLog(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryPredictionDetail(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryPredictionDetail(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryStatSystem(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode queryStatTotal(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode queryStatStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); - Errcode queryStatDayList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryStatStation(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryEnvironment(const httplib::Request& req, httplib::Response& resp, NJsonNode& json); + Errcode queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg); + + + Errcode queryServiceApiList(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode insertServiceApi(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode updateServiceApi(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode deleteServiceApi(const httplib::Request& req, njson& json, std::string& errmsg); }; \ No newline at end of file diff --git a/src/protocol/MqttEntity.cpp b/src/protocol/MqttEntity.cpp index 9fefcbe..ee3b7a3 100644 --- a/src/protocol/MqttEntity.cpp +++ b/src/protocol/MqttEntity.cpp @@ -1,9 +1,58 @@ #include "MqttEntity.h" #include "common/Spdlogger.h" -#include "common/JsonN.h" +#include "common/Utils.h" +#include "app/Application.h" +#include "app/AppData.h" +#include "app/Station.h" +#include "app/Device.h" #define TIMEOUT 10000L +std::string REGAddrOffset(std::string addr, int offset) +{ + unsigned int val; + std::stringstream ss; + ss << std::hex << addr; + ss >> val; + return Utils::toHexStr(val + offset); +} + +static std::map> g_mapRegInfo; + +void MqttClient::loadDataStruct(std::string filename) +{ + njson json; + JSON::load(filename, json); + + // 遍历 JSON 对象 + for (auto& jsonitem : json.items()) + { + std::string name = jsonitem.key(); + auto jsonnodeItem = jsonitem.value(); + int count = jsonnodeItem["count"]; + auto jsonaddrs = jsonnodeItem["addr"]; + + auto& mapItem = g_mapRegInfo[name]; + int size = 0; + for (int i = 0; i<2; ++i) + { + for (auto& item : jsonaddrs) + { + std::string addr = item["key"]; + if (i > 0) + { + addr = REGAddrOffset(addr, size*i); + } + mapItem[addr] = REGInfo(addr, item["datatype"], item["remark"]); + if (i ==0) + { + size += mapItem[addr].bytes; + } + } + } + } +} + int MqttClient::init(string addr, string clientId, string username, string password) { this->addr = addr; @@ -28,7 +77,8 @@ int MqttClient::init(string addr, string clientId, string username, string passw int rc {0}; // "tcp://localhost:1883" - rc = MQTTAsync_create(&client, addr.c_str(), clientId.c_str(), MQTTCLIENT_PERSISTENCE_NONE, NULL); + std::string str = "ESS-" + std::to_string(Utils::random(1000, 9999)) + "-" +clientId; + rc = MQTTAsync_create(&client, addr.c_str(), str.c_str(), MQTTCLIENT_PERSISTENCE_NONE, NULL); if (rc != MQTTASYNC_SUCCESS) { spdlog::error("[mqtt] MQTTAsync_create error: {}", rc); @@ -87,10 +137,10 @@ int MqttClient::init(string addr, string clientId, string username, string passw void MqttClient::destory() { + return; if (client) { MQTTAsync_destroy(&client); - client = nullptr; } } @@ -154,7 +204,7 @@ int MqttClient::publish(string topic, string text) void MqttClient::onConnectionLost(char* cause) { this->isConnected = false; - this->destory(); + //this->destory(); spdlog::error("MQTT connection lost, cause={}", cause); } @@ -165,7 +215,12 @@ std::string GetSubStr(std::string c, std::string& str) if (pos != string::npos) { v = str.substr(0, pos); - str = str.substr(pos); + str = str.substr(pos+1); + } + else + { + v = str; + str = ""; } return v; } @@ -184,15 +239,70 @@ int MqttClient::onMessageArrived(char* topic, int topicLen, MQTTAsync_message* m std::string command = GetSubStr("/", topicStr); std::string deviceCode = GetSubStr("/", topicStr); - if (command == "EMS_YX") {} - else if (command == "EMS_YC") {} - else if (command == "PCU_YX") { this->parsePCU_YX(payload); } - else if (command == "PCU_YC") {} + + njson json; + bool ret = JSON::parse(payload, json); + if (!ret) + { + spdlog::error("[mqtt] json parse error."); + return 1; + } + auto station = Application::data().getStation(Utils::toInt(stationId)); + if (!station) + { + spdlog::error("[mqtt] get station error, clientId={}, stationId={}", clientId, stationId); + return 1; + } + + auto iter = g_mapRegInfo.find(command); + if (iter == g_mapRegInfo.end()) + { + spdlog::error("[mqtt] get register add info error, clientId={}, stationId={}, command={}", clientId, stationId, command); + return 1; + } + std::map& mapRegInfo = iter->second; + + int deviceNo = -1; + JSON::read(json, "no", deviceNo); + auto device = station->getDeviceByType(101, Utils::toStr(deviceNo)); + if (!device) + { + return 1; + } + + for (auto& item: json.items()) + { + std::string key = item.key(); + if (key != "ts" && key != "no") + { + auto data = json.at(key); + if (data.is_array()) + { + auto iter = mapRegInfo.find(key); + for (int i = 0; ifirst; + device->setParam(addr, JSON::readStr(data[i], addr)); + ++iter; + } + } + } + else if (data.is_number()) + { + device->setParam(key, Utils::toStr(data.get())); + } + else if (data.is_string()) + { + device->setParam(key, Utils::toStr(data.get())); + } + } + } // 必须释放消息内存! MQTTAsync_freeMessage(&msg); MQTTAsync_free(topic); - return 1; // 1表示消息已经处理 } @@ -205,7 +315,7 @@ void MqttClient::onDeliveryComplete(MQTTAsync_token token) void MqttClient::onConnectSuccess( MQTTAsync_successData* resp) { - spdlog::info("[mqtt] connect to {} success.", addr); + spdlog::info("[mqtt] connect to {} success, clientId={}.", addr, clientId); this->isConnected = true; this->subscribe(); //MQTTAsync_responseOptions options = MQTTAsync_responseOptions_initializer; @@ -234,23 +344,164 @@ void MqttClient::onConnectSuccess( MQTTAsync_successData* resp) } void MqttClient::onConnectFaiure(MQTTAsync_failureData* resp) { - spdlog::error("[mqtt] connect to {} error.", addr); + spdlog::error("[mqtt] connect to {} error, clientId={}.", addr, clientId); this->isConnected = false; this->destory(); } - -void MqttClient::parseEMS_YC(std::string& text) +void MqttClient::parseEMS_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo) { + int deviceNo = -1; + JSON::read(json, "no", deviceNo); + auto device = station->getDeviceByType(101, Utils::toStr(deviceNo)); + if (!device) + { + return; + } -} -void MqttClient::parsePCU_YX(std::string& text) -{ + for (auto& item: json.items()) + { + std::string key = item.key(); + if (key != "ts" && key != "no") + { + auto data = json.at(key); + if (data.is_array()) + { + auto iter = mapRegInfo.find(key); + for (int i = 0; ifirst; + device->mapParams[addr] = JSON::readStr(data[i], addr); + ++iter; + } + } + } + else if (data.is_number()) + { + device->mapParams[key] = Utils::toStr(data.get()); + } + else if (data.is_string()) + { + device->mapParams[key] = Utils::toStr(data.get()); + } + } + } } -string MQTT::packEquipmentInfo() +string MQTT::pack(std::string name) { - NJsonNode jsonroot; - return jsonroot.dump(); + njson json; + json["ts"] = Utils::time(); + json["no"] = 1; + + if (name == "EMS_YC") + { + //A相电压 R uint32 1V 0x107E + //B相电压 R uint32 1V 0x1080 + //C相电压 R uint32 1V 0x1082 + //A相电流 R int32 1A 0x1084 + //B相电流 R int32 1A 0x1086 + //C相电流 R int32 1A 0x1088 + + //储能系统SOC R uint16 0.1 0x107A + //储能系统SOH R uint16 0.1 0x107B + + json["addr"] = {"0x107A", "0x107B", "0x107E", "0x1080", "0x1082", "0x1084", "0x1086", "0x1088"}; + } + else if (name == "PCS_YC") + { + //总充电量 R uint32 1kWh 0x0003 + //总放电量 R uint32 1kWh 0x0005 + + //A相电压 R int16 1V 0x0010 + //B相电压 R int16 1V 0x0011 + //C相电压 R int16 1V 0x0012 + + //A相电流 R int16 1A 0x0019 + //B相电流 R int16 1A 0x001A + //C相电流 R int16 1A 0x001B + + //三相总有功功率 R int16 1kW 0x0025 + //三相总无功功率 R int16 1kVar 0x0026 + //三相总视在功率 R int16 1kVA 0x0027 + //三相总功率因数 R int16 1 0x0028 + + //充电功率 R int16 1kW 0x002C + //放电功率 R int16 1kW 0x002D + json["addr"] = {"0x0003", "0x0005", "0x0010", "0x0011", "0x0012", "0x0019", "0x001A", "0x001B", "0x0025", "0x0026", "0x0027", "0x0028", "0x002C", "0x002D"}; + } + else if (name == "PCU_YC") + { + //PCS侧线A相电压 R int16 1v 0x0013 + //PCS侧线B相电压 R int16 1v 0x0014 + //PCS侧线C相电压 R int16 1v 0x0015 + + //PCS侧功率因数A R int16 1 0x0019 + //PCS侧功率因数B R int16 1 0x001A + //PCS侧功率因数C R int16 1 0x001B + + //PCS侧相电流A R int16 1A 0x001C + //PCS侧相电流B R int16 1A 0x001D + //PCS侧相电流C R int16 1A 0x001E + + //PCS侧三相总有功功率 R int16 1kW 0x0028 + //PCS侧三相总无功功率 R int16 1kVar 0x0029 + //PCS侧三相总视在功率 R int16 1kVA 0x002A + //PCS侧三相总功率因数 R int16 1 0x002B + + json["addr"] = {"0x0013", "0x0014", "0x0015", "0x1080", "0x1082", "0x1084", "0x1086", "0x1088"}; + } + else if (name == "BMS_YC") + { + //SOC R uint16 0.1 0x0001 + //SOH R uint16 0.1 0x0002 + //电压 R uint32 0.1V 0x0003 + //电流 R int32 0.1A 0x0005 + //可充电量 R uint32 1kWh 0x0007 + //可放电量 R uint32 1kWh 0x0009 + //可充电状态 R uint16 1:可充电;0:不可充电 0x0047 + //可放电状态 R uint16 1:可放电;0:不可放电 0x0048 + //运行状态 R uint16 运行状态 0-正常 1-告警 2-保护 0x0049 + //充放电状态 R uint16 0-待机 1-充电 2-放电 0x004A + + json["addr"] = {"0x0001", "0x0002", "0x0003", "0x0005", "0x0007", "0x0009", "0x0047", "0x0048", "0x0049", "0x004A"}; + } + else if (name == "BCU_YC") + { + //电表类型 R uint16 "0:储能站总表 1:逆变前侧电表 2:逆变后侧电表 3:配电柜电表 4:并网口电表" 0x0008 + //A相电压 R uint32 1V 0x000B + //B相电压 R uint32 1V 0x000D + //C相电压 R uint32 1V 0x000F + //A相电流 R int32 1A 0x0011 + //B相电流 R int32 1A 0x0013 + //C相电流 R int32 1A 0x0015 + + //尖段电价 R uint32 1RMB 0x0027 + //峰段电价 R uint32 1RMB 0x0029 + //平段电价 R uint32 1RMB 0x002B + //谷段电价 R uint32 1RMB 0x002D + //日充电电量 R uint32 1kWh 0x002F + //日放电电量 R uint32 1kWh 0x0031 + //日充电费用 R uint32 1RMB 0x0033 + //日放电费用 R uint32 1RMB 0x0035 + //日收益 R int32 1RMB 0x0037 + + //总充电电量 R uint32 1kWh 0x004D + //总放电电量 R uint32 1kWh 0x004F + //总充电费用 R uint32 1RMB 0x0051 + //总放电费用 R uint32 1RMB 0x0053 + //总收益 R int32 1RMB 0x0055 + } + else if (name == "TH_YC") + { + //所属通道号 R uint16 1 0x0001 + //所属温湿度号 R uint16 1~10 0x0002 + //温度 R int16 0.1℃ 0x0003 + //湿度 R int16 0.1℃ 0x0004 + + } + return json.dump(); } diff --git a/src/protocol/MqttEntity.h b/src/protocol/MqttEntity.h index f709a06..e011e92 100644 --- a/src/protocol/MqttEntity.h +++ b/src/protocol/MqttEntity.h @@ -4,12 +4,34 @@ #include #include #include "MQTTAsync.h" +#include "common/JsonN.h" + +class Station; + +struct REGInfo +{ + std::string key; + std::string datatype; + int bytes {0}; + std::string remark; + int ratio {1}; + + REGInfo() {} + REGInfo(std::string key, std::string datatype, std::string remark) + : key(key), datatype(datatype), remark(remark) + { + if (datatype == "uint16" || datatype == "int16") { bytes = 1; } + else if (datatype == "uint32" || datatype == "int32") { bytes = 2; } + } +}; using namespace std; class MqttClient { public: + static void loadDataStruct(std::string filename); + int init(string addr, string clientId, string username, string password); void destory(); @@ -23,15 +45,32 @@ public: void onConnectSuccess(MQTTAsync_successData* resp); void onConnectFaiure(MQTTAsync_failureData* resp); - void parseEMS_YC(std::string& text); - void parsePCU_YX(std::string& text); + void parseEMS_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseEMS_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parsePCU_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parsePCU_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parsePCS_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parsePCS_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseBMS_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseBCU_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseBCU_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseMEM_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseTH_YC(std::shared_ptr station, njson& json, std::map& mapRegInfo); + //void parseFire40_YX(std::string& text); + //void parseCooling_YX(std::string& text); + //void parseCooling_YC(std::string& text); + //void parseCharger_YC(std::string& text); + //void parseGateway_YX(std::string& text); + //void parseGateway_YC(std::string& text); + //void parseGateway_YT(std::string& text); + //void parseTQ(std::string& text); public: std::string clientId; MQTTAsync client = nullptr; std::vector vecTopic; std::string addr; // "tcp://localhost:1883" - int qos {1}; + int qos {0}; bool isConnected {false}; bool isSubscribed {false}; }; @@ -60,5 +99,5 @@ public: public: - static string packEquipmentInfo(); + static string pack(std::string name); }; \ No newline at end of file diff --git a/src/pv/pages/MaskPageRunning.cpp b/src/pv/pages/MaskPageRunning.cpp index a01e323..2824bc4 100644 --- a/src/pv/pages/MaskPageRunning.cpp +++ b/src/pv/pages/MaskPageRunning.cpp @@ -245,7 +245,7 @@ void MaskPageRunning::initModule(Module& module, std::string name, int x, int y, { module.name = name; - int deviceNum = activeStation->getDeviceNumByGroup(name); + int deviceNum = activeStation->getDeviceNumByGroup(1); int pid = module.widget = PvApp::label(p, 0, x, y, w, h, "", QSS::LABEL_BOX); PvApp::label(p, module.widget, 10, 20, w, 30, module.name, QSS::LABEL_TITLE); pvSetAlignment(p, module.widget, AlignTop | AlignLeft); @@ -283,7 +283,7 @@ void MaskPageRunning::activeBoxPanel(Module* module) { // 更新卡片: std::vector> vecDevice; - activeStation->getDeviceByGroup(module->name, vecDevice); + activeStation->getDeviceByGroup(1, vecDevice); pvSetText(p, module->labelNum, std::to_string(vecDevice.size()).c_str()); @@ -298,7 +298,7 @@ void MaskPageRunning::activeBoxPanel(Module* module) if (typeDef) { std::vector vecKeys; - NJson::parse(typeDef->fieldsAttr.value("key"), vecKeys); + JSON::parse(typeDef->fieldsAttr.value("key"), vecKeys); card->setCard(typeDef->name, device->name, device->code); card->setParamkeys(vecKeys); } diff --git a/src/pv/pages/PanelPolicy.cpp b/src/pv/pages/PanelPolicy.cpp index 488cec4..24616db 100644 --- a/src/pv/pages/PanelPolicy.cpp +++ b/src/pv/pages/PanelPolicy.cpp @@ -265,14 +265,14 @@ void PanelPolicyPeak::setTimeText(int id, std::string s) void PanelPolicyPeak::parseAttr(std::string str) { - NJsonNode jsonroot; - bool ret = NJson::parse(str, jsonroot); + njson jsonroot; + bool ret = JSON::parse(str, jsonroot); if (!ret) { return; } - NJson::read(jsonroot, "times", data.times); + JSON::read(jsonroot, "times", data.times); // 更新UI (充电策略) if (data.times == 2) { @@ -286,7 +286,7 @@ void PanelPolicyPeak::parseAttr(std::string str) } std::vector> vecTmp; - NJson::read>>(jsonroot, "period", vecTmp); + JSON::read>>(jsonroot, "period", vecTmp); for (int row = 0; row < data.vecPeriods.size(); ++row) { auto& vecRows = data.vecPeriods[row]; @@ -358,13 +358,13 @@ void PanelPolicyPeak::parseAttr(std::string str) std::string PanelPolicyPeak::dumpAttr() { - NJsonNode jsonroot; + njson jsonroot; jsonroot["period"] = data.vecPeriods; jsonroot["times"] = data.times; - NJsonNode nodeCycle = NJsonNode::array(); + njson nodeCycle = njson::array(); - NJsonNode nodeAttr1; + njson nodeAttr1; nodeAttr1["charge_start"] = data.attr1.chargeTimeStart; nodeAttr1["charge_end"] = data.attr1.chargeTimeEnd; nodeAttr1["charge_power"] = data.attr1.chargePower; @@ -374,7 +374,7 @@ std::string PanelPolicyPeak::dumpAttr() nodeCycle.push_back(nodeAttr1); if (data.times > 1) { - NJsonNode nodeAttr2; + njson nodeAttr2; nodeAttr2["charge_start"] = data.attr2.chargeTimeStart; nodeAttr2["charge_end"] = data.attr2.chargeTimeEnd; nodeAttr2["charge_power"] = data.attr2.chargePower; @@ -423,17 +423,17 @@ PanelPolicyRequire::PanelPolicyRequire(PARAM* p, int parent, int ix, int iy, int void PanelPolicyRequire::parseAttr(std::string str) { - NJsonNode jsonroot; - bool ret = NJson::parse(str, jsonroot); + njson jsonroot; + bool ret = JSON::parse(str, jsonroot); if (!ret) { return; } - NJson::read(jsonroot, "charge_soc", data.chargeSoc); - NJson::read(jsonroot, "charge_power", data.chargePower); - NJson::read(jsonroot, "discharge_soc", data.dischargeSoc); - NJson::read(jsonroot, "discharge_power", data.dischargePower); + JSON::read(jsonroot, "charge_soc", data.chargeSoc); + JSON::read(jsonroot, "charge_power", data.chargePower); + JSON::read(jsonroot, "discharge_soc", data.dischargeSoc); + JSON::read(jsonroot, "discharge_power", data.dischargePower); // 更新UI pvSetText(p, ui.chargeSoc, std::to_string(data.chargeSoc).c_str()); @@ -444,7 +444,7 @@ void PanelPolicyRequire::parseAttr(std::string str) std::string PanelPolicyRequire::dumpAttr() { - NJsonNode jsonroot; + njson jsonroot; jsonroot["discharge_soc"] = data.dischargeSoc; jsonroot["discharge_power"] = data.dischargePower; jsonroot["charge_soc"] = data.chargeSoc; @@ -471,17 +471,17 @@ PanelPolicySelf::PanelPolicySelf(PARAM* p, int parent, int ix, int iy, int iw, i void PanelPolicySelf::parseAttr(std::string str) { - NJsonNode jsonroot; - bool ret = NJson::parse(str, jsonroot); + njson jsonroot; + bool ret = JSON::parse(str, jsonroot); if (!ret) { return; } - NJson::read(jsonroot, "used_soc", data.usedSoc); - NJson::read(jsonroot, "grid_soc", data.gridSoc); - NJson::read(jsonroot, "charge_power", data.chargePower); - NJson::read(jsonroot, "discharge_power", data.dischargePower); + JSON::read(jsonroot, "used_soc", data.usedSoc); + JSON::read(jsonroot, "grid_soc", data.gridSoc); + JSON::read(jsonroot, "charge_power", data.chargePower); + JSON::read(jsonroot, "discharge_power", data.dischargePower); // 更新UI pvSetText(p, ui.usedSoc, std::to_string(data.usedSoc).c_str()); @@ -492,7 +492,7 @@ void PanelPolicySelf::parseAttr(std::string str) std::string PanelPolicySelf::dumpAttr() { - NJsonNode jsonroot; + njson jsonroot; jsonroot["used_soc"] = data.usedSoc; jsonroot["grid_soc"] = data.gridSoc; jsonroot["charge_power"] = data.chargePower; diff --git a/web/public/config/columnList.js b/web/public/config/columnList.js index 4eb1013..f4f9fee 100644 --- a/web/public/config/columnList.js +++ b/web/public/config/columnList.js @@ -114,6 +114,46 @@ export const columnList = [ } ] }, + { + page: 'permission', + columns: [ + { + title: '权限ID', + dataIndex: 'permission_id', + key: 'permission_id', + ellipsis: true, + // filterable: true, + fixed: 'left' + }, + { + title: '权限名称', + dataIndex: 'name', + key: 'name' + // filterable: true + }, + { + title: '权限描述', + dataIndex: 'describe', + key: 'describe', + ellipsis: true + // filterable: true + }, + + { + title: '是否启用', + dataIndex: 'is_open', + key: 'is_open', + scopedSlots: { customRender: 'is_open' } + } + + // { + // title: '操作', + // dataIndex: 'operate', + // key: 'operate', + // scopedSlots: { customRender: 'action' } + // } + ] + }, { page: 'station', columns: [ @@ -140,16 +180,12 @@ export const columnList = [ { title: '场站经度', dataIndex: 'lon', - width: 50, key: 'lon' - // filterable: true }, { title: '场站纬度', dataIndex: 'lat', - width: 50, key: 'lat' - // filterable: true }, { title: '储能容量', @@ -165,10 +201,9 @@ export const columnList = [ // filterable: true }, { - title: '场站类别', + title: '储能容量', dataIndex: 'capacity', - key: 'capacity', - scopedSlots: { customRender: 'capacity' } + key: 'capacity' }, { title: '场站状态', @@ -375,6 +410,50 @@ export const columnList = [ scopedSlots: { customRender: 'action' } } ] + }, + { + page: 'serviceApi', + columns: [ + { + title: '接口ID', + dataIndex: 'api_id', + key: 'api_id', + ellipsis: true, + // filterable: true, + fixed: 'left' + }, + { + title: '接口名称', + dataIndex: 'name', + key: 'name' + // filterable: true + }, + { + title: '接口描述', + dataIndex: 'describe', + key: 'describe' + // filterable: true + }, + { + title: '接口参数', + dataIndex: 'params', + key: 'params' + }, + + { + title: '是否启用', + dataIndex: 'is_open', + key: 'is_open', + scopedSlots: { customRender: 'is_open' } + }, + + { + title: '操作', + dataIndex: 'operate', + key: 'operate', + scopedSlots: { customRender: 'action' } + } + ] } ] @@ -457,8 +536,54 @@ export const roleOptions = [ value: '', key: 'permission', type: 'slot', - slotName: 'permission', - className: 'item-l' + slotName: 'treetable', + className: 'item-l', + tableData: [], + selectTableData: [], + columns: [ + { + title: '名称', + dataIndex: 'name', + key: 'name', + ellipsis: true, + filterable: true, + fixed: 'left' + }, + { + title: '页面路径', + dataIndex: 'route', + key: 'route' + // filterable: true + }, + { + title: '是否允许新增操作', + dataIndex: 'is_add', + key: 'is_add', + align: 'center', + scopedSlots: { customRender: 'is_add' } + }, + { + title: '是否允许删除操作', + dataIndex: 'is_del', + key: 'is_del', + align: 'center', + scopedSlots: { customRender: 'is_del' } + }, + { + title: '是否允许编辑操作', + dataIndex: 'is_edit', + key: 'is_edit', + align: 'center', + scopedSlots: { customRender: 'is_edit' } + }, + { + title: '是否允许查看操作', + dataIndex: 'is_view', + key: 'is_view', + align: 'center', + scopedSlots: { customRender: 'isQuery' } + } + ] }, { // 0:禁用; 1:启用 @@ -756,6 +881,51 @@ export const alarmlogOptions = [ ruleForm: {} } ] +export const serviceApiOptions = [ + { + title: '基础信息', + icon: 'icon-xinxi', + list: [ + { + label: '接口名称', + value: '', + key: 'name', + type: 'input' + }, + { + label: '接口参数', + value: '', + key: 'params', + type: 'input' + }, + { + label: '接口描述', + value: '', + key: 'describe', + type: 'textarea' + }, + + { + label: '是否启用', + value: '', + key: 'is_open', + type: 'switch', + className: 'item-l', + list: [ + { + label: '禁用', + value: '0' + }, + { + label: '启用', + value: '1' + } + ] + } + ], + ruleForm: {} + } +] export const userFormRules = { account: [ @@ -821,3 +991,13 @@ export const deviceFormRules = { } ] } + +export const serviceApiFormRules = { + name: [ + { + trigger: 'blur', + required: true, + message: '请输入接口名称' + } + ] +} diff --git a/web/src/components/ComTable.vue b/web/src/components/ComTable.vue index 73279b9..d425351 100644 --- a/web/src/components/ComTable.vue +++ b/web/src/components/ComTable.vue @@ -108,7 +108,7 @@ const props = defineProps({ default: () => { return { count: 1, - pageSize: 10, + pageSize: 5, page: 1 } } @@ -410,30 +410,8 @@ defineExpose({ ...toRefs(data), loading, mountedScroll, scroll: data.scroll }) background-color: transparent !important; } -:deep( - .ant-table-wrapper - .ant-table.ant-table-bordered - > .ant-table-container - > .ant-table-body - > table - > tbody - > tr - > .ant-table-cell-fix-right-first::after - ) { - // border-inline-end: 1px solid var(--theme-bg) !important; -} -:deep( - .ant-table-wrapper - .ant-table.ant-table-bordered - > .ant-table-container - > .ant-table-header - > table - > thead - > tr - > .ant-table-cell-fix-right-first::after - ) { - // border-inline-end: 1px solid var(--theme-bg) !important; -} + + :deep(.ant-table-wrapper .ant-table-thead th.ant-table-column-has-sorters:hover) { background: var(--table-select) !important; diff --git a/web/src/components/EditCom.vue b/web/src/components/EditCom.vue index 71247f0..07502d3 100644 --- a/web/src/components/EditCom.vue +++ b/web/src/components/EditCom.vue @@ -27,31 +27,28 @@