Browse Source

update 重建仓库

pull/1/head
lucas 2 weeks ago
commit
82a5fd4cf5
  1. 100
      LICENSE
  2. 19
      README.md
  3. 22
      adaptors/IAdaptor.go
  4. 4
      adaptors/readme.txt
  5. 194
      adaptors/光电光栅中科to明月峡.go
  6. 410
      adaptors/安心云es主题to河北矿山监测.go
  7. 78
      adaptors/振动to明月峡.go
  8. 125
      adaptors/振动to湘潭健康监测.go
  9. 78
      adaptors/振动to重庆资管.go
  10. 121
      adaptors/欧乐称重to重庆资管.go
  11. 156
      adaptors/知物云主题数据to广州高支模省平台.go
  12. 85
      adaptors/统一采集to明月峡.go
  13. 93
      adaptors/统一采集to江苏省农村公路桥梁监测.go
  14. 156
      adaptors/统一采集to湘潭健康监测.go
  15. 125
      adaptors/统一采集to重庆资管.go
  16. 60
      adaptors/视觉位移to魏家滑坡.go
  17. 16
      build/Dockerfile
  18. 21
      build/bin/商用备份/龙河桥/upload/configMqtt.json
  19. 41
      build/bin/商用备份/龙河桥/upload/configSensor.json
  20. 12430
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T03-18-11.040.log
  21. 12355
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T03-34-20.312.log
  22. 12494
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T03-51-11.531.log
  23. 12593
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-08-33.900.log
  24. 12571
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-25-47.510.log
  25. 12508
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-42-37.855.log
  26. 12585
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-59-53.197.log
  27. 12518
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T05-16-53.476.log
  28. 12533
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T05-33-50.803.log
  29. 12473
      build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T05-50-39.154.log
  30. 23
      build/bin/商用备份/龙河桥/upload/logs/logInfo.log
  31. 20
      build/bin/商用备份/龙河桥/upload/ssl/centerCA.crt
  32. 26
      build/bin/重庆资管/数据样例/外购-称重数据样例.json
  33. 335
      build/bin/重庆资管/数据样例/振动数据样例.json
  34. 27
      build/bin/重庆资管/数据样例/称重数据样例.json
  35. 26
      build/bin/重庆资管/数据样例/统一采集软件样例.json
  36. 81
      build/goupload.yaml
  37. 24
      build/jenkinsfile
  38. 24
      build/jenkinsfile_image
  39. 68
      config/configStruct.go
  40. 83
      config/init.go
  41. 41
      configFiles/config_魏家滑坡_视觉位移.json
  42. 69
      configFiles/弃用备份/config_CQZG.json
  43. 451
      configFiles/弃用备份/config_HTJC2.json
  44. 65
      configFiles/弃用备份/config_MYX.json
  45. 76
      configFiles/弃用备份/config_广州高支模_mas.json
  46. 84
      configFiles/弃用备份/config_承德金隅水泥_河北矿山_冀东唐山.json
  47. 33
      configFiles/弃用备份/config_承德金隅水泥_河北矿山_大斜阳.json
  48. 33
      configFiles/弃用备份/config_承德金隅水泥_河北矿山_太平堡.json
  49. 44
      configFiles/弃用备份/config_承德金隅水泥_河北矿山_滦州冀东.json
  50. 45
      configFiles/弃用备份/config_江苏农村公路桥梁.json
  51. 1
      constKey/key.go
  52. 31
      consumers/CDJYSN/config.go
  53. 21
      consumers/CQZG/config.go
  54. 3406
      consumers/CQZG/protoFiles/MonitorDataProtocol_realtime.pb.go
  55. 20
      consumers/CQZG/ssl/centerCA.crt
  56. 39
      consumers/GZGZM/config.go
  57. 78
      consumers/GZGZM/dataModel.go
  58. 19
      consumers/HTJC/config.go
  59. 6
      consumers/IConsumer.go
  60. 30
      consumers/JSNCGLQL/config.go
  61. 41
      consumers/MYX/config.go
  62. 24
      consumers/WJHP/config.go
  63. 23
      consumers/WJHP/dataModel.go
  64. 300
      consumers/consumerCDJYSN.go
  65. 117
      consumers/consumerCQZG.go
  66. 217
      consumers/consumerGZGZM.go
  67. 108
      consumers/consumerHTJC.go
  68. 116
      consumers/consumerJSNCGLQL.go
  69. 206
      consumers/consumerMYX.go
  70. 27
      consumers/consumerManage.go
  71. 104
      consumers/consumerWJHP.go
  72. 262
      consumers/consumer_test.go
  73. 138
      dbHelper/_kafka/consumerGroupHandler.go
  74. 27
      dbHelper/_kafka/kafkaHelper.go
  75. 52
      dbHelper/_kafka/kafka_test.go
  76. 113
      dbHelper/_kafka/producerHelper.go
  77. 38
      dbHelper/apiServer.go
  78. 30
      dbHelper/fileSaveHelper.go
  79. 257
      dbHelper/httpHelper.go
  80. 136
      dbHelper/influxDBHelper.go
  81. 134
      dbHelper/mqttHelper.go
  82. 51
      dbHelper/udpHelper.go
  83. 64
      go.mod
  84. 196
      go.sum
  85. 24
      logSet.go
  86. 18
      logs/logInfo.log
  87. 51
      main.go
  88. 52
      main_test.go
  89. 81
      models/EsAggTop.go
  90. 28
      models/OLCZ.go
  91. 44
      models/TYCJ.go
  92. 12
      models/ZD.go
  93. 20
      models/dx.go
  94. 57
      models/savoirTheme.go
  95. 40
      monitors/fileMonitor.go
  96. 18
      monitors/httpMonitor.go
  97. 28
      monitors/monitorHelper.go
  98. 139
      testUnit/httpPost_test.go
  99. 51
      testUnit/mqttPush_test.go
  100. 34
      testUnit/mqttRecv_test.go

100
LICENSE

@ -0,0 +1,100 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too.
When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
The precise terms and conditions for copying, distribution and modification follow.
GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you".
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy.
2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option).
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License.
d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms.
3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following:
a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.)
Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system.
4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein.
7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation.
8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
NO WARRANTY
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.> Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice
That's all there is to it!

19
README.md

@ -0,0 +1,19 @@
# goUpload
## 功能说明:
功能:用于设备采集数据上报第三方。
数据入口->各类本地采集软件
数据出口->各类第三方数据接口
部署环境:用于windows环境
## 启用配置:
goUpload.exe + configFiles目录下的json配置
(configFiles目录下有几个配置就会生效几个功能,实际部署时,不相干的项目配置不要放进去)
支持-软件列表:
--------------------
**统一采集软件**
**DAAS振动软件**
**称重软件**
**中科-光电txt**

22
adaptors/IAdaptor.go

@ -0,0 +1,22 @@
package adaptors
type IAdaptor interface {
Transform(raw string) []byte
}
type IAdaptor2 interface {
Transform(raw string) [][]byte
}
type IAdaptor3 interface {
Transform(topic, raw string) []byte
}
type IAdaptor4 interface {
Transform(topic, raw string) []NeedPush
}
type NeedPush struct {
Topic string
Payload []byte
}

4
adaptors/readme.txt

@ -0,0 +1,4 @@
数据转换适配器:
1.统一采集软件适配器TYCJ
2.振动数据适配器ZD
3.称重数据适配器CZ

194
adaptors/光电光栅中科to明月峡.go

@ -0,0 +1,194 @@
package adaptors
import (
"bytes"
"fmt"
"goUpload/consumers/MYX"
"goUpload/utils"
"log"
"strconv"
"strings"
"text/template"
"time"
)
// Adaptor_GDGS_MYX 中科光电光栅 转换 明月峡-长江大桥
type Adaptor_GDGS_MYX struct {
IdMap map[string]MYX.CHInfo
}
func (the Adaptor_GDGS_MYX) Transform(rawMsg [][]string) []byte {
//tycj := models.TYCJ{}
//json.Unmarshal([]byte(rawMsg), &tycj)
return the.GDGStoMYCInflux(rawMsg)
}
func (the Adaptor_GDGS_MYX) GDGStoMYCInflux(rawRecords [][]string) (result []byte) {
for _, record := range rawRecords {
if len(record) < 3 {
log.Printf("数据 列<3,无效,跳过,%s", record)
continue
}
//数据处理
recordTime, err := time.Parse("2006-01-02 15:04:05", record[0])
if err != nil {
log.Printf("光电光栅文件 解析数据时间 %s 解析错误", record[0])
continue
}
LastCH, err := strconv.Atoi(record[1])
if err != nil {
log.Printf("行数据首通道[%s]转换int失败:%s", record[1], err.Error())
}
//数据通道 subCh ->归属在大的通道CH中
dataSubCh := 0
for i := 1; i < len(record); i += 2 {
recordCH, err := strconv.Atoi(record[i])
if err != nil {
log.Printf("数据-子通道[%s]转换int失败:%s", record[i], err.Error())
continue
}
//中科光电光栅1个通道下有多个设备 每行数据如下 大通道一样 需要自己按照顺序排布子通道
//2023-12-29 06:54:43,0,1528094,0,1531681,0,1536561,0,1537559,0,1541141,0,1542270,0,1546317,0,1551866,1,1527281,1,1532567,1,1537039,1,1541923,1,1546877,1,1551006,1,1556059,1,1562970,2,1528381,2,1532404,2,1536890,2,1542877,2,1546748,2,1551749,2,1556631,2,1561473,3,1527951,3,1532139,3,1538792,3,1542914,3,1546860,3,1551240,3,1557643,3,1561802,4,1529398,4,1533369,4,1537114,4,1540956,4,1545918,4,1551113,4,1556017,4,1560997,5,1536839,5,1541839,5,1546881,5,1552005,6,1527526,6,1543637,6,1549114
if LastCH == recordCH {
dataSubCh += 1
} else {
LastCH = recordCH
//CH变了,重新开始累计
dataSubCh = 1
}
wavelength, err := strconv.Atoi(record[i+1])
if err != nil {
log.Printf("数据-子通道[%s] 波长转换int失败:%s", record[i+1], err.Error())
continue
}
CH := fmt.Sprintf("CH%d-%d", recordCH, dataSubCh)
log.Printf("光电光栅 传感器[CH%d-%d] 波长=%d", recordCH, dataSubCh, wavelength)
//todo 波长计算应变
//physicalValue := wavelength
sensorInfo, isValid := the.getSensorInfo(CH)
if !isValid {
log.Printf("光电光栅 传感器[%s] 无匹配,跳过", CH)
continue
}
sensorLabel := sensorInfo.Label
//公式表达式
formulaStr := sensorInfo.Formula
if formulaStr == "" {
log.Printf("光电光栅 传感器[%s][%s]波长=%v,无公式计算", CH, sensorLabel, wavelength)
}
log.Printf("光电光栅 传感器[%s][%s]波长=%v,准备公式计算=%s", CH, sensorLabel, wavelength, formulaStr)
phy, err := the.calculatePhy(wavelength, formulaStr, sensorInfo.Params)
if err != nil {
log.Printf("传感器[%s][%s]公式计算异常,err=%s", CH, sensorLabel, err.Error())
continue
}
ThemeValues := []float64{phy}
tableName, fields := the.getFactorFields(sensorInfo.Type)
if sensorInfo.Label == "" || tableName == "" || len(fields) == 0 {
log.Printf("光电光栅 设备[%s][%s] type=%s 无匹配FactorFields tableName=%s,fields=%s",
CH, sensorInfo.Label, sensorInfo.Type, tableName, fields)
continue
}
//动态应变插入
// QLDYBJC,sensor_id=QLDYBJC001 valueV=0.68
var sqlBuilder strings.Builder
sqlBuilder.WriteString(fmt.Sprintf("%s,sensor_id=%s ", tableName, sensorLabel))
for i, field := range fields {
sqlBuilder.WriteString(fmt.Sprintf("%s=%f,", field, ThemeValues[i]))
}
sqlStr := sqlBuilder.String()
sqlStr = sqlStr[:len(sqlStr)-1]
sqlStr += fmt.Sprintf(" %d", recordTime.Add(-8*time.Hour).UnixNano())
log.Printf("光电光栅 设备 [f=%s]-[%s]-[%s]报文=%s 设备时间%v",
sensorInfo.Type, CH, sensorLabel, sqlStr, recordTime)
return []byte(sqlStr)
}
now := time.Now()
log.Println(recordTime, err, now)
}
//Atime, err := time.Parse("2006-01-02T15:04:05.000", tycj.SensorData.Time)
//if err != nil {
// log.Printf("统一采集 设备[%s] 数据时间 %s 解析错误", tycj.SensorData.Name, tycj.SensorData.Time)
// return
//}
//
//sensorCode := the.getSensorId(tycj.SensorData.Name)
//tableName, fields := the.getFactorFields(tycj.SensorData.FactorType)
//if sensorCode == "" || tableName == "" || len(fields) == 0 || len(fields) > len(tycj.SensorData.Data.ThemeValues) {
// log.Printf("统一采集 设备[%s] 数据时间 %s 无匹配 sensorCode=%s,tableName=%s,fields=%s",
// tycj.SensorData.Name, tycj.SensorData.Time, sensorCode, tableName, fields)
// return
//}
//
////insert ND_data,sensor_id=ND000101 valueV=0.68,valueH=290
//var sqlBuilder strings.Builder
//sqlBuilder.WriteString(fmt.Sprintf("%s,sensor_id=%s ", tableName, sensorCode))
//for i, field := range fields {
// sqlBuilder.WriteString(fmt.Sprintf("%s=%f,", field, tycj.SensorData.Data.ThemeValues[i]))
//}
//sqlStr := sqlBuilder.String()
//sqlStr = sqlStr[:len(sqlStr)-1]
//sqlStr += fmt.Sprintf(" %d", Atime.Add(-8*time.Hour).UnixNano())
//log.Printf("TYCJ [f=%d]-[%s]-[%s]报文=%s 设备时间%v", tycj.SensorData.FactorType, tycj.SensorData.Name,
// sensorCode, sqlStr, Atime)
return result
}
func (the Adaptor_GDGS_MYX) calculatePhy(wavelength int, formulaTemplateStr string, params map[string]float64) (float64, error) {
//波长计入参数
params["phy"] = float64(wavelength)
newSensorParams := map[string]string{}
for k, v := range params {
newSensorParams[k] = strconv.FormatFloat(v, 'f', 3, 64)
}
CreateFormulaTemplate := func(name, t string) *template.Template {
return template.Must(template.New(name).Parse(t))
}
formulaTemplate := CreateFormulaTemplate("formulaTemplate", formulaTemplateStr)
formulaBuff := &bytes.Buffer{}
err := formulaTemplate.Execute(formulaBuff, newSensorParams)
if err != nil {
return 0, err
}
//公式表达式计算
result := utils.CalculateFormula(formulaBuff.String())
return result, nil
}
func (the Adaptor_GDGS_MYX) getSensorInfo(rawSensorName string) (info MYX.CHInfo, isValid bool) {
v, isValid := the.IdMap[rawSensorName]
return v, isValid
}
func (the Adaptor_GDGS_MYX) getFactorFields(factorType string) (tableName string, fields []string) {
//这个对应关系 要看现场聚集的统一采集软件 进行调整
switch factorType {
case "QLDYBJC": //桥梁动应变监测 共20个
tableName = factorType
fields = []string{"value"}
case "QLJYBJC": //桥梁静应变监测 共20个
tableName = factorType
fields = []string{"value"}
case "ZLWDJC": //主梁温度监测 共4个
tableName = factorType
fields = []string{"value"}
default:
fields = []string{}
}
return tableName, fields
}

410
adaptors/安心云es主题to河北矿山监测.go

@ -0,0 +1,410 @@
package adaptors
import (
"bytes"
"encoding/json"
"fmt"
"goUpload/models"
"log"
"math"
"strings"
"text/template"
"time"
)
// Adaptor_AXYES_HBKS 统一采集软件数据 转换 湘潭健康监测平台
type Adaptor_AXYES_HBKS struct {
//传感器code转换信息
GnssMap map[string]string
RainMap map[string]string
NBWYMap map[string]string
DXSWMap map[string]string
//一些必要信息
Info map[string]string
}
func (the Adaptor_AXYES_HBKS) Transform(rawMsg string) []byte {
esAggTop := models.EsAggTop{}
err := json.Unmarshal([]byte(rawMsg), &esAggTop)
if err != nil {
return nil
}
return the.EsAggTopToHBKS(esAggTop)
}
func (the Adaptor_AXYES_HBKS) EsAggTopToHBKS(esAggTop models.EsAggTop) (result []byte) {
//var transBytes []byte
fileContent := strings.Builder{}
//写入文本内容的固定头
contentHeader := the.getContentHeader()
fileContent.WriteString(contentHeader)
for _, bucket := range esAggTop.Aggregations.SensorId.Buckets {
for _, hit := range bucket.Last.Hits.Hits {
source := hit.Source
sensorContentTemplate := the.getTemplateStr(source)
sensorContentObj := the.getTemplateObj(source)
if len(sensorContentObj) == 0 {
continue
}
txt, err := templateWork(sensorContentTemplate, sensorContentObj)
if err != nil {
log.Printf("传感器[%s]数据生成出现异常,err=%s", source.SensorName, err.Error())
continue
}
fileContent.WriteString(txt)
}
}
//单个文本文件用“]]]”表示结束
fileContent.WriteString("]]]")
return []byte(fileContent.String())
}
func templateWork(formulaTemplateStr string, templateParams map[string]string) (string, error) {
CreateFormulaTemplate := func(name, t string) *template.Template {
return template.Must(template.New(name).Parse(t))
}
formulaTemplate := CreateFormulaTemplate("formulaTemplate", formulaTemplateStr)
formulaBuff := &bytes.Buffer{}
err := formulaTemplate.Execute(formulaBuff, templateParams)
return formulaBuff.String(), err
}
func (the Adaptor_AXYES_HBKS) getTemplateStr(sensorData models.Source) string {
templateStr := ""
switch sensorData.Factor {
case models.AXY_FactorType_BMWY:
templateStr = "{{.structUploadCode}}{{.sensorType}}{{.sensorCode}};{{.sensorType}};{{.sensorName}};{{.longitude}};{{.latitude}};{{.height}};" +
"{{.x}}|{{.y}}|{{.z}}||||{{.xAcc}}|{{.yAcc}}|{{.zAcc}};{{.unit}};{{.state}};{{.time}}^"
case models.AXY_FactorType_Rain_New:
templateStr = "{{.structUploadCode}}{{.sensorType}}{{.sensorCode}};{{.sensorType}};{{.sensorName}};{{.longitude}};{{.latitude}};{{.height}};" +
"{{.totrainfall}};{{.unit}};{{.state}};{{.time}}^"
case models.AXY_FactorType_SBSPWY:
templateStr = "{{.structUploadCode}}{{.sensorType}}{{.sensorCode}};{{.sensorType}};{{.sensorName}};{{.longitude}};{{.latitude}};{{.height}};" +
"{{.x}}|{{.y}};{{.unit}};{{.state}};{{.time}}^"
case models.AXY_FactorType_DXSW:
templateStr = "{{.structUploadCode}}{{.sensorType}}{{.sensorCode}};{{.sensorType}};{{.sensorName}};{{.longitude}};{{.latitude}};{{.height}};" +
"{{.waterLevel}};{{.unit}};{{.state}};{{.time}}^"
}
return templateStr
}
// 河北矿山GNSS 表面唯一缓存,用于计算加速度
var cacheHBKS = make(map[string]float64)
func (the Adaptor_AXYES_HBKS) getTemplateObj(sensorData models.Source) map[string]string {
templateMap := make(map[string]string)
sensorCode, sensorType := the.getSensorCodeAndType(sensorData)
if sensorCode == "" {
return templateMap
}
for k, v := range the.Info {
templateMap[k] = v
}
templateMap["sensorCode"] = sensorCode
templateMap["sensorType"] = sensorType
templateMap["sensorName"] = sensorData.SensorName
longitude, latitude, height := the.getJWDbySensorName(sensorData)
templateMap["longitude"] = longitude
templateMap["latitude"] = latitude
templateMap["height"] = height
templateMap["state"] = "00000000"
templateMap["time"] = sensorData.CollectTime.Add(8 * time.Hour).Format("2006-01-02 15:04:05")
switch sensorData.Factor {
case models.AXY_FactorType_BMWY:
templateMap["x"] = fmt.Sprintf("%.3f", sensorData.Data["x"])
templateMap["y"] = fmt.Sprintf("%.3f", sensorData.Data["y"])
templateMap["z"] = fmt.Sprintf("%.3f", sensorData.Data["z"])
xAcc := 0.0
yAcc := 0.0
zAcc := 0.0
cacheKey_x := fmt.Sprintf("%s_x", sensorData.SensorName)
cacheKey_y := fmt.Sprintf("%s_y", sensorData.SensorName)
cacheKey_z := fmt.Sprintf("%s_z", sensorData.SensorName)
xLast, isHave := cacheHBKS[cacheKey_x]
if isHave {
log.Printf("[%s]上次值 xLast=%.3f", sensorData.SensorName, xLast)
xAcc = sensorData.Data["x"] - xLast
}
yLast, isHave := cacheHBKS[cacheKey_y]
if isHave {
log.Printf("[%s]上次值 yLast=%.3f", sensorData.SensorName, yLast)
yAcc = sensorData.Data["y"] - yLast
}
zLast, isHave := cacheHBKS[cacheKey_z]
if isHave {
log.Printf("[%s]上次值 zLast=%.3f", sensorData.SensorName, zLast)
zAcc = sensorData.Data["z"] - zLast
}
templateMap["xAcc"] = fmt.Sprintf("%.3f", xAcc)
templateMap["yAcc"] = fmt.Sprintf("%.3f", yAcc)
templateMap["zAcc"] = fmt.Sprintf("%.3f", zAcc)
templateMap["unit"] = "mm"
cacheHBKS[cacheKey_x] = sensorData.Data["x"]
cacheHBKS[cacheKey_y] = sensorData.Data["y"]
cacheHBKS[cacheKey_z] = sensorData.Data["z"]
case models.AXY_FactorType_SBSPWY:
templateMap["x"] = fmt.Sprintf("%.3f", sensorData.Data["x"])
templateMap["y"] = fmt.Sprintf("%.3f", sensorData.Data["y"])
templateMap["unit"] = "mm"
case models.AXY_FactorType_Rain_New:
templateMap["totrainfall"] = fmt.Sprintf("%.3f", sensorData.Data["totrainfall"])
templateMap["unit"] = "mm"
case models.AXY_FactorType_DXSW:
templateMap["waterLevel"] = fmt.Sprintf("%.3f", sensorData.Data["waterLevel"])
templateMap["unit"] = "m"
}
return templateMap
}
func (the Adaptor_AXYES_HBKS) getStructureId() string {
structureId, ok := the.Info["structureId"] //涿鹿金隅水泥有限公司大斜阳矿
if !ok {
log.Panic("配置文件info中 无structureId")
}
return structureId
}
func (the Adaptor_AXYES_HBKS) getJWDbySensorName(sensorData models.Source) (longitude, latitude, height string) {
structureId := the.getStructureId()
switch structureId {
case models.AXY_StructId_DXY: //大斜阳
longitude, latitude, height = jwdDXY(sensorData.SensorName)
case models.AXY_StructId_TPB: //太平堡
longitude, latitude, height = jwdTPB(sensorData.SensorName)
case models.AXY_StructId_TSJD:
longitude, latitude, height = jwdTSJD(sensorData.SensorName)
}
return
}
func (the Adaptor_AXYES_HBKS) getSensorCodeAndType(sensorData models.Source) (code, typeCode string) {
switch sensorData.Factor {
case models.AXY_FactorType_BMWY:
typeCode = "02"
v, isValid := the.GnssMap[sensorData.SensorName]
if !isValid {
return
}
code = v
case models.AXY_FactorType_Rain_New:
typeCode = "03"
v, isValid := the.RainMap[sensorData.SensorName]
if !isValid {
code = ""
}
code = v
case models.AXY_FactorType_SBSPWY:
typeCode = "04"
v, isValid := the.NBWYMap[sensorData.SensorName]
if !isValid {
code = ""
}
code = v
case models.AXY_FactorType_DXSW:
typeCode = "09"
v, isValid := the.DXSWMap[sensorData.SensorName]
if !isValid {
code = ""
}
code = v
}
return
}
func (the Adaptor_AXYES_HBKS) getTimeBytes(sensorTime time.Time) []byte {
year := int8(sensorTime.Year() - 1900)
month := int8(sensorTime.Month())
day := int8(sensorTime.Day())
hour := int8(sensorTime.Hour())
minute := int8(sensorTime.Minute())
millisecond := uint16(sensorTime.Second()*1000 + sensorTime.Nanosecond()/1e6)
bytes := make([]byte, 0)
bytes = append(bytes,
byte(year),
byte(month),
byte(day),
byte(hour),
byte(minute),
byte(millisecond&0xFF),
byte(millisecond>>8),
)
return bytes
}
func (the Adaptor_AXYES_HBKS) getDatasBytes(datas []float32) []byte {
bytes := make([]byte, 0)
for _, data := range datas {
bits := math.Float32bits(data)
bytes = append(bytes,
byte(bits&0xFF),
byte(bits>>8&0xFF),
byte(bits>>16&0xFF),
byte(bits>>24&0xFF),
)
}
return bytes
}
// 实时数据文件
func (the Adaptor_AXYES_HBKS) getContentHeader() string {
header := the.Info["fileContentHeader"]
//数据上传时间
timeNow := time.Now().Format("2006-01-02 15:04:05")
header += fmt.Sprintf("%s^", timeNow)
return header
}
// 测点信息文件
func (the Adaptor_AXYES_HBKS) getInfoContentHeader() string {
header := the.Info["fileContentHeader"]
//安标有效期
vaildDate := "2026-12-30"
//数据上传时间
timeNow := time.Now().Format("2006-01-02 15:04:05")
header += fmt.Sprintf("%s;%s^", vaildDate, timeNow)
return header
}
func jwdDXY(sensorName string) (longitude, latitude, height string) {
switch sensorName {
//大斜阳矿
case "JC01":
longitude = "115.243554"
latitude = "40.114834"
height = "1297"
case "JC02":
longitude = "115.241985"
latitude = "40.115445"
height = "1317"
case "JC03":
longitude = "115.241080"
latitude = "40.115698"
height = "1317"
case "雨量":
longitude = "115.244209"
latitude = "40.123344"
height = "1217"
}
return
}
func jwdTPB(sensorName string) (longitude, latitude, height string) {
switch sensorName {
case "JC01":
longitude = "115.370653"
latitude = "40.119892"
height = "1085"
case "JC02":
longitude = "115.366018"
latitude = "40.117782"
height = "1115"
case "雨量":
longitude = "115.366922"
latitude = "40.117217"
height = "1107"
}
return
}
func jwdTSJD(sensorName string) (longitude, latitude, height string) {
//传感器所在孔
holeName := []rune(sensorName)
holeIndex := string(holeName[:len(holeName)-1])
switch holeIndex {
case "Y":
longitude = "118.249646"
latitude = "39.934143"
height = "100"
case "BC190_10":
longitude = "118.238283"
latitude = "39.946949"
height = "190"
case "BC170_30":
longitude = "118.242235"
latitude = "39.945843"
height = "170"
case "BC170_40":
longitude = "118.244229"
latitude = "39.945138"
height = "170"
case "BC150_10":
longitude = "118.237151"
latitude = "39.946451"
height = "150"
case "BC150_20":
longitude = "118.239612"
latitude = "39.945954"
height = "150"
case "BC130_30":
longitude = "118.240133"
latitude = "39.945304"
height = "130"
case "BC130_40":
longitude = "118.242631"
latitude = "39.944875"
height = "130"
case "BC115_10":
longitude = "118.238570"
latitude = "39.944695"
height = "115"
case "BC115_20":
longitude = "118.243008"
latitude = "39.943796"
height = "115"
case "BC115_30":
longitude = "118.243000"
latitude = "39.944419"
height = "115"
case "BC100_30":
longitude = "118.242954"
latitude = "39.942911"
height = "100"
case "BC100_40":
longitude = "118.244194"
latitude = "39.940684"
height = "100"
case "NC110_40":
longitude = "118.249610"
latitude = "39.944820"
height = "110"
case "NC120_10":
longitude = "118.249305"
latitude = "39.934018"
height = "120"
case "NC120_20":
longitude = "118.249700"
latitude = "39.932248"
height = "120"
case "NC120_30":
longitude = "118.250113"
latitude = "39.929592"
height = "120"
case "NC140_20":
longitude = "118.251119"
latitude = "39.932524"
height = "140"
case "NC140_30":
longitude = "118.251605"
latitude = "39.929896"
height = "140"
}
return
}

78
adaptors/振动to明月峡.go

@ -0,0 +1,78 @@
package adaptors
import (
"encoding/json"
"fmt"
"goUpload/models"
"goUpload/utils"
"log"
"strings"
"time"
)
// Adaptor_ZD_MYX 振动DAAS数据 转换 湘潭健康监测平台
type Adaptor_ZD_MYX struct {
IdMap map[string]string
}
func (the Adaptor_ZD_MYX) Transform(rawMsg string) []byte {
zd := models.ZD{}
json.Unmarshal([]byte(rawMsg), &zd)
return the.ZDtoMYCInflux(zd)
}
func (the Adaptor_ZD_MYX) ZDtoMYCInflux(zd models.ZD) (result []byte) {
Atime := time.UnixMilli(zd.Ticks)
var sensorAccDataList = zd.AccValues
sensorCode := the.getSensorId(zd.Module)
if sensorCode == "" || len(sensorAccDataList) < 5 {
log.Printf("振动DAAS 设备[%s] 无匹配的明月峡id,请检查配置文件", zd.Module)
return
}
//振动DAAS数据 分为3种 :
// 1. 用来计算索力 2.用来计算梁体振动 3.用来船撞振动
//由于 船撞/地震振动监测 和 主梁振动监测 都是共用DAAS 无法区分监测类型,通过测点来获取表名
//测点如 CZDZJC001 表=CZDZJC, 测点ZLZDJC001 表=ZLZDJC
tableName := sensorCode[:6]
var sqlBuilder strings.Builder
sensorType := sensorCode[:2]
switch sensorType {
case "SL":
tableName = "XLSSLJC"
slTimeNanosecond := Atime.Add(-8 * time.Hour).UnixNano()
sqlBuilder.WriteString(fmt.Sprintf("%s,sensor_id=%s value=%f %d", tableName, sensorCode, zd.ThemeValue[0], slTimeNanosecond))
default:
switch sensorType {
case "CZ":
tableName = "CZDZJC"
case "ZD":
tableName = "ZLZDJC"
default:
log.Printf("无法识别的 sensorType=%s", sensorType)
}
for i, sensorData := range sensorAccDataList {
timeSpan := i * 1000000000 / zd.Frequency
dataTimeNanosecond := Atime.Add(-8 * time.Hour).Add(time.Nanosecond * time.Duration(timeSpan)).UnixNano()
sqlBuilder.WriteString(fmt.Sprintf("%s,sensor_id=%s value=%f %d", tableName, sensorCode, sensorData, dataTimeNanosecond))
sqlBuilder.WriteString("\n")
}
}
sqlBuilder.WriteString("\n")
sqlStr := sqlBuilder.String()
log.Printf("ZD [%s]-[%s]报文=\n %s... 设备时间%v", zd.Module, sensorCode, utils.LimitStringLength(sqlStr, 200), Atime)
result = []byte(sqlStr)
return result
}
func (the Adaptor_ZD_MYX) getSensorId(rawSensorName string) string {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = ""
}
return v
}

125
adaptors/振动to湘潭健康监测.go

@ -0,0 +1,125 @@
package adaptors
import (
"encoding/json"
"goUpload/models"
"log"
"math"
"time"
)
// Adaptor_ZD_XTJC 振动DAAS数据 转换 湘潭健康监测平台
type Adaptor_ZD_XTJC struct {
IdMap map[string]int16
}
func (the Adaptor_ZD_XTJC) Transform(rawMsg string) [][]byte {
zd := models.ZD{}
var result [][]byte
json.Unmarshal([]byte(rawMsg), &zd)
result = append(result, the.ZDtoXTJC(zd))
return result
}
func (the Adaptor_ZD_XTJC) ZDtoXTJC(zd models.ZD) (result []byte) {
Atime := time.UnixMilli(zd.Ticks)
var transBytes []byte
var sensorDataList []float32 = zd.AccValues
//1.添加通用报文头段
commPayloadHeader := the.getPayloadHeader(int16(len(sensorDataList)))
transBytes = append(transBytes, commPayloadHeader...)
//2.添加时间段
transBytes = append(transBytes, the.getTimeBytes(Atime)...)
//3.添加对象码段
sensorCode := the.getSensorId(zd.Module)
if sensorCode != 0 {
transBytes = append(transBytes, the.getCodeBytes(sensorCode)...)
} else {
log.Printf("振动DAAS 设备[%s] 无匹配的湘潭监测id,请检查配置文件", zd.Module)
return
}
//4.添加数据值段
transBytes = append(transBytes, the.getDatasBytes(sensorDataList)...)
return transBytes
}
func (the Adaptor_ZD_XTJC) getSensorId(rawSensorName string) int16 {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = 0
}
return v
}
func (the Adaptor_ZD_XTJC) getCodeBytes(sensorCode int16) []byte {
bytes := make([]byte, 0)
bytes = append(bytes,
byte(sensorCode&0xFF),
byte(sensorCode>>8),
)
return bytes
}
func (the Adaptor_ZD_XTJC) getTimeBytes(sensorTime time.Time) []byte {
year := int8(sensorTime.Year() - 1900)
month := int8(sensorTime.Month())
day := int8(sensorTime.Day())
hour := int8(sensorTime.Hour())
minute := int8(sensorTime.Minute())
millisecond := uint16(sensorTime.Second()*1000 + sensorTime.Nanosecond()/1e6)
bytes := make([]byte, 0)
bytes = append(bytes,
byte(year),
byte(month),
byte(day),
byte(hour),
byte(minute),
byte(millisecond&0xFF),
byte(millisecond>>8),
)
return bytes
}
func (the Adaptor_ZD_XTJC) getDatasBytes(datas []float32) []byte {
bytes := make([]byte, 0)
for _, data := range datas {
bits := math.Float32bits(data)
bytes = append(bytes,
byte(bits&0xFF),
byte(bits>>8&0xFF),
byte(bits>>16&0xFF),
byte(bits>>24&0xFF),
)
}
return bytes
}
func (the Adaptor_ZD_XTJC) getPayloadHeader(floatCount int16) []byte {
bytes := make([]byte, 0)
bytes = append(bytes,
//报文类型
0x02,
0x00,
//1:上行信息
0x01,
//默认,通讯计算机编号
0x00,
//命令码
0x01,
//报文长度
byte((floatCount*4+9)&0xFF),
byte((floatCount*4+9)>>8),
)
return bytes
}

78
adaptors/振动to重庆资管.go

@ -0,0 +1,78 @@
package adaptors
import (
"crypto/rc4"
"encoding/json"
"goUpload/consumers/CQZG/protoFiles"
"goUpload/models"
"goUpload/utils"
"google.golang.org/protobuf/proto"
"log"
)
// Adaptor_ZD_CQZG 振动数据转换器
type Adaptor_ZD_CQZG struct {
IdMap map[string]int64
RC4Key string
}
func (the Adaptor_ZD_CQZG) Transform(rawMsg string) []byte {
zd := models.ZD{}
json.Unmarshal([]byte(rawMsg), &zd)
return the.ZDtoCQZG(zd)
}
func (the Adaptor_ZD_CQZG) ZDtoCQZG(zd models.ZD) (result []byte) {
var transBytes []byte
ComplexData_HSD := &protoFiles.ComplexData{
SensorData: make([]*protoFiles.SensorData, 0),
}
sensorData := &protoFiles.SensorData{
MonitorType: protoFiles.MonitoryType_VIB, //监测类型 转换
SensorID: the.getSensorId(zd.Module), //id转换
EventTime: zd.Ticks / 1000 * 1000, //由于振动时间问题,去掉毫秒
ChannelCode: "",
DataBody: &protoFiles.SensorData_Vib{
Vib: &protoFiles.VIBRealTime{
MonitorValues: zd.AccValues,
},
},
}
//无匹配 提前返回
if sensorData.SensorID == 0 {
log.Printf("振动测点[%s] 数据无匹配的资管平台id,请检查配置文件", zd.Module)
return
}
ComplexData_HSD.SensorData = append(ComplexData_HSD.SensorData, sensorData)
transBytes, _ = proto.Marshal(ComplexData_HSD)
resultByCrc16 := utils.NewCRC16CCITT().GetWCRCin(transBytes)
needRC4 := append(transBytes, resultByCrc16...)
rc4Key := []byte(the.RC4Key)
// 加密操作
dest1 := make([]byte, len(needRC4))
rc4.NewCipher(rc4Key)
cipher1, _ := rc4.NewCipher(rc4Key)
cipher1.XORKeyStream(dest1, needRC4)
//log.Printf("rc4加密结果=> %s \n", hex.EncodeToString(dest1))
return dest1
}
func (the Adaptor_ZD_CQZG) getSensorId(rawSensorName string) int64 {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = 0
}
return v
}
// DAAS软件 振动对方平台id对于关系
//var idMapZD = map[string]int64{
// "1": 5000200017,
// "2": 5000200018,
//}

121
adaptors/欧乐称重to重庆资管.go

@ -0,0 +1,121 @@
package adaptors
import (
"crypto/rc4"
"encoding/hex"
"encoding/json"
"goUpload/consumers/CQZG/protoFiles"
"goUpload/models"
"goUpload/utils"
"google.golang.org/protobuf/proto"
"log"
"strconv"
"time"
)
// Adaptor_OLCZ_CQZG 称重数据转换器
type Adaptor_OLCZ_CQZG struct {
IdMap map[string]int64
RC4Key string
}
func (the Adaptor_OLCZ_CQZG) Transform(rawMsg string) []byte {
cz := models.OLCZ{}
json.Unmarshal([]byte(rawMsg), &cz)
return the.OLCZtoCQZG(cz)
}
func (the Adaptor_OLCZ_CQZG) OLCZtoCQZG(cz models.OLCZ) (result []byte) {
var transBytes []byte
ComplexData_HSD := &protoFiles.ComplexData{
SensorData: make([]*protoFiles.SensorData, 0),
}
Atime, err := time.Parse("2006-01-02 15:04:05", cz.Atime)
if err != nil {
log.Printf("称重数据时间 %s 解析错误 ", cz.Atime)
Atime = time.Now()
}
sensorData := &protoFiles.SensorData{
MonitorType: protoFiles.MonitoryType_HSD, //监测类型 转换
SensorID: the.getSensorId(strconv.Itoa(int(cz.Roadno))), //id转换
EventTime: Atime.Add(-8 * time.Hour).UnixMilli(),
ChannelCode: "",
DataBody: &protoFiles.SensorData_Hsd{
Hsd: &protoFiles.HSDRealTime{
LaneId: cz.Roadno,
OperDirec: cz.OperDirec, //0上行,1下行 在称重软件上设置
AxleNum: cz.AxisCount,
AxleGrpNum: cz.AxleGrpNum, //轴组数
GrossLoad: cz.GrossWeight,
VehType: the.getVehType(cz.Carmodel),
Speed: cz.Speed,
},
},
}
ComplexData_HSD.SensorData = append(ComplexData_HSD.SensorData, sensorData)
CZStr, _ := json.Marshal(ComplexData_HSD)
log.Printf("cz [r=%d] -[%d]原始报文 ComplexData_HSD=%s",
cz.Roadno,
sensorData.SensorID,
CZStr)
transBytes, _ = proto.Marshal(ComplexData_HSD)
log.Printf("cz [r=%d] -[%d]报文 proto.Marshal=%s",
cz.Roadno,
sensorData.SensorID,
hex.EncodeToString(transBytes))
resultByCrc16 := utils.NewCRC16CCITT().GetWCRCin(transBytes)
needRC4 := append(transBytes, resultByCrc16...)
log.Printf("cz [r=%d] -[%d]报文 needRC4=%s", cz.Roadno, sensorData.SensorID, hex.EncodeToString(needRC4))
// 加密操作
rc4Key := []byte(the.RC4Key)
dest1 := make([]byte, len(needRC4))
rc4.NewCipher(rc4Key)
cipher1, _ := rc4.NewCipher(rc4Key)
cipher1.XORKeyStream(dest1, needRC4)
log.Printf("cz [r=%d] -[%d]最终报文 dest1=%s", cz.Roadno, sensorData.SensorID, hex.EncodeToString(dest1))
return dest1
}
func (the Adaptor_OLCZ_CQZG) getVehType(Carmodel string) (VehType int32) {
switch Carmodel {
case "A":
VehType = 1
case "B":
VehType = 2
case "C":
VehType = 3
case "D":
VehType = 4
case "E":
VehType = 5
case "F":
VehType = 6
case "G":
VehType = 7
case "H":
VehType = 8
case "I":
VehType = 9
}
return
}
func (the Adaptor_OLCZ_CQZG) getSensorId(rawSensorName string) int64 {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = 0
}
return v
}
// 称重软件 传感器车道和对方平台id对于关系
//var idMapCZ = map[string]int64{
// "1": 5000200024,
// "2": 5000200025,
// "3": 5000200026,
//}

156
adaptors/知物云主题数据to广州高支模省平台.go

@ -0,0 +1,156 @@
package adaptors
import (
"encoding/json"
"fmt"
"goUpload/consumers/GZGZM"
"goUpload/models"
"log"
"math"
"strconv"
"time"
)
// Adaptor_THEME_GZGZM 知物云kafka主题数据 转换 广东省高支模平台
type Adaptor_THEME_GZGZM struct {
GZGZM.SensorConfig
}
func (the Adaptor_THEME_GZGZM) Transform(topic, rawMsg string) []byte {
theme := models.SavoirTheme{}
json.Unmarshal([]byte(rawMsg), &theme)
return the.Theme2GzGZM(theme)
}
func (the Adaptor_THEME_GZGZM) Theme2GzGZM(theme models.SavoirTheme) (result []byte) {
Atime, err := time.Parse("2006-01-02T15:04:05.000+0800", theme.AcqTime)
if err != nil {
log.Printf("知物云 测点[%s] 数据时间 %s 解析错误", theme.Station.Name, theme.AcqTime)
return
}
timeStr := Atime.Format("2006-01-02 15:04:05")
inStationId := strconv.Itoa(theme.Station.Id)
outStationInfo := the.getSensorId(inStationId)
postData := GZGZM.PostData{
MonitorDataId: fmt.Sprintf("%d_%d", theme.Station.Id, Atime.Unix()),
UploadTime: timeStr,
StartTime: timeStr,
Contractor: outStationInfo.Contractor, //厂商编号
Type: GZGZM.MonitorTypeCodeZL, //监测类型code
DeviceSn: outStationInfo.DeviceSn, //设备code
DeviceIp: outStationInfo.DeviceIp, //设备ip(可不)
Soc: 100, //设备电量
MeasuredPoint: outStationInfo.Code, //测点编号(高支模平台点id)
BranchCode: outStationInfo.BranchCode, //分部码
Status: 1, //数据状态 1正常 2预警 3报警
Data: GZGZM.PointData{
Unit: GZGZM.UnitZL,
MeasuredValue1: 0,
CumulativeValue1: 0, //变化量
InitAmount1: outStationInfo.InitAmount1, //初始归0值 (目前看 配置文件中获取较好)
},
}
//var sensorDataList []float32
switch theme.Station.Factor.Id {
case models.Savoir_FactorType_QX_ZL: //x,y,force
if v, ok := theme.Data["force"]; ok {
//赋值
postData.Data.MeasuredValue1 = v
}
case models.Savoir_FactorType_QX_SP: //x,y,displacement
if v, ok := theme.Data["displacement"]; ok {
//赋值
postData.Data.MeasuredValue1 = v
}
case models.Savoir_FactorType_QX_CZ: //x,y,settling
if v, ok := theme.Data["settling"]; ok {
//赋值
postData.Data.MeasuredValue1 = v
}
default:
return
}
//结构转为
result, _ = json.Marshal(postData)
return result
}
func (the Adaptor_THEME_GZGZM) getSensorId(sensorId string) GZGZM.SensorInfo {
s := GZGZM.SensorInfo{}
if v, ok := the.SensorInfoMap[sensorId]; ok {
s = v
}
return s
}
func (the Adaptor_THEME_GZGZM) getCodeBytes(sensorCode int16) []byte {
bytes := make([]byte, 0)
bytes = append(bytes,
byte(sensorCode&0xFF),
byte(sensorCode>>8),
)
return bytes
}
func (the Adaptor_THEME_GZGZM) getTimeBytes(sensorTime time.Time) []byte {
year := int8(sensorTime.Year() - 1900)
month := int8(sensorTime.Month())
day := int8(sensorTime.Day())
hour := int8(sensorTime.Hour())
minute := int8(sensorTime.Minute())
millisecond := uint16(sensorTime.Second()*1000 + sensorTime.Nanosecond()/1e6)
bytes := make([]byte, 0)
bytes = append(bytes,
byte(year),
byte(month),
byte(day),
byte(hour),
byte(minute),
byte(millisecond&0xFF),
byte(millisecond>>8),
)
return bytes
}
func (the Adaptor_THEME_GZGZM) getDatasBytes(datas []float32) []byte {
bytes := make([]byte, 0)
for _, data := range datas {
bits := math.Float32bits(data)
bytes = append(bytes,
byte(bits&0xFF),
byte(bits>>8&0xFF),
byte(bits>>16&0xFF),
byte(bits>>24&0xFF),
)
}
return bytes
}
func (the Adaptor_THEME_GZGZM) getPayloadHeader(floatCount int16) []byte {
bytes := make([]byte, 0)
bytes = append(bytes,
//报文类型
0x02,
0x00,
//1:上行信息
0x01,
//默认,通讯计算机编号
0x00,
//命令码
0x01,
//报文长度
byte((floatCount*4+9)&0xFF),
byte((floatCount*4+9)>>8),
)
return bytes
}

85
adaptors/统一采集to明月峡.go

@ -0,0 +1,85 @@
package adaptors
import (
"encoding/json"
"fmt"
"goUpload/models"
"log"
"strings"
"time"
)
// Adaptor_TYCJ_MYX 统一采集软件数据 转换 明月峡-长江大桥
type Adaptor_TYCJ_MYX struct {
IdMap map[string]string
}
func (the Adaptor_TYCJ_MYX) Transform(rawMsg string) []byte {
tycj := models.TYCJ{}
json.Unmarshal([]byte(rawMsg), &tycj)
return the.TYCJtoMYCInflux(tycj)
}
func (the Adaptor_TYCJ_MYX) TYCJtoMYCInflux(tycj models.TYCJ) (result []byte) {
Atime, err := time.Parse("2006-01-02T15:04:05.000", tycj.SensorData.Time)
if err != nil {
log.Printf("统一采集 设备[%s] 数据时间 %s 解析错误", tycj.SensorData.Name, tycj.SensorData.Time)
return
}
sensorCode := the.getSensorId(tycj.SensorData.Name)
tableName, fields := the.getFactorFields(tycj.SensorData.FactorType)
if sensorCode == "" || tableName == "" || len(fields) == 0 || len(fields) > len(tycj.SensorData.Data.ThemeValues) {
log.Printf("统一采集 设备[%s] 数据时间 %s 无匹配 sensorCode=%s,tableName=%s,fields=%s",
tycj.SensorData.Name, tycj.SensorData.Time, sensorCode, tableName, fields)
return
}
//insert ND_data,sensor_id=ND000101 valueV=0.68,valueH=290
var sqlBuilder strings.Builder
sqlBuilder.WriteString(fmt.Sprintf("%s,sensor_id=%s ", tableName, sensorCode))
for i, field := range fields {
sqlBuilder.WriteString(fmt.Sprintf("%s=%f,", field, tycj.SensorData.Data.ThemeValues[i]))
}
sqlStr := sqlBuilder.String()
sqlStr = sqlStr[:len(sqlStr)-1]
sqlStr += fmt.Sprintf(" %d", Atime.Add(-8*time.Hour).UnixNano())
log.Printf("TYCJ [f=%d]-[%s]-[%s]报文=%s 设备时间%v", tycj.SensorData.FactorType, tycj.SensorData.Name,
sensorCode, sqlStr, Atime)
return []byte(sqlStr)
}
func (the Adaptor_TYCJ_MYX) getSensorId(rawSensorName string) string {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = ""
}
return v
}
func (the Adaptor_TYCJ_MYX) getFactorFields(floatCount int) (tableName string, fields []string) {
//这个对应关系 要看现场聚集的统一采集软件 进行调整
switch floatCount {
case 5: //温湿度 1个
tableName = "WSDJC"
fields = []string{"value", "value_2"}
case 18: //风速风向 共2个
tableName = "FSFXJC"
fields = []string{"value", "value_2"}
case 20: //塔顶倾斜 共2个 角度设备 -》对应时序库的 主塔位监测 微信群确认
tableName = "ZTWJC"
fields = []string{"value", "value_2"}
case 90: //桥头倾斜 -》 梁端转角
tableName = "LDZJJC"
fields = []string{"value", "value_2"}
case 22: //伸缩缝 2个
tableName = "SSFJC"
fields = []string{"value"}
default:
fields = []string{}
}
return tableName, fields
}

93
adaptors/统一采集to江苏省农村公路桥梁监测.go

@ -0,0 +1,93 @@
package adaptors
import (
"encoding/json"
"fmt"
"goUpload/models"
"goUpload/utils"
"log"
"time"
)
// Adaptor_TYCJ_JSNCGLQL 统一采集软件数据 转换 江苏农村公路桥梁监测系统
type Adaptor_TYCJ_JSNCGLQL struct {
IdMap map[string]string
}
func (the Adaptor_TYCJ_JSNCGLQL) Transform(rawMsg string) []NeedPush {
tycj := models.TYCJ{}
json.Unmarshal([]byte(rawMsg), &tycj)
return the.TYCJtoJSNCGLQL(tycj)
}
func (the Adaptor_TYCJ_JSNCGLQL) TYCJtoJSNCGLQL(tycj models.TYCJ) (result []NeedPush) {
Atime, err := time.Parse("2006-01-02T15:04:05.000", tycj.SensorData.Time)
if err != nil {
log.Printf("统一采集 设备[%s] 数据时间 %s 解析错误", tycj.SensorData.Name, tycj.SensorData.Time)
return
}
var sensorDataList []float32
switch tycj.SensorData.FactorType {
case models.TYCJ_FactorType_YLYB, models.TYCJ_FactorType_DTQYB: //应变23,挡土墙应变13 FS-BM50
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
case models.TYCJ_FactorType_QDQX: //桥墩倾斜20 X (mm) Y (mm)
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[1])
default:
log.Printf("监测因素[%d] 无匹配", tycj.SensorData.FactorType)
return
}
var transBytes []byte
//1.添加时间段
transBytes = append(transBytes, the.getTimeBytes(Atime)...)
//2.获取对方系统 id
sensorCode := the.getSensorCode(tycj.SensorData.Name)
if sensorCode == "" {
log.Printf("统一采集 设备[%s] 无匹配的 江苏农村公路桥梁监测系统 测点id,请检查配置文件", tycj.SensorData.Name)
return
}
//todo 桥梁编码
bridgeCode := sensorCode
topic := fmt.Sprintf("data/%s/%s", bridgeCode, sensorCode)
for _, sensorData := range sensorDataList {
//4.添加数据值段
bs := utils.Float32ToBytes(sensorData)
transBytes = append(transBytes, bs...)
}
result = append(result, NeedPush{
Topic: topic,
Payload: transBytes,
})
return result
}
func (the Adaptor_TYCJ_JSNCGLQL) getSensorCode(rawSensorName string) string {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = ""
}
return v
}
func (the Adaptor_TYCJ_JSNCGLQL) getTimeBytes(sensorTime time.Time) []byte {
year := uint16(sensorTime.Year())
month := int8(sensorTime.Month())
day := int8(sensorTime.Day())
hour := int8(sensorTime.Hour())
minute := int8(sensorTime.Minute())
second := int8(sensorTime.Second())
bytes := make([]byte, 0)
bytes = append(bytes,
byte(year),
byte(month),
byte(day),
byte(hour),
byte(minute),
byte(second),
)
return bytes
}

156
adaptors/统一采集to湘潭健康监测.go

@ -0,0 +1,156 @@
package adaptors
import (
"encoding/hex"
"encoding/json"
"goUpload/models"
"log"
"math"
"time"
)
// Adaptor_TYCJ_XTJC 统一采集软件数据 转换 湘潭健康监测平台
type Adaptor_TYCJ_XTJC struct {
IdMap map[string]int16
}
func (the Adaptor_TYCJ_XTJC) Transform(rawMsg string) [][]byte {
tycj := models.TYCJ{}
json.Unmarshal([]byte(rawMsg), &tycj)
return the.TYCJtoXTJC(tycj)
}
func (the Adaptor_TYCJ_XTJC) TYCJtoXTJC(tycj models.TYCJ) (result [][]byte) {
Atime, err := time.Parse("2006-01-02T15:04:05.000", tycj.SensorData.Time)
if err != nil {
log.Printf("统一采集 设备[%s] 数据时间 %s 解析错误", tycj.SensorData.Name, tycj.SensorData.Time)
return
}
var sensorDataList []float32
switch tycj.SensorData.FactorType {
case models.TYCJ_FactorType_QLSSF: //桥梁伸缩缝监测22
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
case models.TYCJ_FactorType_YLYB, models.TYCJ_FactorType_DTQYB: //应变23,挡土墙应变13
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
case models.TYCJ_FactorType_RD: //扰度31
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
case models.TYCJ_FactorType_QDQX: //桥墩倾斜20 X (mm) Y (mm) Z (mm) 温度(℃) 20240315对方要求每个监测项 分开上报
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[1])
case models.TYCJ_FactorType_LF: //裂缝28
sensorDataList = append(sensorDataList, tycj.SensorData.Data.ThemeValues[0])
default:
log.Printf("监测因素[%d] 无匹配", tycj.SensorData.FactorType)
return
}
for i, sensorData := range sensorDataList {
var transBytes []byte
//1.添加通用报文头段
commPayloadHeader := the.getPayloadHeader(int16(1)) //20240315 客户确认 如双轴倾角 改成2条上报
transBytes = append(transBytes, commPayloadHeader...)
//2.添加时间段
transBytes = append(transBytes, the.getTimeBytes(Atime)...)
//3.添加对象码段
sensorCode := the.getSensorId(tycj.SensorData.Name)
if i == 1 {
//2项数据的目前只有倾斜 2桥 =》 Y轴id=X轴id+39 1桥=》Y轴id=X轴id+10000
sensorCode = sensorCode + 39
}
//
if sensorCode != 0 {
transBytes = append(transBytes, the.getCodeBytes(sensorCode)...)
} else {
log.Printf("统一采集 设备[%s] 无匹配的湘潭监测id,请检查配置文件", tycj.SensorData.Name)
return
}
d := []float32{sensorData}
//4.添加数据值段
transBytes = append(transBytes, the.getDatasBytes(d)...)
log.Printf("TYCJ [f=%d]-[%s]-[%d]-[%d]报文=%s", tycj.SensorData.FactorType, tycj.SensorData.Name, i,
the.getSensorId(tycj.SensorData.Name),
hex.EncodeToString(transBytes))
result = append(result, transBytes)
}
return result
}
func (the Adaptor_TYCJ_XTJC) getSensorId(rawSensorName string) int16 {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = 0
}
return v
}
func (the Adaptor_TYCJ_XTJC) getCodeBytes(sensorCode int16) []byte {
bytes := make([]byte, 0)
bytes = append(bytes,
byte(sensorCode&0xFF),
byte(sensorCode>>8),
)
return bytes
}
func (the Adaptor_TYCJ_XTJC) getTimeBytes(sensorTime time.Time) []byte {
year := int8(sensorTime.Year() - 1900)
month := int8(sensorTime.Month())
day := int8(sensorTime.Day())
hour := int8(sensorTime.Hour())
minute := int8(sensorTime.Minute())
millisecond := uint16(sensorTime.Second()*1000 + sensorTime.Nanosecond()/1e6)
bytes := make([]byte, 0)
bytes = append(bytes,
byte(year),
byte(month),
byte(day),
byte(hour),
byte(minute),
byte(millisecond&0xFF),
byte(millisecond>>8),
)
return bytes
}
func (the Adaptor_TYCJ_XTJC) getDatasBytes(datas []float32) []byte {
bytes := make([]byte, 0)
for _, data := range datas {
bits := math.Float32bits(data)
bytes = append(bytes,
byte(bits&0xFF),
byte(bits>>8&0xFF),
byte(bits>>16&0xFF),
byte(bits>>24&0xFF),
)
}
return bytes
}
func (the Adaptor_TYCJ_XTJC) getPayloadHeader(floatCount int16) []byte {
bytes := make([]byte, 0)
bytes = append(bytes,
//报文类型
0x02,
0x00,
//1:上行信息
0x01,
//默认,通讯计算机编号
0x00,
//命令码
0x01,
//报文长度
byte((floatCount*4+9)&0xFF),
byte((floatCount*4+9)>>8),
)
return bytes
}

125
adaptors/统一采集to重庆资管.go

@ -0,0 +1,125 @@
package adaptors
import (
"crypto/rc4"
"encoding/hex"
"encoding/json"
"goUpload/consumers/CQZG/protoFiles"
"goUpload/models"
"goUpload/utils"
"google.golang.org/protobuf/proto"
"log"
"time"
)
// Adaptor_TYCJ_CQZG 统一采集软件数据转换器
type Adaptor_TYCJ_CQZG struct {
IdMap map[string]int64
RC4Key string
}
func (the Adaptor_TYCJ_CQZG) Transform(rawMsg string) []byte {
tycj := models.TYCJ{}
json.Unmarshal([]byte(rawMsg), &tycj)
return the.TYCJtoCQZG(tycj)
}
func (the Adaptor_TYCJ_CQZG) TYCJtoCQZG(tycj models.TYCJ) (result []byte) {
Atime, err := time.Parse("2006-01-02T15:04:05.000", tycj.SensorData.Time)
if err != nil {
log.Printf("统一采集数据时间 %s 解析错误 ", tycj.SensorData.Time)
Atime = time.Now()
}
var transBytes []byte
switch tycj.SensorData.FactorType {
case models.TYCJ_FactorType_WSD:
ComplexData_WSD := &protoFiles.ComplexData{
SensorData: make([]*protoFiles.SensorData, 0),
}
sensorData := &protoFiles.SensorData{
MonitorType: the.getMonitorType(tycj.SensorData.FactorType), //监测类型 转换
SensorID: the.getSensorId(tycj.SensorData.Name), //id转换
EventTime: Atime.Add(-8 * time.Hour).UnixMilli(),
ChannelCode: "",
DataBody: &protoFiles.SensorData_Rhs{
Rhs: &protoFiles.RHSRealTime{
Temperature: []float32{tycj.SensorData.Data.ThemeValues[0]},
Humidity: []float32{tycj.SensorData.Data.ThemeValues[1]},
},
},
}
ComplexData_WSD.SensorData = append(ComplexData_WSD.SensorData, sensorData)
transBytes, _ = proto.Marshal(ComplexData_WSD)
case models.TYCJ_FactorType_YLYB: //应变 特殊 要把温度拆开为独立数据
ComplexData_YLYB := &protoFiles.ComplexData{
SensorData: make([]*protoFiles.SensorData, 0),
}
sensorData := &protoFiles.SensorData{
MonitorType: the.getMonitorType(tycj.SensorData.FactorType), //监测类型 转换
SensorID: the.getSensorId(tycj.SensorData.Name), //id转换
EventTime: Atime.Add(-8 * time.Hour).UnixMilli(),
ChannelCode: "",
DataBody: &protoFiles.SensorData_Rsg{
Rsg: &protoFiles.RSGRealTime{
Strain: []float32{tycj.SensorData.Data.ThemeValues[0]},
Temperature: []float32{tycj.SensorData.Data.RawValues[1]},
},
},
}
ComplexData_YLYB.SensorData = append(ComplexData_YLYB.SensorData, sensorData)
TYCJStr, _ := json.Marshal(ComplexData_YLYB)
log.Printf("TYCJ [f=%d] -[%s]-[%d]原始报文=%s",
tycj.SensorData.FactorType,
tycj.SensorData.Name,
the.getSensorId(tycj.SensorData.Name),
TYCJStr)
transBytes, _ = proto.Marshal(ComplexData_YLYB)
}
log.Printf("TYCJ [f=%d] -[%s]-[%d]报文proto.Marshal=%s",
tycj.SensorData.FactorType,
tycj.SensorData.Name,
the.getSensorId(tycj.SensorData.Name),
hex.EncodeToString(transBytes))
resultByCrc16 := utils.NewCRC16CCITT().GetWCRCin(transBytes)
needRC4 := append(transBytes, resultByCrc16...)
log.Printf("needRC4=%s", hex.EncodeToString(needRC4))
rc4Key := []byte(the.RC4Key)
// 加密操作
dest1 := make([]byte, len(needRC4))
rc4.NewCipher(rc4Key)
cipher1, _ := rc4.NewCipher(rc4Key)
cipher1.XORKeyStream(dest1, needRC4)
log.Printf("rc4加密结果=> %s ", hex.EncodeToString(dest1))
return dest1
}
func (the Adaptor_TYCJ_CQZG) getMonitorType(rawId int) (MonitorType protoFiles.MonitoryType) {
switch rawId {
case models.TYCJ_FactorType_YLYB:
MonitorType = protoFiles.MonitoryType_RSG
default:
MonitorType = protoFiles.MonitoryType_CMM
}
return
}
func (the Adaptor_TYCJ_CQZG) getSensorId(rawSensorName string) int64 {
v, isValid := the.IdMap[rawSensorName]
if !isValid {
v = 0
}
return v
}
// 统一采集软件 传感器名称和对方平台id对于关系
//var idMapTYCJ = map[string]int64{
// "GXGL-G-03": 5000200001,
// "GXGL-P-01": 5000200002,
// "GXGL-G-01": 5000200003,
//}

60
adaptors/视觉位移to魏家滑坡.go

@ -0,0 +1,60 @@
package adaptors
import (
"encoding/json"
"fmt"
"goUpload/consumers/WJHP"
"log"
"strconv"
"time"
)
// Adaptor_SJWY_WJHP 飞尚视觉位移 转换 魏家滑坡+实验室
type Adaptor_SJWY_WJHP struct {
IdMap WJHP.SensorConfig
}
func (the Adaptor_SJWY_WJHP) Transform(topic, rawMsg string) []byte {
return the.GDRDtoUpload(topic, rawMsg)
}
func (the Adaptor_SJWY_WJHP) GDRDtoUpload(devModule, rawRecords string) (result []byte) {
log.Printf("收到模块号[%s]设备mq数据:%s", devModule, rawRecords)
d := WJHP.PosData{}
err := json.Unmarshal([]byte(rawRecords), &d)
if err != nil {
return nil
}
sensorInfo := the.matchStationId(devModule)
if sensorInfo.StationId == 0 {
return nil
}
rp := devToUpload(d)
deviceId := strconv.Itoa(sensorInfo.StationId)
upData := WJHP.UploadHistoryData{
DeviceId: deviceId,
Apikey: sensorInfo.AppKey,
Data: map[string]WJHP.HistoryData{
deviceId: rp,
},
}
result, _ = json.Marshal(upData)
return result
}
func (the Adaptor_SJWY_WJHP) matchStationId(devId string) (sensorInfo WJHP.SensorInfo) {
if v, ok := the.IdMap.SjwySensorInfo[devId]; ok {
sensorInfo = v
} else {
log.Printf("未匹配到设备[%s]的stationId", devId)
}
return sensorInfo
}
func devToUpload(deviceData WJHP.PosData) (result WJHP.HistoryData) {
k := deviceData.Timestamp.Add(time.Hour * -8).Format("2006-01-02T15:04:05.000Z")
d := WJHP.HistoryData{
L1_GP_1: map[string]string{
k: fmt.Sprintf("%0.3f,%0.3f,%0.3f", deviceData.XReal, 0.0, deviceData.YReal),
},
}
return d
}

16
build/Dockerfile

@ -0,0 +1,16 @@
FROM registry.ngaiot.com/base-images/golang:1.20-fs-10
WORKDIR /app/
COPY . .
RUN pwd && ls
RUN go env -w GOPROXY=https://goproxy.cn
RUN go env -w GO111MODULE=on
RUN CGO_ENABLED=0 go build -a -v -o app.exe main.go
FROM registry.ngaiot.com/base-images/golang:1.20-fs-10
WORKDIR /app/
COPY --from=0 /app/app.exe /app
COPY --from=0 /app/configFiles /app
CMD ["/app/app.exe"]

21
build/bin/商用备份/龙河桥/upload/configMqtt.json

@ -0,0 +1,21 @@
{
"inMqtt": {
"host": "192.168.59.245",
"port": 1883,
"userName": "lzwjdq500101-in",
"password": "123456",
"clientId": "id-in-123",
"Topics": ["upload/#"]
},
"outMqtt": {
"host": "192.168.58.232",
"port": 9999,
"userName": "lhq500103",
"password": "MzeQkzLAyF2U",
"clientId": "lhq500103_1",
"Topics": ["t/500103"]
},
"rc4key": "t/500103"
}

41
build/bin/商用备份/龙河桥/upload/configSensor.json

@ -0,0 +1,41 @@
{
"TYCJsensorNameMap": {
"LHTDQ-RSG-L04-001-01": 5001030037,
"LHTDQ-RSG-L04-001-02": 5001030038,
"LHTDQ-RSG-L04-001-03": 5001030039,
"LHTDQ-RSG-L04-001-04": 5001030040,
"LHTDQ-RSG-L06-001-01": 5001030041,
"LHTDQ-RSG-L06-001-02": 5001030042,
"LHTDQ-RSG-L07-001-01": 5001030043,
"LHTDQ-RSG-L07-001-02": 5001030044,
"LHTDQ-RSG-L04-001-05": 5001030045,
"LHTDQ-RSG-L04-001-06": 5001030046,
"LHTDQ-RSG-L04-001-07": 5001030047,
"LHTDQ-RSG-L04-001-08": 5001030048,
"LHTDQ-RSG-L06-001-03": 5001030049,
"LHTDQ-RSG-L06-001-04": 5001030050,
"LHTDQ-RSG-L07-001-03": 5001030051,
"LHTDQ-RSG-L07-001-04": 5001030052
},
"CZsensorRoadnoMap": {
"1": 5001030053,
"2": 5001030054,
"3": 5001030055,
"4": 5001030056
},
"ZDsensorM-CMap": {
"LHTDQ-VIB-L02-001-01": 5001030024,
"LHTDQ-VIB-L03-001-01": 5001030025,
"LHTDQ-VIB-L04-001-01": 5001030026,
"LHTDQ-VIB-L05-001-01": 5001030027,
"LHTDQ-VIB-L08-001-01": 5001030028,
"LHTDQ-VIB-L02-002-01": 5001030029,
"LHTDQ-VIB-L03-002-01": 5001030030,
"LHTDQ-VIB-L04-002-01": 5001030031,
"LHTDQ-VIB-L05-002-01": 5001030032,
"LHTDQ-VIB-L08-002-01": 5001030033,
"LHTDQ-VIE-D06-001-01-X": 5001030034,
"LHTDQ-VIE-D06-001-01-Y": 5001030035,
"LHTDQ-VIE-D06-001-01-Z": 5001030036
}
}

12430
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T03-18-11.040.log

File diff suppressed because it is too large

12355
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T03-34-20.312.log

File diff suppressed because it is too large

12494
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T03-51-11.531.log

File diff suppressed because it is too large

12593
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-08-33.900.log

File diff suppressed because it is too large

12571
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-25-47.510.log

File diff suppressed because it is too large

12508
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-42-37.855.log

File diff suppressed because it is too large

12585
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T04-59-53.197.log

File diff suppressed because it is too large

12518
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T05-16-53.476.log

File diff suppressed because it is too large

12533
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T05-33-50.803.log

File diff suppressed because it is too large

12473
build/bin/商用备份/龙河桥/upload/logs/logInfo-2023-11-28T05-50-39.154.log

File diff suppressed because it is too large

23
build/bin/商用备份/龙河桥/upload/logs/logInfo.log

@ -0,0 +1,23 @@
2023/11/28 13:50:39 mqtt-recv:[upload/ZD/LHTDQ-VIB-L03-002-01][t/500103]:{"Sensorid":0,"Module":"LHTDQ-VIB-L03-002-01","Channel":0,"ThemeValue":[4.028808 ...
2023/11/28 13:50:39 取出ch数据,剩余[1]
2023/11/28 13:50:39 [振动软件]-上报,准备处理
2023/11/28 13:50:39 推送[t/500103]: len=1307
2023/11/28 13:50:39 收到数据 [51742] TOPIC: upload/ZD/LHTDQ-VIB-L04-002-01,MSGLen: 2170
2023/11/28 13:50:39 mqtt-recv:[upload/ZD/LHTDQ-VIB-L04-002-01][t/500103]:{"Sensorid":0,"Module":"LHTDQ-VIB-L04-002-01","Channel":0,"ThemeValue":[4.763183 ...
2023/11/28 13:50:39 [振动软件]-上报,准备处理
2023/11/28 13:50:39 取出ch数据,剩余[1]
2023/11/28 13:50:39 收到数据 [51743] TOPIC: upload/ZD/LHTDQ-VIB-L05-002-01,MSGLen: 2164
2023/11/28 13:50:39 推送[t/500103]: len=1307
2023/11/28 13:50:39 mqtt-recv:[upload/ZD/LHTDQ-VIB-L05-002-01][t/500103]:{"Sensorid":0,"Module":"LHTDQ-VIB-L05-002-01","Channel":0,"ThemeValue":[3.819335 ...
2023/11/28 13:50:39 [振动软件]-上报,准备处理
2023/11/28 13:50:39 取出ch数据,剩余[1]
2023/11/28 13:50:39 收到数据 [51744] TOPIC: upload/ZD/LHTDQ-VIB-L08-002-01,MSGLen: 2221
2023/11/28 13:50:39 推送[t/500103]: len=1307
2023/11/28 13:50:39 mqtt-recv:[upload/ZD/LHTDQ-VIB-L08-002-01][t/500103]:{"Sensorid":0,"Module":"LHTDQ-VIB-L08-002-01","Channel":0,"ThemeValue":[2.275878 ...
2023/11/28 13:50:39 [振动软件]-上报,准备处理
2023/11/28 13:50:39 取出ch数据,剩余[1]
2023/11/28 13:50:39 推送[t/500103]: len=1307
2023/11/28 13:50:39 取出ch数据,剩余[1]
2023/11/28 13:50:39 推送[t/500103]: len=1307
2023/11/28 13:50:39 取出ch数据,剩余[0]
2023/11/28 13:50:39 推送[t/500103]: len=1307

20
build/bin/商用备份/龙河桥/upload/ssl/centerCA.crt

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIJAM7Nl5kGCS8TMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
Q29tcGFueSBMdGQwHhcNMjMxMDI1MDYyNTE2WhcNMzMxMDIyMDYyNTE2WjBCMQsw
CQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZh
dWx0IENvbXBhbnkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
4ahzVwl/etMwmaLAIFpkce65zV274AxznlW+w0ygXsPBPM1jtiILyyztYrP37uTG
5Hcg6UY460rT6BOb0Gx697VHI7jfwqbdhNh89lAhktZVk9AkUEa1bD/+NiLZKgNq
mUjmd7ILkTHGWOzdlyURxMfcHG4Lx+wwZO0rw3J7R4l7f1qFemHYtRK1AKdRnVBn
p3TL0nkkx86FwDxhHtcLlkW6GfDGCg6/oZyndFcPH8jOXpduQMtiVfKP9ALJLDfI
cKczvmyNbLCCkksa1gY0H+QYLxYXIW86nKDJA2RbtKuUK4ZMCYijCXQfwwq8nfPf
TqpYSGL9P0z7G6YElkblnQIDAQABo1AwTjAdBgNVHQ4EFgQUtZOYDqeF99820Gh5
iCJRzu+JFZYwHwYDVR0jBBgwFoAUtZOYDqeF99820Gh5iCJRzu+JFZYwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA3bWDFpGTAlbqp8czhlCVFdrKejye
uSdTqh8Q++eiYbBfup5cyFqAxVyqjZZuE02DcYxJLcj0DW2M0YUDDfsGg7SfF0oV
zUwseJqlIlaIYapJK8aMefp0U7CNJXyqKQSyFO9H3X9qboDs+o1SqFwsDYBO/6r0
QflTYFLYiW3WbM7Tl/IP61SVKW7SAIzhg0n6G7jLCdKlxjsbrSlYuZs+mU5xfVv3
nG7HCipEwVCjusi4Tu8sQVHreiYPKlfrXq0c/vQGS+XznSTzWGnEYsHpBAkObrDo
Z9LqELndCUh1hMwO615tLVN0q1EKVpAXCOwwF956I16vQ7MdmpzPgK6MVA==
-----END CERTIFICATE-----

26
build/bin/重庆资管/数据样例/外购-称重数据样例.json

@ -0,0 +1,26 @@
{
"roadno": 4,
"speed": 124,
"AxisCount": 2,
"AxleGrplum": 2,
"AxieWeight1": 1259,
"AxieWeight2": 1231,
"AxieWeight3": 0,
"AxieWeight4": 0,
"AxieWeight5": 0,
"AxieWeight6": 0,
"AxieWeight7": 0,
"AxieWeight8": 0,
"AxieWeight9": 0,
"AxieWeight10": 0,
"GrossWeight": 2490,
"operDirec": 1,
"strTimeYear": "",
"carmodel": "A",
"carlen": 4.2,
"license": "",
"LimitWeight": 0,
"IP": "10.27.171.207",
"DataState": 0,
"atime": "2024-06-03 10:37:01"
}

335
build/bin/重庆资管/数据样例/振动数据样例.json

@ -0,0 +1,335 @@
{
"Sensorid": 0,
"Module": "ZD001",
"Channel": 0,
"Frequency": 64,
"ThemeValue": [
999.5325927734375
],
"RawValues": [
],
"AccValues": [
355.161,
129.481,
582.636,
101.279,
561.869,
346.186,
770.402,
864.968,
691.056,
761.111,
976.796,
586.141,
171.401,
357.876,
690.816,
203.352,
510.548,
0.172,
215.837,
277.666,
642.827,
939.431,
86.949,
735.316,
376.541,
2.991,
84.409,
659.925,
586.231,
541.106,
52.137,
491.491,
376.032,
572.095,
506.356,
352.586,
116.435,
859.67,
2.938,
60.154,
903.874,
59.496,
139.72,
952.416,
164.235,
672.223,
446.79,
662.771,
58.282,
395.8,
828.188,
525.992,
662.371,
583.415,
393.231,
415.73,
42.531,
847.32,
724.737,
558.878,
261.778,
110.477,
278.737,
149.95,
708.974,
485.306,
210.109,
599.306,
851.52,
338.23,
86.918,
650.878,
997.234,
155.683,
373.792,
583.331,
799.71,
134.534,
571.081,
704.319,
556.201,
421.638,
601.644,
190.431,
712.918,
526.145,
829.119,
792.617,
178.864,
90.626,
310.054,
269.115,
134.933,
444.06,
798.377,
793.397,
780.759,
989.77,
243.442,
678.929,
462.114,
847.484,
811.25,
720.051,
308.882,
177.311,
528.758,
506.689,
209.623,
809.9,
616.019,
907.997,
276.238,
20.419,
2.677,
840.14,
508.833,
88.306,
437.032,
182.829,
656.187,
417.492,
420.442,
760.895,
28.176,
817.803,
104.335,
16.133,
103.699,
749.827,
777.756,
510.215,
718.825,
996.351,
340.959,
523.697,
441.778,
481.867,
792.584,
937.787,
288.622,
915.982,
298.555,
360.119,
327.327,
479.646,
6.729,
75.693,
269.34,
984.295,
20.987,
171.266,
146.076,
989.346,
130.844,
359.154,
848.001,
37.223,
741.701,
527.604,
742.288,
732.951,
727.68,
16.578,
360.587,
348.794,
784.157,
729.756,
767.163,
779.208,
288.641,
362.138,
984.054,
884.711,
678.391,
705.011,
890.179,
680.627,
349.459,
474.114,
11.145,
28.642,
746.793,
119.404,
728.84,
606.491,
364.139,
729.478,
865.507,
981.804,
675.696,
404.555,
740.166,
264.98,
195.499,
555.671,
188.302,
281.977,
999.533,
978.533,
695.489,
276.974,
308.53,
490.133,
695.654,
658.849,
187.212,
261.365,
310.955,
425.834,
468.975,
167.374,
687.764,
267.587,
516.459,
713.646,
986.158,
608.276,
287.737,
754.096,
984.655,
54.679,
864.249,
785.358,
103.512,
884.086,
621.971,
719.074,
689.212,
122.72,
516.709,
608.201,
681.095,
370.926,
778.625,
734.171,
720.112,
256.66,
423.751,
69.991,
419.279,
102.774,
418.523,
439.673,
512.829,
508.322,
716.791,
472.579,
748.521,
481.853,
569.512,
580.025,
375.935,
196.204,
323.75,
611.819,
445.13,
548.142,
115.304,
629.419,
114.578,
655.034,
643.489,
158.308,
101.217,
37.953,
586.399,
253.133,
506.922,
340.066,
465.887,
68.832,
503.502,
457.292,
620.736,
582.619,
763.438,
982.724,
67.508,
938.375,
951.671,
982.562,
13.043,
846.362,
509.494,
508.183,
327.399,
156.654,
167.276,
854.984,
889.487,
205.237,
432.137,
677.839,
966.752,
719.164,
940.283,
932.693,
861.539,
122.316,
396.194,
146.391,
68.349,
285.963,
763.303,
568.54,
829.288,
918.643,
575.468,
741.131,
848.381,
462.406,
480.634,
176.929,
677.748,
132.016,
641.991,
797.128,
648.814,
593.034
],
"Ticks": 1703128511937
}

27
build/bin/重庆资管/数据样例/称重数据样例.json

@ -0,0 +1,27 @@
{
"roadno": 1,//
"speed": 17, //km/h
"AxisCount": 2, //
"AxieWeight1": 15500, //1 kg
"AxieWeight2": 17300, //2 kg
"AxieWeight3": 0,
"AxieWeight4": 0,
"AxieWeight5": 0,
"AxieWeight6": 0,
"AxieWeight7": 0,
"AxieWeight8": 0,
"AxieWeight9": 0,
"AxieWeight10": 0,
"GrossWeight": 32800, // kg
"operDirec": 0 //
"strTimeYear": "2023-10-25 15:00:36+08:00",//
"carmodel": 0, //0 1
// 0- 1- 2- 3-轿 4- 5- 6 7- 8 9-SUV/MPV 10- 11- 12- 13-轿 14-轿 15- 16-
"carlen": 0, //m
"license": "苏LG765L", //
"LimitWeight": 0, // kg
"IP": "127.0.0.1", //ip
"DataState": 1, // 0 1
"atime": "2023-10-25T15:00:36+08:00" //
}

26
build/bin/重庆资管/数据样例/统一采集软件样例.json

@ -0,0 +1,26 @@
{
"dtuInfo": {
"id": 0,
"code": "20230918"
},
"sensorData": {
"id": 7,
"name": "温湿度122",
"module": "2",
"channel": "2",
"factorType": 5,
"productCode": "FS-TRWSD-MX",
"structId": 0,
"data": {
"RawValues": [
13.5,
23.9
],
"ThemeValues": [
13.5,
23.9
]
},
"time": "2023-11-07T10:40:04.000"
}
}

81
build/goupload.yaml

@ -0,0 +1,81 @@
apiVersion: apps/v1 #指定API版本标签
kind: Deployment #定义资源的类型/角色,deployment为控制器,service,endpoints
metadata: #定义资源的元数据信息
name: goupload-deployment #定义资源的名称,在同一个namespace空间中必须是唯一的
namespace: lk #默认default
labels: #定义资源标签
app: yaml-goupload-d
spec:
replicas: 1 #定义副本数量
selector: #定义选择器
matchLabels: #匹配上边的标签
app: yaml-goupload-d #名称
template: #定义模板
metadata:
labels:
app: yaml-goupload-d
spec:
containers:
- name: yaml-goupload #容器名,与标签名要相同
image: registry.ngaiot.com/local/git-goupload-image:12
imagePullPolicy: IfNotPresent
volumeMounts:
- name: config
subPath: config.json
mountPath: /app/configFiles/config_魏家滑坡_视觉位移.json
volumes: # volumes和container处于同一层级,别搞错了
- name: config
configMap:
name: config-goupload
---
apiVersion: v1
kind: ConfigMap
metadata:
name: config-goupload
namespace: lk
data: #监测因素 统计字段表
config.json: |
{
"consumer": "consumerWJHP",
"ioConfig": {
"inMqtt": {
"host": "218.3.126.49",
"port": 1883,
"userName": "wjhp-sjwy-upload",
"password": "123456",
"clientId": "wjhp-sjwy-upload",
"Topics": [
"/fs-flexometer/admin123"
]
},
"outHttp": {
"url": "http://111.74.0.226:10010/api/devices/datapoints?type=2",
"method": "post"
}
},
"sensors": {
"sjwySensorInfo": {
"admin123-1": {
"name": "WJHP-SJWY01",
"stationId": 20263956,
"appKey": "72e6ait21ux9o853",
"monitorType": "L1_GP_1"
},
"admin123-2": {
"name": "WJHP-SJWY02",
"stationId": 38324713,
"appKey": "yk351ar0rfv59dw7",
"monitorType": "L1_GP_1"
},
"admin123-3": {
"name": "WJHP-SJWY03",
"stationId": 89889930,
"appKey": "gkstwl07e66e403l",
"monitorType": "L1_GP_1"
}
}
}
}

24
build/jenkinsfile

@ -0,0 +1,24 @@
podTemplate {
node('pod-templ-jenkins-slave-golang') {
env.IMAGE_NAME = "${IOT_IMAGES_REGISTRY}/${LOCAL}/${JOB_NAME}"
env.IMAGE_NAME_SHORT = "${LOCAL}/${JOB_NAME}"
env.CODE_ADDR = "${GIT_ADDRESS}/DevOps/goUpload.git"
stage('Run shell') {
git branch: 'develop', credentialsId: 'gitea-builder', url: "${CODE_ADDR}"
container('golang-builder-1-22') {
sh'''
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GO111MODULE=on
CGO_ENABLED=0 go build -ldflags "-extldflags -static " -a -v -o app.exe main.go
tar -cvf out.tar *.exe configFiles/
'''
}
archiveArtifacts artifacts: 'out.tar', followSymlinks: false
buildName "${IMAGE_NAME_SHORT}:${IMAGE_VERSION}"
buildDescription "${IMAGE_NAME}:${IMAGE_VERSION}"
}
}
}

24
build/jenkinsfile_image

@ -0,0 +1,24 @@
podTemplate {
node('pod-templ-jenkins-slave-golang') {
env.IMAGE_NAME = "${IOT_IMAGES_REGISTRY}/${LOCAL}/${JOB_NAME}"
env.IMAGE_NAME_SHORT = "${LOCAL}/${JOB_NAME}"
env.CODE_ADDR = "${GIT_ADDRESS}/DevOps/goUpload.git"
stage('Run shell') {
git branch: 'develop', credentialsId: 'gitea-builder', url: "${CODE_ADDR}"
container('image-builder') {
sh'''
echo "当前目==="
pwd
ls
echo "========"
/kaniko/executor --context=${BUILD_WORKSPACE} --dockerfile=build/Dockerfile --destination=${IMAGE_NAME}:${IMAGE_VERSION} --cache=false --cleanup
'''
}
buildName "${IMAGE_NAME_SHORT}:${IMAGE_VERSION}"
buildDescription "${IMAGE_NAME}:${IMAGE_VERSION}"
}
}
}

68
config/configStruct.go

@ -0,0 +1,68 @@
package config
type Consumer struct {
Consumer string `json:"consumer"`
}
type MqttConfig struct {
Host string `json:"host"`
Port int `json:"port"`
UserName string `json:"userName"`
Password string `json:"password"`
ClientId string `json:"clientId"`
Topics []string `json:"topics"`
}
type KafkaConfig struct {
Brokers []string `json:"brokers"`
GroupId string `json:"groupId"`
Topics []string `json:"topics"`
}
type UdpConfig struct {
Host string `json:"host"`
Port int `json:"port"`
}
type HttpConfig struct {
Url string `json:"url"`
Method string `json:"method"` //post,put,get,delete
Token Token `json:"token,omitempty"`
}
type Token struct {
Static string `json:"static,omitempty"`
RefreshInterval string `json:"refreshInterval,omitempty"`
Url string `json:"url,omitempty"`
AppKey string `json:"appKey,omitempty"`
AppSecret string `json:"appSecret,omitempty"`
}
type FileConfig struct {
Directory string `json:"directory"` //文件目录
FileNameExtension string `json:"fileNameExtension"` //文件拓展名 如"*.csv,*.txt"
}
type FileMonitorConfig struct {
FileConfig
CronStr string `json:"cronStr"`
}
//type configFile struct {
// Consumer
// IOConfig string `json:"config"`
// SensorMap string `json:"sensorMap"`
//}
//
//type UserConfig struct {
// InMqtt MqttConfig `json:"inMqtt"`
// OutMqtt MqttConfig `json:"outMqtt"`
// SensorConfig sensorConfig `json:"SensorConfig"`
// Rc4key string `json:"rc4key"`
//}
//
//type sensorConfig struct {
// TYCJsensorNameMap map[string]int64 `json:"TYCJsensorNameMap"`
// CZsensorRoadnoMap map[string]int64 `json:"CZsensorRoadnoMap"`
// ZDsensorMCMap map[string]int64 `json:"ZDsensorM-CMap"`
//}

83
config/init.go

@ -0,0 +1,83 @@
package config
import (
"encoding/json"
"fmt"
"log"
"os"
)
func LoadConfigJson() map[string]string {
//加载目录下所有文件
allConfig := make(map[string]string)
files, err := os.ReadDir("configFiles")
if err != nil {
log.Fatal(err)
}
for _, file := range files {
log.Printf("加载配置文件:%s", file.Name())
if file.IsDir() {
log.Printf("非文件[%s]跳过", file.Name())
continue
}
// 读取mqtt配置
configMqttBytes, _ := os.ReadFile(fmt.Sprintf("configFiles/%s", file.Name()))
consumer := new(Consumer)
// 将 JSON 格式的数据解析到结构体中
err = json.Unmarshal(configMqttBytes, &consumer)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", consumer.Consumer, err.Error())
continue
}
allConfig[consumer.Consumer] = string(configMqttBytes)
//// 读取sensor配置
//configSensorBytes, _ := os.ReadFile("configSensor.json")
//// 将 JSON 格式的数据解析到结构体中
//err2 := json.Unmarshal(configSensorBytes, &userConfig.SensorConfig)
//if err2 != nil {
// log.Printf("读取mqtt配置异常 err=%v", err2.Error())
//}
//allConfig[]
}
return allConfig
}
func LoadConfigJsonByPath(path string) map[string]string {
//加载目录下所有文件
allConfig := make(map[string]string)
files, err := os.ReadDir(path)
if err != nil {
log.Fatal(err)
}
for _, file := range files {
log.Printf("加载配置文件:%s", file.Name())
if file.IsDir() {
log.Printf("非文件[%s]跳过", file.Name())
continue
}
// 读取mqtt配置
filePath := fmt.Sprintf("%s/%s", path, file.Name())
configMqttBytes, _ := os.ReadFile(filePath)
consumer := new(Consumer)
// 将 JSON 格式的数据解析到结构体中
err = json.Unmarshal(configMqttBytes, &consumer)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", consumer.Consumer, err.Error())
continue
}
allConfig[consumer.Consumer] = string(configMqttBytes)
//// 读取sensor配置
//configSensorBytes, _ := os.ReadFile("configSensor.json")
//// 将 JSON 格式的数据解析到结构体中
//err2 := json.Unmarshal(configSensorBytes, &userConfig.SensorConfig)
//if err2 != nil {
// log.Printf("读取mqtt配置异常 err=%v", err2.Error())
//}
//allConfig[]
}
return allConfig
}

41
configFiles/config_魏家滑坡_视觉位移.json

@ -0,0 +1,41 @@
{
"consumer": "consumerWJHP",
"ioConfig": {
"inMqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "wjhp-sjwy-upload",
"password": "123456",
"clientId": "wjhp-sjwy-upload",
"Topics": [
"/fs-flexometer/admin123"
]
},
"outHttp": {
"url": "http://111.74.0.226:10010/api/devices/datapoints?type=2",
"method": "post"
}
},
"sensors": {
"sjwySensorInfo": {
"admin123-1": {
"name": "WJHP-SJWY01",
"stationId": 20263956,
"appKey": "72e6ait21ux9o853",
"monitorType": "L1_GP_1"
},
"admin123-2": {
"name": "WJHP-SJWY02",
"stationId": 38324713,
"appKey": "yk351ar0rfv59dw7",
"monitorType": "L1_GP_1"
},
"admin123-3": {
"name": "WJHP-SJWY03",
"stationId": 89889930,
"appKey": "gkstwl07e66e403l",
"monitorType": "L1_GP_1"
}
}
}
}

69
configFiles/弃用备份/config_CQZG.json

@ -0,0 +1,69 @@
{
"consumer": "consumerCQZG",
"ioConfig": {
"inMqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "lzwjdq500101-in",
"password": "123456",
"clientId": "id-in-123",
"Topics": [
"upload/CZ/+",
"upload/uds/+",
"upload/ZD/LHTDQ-VIB-L02-001-01"
]
},
"outMqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "lhq500103",
"password": "MzeQkzLAyF2U",
"clientId": "lhq500103_lhq",
"Topics": [
"t/500103"
]
},
"rc4key": "t/500103"
},
"sensorMap": {
"TYCJsensorNameMap": {
"LHTDQ-RSG-L04-001-01": 5001030037,
"LHTDQ-RSG-L04-001-02": 5001030038,
"LHTDQ-RSG-L04-001-03": 5001030039,
"LHTDQ-RSG-L04-001-04": 5001030040,
"LHTDQ-RSG-L06-001-01": 5001030041,
"LHTDQ-RSG-L06-001-02": 5001030042,
"LHTDQ-RSG-L07-001-01": 5001030043,
"LHTDQ-RSG-L07-001-02": 5001030044,
"LHTDQ-RSG-L04-001-05": 5001030045,
"LHTDQ-RSG-L04-001-06": 5001030046,
"LHTDQ-RSG-L04-001-07": 5001030047,
"LHTDQ-RSG-L04-001-08": 5001030048,
"LHTDQ-RSG-L06-001-03": 5001030049,
"LHTDQ-RSG-L06-001-04": 5001030050,
"LHTDQ-RSG-L07-001-03": 5001030051,
"LHTDQ-RSG-L07-001-04": 5001030052
},
"CZsensorRoadnoMap": {
"1": 5001030053,
"2": 5001030054,
"3": 5001030055,
"4": 5001030056
},
"ZDsensorM-CMap": {
"LHTDQ-VIB-L02-001-01": 5001030024,
"LHTDQ-VIB-L03-001-01": 5001030025,
"LHTDQ-VIB-L04-001-01": 5001030026,
"LHTDQ-VIB-L05-001-01": 5001030027,
"LHTDQ-VIB-L08-001-01": 5001030028,
"LHTDQ-VIB-L02-002-01": 5001030029,
"LHTDQ-VIB-L03-002-01": 5001030030,
"LHTDQ-VIB-L04-002-01": 5001030031,
"LHTDQ-VIB-L05-002-01": 5001030032,
"LHTDQ-VIB-L08-002-01": 5001030033,
"LHTDQ-VIE-D06-001-01-X": 5001030034,
"LHTDQ-VIE-D06-001-01-Y": 5001030035,
"LHTDQ-VIE-D06-001-01-Z": 5001030036
}
}
}

451
configFiles/弃用备份/config_HTJC2.json

@ -0,0 +1,451 @@
{
"consumer": "consumerHTJC",
"ioConfig": {
"inMqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "xtjc-in",
"password": "123456",
"clientId": "xtjc-in-123",
"topics": [
"upload/uds/+","upload/ZD/+"
]
},
"outUdp": {
"host": "127.0.0.1",
"port": 8888
}
},
"sensorMap": {
"TYCJsensorNameMap": {
"1-QX-1": 12040,
"2-QX-1": 12041,
"3-QX-1": 12042,
"4-QX-1": 12043,
"5-QX-1": 12044,
"6-QX-1": 12045,
"7-QX-1": 12046,
"1-JD-1": 2391,
"2-ND-1": 2392,
"3-ND-1": 2393,
"3-NDZD-1": 2394,
"4-ND-1": 2395,
"5-ND-1": 2396,
"6-ND-1": 2397,
"7-ND-1": 2398,
"7-NDZD-1": 2399,
"2-LF-1": 2438,
"5-LF-1": 2439,
"9-LF-1": 2440,
"8-ND-1": 2400,
"9-ND-1": 2401,
"10-ND-1": 2402,
"11-NDJD-1": 2404,
"11-ND-1": 2403,
"12-ND-1": 2405,
"13-ND-1": 2406,
"8-QX-1": 12047,
"9-QX-1": 12048,
"10-QX-1": 12049,
"11-QX-1": 12050,
"12-QX-1": 12051,
"13-QX-1": 12052,
"21-QX-1": 12060,
"22-QX-1": 12061,
"23-QX-1": 12062,
"24-QX-1": 12063,
"25-QX-1": 12064,
"21-ND-1": 2416,
"22-ND-1": 2417,
"23-ND-1": 2418,
"24-ND-1": 2419,
"25-ND-1": 2420,
"25-NDJD-1": 2421,
"24-LF-1": 2441,
"24-LF-2": 2442,
"24-LF-3": 2443,
"26-LF-1": 2444,
"26-LF-2": 2445,
"28-LF-1": 2446,
"28-LF-2": 2447,
"28-LF-3": 2448,
"26-ND-1": 2422,
"27-ND-1": 2423,
"28-ND-1": 2424,
"26-QX-1": 12065,
"27-QX-1": 12066,
"28-QX-1": 12067,
"14-QX-1": 12053,
"15-QX-1": 12054,
"16-QX-1": 12055,
"17-QX-1": 12056,
"18-QX-1": 12057,
"19-QX-1": 12058,
"20-QX-1": 12059,
"14-ND-1": 2407,
"15-ND-1": 2408,
"15-NDJD-1": 2409,
"16-ND-1": 2410,
"17-ND-1": 2411,
"18-ND-1": 2412,
"19-ND-1": 2413,
"19-NDJD-1": 2414,
"20-ND-1": 2415,
"29-ND-1": 2425,
"29-NDJD-1": 2426,
"30-ND-1": 2427,
"31-ND-1": 2428,
"32-ND-1": 2429,
"30-LF-1": 2449,
"32-LF-1": 2450,
"32-LF-2": 2451,
"32-LF-4": 2453,
"29-QX-1": 12068,
"30-QX-1": 12069,
"31-QX-1": 12070,
"32-QX-1": 12071,
"33-QX-1": 12072,
"34-QX-1": 12073,
"35-QX-1": 12074,
"36-QX-1": 12075,
"33-NDJD-1": 2431,
"33-ND-1": 2430,
"34-ND-1": 2432,
"35-ND-1": 2433,
"36-ND-1": 2434,
"34-LF-1": 2454,
"34-LF-2": 2455,
"36-LF-1": 2456,
"36-LF-2": 2457,
"36-LF-3": 2458,
"38-LF-1": 2459,
"38-LF-2": 2460,
"37-ND-1": 2435,
"38-ND-1": 2436,
"37-QX-1": 12076,
"38-QX-1": 12077,
"39-QX-1": 12078,
"1-YB-1": 2079,
"1-YB-2": 2080,
"1-YB-3": 2081,
"1-YB-4": 2082,
"1-HYB-1": 2083,
"1-HYB-2": 2084,
"1-HYB-3": 2085,
"1-HYB-4": 2086,
"2-YB-1": 2087,
"2-YB-2": 2088,
"2-YB-3": 2089,
"2-YB-4": 2090,
"2-HYB-1": 2091,
"2-HYB-2": 2092,
"2-HYB-3": 2093,
"2-HYB-4": 2094,
"3-YB-1": 2095,
"3-YB-2": 2096,
"3-YB-3": 2097,
"3-YB-4": 2098,
"3-HYB-1": 2099,
"3-HYB-2": 2100,
"3-HYB-3": 2101,
"3-HYB-4": 2102,
"4-YB-1": 2103,
"4-YB-2": 2104,
"4-YB-3": 2105,
"4-YB-4": 2106,
"4-HYB-1": 2107,
"4-HYB-2": 2108,
"4-HYB-3": 2109,
"4-HYB-4": 2110,
"5-YB-1": 2111,
"5-YB-2": 2112,
"5-YB-3": 2113,
"5-YB-4": 2114,
"5-HYB-1": 2115,
"5-HYB-2": 2116,
"5-HYB-3": 2117,
"5-HYB-4": 2118,
"6-YB-1": 2119,
"6-YB-2": 2120,
"6-YB-3": 2121,
"6-YB-4": 2122,
"6-HYB-1": 2123,
"6-HYB-2": 2124,
"6-HYB-3": 2125,
"6-HYB-4": 2126,
"7-YB-1": 2127,
"7-YB-2": 2128,
"7-YB-3": 2129,
"7-YB-4": 2130,
"7-HYB-1": 2131,
"7-HYB-2": 2132,
"7-HYB-3": 2133,
"7-HYB-4": 2134,
"8-YB-1": 2135,
"8-YB-2": 2136,
"8-YB-3": 2137,
"8-YB-4": 2138,
"8-HYB-1": 2139,
"8-HYB-2": 2140,
"8-HYB-3": 2141,
"8-HYB-4": 2142,
"9-YB-1": 2143,
"9-YB-2": 2144,
"9-YB-3": 2145,
"9-YB-4": 2146,
"9-HYB-1": 2147,
"9-HYB-2": 2148,
"9-HYB-3": 2149,
"9-HYB-4": 2150,
"10-YB-1": 2151,
"10-YB-2": 2152,
"10-YB-3": 2153,
"10-YB-4": 2154,
"10-HYB-1": 2155,
"10-HYB-2": 2156,
"10-HYB-3": 2157,
"10-HYB-4": 2158,
"11-YB-1": 2159,
"11-YB-2": 2160,
"11-YB-3": 2161,
"11-YB-4": 2162,
"11-HYB-1": 2163,
"11-HYB-2": 2164,
"11-HYB-3": 2165,
"11-HYB-4": 2166,
"12-YB-1": 2167,
"12-YB-2": 2168,
"12-YB-3": 2169,
"12-YB-4": 2170,
"12-HYB-1": 2171,
"12-HYB-2": 2172,
"12-HYB-3": 2173,
"12-HYB-4": 2174,
"13-YB-1": 2175,
"13-YB-2": 2176,
"13-YB-3": 2177,
"13-YB-4": 2178,
"13-HYB-1": 2179,
"13-HYB-2": 2180,
"13-HYB-3": 2181,
"13-HYB-4": 2182,
"14-YB-1": 2183,
"14-YB-2": 2184,
"14-YB-3": 2185,
"14-YB-4": 2186,
"14-HYB-1": 2187,
"14-HYB-2": 2188,
"14-HYB-3": 2189,
"14-HYB-4": 2190,
"15-YB-1": 2191,
"15-YB-2": 2192,
"15-YB-3": 2193,
"15-YB-4": 2194,
"15-HYB-1": 2195,
"15-HYB-2": 2196,
"15-HYB-3": 2197,
"15-HYB-4": 2198,
"16-YB-1": 2199,
"16-YB-2": 2200,
"16-YB-3": 2201,
"16-YB-4": 2202,
"16-HYB-1": 2203,
"16-HYB-2": 2204,
"16-HYB-3": 2205,
"16-HYB-4": 2206,
"17-YB-1": 2207,
"17-YB-2": 2208,
"17-YB-3": 2209,
"17-YB-4": 2210,
"17-HYB-1": 2211,
"17-HYB-2": 2212,
"17-HYB-3": 2213,
"17-HYB-4": 2214,
"18-YB-1": 2215,
"18-YB-2": 2216,
"18-YB-3": 2217,
"18-YB-4": 2218,
"18-HYB-1": 2219,
"18-HYB-2": 2220,
"18-HYB-3": 2221,
"18-HYB-4": 2222,
"19-YB-1": 2223,
"19-YB-2": 2224,
"19-YB-3": 2225,
"19-YB-4": 2226,
"19-HYB-1": 2227,
"19-HYB-2": 2228,
"19-HYB-3": 2229,
"19-HYB-4": 2230,
"20-YB-1": 2231,
"20-YB-2": 2232,
"20-YB-3": 2233,
"20-YB-4": 2234,
"20-HYB-1": 2235,
"20-HYB-2": 2236,
"20-HYB-3": 2237,
"20-HYB-4": 2238,
"21-YB-1": 2239,
"21-YB-2": 2240,
"21-YB-3": 2241,
"21-YB-4": 2242,
"21-HYB-1": 2243,
"21-HYB-2": 2244,
"21-HYB-3": 2245,
"21-HYB-4": 2246,
"22-YB-1": 2247,
"22-YB-2": 2248,
"22-YB-3": 2249,
"22-YB-4": 2250,
"22-HYB-1": 2251,
"22-HYB-2": 2252,
"22-HYB-3": 2253,
"22-HYB-4": 2254,
"23-YB-1": 2255,
"23-YB-2": 2256,
"23-YB-3": 2257,
"23-YB-4": 2258,
"23-HYB-1": 2259,
"23-HYB-2": 2260,
"23-HYB-3": 2261,
"23-HYB-4": 2262,
"24-YB-1": 2263,
"24-YB-2": 2264,
"24-YB-3": 2265,
"24-YB-4": 2266,
"24-HYB-1": 2267,
"24-HYB-2": 2268,
"24-HYB-3": 2269,
"24-HYB-4": 2270,
"25-YB-1": 2271,
"25-YB-2": 2272,
"25-YB-3": 2273,
"25-YB-4": 2274,
"25-HYB-1": 2275,
"25-HYB-2": 2276,
"25-HYB-3": 2277,
"25-HYB-4": 2278,
"26-YB-1": 2279,
"26-YB-2": 2280,
"26-YB-3": 2281,
"26-YB-4": 2282,
"26-HYB-1": 2283,
"26-HYB-2": 2284,
"26-HYB-3": 2285,
"26-HYB-4": 2286,
"27-YB-1": 2287,
"27-YB-2": 2288,
"27-YB-3": 2289,
"27-YB-4": 2290,
"27-HYB-1": 2291,
"27-HYB-2": 2292,
"27-HYB-3": 2293,
"27-HYB-4": 2294,
"28-YB-1": 2295,
"28-YB-2": 2296,
"28-YB-3": 2297,
"28-YB-4": 2298,
"28-HYB-1": 2299,
"28-HYB-2": 2300,
"28-HYB-3": 2301,
"28-HYB-4": 2302,
"29-YB-1": 2303,
"29-YB-2": 2304,
"29-YB-3": 2305,
"29-YB-4": 2306,
"29-HYB-1": 2307,
"29-HYB-2": 2308,
"29-HYB-3": 2309,
"29-HYB-4": 2310,
"30-YB-1": 2311,
"30-YB-2": 2312,
"30-YB-3": 2313,
"30-YB-4": 2314,
"30-HYB-1": 2315,
"30-HYB-2": 2316,
"30-HYB-3": 2317,
"30-HYB-4": 2318,
"31-YB-1": 2319,
"31-YB-2": 2320,
"31-YB-3": 2321,
"31-YB-4": 2322,
"31-HYB-1": 2323,
"31-HYB-2": 2324,
"31-HYB-3": 2325,
"31-HYB-4": 2326,
"36-YB-1": 2359,
"36-YB-2": 2360,
"36-YB-3": 2361,
"36-YB-4": 2362,
"36-HYB-1": 2363,
"36-HYB-2": 2364,
"36-HYB-3": 2365,
"36-HYB-4": 2366,
"37-YB-1": 2367,
"37-YB-2": 2368,
"37-YB-3": 2369,
"37-YB-4": 2370,
"37-HYB-1": 2371,
"37-HYB-2": 2372,
"37-HYB-3": 2373,
"37-HYB-4": 2374,
"38-YB-1": 2375,
"38-YB-2": 2376,
"38-YB-3": 2377,
"38-YB-4": 2378,
"38-HYB-1": 2379,
"38-HYB-2": 2380,
"38-HYB-3": 2381,
"38-HYB-4": 2382,
"39-YB-1": 2383,
"39-YB-2": 2384,
"39-YB-3": 2385,
"39-YB-4": 2386,
"39-HYB-1": 2387,
"39-HYB-2": 2388,
"39-HYB-3": 2389,
"39-HYB-4": 2390
},
"ZDsensorM-CMap": {
"227-1": 2001,
"227-2": 2002,
"227-3": 2003,
"227-4": 2004,
"227-5": 2005,
"227-6": 2006,
"227-7": 2007,
"227-8": 2008,
"228-1": 2009,
"228-2": 2010,
"228-3": 2011,
"228-4": 2012,
"228-5": 2013,
"228-6": 2014,
"228-7": 2015,
"228-8": 2016,
"229-1": 2017,
"229-2": 2018,
"229-3": 2019,
"229-4": 2020,
"229-5": 2021,
"229-6": 2022,
"229-7": 2023,
"229-8": 2024,
"230-1": 2025,
"230-2": 2026,
"230-3": 2027,
"230-4": 2028,
"230-5": 2029,
"230-6": 2030,
"230-7": 2031,
"231-1": 2032,
"231-2": 2033,
"231-3": 2034,
"231-4": 2035,
"231-5": 2036,
"231-6": 2037,
"231-7": 2038,
"231-8": 2039
}
}
}

65
configFiles/弃用备份/config_MYX.json

@ -0,0 +1,65 @@
{
"consumer": "consumerMYX",
"ioConfig": {
"inMqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "xtjc-in",
"password": "123456",
"clientId": "xtjc-in-123",
"Topics": [
"upload/uds/+","content/ZD/+"
]
},
"inFile": {
"directory": "G:\\工作记录\\每月任务需求\\202312需求\\明月峡数据接入influxDB\\光电光栅数据文件CSV",
"filenameExtension": "*.csv",
"cronStr": "0/1 * * * *"
},
"outHttp": {
"url": "http://127.0.0.1:4009/write?u=mingyuexia_wkd&p=mingyuexia_wkd&db=MingYueXia_Bridge&rp=autogen",
"method": "post"
}
},
"sensors": {
"TYCJsensorNameMap": {
"小里程-塔顶倾斜": "ZTWJC001",
"小里程-桥头测斜": "LDZJJC001",
"小里程-桥头伸缩缝磁滞位移": "SSFJC001",
"小里程-二层桥面中间温湿度": "WSDJC001",
"小里程-二层桥面中间风速风向": "FSFXJC001",
"大里程-塔顶倾斜": "ZTWJC002",
"大里程-桥头测斜": "LDZJJC002",
"大里程-桥头伸缩缝磁滞位移": "SSFJC002",
"大里程-塔顶风速风向": "FSFXJC002"
},
"ZDsensorM-CMap": {
"47388-1": "SL010101",
"47388-2": "SL010201",
"47388-3": "SL020101",
"47388-4": "SL020201",
"47388-5": "SL030101",
"47388-6": "SL030201",
"47388-7": "SL040101",
"47388-8": "SL040201",
"1125-1": "CZZD05303",
"1125-2": "CZZD05302",
"1125-3": "CZZD05301",
"1125-4": "SL050201",
"1125-5": "SL050101",
"46639-1": "SL060101",
"46639-2": "SL060201",
"46639-3": "SL070101",
"46639-4": "SL070201",
"46639-5": "SL080101",
"46639-6": "SL080201",
"44453-1": "ZD060303",
"44453-2": "ZD060302",
"44453-3": "ZD060301",
"44453-4": "CZZD07303",
"44453-5": "CZZD07302",
"44453-6": "CZZD07301"
}
}
}

76
configFiles/弃用备份/config_广州高支模_mas.json

@ -0,0 +1,76 @@
{
"consumer": "consumerGZGZM",
"ioConfig": {
"in": {
"kafka": {
"brokers": [
"10.8.30.160:30992"
],
"groupId": "masGZM",
"topics": [
"savoir_theme"
]
}
},
"out": {
"Http": {
"url": "http://sit.gibs.deagluo.top:32001/openApi/gzm_v1/monitorData/create",
"method": "post",
"token": {
"static": "",
"refreshInterval": "1 hour",
"url": "http://sit.gibs.deagluo.top:32001/openApi/gzm_v1/getToken",
"appKey": "gykj",
"appSecret": "gykj"
}
}
}
},
"info": {
"structureId": "3676",
"structUploadCode": "130208030020",
"fileNamePrefix": "130208030020_LTCDSS",
"fileContentHeader": "130208030020;唐山冀东水泥股份有限公司石灰石矿;"
},
"sensorInfoMap": {
"44823": {
"name": "ZY01",
"code": "44823",
"branchCode": "FB202409100002",
"contractor": "mas",
"deviceSn": "ZY01",
"deviceIp": "",
"type": "supporting_force",
"initAmount1": 0,
"initAmount2": 0,
"initAmount3": 0,
"unit": "kN"
},
"44824": {
"Name": "WY01",
"code": "44824",
"branchCode": "FB202409100002",
"contractor": "mas",
"deviceSn": "WY01",
"deviceIp": "",
"type": "displacement",
"initAmount1": 0,
"initAmount2": 0,
"initAmount3": 0,
"unit": "mm"
},
"44825": {
"Name": "QJ01",
"code": "44825",
"branchCode": "FB202409100002",
"contractor": "mas",
"deviceSn": "QJ01",
"deviceIp": "",
"type": "inclination",
"initAmount1": 0,
"initAmount2": 0,
"initAmount3": 0,
"unit": "°"
}
}
}

84
configFiles/弃用备份/config_承德金隅水泥_河北矿山_冀东唐山.json

@ -0,0 +1,84 @@
{
"consumer": "consumerCDJYSN",
"ioConfig": {
"in": {
"http": {
"url": "https://esproxy.anxinyun.cn/anxincloud_themes/_search"
},
"cronStr": "48 0/1 * * *"
},
"out": {
"file": {
"directory": "G:\\工作记录\\每月任务需求\\202402需求\\河北矿山数据本地数据工具开发\\saveTxts2",
"fileNameExtension": ".txt"
}
}
},
"info": {
"structureId": "3676",
"structUploadCode": "130208030020",
"fileNamePrefix": "130208030020_LTCDSS",
"fileContentHeader": "130208030020;唐山冀东水泥股份有限公司石灰石矿;"
},
"sensorMap": {
"NBWYSensorMap": {
"BC190_101": "190011",
"BC190_102": "190012",
"BC190_103": "190013",
"BC170_301": "170031",
"BC170_302": "170032",
"BC170_303": "170033",
"BC170_401": "170041",
"BC170_402": "170042",
"BC170_403": "170043",
"BC150_101": "150011",
"BC150_102": "150012",
"BC150_103": "150013",
"BC150_201": "150021",
"BC150_202": "150022",
"BC150_203": "150023",
"BC130_301": "130031",
"BC130_302": "130032",
"BC130_303": "130033",
"BC130_401": "130041",
"BC130_402": "130042",
"BC130_403": "130043",
"BC115_101": "115011",
"BC115_102": "115012",
"BC115_103": "115013",
"BC115_201": "115021",
"BC115_202": "115022",
"BC115_203": "115023",
"BC115_301": "115031",
"BC115_302": "115032",
"BC115_303": "115033",
"BC100_301": "100031",
"BC100_302": "100032",
"BC100_303": "100033",
"BC100_401": "100041",
"BC100_402": "100042",
"BC100_403": "100043",
"NC110_401": "110041",
"NC110_402": "110042",
"NC110_403": "110043",
"NC120_101": "120011",
"NC120_102": "120012",
"NC120_103": "120013",
"NC120_201": "120021",
"NC120_202": "120022",
"NC120_203": "120023",
"NC120_301": "120031",
"NC120_302": "120032",
"NC120_303": "120033",
"NC140_201": "140021",
"NC140_202": "140022",
"NC140_203": "140023",
"NC140_301": "140031",
"NC140_302": "140032",
"NC140_303": "140033"
},
"RainSensorMap": {
"YL": "200001"
}
}
}

33
configFiles/弃用备份/config_承德金隅水泥_河北矿山_大斜阳.json

@ -0,0 +1,33 @@
{
"consumer": "consumerCDJYSN",
"ioConfig": {
"in": {
"http": {
"url": "https://esproxy.anxinyun.cn/anxincloud_themes/_search"
},
"cronStr": "18 0/1 * * *"
},
"out": {
"file": {
"directory": "G:\\工作记录\\每月任务需求\\202402需求\\河北矿山数据本地数据工具开发\\saveTxts",
"fileNameExtension": ".txt"
}
}
},
"info": {
"structureId": "4570",
"structUploadCode": "130731030001",
"fileNamePrefix": "130731030001_LTCDSS",
"fileContentHeader": "130731030001;涿鹿金隅水泥大斜阳矿山;"
},
"sensorMap": {
"GnssSensorMap": {
"JC01": "100001",
"JC02": "100002",
"JC03": "100003"
},
"RainSensorMap": {
"雨量": "200001"
}
}
}

33
configFiles/弃用备份/config_承德金隅水泥_河北矿山_太平堡.json

@ -0,0 +1,33 @@
{
"consumer": "consumerCDJYSN",
"ioConfig": {
"in": {
"http": {
"url": "https://esproxy.anxinyun.cn/anxincloud_themes/_search"
},
"cronStr": "18 0/1 * * *"
},
"out": {
"file": {
"directory": "G:\\工作记录\\每月任务需求\\202402需求\\河北矿山数据本地数据工具开发\\saveTxts",
"fileNameExtension": ".txt"
}
}
},
"info": {
"structureId": "4571",
"structUploadCode": "130731030007",
"fileNamePrefix": "130731030007_LTCDSS",
"fileContentHeader": "130731030007;涿鹿金隅水泥有限公司太平堡水泥灰岩矿东矿区;"
},
"sensorMap": {
"GnssSensorMap": {
"JC01": "100001",
"JC02": "100002",
"JC03": "100003"
},
"RainSensorMap": {
"雨量": "200001"
}
}
}

44
configFiles/弃用备份/config_承德金隅水泥_河北矿山_滦州冀东.json

@ -0,0 +1,44 @@
{
"consumer": "consumerCDJYSN",
"ioConfig": {
"in": {
"http": {
"url": "https://esproxy.anxinyun.cn/anxincloud_themes/_search"
},
"cronStr": "32 0/1 * * *"
},
"out": {
"file": {
"directory": "G:\\工作记录\\每月任务需求\\202402需求\\河北矿山数据本地数据工具开发\\saveTxts2",
"fileNameExtension": ".txt"
}
}
},
"info": {
"structureId": "3318",
"structUploadCode": "130284030001",
"fileNamePrefix": "130284030001_LTCDSS",
"fileContentHeader": "130284030001;冀东水泥滦州有限责任公司边坡;"
},
"sensorMap": {
"GnssSensorMap": {
"CS185_G1": "100011",
"CS137_G1": "100012",
"CS185_G2": "100021",
"CS137_G2": "100022",
"TS242_G3": "100031",
"TS212_G3": "100032",
"TS196_G7": "100071",
"TS242_G4": "100041",
"TS212_G4": "100042",
"TS182_G4": "100043",
"TS242_G5": "100051",
"TS212_G5": "100052",
"TS242_G6": "100061",
"TS212_G6": "100062"
},
"RainSensorMap": {
"JYL": "200001"
}
}
}

45
configFiles/弃用备份/config_江苏农村公路桥梁.json

@ -0,0 +1,45 @@
{
"consumer": "consumerJSNCGLQL",
"ioConfig": {
"in": {
"mqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "goUpload",
"password": "",
"clientId": "goUpload_JSNCGLQL",
"Topics": [
"upload/uds/+",
"upload/ZD/+"
]
}
},
"out": {
"mqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "upload",
"password": "",
"clientId": "upload1",
"Topics": [
"data/bridgeCode"
]
}
}
},
"info": {
"structUploadCode": "G2320281L0012"
},
"sensorInfoMap": {
"sensorMap": {
"TYCJsensorMap": {
"m1c1": "JY-HSD-G05-001-01",
"m1c2": "LHTDQ-RSG-L04-001-03"
},
"ZDsensorMap": {
"m1c1": "LHTDQ-VIB-C08-001-01",
"m1c2": "LHTDQ-VIB-L03-001-01"
}
}
}
}

1
constKey/key.go

@ -0,0 +1 @@
package constKey

31
consumers/CDJYSN/config.go

@ -0,0 +1,31 @@
package CDJYSN
import "goUpload/config"
type ConfigFile struct {
config.Consumer
IoConfig ioConfig `json:"ioConfig"`
SensorMap sensorConfig `json:"sensorMap"`
Info map[string]string `json:"info,omitempty"`
}
type ioConfig struct {
In In `json:"in"`
Out OUT `json:"out"`
}
type In struct {
Http config.HttpConfig `json:"http"`
CronStr string `json:"cronStr"`
}
type OUT struct {
File config.FileConfig `json:"file"`
}
type sensorConfig struct {
GnssSensorMap map[string]string `json:"GnssSensorMap"`
RainSensorMap map[string]string `json:"RainSensorMap"`
//内部位移
NBWYSensorMap map[string]string `json:"NBWYSensorMap"`
}

21
consumers/CQZG/config.go

@ -0,0 +1,21 @@
package CQZG
import "goUpload/config"
type ConfigFile struct {
config.Consumer
Config UserConfig `json:"config"`
SensorMap sensorConfig `json:"sensorMap"`
}
type UserConfig struct {
InMqtt config.MqttConfig `json:"inMqtt"`
OutMqtt config.MqttConfig `json:"outMqtt"`
Rc4key string `json:"rc4key,omitempty"`
}
type sensorConfig struct {
TYCJsensorNameMap map[string]int64 `json:"TYCJsensorNameMap"`
CZsensorRoadnoMap map[string]int64 `json:"CZsensorRoadnoMap"`
ZDsensorMCMap map[string]int64 `json:"ZDsensorM-CMap"`
}

3406
consumers/CQZG/protoFiles/MonitorDataProtocol_realtime.pb.go

File diff suppressed because it is too large

20
consumers/CQZG/ssl/centerCA.crt

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIJAM7Nl5kGCS8TMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
Q29tcGFueSBMdGQwHhcNMjMxMDI1MDYyNTE2WhcNMzMxMDIyMDYyNTE2WjBCMQsw
CQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZh
dWx0IENvbXBhbnkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
4ahzVwl/etMwmaLAIFpkce65zV274AxznlW+w0ygXsPBPM1jtiILyyztYrP37uTG
5Hcg6UY460rT6BOb0Gx697VHI7jfwqbdhNh89lAhktZVk9AkUEa1bD/+NiLZKgNq
mUjmd7ILkTHGWOzdlyURxMfcHG4Lx+wwZO0rw3J7R4l7f1qFemHYtRK1AKdRnVBn
p3TL0nkkx86FwDxhHtcLlkW6GfDGCg6/oZyndFcPH8jOXpduQMtiVfKP9ALJLDfI
cKczvmyNbLCCkksa1gY0H+QYLxYXIW86nKDJA2RbtKuUK4ZMCYijCXQfwwq8nfPf
TqpYSGL9P0z7G6YElkblnQIDAQABo1AwTjAdBgNVHQ4EFgQUtZOYDqeF99820Gh5
iCJRzu+JFZYwHwYDVR0jBBgwFoAUtZOYDqeF99820Gh5iCJRzu+JFZYwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA3bWDFpGTAlbqp8czhlCVFdrKejye
uSdTqh8Q++eiYbBfup5cyFqAxVyqjZZuE02DcYxJLcj0DW2M0YUDDfsGg7SfF0oV
zUwseJqlIlaIYapJK8aMefp0U7CNJXyqKQSyFO9H3X9qboDs+o1SqFwsDYBO/6r0
QflTYFLYiW3WbM7Tl/IP61SVKW7SAIzhg0n6G7jLCdKlxjsbrSlYuZs+mU5xfVv3
nG7HCipEwVCjusi4Tu8sQVHreiYPKlfrXq0c/vQGS+XznSTzWGnEYsHpBAkObrDo
Z9LqELndCUh1hMwO615tLVN0q1EKVpAXCOwwF956I16vQ7MdmpzPgK6MVA==
-----END CERTIFICATE-----

39
consumers/GZGZM/config.go

@ -0,0 +1,39 @@
package GZGZM
import "goUpload/config"
type ConfigFile struct {
config.Consumer
IoConfig ioConfig `json:"ioConfig"`
SensorConfig
}
type ioConfig struct {
In In `json:"in"`
Out OUT `json:"out"`
}
type In struct {
Kafka config.KafkaConfig `json:"kafka"`
CronStr string `json:"cronStr"`
}
type OUT struct {
Http config.HttpConfig `json:"http"`
}
type SensorConfig struct {
SensorInfoMap map[string]SensorInfo `json:"sensorInfoMap"`
}
type SensorInfo struct {
Name string `json:"name"` //测点名称
BranchCode string `json:"branchCode"` //分部编码,必填
Code string `json:"code"` //测点编号
Contractor string `json:"contractor"` //厂商编码或者名称
DeviceSn string `json:"deviceSn"` //设备code
DeviceIp string `json:"deviceIp"` //设备ip
Type string `json:"type"` //监测类型
InitAmount1 float64 `json:"initAmount1"` ///检测归零值1(初值)
InitAmount2 float64 `json:"initAmount2"` ///检测归零值2(初值)
InitAmount3 float64 `json:"initAmount3"` ///检测归零值3(初值)
Unit string `json:"unit"`
}

78
consumers/GZGZM/dataModel.go

@ -0,0 +1,78 @@
package GZGZM
const (
UnitCJ = "mm"
UnitSP = "mm"
UnitZL = "kN"
UnitQX = "°"
MonitorTypeCodeCJ = "settlement"
MonitorTypeCodeSP = "displacement"
MonitorTypeCodeZL = "supporting_force"
MonitorTypeCodeQX = "inclination"
)
type TokenBody struct {
Code int `json:"code"`
Message string `json:"message"`
Data string `json:"data"`
}
type PostData struct {
MonitorDataId string `json:"monitorDataId"` // 第三方平台监测数据Id,必填
UploadTime string `json:"uploadTime"` //上传时间,格式为yyyy-MM-dd HH:mm:ss,必填
StartTime string `json:"startTime"` //开始时间,格式为yyyy-MM-dd HH:mm:ss,必填
Contractor string `json:"contractor"` //厂商编码或者名称,必填
Type string `json:"type"` //监测类型code,对应的值下方字典有说明:supporting_force\settlement\displacement\inclination
DeviceSn string `json:"deviceSn"` //设备code,必填
DeviceIp string `json:"deviceIp"` //设备ip
Soc int `json:"soc"` //设备剩余电量
MeasuredPoint string `json:"measuredPoint"` // 测点编号,必填
BranchCode string `json:"branchCode"` // 分部编码,必填
Status int `json:"status"` // 数据状态,1正常,2预警,3报警。必填
Data PointData `json:"data"`
}
type PointData struct {
Unit string `json:"unit"` //单位
MeasuredValue1 float64 `json:"measuredValue1"` //当前测量值1,必填
MeasuredValue2 float64 `json:"measuredValue2"` //当前测量值2,如果有值时传
MeasuredValue3 float64 `json:"measuredValue3"` //当前测量值3,如果有值时传
CumulativeValue1 float64 `json:"cumulativeValue1"` // 变化量1,倾角时对应x,必填
CumulativeValue2 float64 `json:"cumulativeValue2"` // 变化量2,倾角时对应y
CumulativeValue3 float64 `json:"cumulativeValue3"` // 变化量3,倾角时对应z
InitAmount1 float64 `json:"initAmount1"` //检测归零值1,倾角时的x值,必填
InitAmount2 float64 `json:"initAmount2"` //检测归零值2,倾角时的y值
InitAmount3 float64 `json:"initAmount3"` //检测归零值3,倾角时的Z值
}
type UploadHistoryData struct {
DeviceId string `json:"deviceId"`
Apikey string `json:"apikey"`
Data map[string]HistoryData `json:"data"`
}
type HistoryData struct {
L1_GP_1 map[string]string `json:"L1_GP_1"`
}
type RegisterPointBody struct {
ThirdId string `json:"thirdId"` //第三方系统ID
BranchCode string `json:"branchCode"` //分部编码,必填
Name string `json:"name"` // 监测点位名称,必填
Code string `json:"code"` // 监测点位编号,必填
Type string `json:"type"` // 监测类型code,必填。对应的值下方字典有说明:supporting_force\settlement\displacement\inclination
AlarmValue1 float64 `json:"alarmValue1"` // 报警值1,必填
AlarmValue2 float64 `json:"alarmValue2"`
AlarmValue3 float64 `json:"alarmValue3"`
WarnValue1 float64 `json:"warnValue1"` // 预警值1,必填
WarnValue2 float64 `json:"warnValue2"`
WarnValue3 float64 `json:"warnValue3"`
AlarmCount int `json:"alarmCount"` // 报警次数,默认为0
WarnCount int `json:"warnCount"` // 预警次数,默认为0
InitAmount1 float64 `json:"initAmount1"` // 监测归零值1,必填
InitAmount2 float64 `json:"initAmount2"` // 监测归零值2,倾角时传y值
InitAmount3 float64 `json:"initAmount3"` // 监测归零值3,如果有z值时
Unit string `json:"unit"` //数据单位
IsClose int `json:"isClose"` //是否关闭,1是0否,必填
}

19
consumers/HTJC/config.go

@ -0,0 +1,19 @@
package HTJC
import "goUpload/config"
type ConfigFile struct {
config.Consumer
Config UserConfig `json:"ioConfig"`
SensorMap sensorConfig `json:"sensorMap"`
}
type UserConfig struct {
InMqtt config.MqttConfig `json:"inMqtt"`
OutUdp config.UdpConfig `json:"outUdp"`
}
type sensorConfig struct {
TYCJsensorNameMap map[string]int16 `json:"TYCJsensorNameMap"`
ZDsensorMCMap map[string]int16 `json:"ZDsensorM-CMap"`
}

6
consumers/IConsumer.go

@ -0,0 +1,6 @@
package consumers
type IConsumer interface {
Initial(configStr string) error
Work()
}

30
consumers/JSNCGLQL/config.go

@ -0,0 +1,30 @@
package JSNCGLQL
import "goUpload/config"
type ConfigFile struct {
config.Consumer
IoConfig ioConfig `json:"ioConfig"`
SensorConfig
}
type ioConfig struct {
In In `json:"in"`
Out OUT `json:"out"`
}
type In struct {
Mqtt config.MqttConfig `json:"mqtt"`
}
type OUT struct {
Mqtt config.MqttConfig `json:"mqtt"`
}
type SensorConfig struct {
TYCJsensorMap map[string]string `json:"TYCJsensorMap"`
ZDsensorMap map[string]string `json:"ZDsensorMap"`
}
type SensorInfo struct {
Name string `json:"name"` //测点名称
Code string `json:"code"` //测点编号 宜由“桥名简称-监测类别简称-构件类型编码-截面序号-构件序号-测点编号”组成
}

41
consumers/MYX/config.go

@ -0,0 +1,41 @@
package MYX
import "goUpload/config"
type ConfigFile struct {
config.Consumer
IOConfig UserConfig `json:"ioConfig"`
Sensors sensorConfig `json:"sensors"`
}
type UserConfig struct {
InMqtt config.MqttConfig `json:"inMqtt"`
InFileMonitor config.FileMonitorConfig `json:"inFile"`
OutHttpPost config.HttpConfig `json:"outHttp"`
}
type sensorConfig struct {
TYCJsensorNameMap map[string]string `json:"TYCJsensorNameMap"`
ZDsensorMCMap map[string]string `json:"ZDsensorM-CMap"`
GDGSsensorNameMap []GDGSsensorNameMap `json:"GDGSsensorNameMap"`
}
//gdgsSensorNameMap
type GDGSsensorNameMap struct {
Type string `json:"type"`
Map map[string]SensorInfo `json:"map"`
Formula string `json:"formula,omitempty"`
}
type SensorInfo struct {
Label string `json:"Label"`
Params map[string]float64 `json:"params,omitempty"`
}
// CHInfo 光电光栅的通道的对应信息
type CHInfo struct {
SensorInfo
Type string
Formula string
}

24
consumers/WJHP/config.go

@ -0,0 +1,24 @@
package WJHP
import "goUpload/config"
type ConfigFile struct {
config.Consumer
IOConfig UserConfig `json:"ioConfig"`
SensorConfig SensorConfig `json:"sensors"`
}
type UserConfig struct {
InMqtt config.MqttConfig `json:"inMqtt"`
OutHttpPost config.HttpConfig `json:"outHttp"`
}
type SensorConfig struct {
SjwySensorInfo map[string]SensorInfo `json:"sjwySensorInfo"`
}
type SensorInfo struct {
StationId int `json:"stationId"`
AppKey string `json:"appKey"`
MonitorType string `json:"monitorType"`
}

23
consumers/WJHP/dataModel.go

@ -0,0 +1,23 @@
package WJHP
import "time"
type PosData struct {
Arg string `json:"arg"`
Des string `json:"des"`
Pos string `json:"pos"` //采集点号
Tar string `json:"tar"`
XReal float64 `json:"xReal"` //X方向位移
YReal float64 `json:"yReal"` //Y方向位移
Timestamp time.Time `json:"timestamp"` //采集时间
}
type UploadHistoryData struct {
DeviceId string `json:"deviceId"`
Apikey string `json:"apikey"`
Data map[string]HistoryData `json:"data"`
}
type HistoryData struct {
L1_GP_1 map[string]string `json:"L1_GP_1"`
}

300
consumers/consumerCDJYSN.go

@ -0,0 +1,300 @@
package consumers
import (
"encoding/json"
"fmt"
"github.com/robfig/cron/v3"
"goUpload/adaptors"
"goUpload/consumers/CDJYSN"
"goUpload/dbHelper"
"goUpload/monitors"
"goUpload/utils"
"log"
"path"
"time"
)
type consumerCDJYSN struct {
//数据缓存管道
dataCache chan []byte
//具体配置
ConfigInfo CDJYSN.ConfigFile
//InHttp *dbHelper.HttpHelper
OutFile *dbHelper.FileSaveHelper
InHttp monitors.HttpMonitor
configCron *cron.Cron
}
func (the *consumerCDJYSN) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.ConfigInfo)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerCDJYSN) Initial(cfg string) error {
the.LoadConfigJson(cfg)
err := the.InputInitial()
if err != nil {
return err
}
err = the.OutputInitial()
return err
}
func (the *consumerCDJYSN) InputInitial() error {
the.dataCache = make(chan []byte, 200)
//数据入口
the.InHttp = monitors.HttpMonitor{
HttpClient: &dbHelper.HttpHelper{Url: the.ConfigInfo.IoConfig.In.Http.Url, Token: ""},
MonitorHelper: &monitors.MonitorHelper{CronStr: the.ConfigInfo.IoConfig.In.CronStr},
}
the.InHttp.Start()
the.InHttp.RegisterFun(the.getEsData)
return nil
}
func (the *consumerCDJYSN) OutputInitial() error {
//数据出口
the.OutFile = &dbHelper.FileSaveHelper{
Directory: the.ConfigInfo.IoConfig.Out.File.Directory,
FilenameExtension: the.ConfigInfo.IoConfig.Out.File.FileNameExtension,
}
the.OutFile.Initial()
return nil
}
func (the *consumerCDJYSN) Work() {
//每次启动生成测点配置文件
the.saveConfig()
the.configCron = cron.New()
the.configCron.AddFunc("10 12 * * *", func() {
log.Println("执行每天刷新传感器基础配置任务:")
the.saveConfig()
})
go func() {
for {
pushBytes := <-the.dataCache
log.Printf("取出ch数据,剩余[%d] ", len(the.dataCache))
log.Printf("推送[%v]: len=%d", the.OutFile.Directory, len(pushBytes))
//hex.EncodeToString(pushBytes)
//非煤矿山编码_文件分类_时间.txt
fileName := fmt.Sprintf("%s_%s.txt", the.ConfigInfo.Info["fileNamePrefix"], time.Now().Format("20060102150405"))
filePath := path.Join(the.ConfigInfo.IoConfig.Out.File.Directory, fileName)
the.OutFile.Save(filePath, string(pushBytes))
time.Sleep(10 * time.Millisecond)
}
}()
}
func (the *consumerCDJYSN) getStructureId() string {
structureId, ok := the.ConfigInfo.Info["structureId"] //涿鹿金隅水泥有限公司大斜阳矿
if !ok {
structureId = "4570" //斜阳矿4570,太平堡4571,冀东唐山3676
}
return structureId
}
func (the *consumerCDJYSN) saveConfig() {
//130731030001;涿鹿金隅水泥大斜阳矿山;DXYKSJC;涿鹿金隅水泥大斜阳矿山安全监测;承德金隅水泥有限公司;2030-12-30;2024-02-06 11:39:02^13073103000103200001;雨量;01;130731030001;0101;03;;mm;;100;90;80;70;采场;115.244209;40.123344;1217;2020-07-01;武汉新普惠;4;1;0;2024-02-06 10:55:45^13073103000102100001;JC01;01;130731030001;0101;02;;mm;;100;90;80;70;排土1297平台;115.243554;40.114834;1297;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^13073103000102100002;JC02;01;130731030001;0101;02;;mm;;100;90;80;70;边坡1317平台;115.241985;40.115445;1317;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^13073103000102100003;JC03;01;130731030001;0101;02;;mm;;100;90;80;70;边坡1317平台;115.241080;40.115698;1317;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^]]]
//"structUploadCode": "130731030001",
//"fileNamePrefix": "130731030001_LTCDSS",
//"fileContentHeader": "130731030001;涿鹿金隅水泥大斜阳矿山;"
structureId := the.getStructureId()
contentConfig := ""
switch structureId {
case "4570": //斜阳矿
contentConfig = fmt.Sprintf(`130731030001;涿鹿金隅水泥大斜阳矿山;DXYKSJC;涿鹿金隅水泥大斜阳矿山安全监测;承德金隅水泥有限公司;2030-12-30;2024-02-06 11:39:02^13073103000103200001;雨量;01;130731030001;0101;03;;mm;;100;90;80;70;采场;115.244209;40.123344;1217;2020-07-01;武汉新普惠;4;1;0;2024-02-06 10:55:45^13073103000102100001;JC01;01;130731030001;0101;02;;mm;;100;90;80;70;排土1297平台;115.243554;40.114834;1297;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^13073103000102100002;JC02;01;130731030001;0101;02;;mm;;100;90;80;70;边坡1317平台;115.241985;40.115445;1317;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^13073103000102100003;JC03;01;130731030001;0101;02;;mm;;100;90;80;70;边坡1317平台;115.241080;40.115698;1317;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^]]]`)
case "4571": //太平堡
contentConfig = fmt.Sprintf(`130731030007;涿鹿金隅水泥有限公司太平堡水泥灰岩矿东矿区;TPBKSJC;涿鹿金隅水泥太平堡矿山安全监测;承德金隅水泥有限公司;2030-12-30;2024-02-06 11:39:02^13073103000703200001;雨量;01;130731030007;0101;03;;mm;;100;90;80;70;采场;115.244209;40.123344;1217;2020-07-01;武汉新普惠;4;1;0;2024-02-06 10:55:45^13073103000702100001;JC01;01;130731030007;0101;02;;mm;;100;90;80;70;排土1297平台;115.243554;40.114834;1297;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^13073103000702100002;JC02;01;130731030007;0101;02;;mm;;100;90;80;70;边坡1317平台;115.241985;40.115445;1317;2020-07-01;江西飞尚科技;1000;1;0;2024-02-06 10:55:45^]]]`)
case "3676": //唐山冀东水泥
contentConfigHead := the.ConfigInfo.Info["fileContentHeader"] + //非煤矿山编码 130208030020,非煤矿山名称
"TSJDKSJC;" + //系统型号
"唐山冀东水泥股份有限公司石灰石矿安全监测;" + //系统名称
"承德金隅水泥有限公司;" + //生产厂家名称
"2030-12-30;" + //安标有效期
"2024-05-14 15:00:00" //数据上传时间
contentConfigBody := "" +
//测点编码;测点名称;系统编码;露天矿山编码;边坡编号;传感器类型;测点数值类型;测点数值单位;埋深;一级阈值;二级阈值;三级阈值;四级阈值;测点安装位置;位置X;位置Y;位置Z;安装日期;生产厂家;量程;在用状态;故障状态;数据时间
"^13020803002003200001;YL;01;130208030020;0101;03;;mm;;250;100;50;25;排土120平台;118.249646;39.934143;100;2019-05-01;武汉新普惠;4;1;0;2024-05-14 10:00:00" +
"^13020803002004190011;BC190_101;01;130208030020;0101;04;;mm;;70;60;50;40;排土190平台;118.238283;39.946949;190;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004190012;BC190_102;01;130208030020;0101;04;;mm;;70;60;50;40;排土190平台;118.238283;39.946949;190;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004190013;BC190_103;01;130208030020;0101;04;;mm;;70;60;50;40;排土190平台;118.238283;39.946949;190;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004170031;BC170_301;01;130208030020;0101;04;;mm;;70;60;50;40;排土170平台;118.242235;39.945843;170;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004170032;BC170_302;01;130208030020;0101;04;;mm;;70;60;50;40;排土170平台;118.242235;39.945843;170;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004170033;BC170_303;01;130208030020;0101;04;;mm;;70;60;50;40;排土170平台;118.242235;39.945843;170;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004170041;BC170_401;01;130208030020;0101;04;;mm;;70;60;50;40;排土170平台;118.244229;39.945138;170;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004170042;BC170_402;01;130208030020;0101;04;;mm;;70;60;50;40;排土170平台;118.244229;39.945138;170;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004170043;BC170_403;01;130208030020;0101;04;;mm;;70;60;50;40;排土170平台;118.244229;39.945138;170;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004150011;BC150_101;01;130208030020;0101;04;;mm;;70;60;50;40;排土150平台;118.237151;39.946451;150;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004150012;BC150_102;01;130208030020;0101;04;;mm;;70;60;50;40;排土150平台;118.237151;39.946451;150;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004150013;BC150_103;01;130208030020;0101;04;;mm;;70;60;50;40;排土150平台;118.237151;39.946451;150;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004150021;BC150_201;01;130208030020;0101;04;;mm;;70;60;50;40;排土150平台;118.239612;39.945954;150;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004150022;BC150_202;01;130208030020;0101;04;;mm;;70;60;50;40;排土150平台;118.239612;39.945954;150;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004150023;BC150_203;01;130208030020;0101;04;;mm;;70;60;50;40;排土150平台;118.239612;39.945954;150;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130031;BC130_301;01;130208030020;0101;04;;mm;;70;60;50;40;排土130平台;118.240133;39.945304;130;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130032;BC130_302;01;130208030020;0101;04;;mm;;70;60;50;40;排土130平台;118.240133;39.945304;130;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130033;BC130_303;01;130208030020;0101;04;;mm;;70;60;50;40;排土130平台;118.240133;39.945304;130;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130041;BC130_401;01;130208030020;0101;04;;mm;;70;60;50;40;排土130平台;118.242631;39.944875;130;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130042;BC130_402;01;130208030020;0101;04;;mm;;70;60;50;40;排土130平台;118.242631;39.944875;130;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130043;BC130_403;01;130208030020;0101;04;;mm;;70;60;50;40;排土130平台;118.242631;39.944875;130;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115011;BC115_101;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.238570;39.944695;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115012;BC115_102;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.238570;39.944695;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115013;BC115_103;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.238570;39.944695;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115021;BC115_201;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.243008;39.943796;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115022;BC115_202;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.243008;39.943796;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115023;BC115_203;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.243008;39.943796;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115031;BC115_301;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.243000;39.944419;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115032;BC115_302;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.243000;39.944419;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004115033;BC115_303;01;130208030020;0101;04;;mm;;70;60;50;40;排土115平台;118.243000;39.944419;115;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130031;BC100_301;01;130208030020;0101;04;;mm;;70;60;50;40;排土100平台;118.242954;39.942911;100;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004130032;BC100_302;01;130208030020;0101;04;;mm;;70;60;50;40;排土100平台;118.242954;39.942911;100;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004130033;BC100_303;01;130208030020;0101;04;;mm;;70;60;50;40;排土100平台;118.242954;39.942911;100;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004130041;BC100_401;01;130208030020;0101;04;;mm;;70;60;50;40;排土100平台;118.244194;39.940684;100;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130042;BC100_402;01;130208030020;0101;04;;mm;;70;60;50;40;排土100平台;118.244194;39.940684;100;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004130043;BC100_403;01;130208030020;0101;04;;mm;;70;60;50;40;排土100平台;118.244194;39.940684;100;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004110041;NC110_401;01;130208030020;0101;04;;mm;;70;60;50;40;排土110平台;118.249610;39.944820;110;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004110042;NC110_402;01;130208030020;0101;04;;mm;;70;60;50;40;排土110平台;118.249610;39.944820;110;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004110043;NC110_403;01;130208030020;0101;04;;mm;;70;60;50;40;排土110平台;118.249610;39.944820;110;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004120011;NC120_101;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.249305;39.934018;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120012;NC120_102;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.249305;39.934018;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120013;NC120_103;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.249305;39.934018;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120021;NC120_201;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.249700;39.932248;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120022;NC120_202;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.249700;39.932248;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120023;NC120_203;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.249700;39.932248;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120031;NC120_301;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.250113;39.929592;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120032;NC120_302;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.250113;39.929592;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004120033;NC120_303;01;130208030020;0101;04;;mm;;70;60;50;40;排土120平台;118.250113;39.929592;120;2019-05-01;金马;15;1;0;2024-05-14 10:00:00" +
"^13020803002004140021;NC140_201;01;130208030020;0101;04;;mm;;70;60;50;40;排土140平台;118.251119;39.932524;140;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004140022;NC140_202;01;130208030020;0101;04;;mm;;70;60;50;40;排土140平台;118.251119;39.932524;140;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004140023;NC140_203;01;130208030020;0101;04;;mm;;70;60;50;40;排土140平台;118.251119;39.932524;140;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004140031;NC140_301;01;130208030020;0101;04;;mm;;70;60;50;40;排土140平台;118.251605;39.929896;140;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004140032;NC140_302;01;130208030020;0101;04;;mm;;70;60;50;40;排土140平台;118.251605;39.929896;140;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^13020803002004140033;NC140_303;01;130208030020;0101;04;;mm;;70;60;50;40;排土140平台;118.251605;39.929896;140;2019-05-01;江西飞尚科技;30;1;0;2024-05-14 10:00:00" +
"^]]]"
contentConfig = contentConfigHead + contentConfigBody
case "3318": //滦州冀东水泥
contentConfigHead := the.ConfigInfo.Info["fileContentHeader"] + //非煤矿山编码 130284030001,边坡名称
"LZJDBPJC;" + //系统型号
"滦州冀东水泥股份有限公司边坡安全监测;" + //系统名称
"滦州冀东水泥股份有限公司;" + //生产厂家名称
"2030-12-30;" + //安标有效期
"2024-09-25 15:00:00" //数据上传时间
contentConfigBody := "" +
//测点编码;测点名称;系统编码;露天矿山编码;边坡编号;传感器类型;测点数值类型;测点数值单位;埋深;一级阈值;二级阈值;三级阈值;四级阈值;测点安装位置;位置X;位置Y;位置Z;安装日期;生产厂家;量程;在用状态;故障状态;数据时间
"^13028403000103200001;JYL;01;130284030001;0101;03;;mm;;250;100;50;25;桃山;115.366921;40.117217;125;2020-08-01;武汉新普惠;4;1;0;2024-09-25 10:00:00" +
"^13028403000102100011;CS185_G1;01;130284030001;0101;02;;mm;;;;;;蔡山;118.361332;39.915961;185;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100012;CS137_G1;01;130284030001;0101;02;;mm;;;;;;蔡山;118.361709;39.916477;137;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100021;CS185_G2;01;130284030001;0101;02;;mm;;;;;;蔡山;118.360645;39.916411;185;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100022;CS137_G2;01;130284030001;0101;02;;mm;;;;;;蔡山;118.360469;39.917361;137;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100031;TS242_G3;01;130284030001;0101;02;;mm;;;;;;桃山;118.351081;39.919035;242;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100032;TS212_G3;01;130284030001;0101;02;;mm;;;;;;桃山;118.351206;39.918518;212;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100071;TS196_G7;01;130284030001;0101;02;;mm;;;;;;桃山;118.354346;39.923345;196;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100041;TS242_G4;01;130284030001;0101;02;;mm;;;;;;桃山;118.352003;39.919398;242;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100042;TS212_G4;01;130284030001;0101;02;;mm;;;;;;桃山;118.352601;39.918982;212;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100043;TS182_G4;01;130284030001;0101;02;;mm;;;;;;桃山;118.353018;39.918586;196;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100051;TS242_G5;01;130284030001;0101;02;;mm;;;;;;桃山;118.351948;39.920629;242;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100052;TS212_G5;01;130284030001;0101;02;;mm;;;;;;桃山;118.351948;39.920629;212;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100061;TS242_G6;01;130284030001;0101;02;;mm;;;;;;桃山;118.350663;39.922561;242;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^13028403000102100062;TS212_G6;01;130284030001;0101;02;;mm;;;;;;桃山;118.351561;40.117217;212;2020-08-01;司南导航;15;1;0;2024-09-25 10:00:00" +
"^]]]"
contentConfig = contentConfigHead + contentConfigBody
}
fileName := fmt.Sprintf("%s_LTCDJC_%s.txt", the.ConfigInfo.Info["structUploadCode"], time.Now().Format("20060102150405"))
filePath := path.Join(the.ConfigInfo.IoConfig.Out.File.Directory, fileName)
the.OutFile.Save(filePath, contentConfig)
}
func (the *consumerCDJYSN) getEsData() {
structureId := the.getStructureId()
start, end := utils.GetTimeRangeByHour(-1)
log.Printf("查询数据时间范围 %s - %s", start, end)
//start := "2024-02-05T00:00:00.000+0800"
//end := "2024-02-05T23:59:59.999+0800"
esQuery := fmt.Sprintf(`
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"structure": {
"value": %s
}
}
},
{
"range": {
"collect_time": {
"from": "%s",
"to": "%s"
}
}
}
]
}
},
"sort": [
{
"collect_time": {
"order": "desc"
}
}
],
"aggs": {
"gpBySensorId": {
"terms": {
"field": "sensor",
"size": 60
},
"aggs": {
"last": {
"top_hits": {
"size": 1,
"sort": [
{
"collect_time": {
"order": "desc"
}
}
]
}
}
}
}
}
}
`, structureId, start, end)
auth := map[string]string{"Authorization": "Bear 85a441d4-022b-4613-abba-aaa8e2693bf7"}
esAggResult := the.InHttp.HttpClient.HttpGetWithHeader(esQuery, auth)
var needPush []byte
adaptor := the.getAdaptor()
if adaptor != nil {
needPush = adaptor.Transform(esAggResult)
if len(needPush) > 0 {
the.dataCache <- needPush
}
}
}
func (the *consumerCDJYSN) getAdaptor() (adaptor adaptors.IAdaptor) {
//maps.Copy(the.ConfigInfo.SensorMap.GnssSensorMap, the.ConfigInfo.SensorMap.RainSensorMap)
return adaptors.Adaptor_AXYES_HBKS{
GnssMap: the.ConfigInfo.SensorMap.GnssSensorMap,
RainMap: the.ConfigInfo.SensorMap.RainSensorMap,
NBWYMap: the.ConfigInfo.SensorMap.NBWYSensorMap,
Info: the.ConfigInfo.Info,
}
}
// 获取 内部位移安装位置
func (the *consumerCDJYSN) getNBWYLocation(pointCode string) string {
platformCode := pointCode[:3]
location := fmt.Sprintf("排土%s平台", platformCode)
return location
}

117
consumers/consumerCQZG.go

@ -0,0 +1,117 @@
package consumers
import (
"encoding/json"
"goUpload/adaptors"
"goUpload/consumers/CQZG"
"goUpload/dbHelper"
"log"
"os"
"strings"
"time"
)
type consumerCQZG struct {
//数据缓存管道
ch_t500101 chan []byte
//具体配置
Info CQZG.ConfigFile
InMqtt *dbHelper.MqttHelper
outMqtt *dbHelper.MqttHelper
}
func (the *consumerCQZG) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.Info)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerCQZG) Initial(cfg string) error {
the.LoadConfigJson(cfg)
err := the.InputInitial()
if err != nil {
return err
}
err = the.OutputInitial()
return err
}
func (the *consumerCQZG) InputInitial() error {
os.Setenv("RC4Key", the.Info.Config.Rc4key)
log.Printf("RC4Key=%s", the.Info.Config.Rc4key)
the.ch_t500101 = make(chan []byte, 200)
//数据入口
the.InMqtt = dbHelper.MqttInitial(
the.Info.Config.InMqtt.Host,
the.Info.Config.InMqtt.Port,
the.Info.Config.InMqtt.ClientId,
the.Info.Config.InMqtt.UserName,
the.Info.Config.InMqtt.Password,
false)
//inTopic := "Upload/#" //荔枝乌江大桥
for _, inTopic := range the.Info.Config.InMqtt.Topics {
the.InMqtt.Subscribe(inTopic, the.onData)
}
return nil
}
func (the *consumerCQZG) OutputInitial() error {
//数据出口
the.outMqtt = dbHelper.MqttInitial(
the.Info.Config.OutMqtt.Host,
the.Info.Config.OutMqtt.Port,
the.Info.Config.OutMqtt.ClientId,
the.Info.Config.OutMqtt.UserName,
the.Info.Config.OutMqtt.Password,
true,
"consumers/CQZG/ssl/centerCA.crt")
return nil
}
func (the *consumerCQZG) Work() {
go func() {
for {
pushBytes := <-the.ch_t500101
log.Printf("取出ch数据,剩余[%d] ", len(the.ch_t500101))
for _, outTopic := range the.Info.Config.OutMqtt.Topics {
log.Printf("推送[%s]: len=%d", outTopic, len(pushBytes))
//hex.EncodeToString(pushBytes)
the.outMqtt.Publish(outTopic, pushBytes)
}
time.Sleep(100 * time.Millisecond)
}
}()
}
func (the *consumerCQZG) onData(Topic string, Msg string) {
if len(Msg) > 80 {
log.Printf("mqtt-recv:[%s]:%s ...", Topic, Msg[:80])
}
var needPush []byte
topicPrefixIndex := strings.LastIndex(Topic, "/")
matchTopic := Topic[:topicPrefixIndex]
adaptor := the.getAdaptor(matchTopic)
if adaptor != nil {
needPush = adaptor.Transform(Msg)
if len(needPush) > 0 {
the.ch_t500101 <- needPush
}
}
}
func (the *consumerCQZG) getAdaptor(flag string) (adaptor adaptors.IAdaptor) {
RC4Key := os.Getenv("RC4Key")
switch flag {
case "upload/uds":
log.Printf("[统一采集软件]-上报,准备处理")
adaptor = adaptors.Adaptor_TYCJ_CQZG{IdMap: the.Info.SensorMap.TYCJsensorNameMap, RC4Key: RC4Key}
case "upload/CZ":
log.Printf("[称重软件]-上报,准备处理")
adaptor = adaptors.Adaptor_OLCZ_CQZG{IdMap: the.Info.SensorMap.CZsensorRoadnoMap, RC4Key: RC4Key}
case "upload/ZD":
log.Printf("[振动软件]-上报,准备处理")
adaptor = adaptors.Adaptor_ZD_CQZG{IdMap: the.Info.SensorMap.ZDsensorMCMap, RC4Key: RC4Key}
default:
log.Printf("[无匹配 %s],不处理", flag)
}
return adaptor
}

217
consumers/consumerGZGZM.go

@ -0,0 +1,217 @@
package consumers
import (
"crypto/md5"
"encoding/json"
"fmt"
"goUpload/adaptors"
"goUpload/consumers/GZGZM"
"goUpload/dbHelper"
"goUpload/dbHelper/_kafka"
"io"
"log"
"math/rand"
"time"
)
type consumerGZGZM struct {
//数据缓存管道
dataCache chan []byte
//具体配置
ConfigInfo GZGZM.ConfigFile
InKafka _kafka.KafkaHelper
OutHttp *dbHelper.HttpHelper
}
func (the *consumerGZGZM) RegisterPoint(thirdId string, sensorInfo GZGZM.SensorInfo) error {
registerUrl := "http://sit.gibs.deagluo.top:32001/openApi/gzm_v1/monitorPoint/create"
r := GZGZM.RegisterPointBody{
ThirdId: thirdId,
BranchCode: sensorInfo.BranchCode,
Name: sensorInfo.Name,
Code: sensorInfo.Code,
Type: sensorInfo.Type,
AlarmValue1: 0,
AlarmValue2: 0,
AlarmValue3: 0,
WarnValue1: 0,
WarnValue2: 0,
WarnValue3: 0,
AlarmCount: 0,
WarnCount: 0,
InitAmount1: sensorInfo.InitAmount1,
InitAmount2: sensorInfo.InitAmount2,
InitAmount3: sensorInfo.InitAmount3,
Unit: sensorInfo.Unit,
IsClose: 0,
}
the.OutHttp.Url = registerUrl
body, _ := json.Marshal(r)
resp, err := the.OutHttp.PublishWithHeader(body, map[string]string{"Authorization": the.OutHttp.Token})
if err != nil {
log.Printf(" 注册测点异常 err=%v \n,resp=%s", err, resp)
}
return err
}
func (the *consumerGZGZM) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.ConfigInfo)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerGZGZM) Initial(cfg string) error {
the.dataCache = make(chan []byte, 200)
the.LoadConfigJson(cfg)
err := the.inputInitial()
if err != nil {
return err
}
err = the.outputInitial()
return err
}
func (the *consumerGZGZM) inputInitial() error {
//数据入口
the.InKafka = _kafka.KafkaHelper{
Brokers: the.ConfigInfo.IoConfig.In.Kafka.Brokers,
GroupId: the.ConfigInfo.IoConfig.In.Kafka.GroupId,
}
the.InKafka.Initial()
for _, inTopic := range the.ConfigInfo.IoConfig.In.Kafka.Topics {
the.InKafka.Subscribe(inTopic, the.onData)
}
the.InKafka.Worker()
return nil
}
func (the *consumerGZGZM) outputInitial() error {
//数据出口
the.OutHttp = &dbHelper.HttpHelper{
Url: the.ConfigInfo.IoConfig.Out.Http.Url,
}
the.OutHttp.Initial()
//判断有无token
if the.ConfigInfo.IoConfig.Out.Http.Token.Static != "" {
//静态token
the.OutHttp.Token = the.ConfigInfo.IoConfig.Out.Http.Token.Static
} else { //需要动态获取的token
if the.ConfigInfo.IoConfig.Out.Http.Token.Url != "" {
go the.RefreshTask()
}
}
return nil
}
func (the *consumerGZGZM) RefreshTask() {
the.tokenRefresh()
ticker := time.NewTicker(24 * time.Hour)
defer ticker.Stop()
for true {
<-ticker.C
the.tokenRefresh()
}
}
func (the *consumerGZGZM) tokenRefresh() {
url := the.ConfigInfo.IoConfig.Out.Http.Token.Url
appKey := the.ConfigInfo.IoConfig.Out.Http.Token.AppKey
appSecret := the.ConfigInfo.IoConfig.Out.Http.Token.AppSecret
randomStr16 := string(Krand(16, KC_RAND_KIND_NUM))
timestamp := time.Now().UnixMilli()
secretRaw := fmt.Sprintf("%s%s%s%d", appKey, appSecret, randomStr16, timestamp)
h := md5.New()
io.WriteString(h, secretRaw)
secret := fmt.Sprintf("%x", h.Sum(nil))
queryUrl := url + "?" +
fmt.Sprintf("&appKey=%s", appKey) +
fmt.Sprintf("&random=%s", randomStr16) +
fmt.Sprintf("&timestamp=%d", timestamp) +
fmt.Sprintf("&secret=%s", secret)
tokenHttp := &dbHelper.HttpHelper{
Url: queryUrl,
}
tokenHttp.Initial()
tokenResp := tokenHttp.HttpGet("")
tokenBody := GZGZM.TokenBody{}
err := json.Unmarshal([]byte(tokenResp), &tokenBody)
if err != nil {
log.Printf("解析异常 err=%s,body=%s", err.Error(), tokenResp)
return
}
if tokenBody.Code == 200 {
the.OutHttp.Token = tokenBody.Data
log.Printf("刷新成功,token=%s", the.OutHttp.Token)
}
}
func (the *consumerGZGZM) Work() {
go func() {
for {
pushBytes := <-the.dataCache
log.Printf("取出ch数据,剩余[%d] ", len(the.dataCache))
log.Printf("推送[%v]: len=%d", the.OutHttp.Url, len(pushBytes))
the.OutHttp.PublishWithHeader(pushBytes, map[string]string{"Authorization": the.OutHttp.Token})
time.Sleep(10 * time.Millisecond)
}
}()
}
func (the *consumerGZGZM) onData(topic string, msg string) bool {
if len(msg) > 80 {
log.Printf("recv:[%s]:%s ...", topic, msg[:80])
}
adaptor := the.getAdaptor()
if adaptor != nil {
needPush := adaptor.Transform(topic, msg)
if len(needPush) > 0 {
the.dataCache <- needPush
}
}
return true
}
func (the *consumerGZGZM) getAdaptor() (adaptor adaptors.IAdaptor3) {
return adaptors.Adaptor_THEME_GZGZM{
GZGZM.SensorConfig{
SensorInfoMap: the.ConfigInfo.SensorInfoMap,
},
}
}
// 随机字符串
func Krand(size int, kind int) []byte {
ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
is_all := kind > 2 || kind < 0
//rand.Seed(time.Now().UnixNano())
for i := 0; i < size; i++ {
if is_all { // random ikind
ikind = rand.Intn(3)
}
scope, base := kinds[ikind][0], kinds[ikind][1]
result[i] = uint8(base + rand.Intn(scope))
}
return result
}
const (
KC_RAND_KIND_NUM = 0 // 纯数字
KC_RAND_KIND_LOWER = 1 // 小写字母
KC_RAND_KIND_UPPER = 2 // 大写字母
KC_RAND_KIND_ALL = 3 // 数字、大小写字母
)

108
consumers/consumerHTJC.go

@ -0,0 +1,108 @@
package consumers
import (
"encoding/json"
"goUpload/adaptors"
"goUpload/consumers/HTJC"
"goUpload/dbHelper"
"log"
"strings"
"time"
)
type consumerHTJC struct {
//数据缓存管道
dataCache chan []byte
//具体配置
Info HTJC.ConfigFile
InMqtt *dbHelper.MqttHelper
outUdp *dbHelper.UdpHelper
}
func (the *consumerHTJC) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.Info)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerHTJC) Initial(cfg string) error {
the.LoadConfigJson(cfg)
err := the.InputInitial()
if err != nil {
return err
}
err = the.OutputInitial()
return err
}
func (the *consumerHTJC) InputInitial() error {
the.dataCache = make(chan []byte, 1000)
//数据入口
the.InMqtt = dbHelper.MqttInitial(
the.Info.Config.InMqtt.Host,
the.Info.Config.InMqtt.Port,
the.Info.Config.InMqtt.ClientId,
the.Info.Config.InMqtt.UserName,
the.Info.Config.InMqtt.Password,
false)
//inTopic := "Upload/#" //荔枝乌江大桥
for _, inTopic := range the.Info.Config.InMqtt.Topics {
the.InMqtt.Subscribe(inTopic, the.onData)
}
return nil
}
func (the *consumerHTJC) OutputInitial() error {
//数据出口
the.outUdp = &dbHelper.UdpHelper{
Host: the.Info.Config.OutUdp.Host,
Port: the.Info.Config.OutUdp.Port,
}
the.outUdp.Initial()
return nil
}
func (the *consumerHTJC) Work() {
go func() {
for {
pushBytes := <-the.dataCache
log.Printf("取出ch数据,剩余[%d] ", len(the.dataCache))
log.Printf("推送[%v]: len=%d", the.outUdp, len(pushBytes))
go the.outUdp.Publish(pushBytes)
time.Sleep(2 * time.Millisecond)
}
}()
}
func (the *consumerHTJC) onData(Topic string, Msg string) {
if len(Msg) > 80 {
log.Printf("mqtt-recv:[%s]:%s ...", Topic, Msg[:80])
}
var needPushs [][]byte
topicPrefixIndex := strings.LastIndex(Topic, "/")
matchTopic := Topic[:topicPrefixIndex]
adaptor := the.getAdaptor(matchTopic)
if adaptor != nil {
needPushs = adaptor.Transform(Msg)
for _, needPush := range needPushs {
if len(needPush) > 0 {
the.dataCache <- needPush
}
}
}
}
func (the *consumerHTJC) getAdaptor(flag string) (adaptor adaptors.IAdaptor2) {
switch flag {
case "upload/uds":
log.Printf("[统一采集软件]-上报,准备处理")
adaptor = adaptors.Adaptor_TYCJ_XTJC{IdMap: the.Info.SensorMap.TYCJsensorNameMap}
case "upload/ZD":
log.Printf("[振动软件]-上报,准备处理")
adaptor = adaptors.Adaptor_ZD_XTJC{IdMap: the.Info.SensorMap.ZDsensorMCMap}
default:
log.Printf("[无匹配 %s],不处理", flag)
}
return adaptor
}

116
consumers/consumerJSNCGLQL.go

@ -0,0 +1,116 @@
package consumers
import (
"encoding/json"
"goUpload/adaptors"
"goUpload/consumers/JSNCGLQL"
"goUpload/dbHelper"
"log"
"strings"
"time"
)
type consumerJSNCGLQL struct {
//数据缓存管道
ch chan []adaptors.NeedPush
//具体配置
Info JSNCGLQL.ConfigFile
InMqtt *dbHelper.MqttHelper
outMqtt *dbHelper.MqttHelper
}
func (the *consumerJSNCGLQL) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.Info)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerJSNCGLQL) Initial(cfg string) error {
the.LoadConfigJson(cfg)
err := the.InputInitial()
if err != nil {
return err
}
err = the.OutputInitial()
return err
}
func (the *consumerJSNCGLQL) InputInitial() error {
the.ch = make(chan []adaptors.NeedPush, 200)
//数据入口
the.InMqtt = dbHelper.MqttInitial(
the.Info.IoConfig.In.Mqtt.Host,
the.Info.IoConfig.In.Mqtt.Port,
the.Info.IoConfig.In.Mqtt.ClientId,
the.Info.IoConfig.In.Mqtt.UserName,
the.Info.IoConfig.In.Mqtt.Password,
false)
//inTopic := "Upload/#" //荔枝乌江大桥
for _, inTopic := range the.Info.IoConfig.In.Mqtt.Topics {
the.InMqtt.Subscribe(inTopic, the.onData)
}
return nil
}
func (the *consumerJSNCGLQL) OutputInitial() error {
//数据出口
the.outMqtt = dbHelper.MqttInitial(
the.Info.IoConfig.Out.Mqtt.Host,
the.Info.IoConfig.Out.Mqtt.Port,
the.Info.IoConfig.Out.Mqtt.ClientId,
the.Info.IoConfig.Out.Mqtt.UserName,
the.Info.IoConfig.Out.Mqtt.Password,
false, //按照具体项目来
"consumers/CQZG/ssl/centerCA.crt")
return nil
}
func (the *consumerJSNCGLQL) Work() {
go func() {
for {
needPushs := <-the.ch
log.Printf("取出ch数据,剩余[%d] ", len(the.ch))
for _, outTopic := range the.Info.IoConfig.Out.Mqtt.Topics {
for _, push := range needPushs {
log.Printf("推送[%s]: len=%d", outTopic, len(push.Payload))
//hex.EncodeToString(pushBytes)
if push.Topic != "" {
outTopic = push.Topic
}
the.outMqtt.Publish(outTopic, push.Payload)
}
}
time.Sleep(100 * time.Millisecond)
}
}()
}
func (the *consumerJSNCGLQL) onData(inTopic string, Msg string) {
if len(Msg) > 100 {
log.Printf("mqtt-recv:[%s]:%s ...", inTopic, Msg[:100])
}
topicPrefixIndex := strings.LastIndex(inTopic, "/")
matchTopic := inTopic[:topicPrefixIndex]
adaptor := the.getAdaptor(matchTopic)
if adaptor != nil {
needPush := adaptor.Transform(inTopic, Msg)
if len(needPush) > 0 {
the.ch <- needPush
}
}
}
func (the *consumerJSNCGLQL) getAdaptor(flag string) (adaptor adaptors.IAdaptor4) {
switch flag {
case "upload/uds":
log.Printf("[统一采集软件]-上报,准备处理")
//adaptor = adaptors.Adaptor_TYCJ_JSNCGLQL{IdMap: the.Info.TYCJsensorMap}
case "upload/ZD":
log.Printf("[振动软件]-上报,准备处理")
//adaptor = adaptors.Adaptor_ZD_CQZG{IdMap: the.Info.SensorMap.ZDsensorMCMap, RC4Key: RC4Key}
default:
log.Printf("[无匹配 %s],不处理", flag)
}
return adaptor
}

206
consumers/consumerMYX.go

@ -0,0 +1,206 @@
package consumers
import (
"bufio"
"encoding/csv"
"encoding/json"
"fmt"
"goUpload/adaptors"
"goUpload/consumers/MYX"
"goUpload/dbHelper"
"goUpload/monitors"
"golang.org/x/text/encoding/unicode"
"log"
"os"
"path/filepath"
"strings"
"time"
)
type consumerMYX struct {
//数据缓存管道
dataCache chan []byte
//具体配置
Info MYX.ConfigFile
InMqtt *dbHelper.MqttHelper
InFileMonitor *monitors.FileMonitor
outHttpPost *dbHelper.HttpHelper
}
func (the *consumerMYX) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.Info)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerMYX) Initial(cfg string) error {
the.LoadConfigJson(cfg)
err := the.InputInitial()
if err != nil {
return err
}
err = the.OutputInitial()
return err
}
func (the *consumerMYX) InputInitial() error {
the.dataCache = make(chan []byte, 200)
//mqtt数据入口
the.InMqtt = dbHelper.MqttInitial(
the.Info.IOConfig.InMqtt.Host,
the.Info.IOConfig.InMqtt.Port,
the.Info.IOConfig.InMqtt.ClientId,
the.Info.IOConfig.InMqtt.UserName,
the.Info.IOConfig.InMqtt.Password,
false)
for _, inTopic := range the.Info.IOConfig.InMqtt.Topics {
the.InMqtt.Subscribe(inTopic, the.onData)
}
//文件监视器数据入口
the.InFileMonitor = monitors.FileMonitorInitial(
the.Info.IOConfig.InFileMonitor.Directory,
the.Info.IOConfig.InFileMonitor.FileNameExtension,
the.Info.IOConfig.InFileMonitor.CronStr,
)
the.InFileMonitor.Subscribe(the.onFileData)
return nil
}
func (the *consumerMYX) OutputInitial() error {
//数据出口
the.outHttpPost = &dbHelper.HttpHelper{
Url: the.Info.IOConfig.OutHttpPost.Url,
}
the.outHttpPost.Initial()
return nil
}
func (the *consumerMYX) Work() {
go func() {
for {
pushBytes := <-the.dataCache
log.Printf("取出ch数据,剩余[%d] ", len(the.dataCache))
log.Printf("推送[%v]: len=%d", the.outHttpPost.Url, len(pushBytes))
//hex.EncodeToString(pushBytes)
the.outHttpPost.Publish(pushBytes)
time.Sleep(50 * time.Millisecond)
}
}()
}
func (the *consumerMYX) onData(Topic string, Msg string) {
if len(Msg) > 80 {
log.Printf("mqtt-recv:[%s]:%s ...", Topic, Msg[:80])
}
var needPush []byte
topicPrefixIndex := strings.LastIndex(Topic, "/")
matchTopic := Topic[:topicPrefixIndex]
adaptor := the.getAdaptor(matchTopic)
if adaptor != nil {
needPush = adaptor.Transform(Msg)
if len(needPush) > 0 {
the.dataCache <- needPush
}
}
}
func (the *consumerMYX) getAdaptor(flag string) (adaptor adaptors.IAdaptor) {
switch flag {
case "upload/uds":
log.Printf("[统一采集软件]-上报,准备处理")
adaptor = adaptors.Adaptor_TYCJ_MYX{IdMap: the.Info.Sensors.TYCJsensorNameMap}
case "content/ZD":
log.Printf("[振动软件]-上报,准备处理")
adaptor = adaptors.Adaptor_ZD_MYX{IdMap: the.Info.Sensors.ZDsensorMCMap}
default:
log.Printf("[无匹配 %s],不处理", flag)
}
return adaptor
}
func (the *consumerMYX) onFileData() {
dir := the.InFileMonitor.Directory
log.Printf("执行文件监视器-任务 扫描目录:%s....", dir)
adaptor := adaptors.Adaptor_GDGS_MYX{
IdMap: getGDGSIdMap(the.Info.Sensors.GDGSsensorNameMap),
}
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
isUTF8BOM := isUTF8BOM(path)
println(isUTF8BOM)
if filepath.Ext(path) == ".bbcsv" { //商用改为.csv
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
reader := csv.NewReader(unicode.UTF8BOM.NewDecoder().Reader(file))
records, err := reader.ReadAll()
if err != nil {
return err
}
fmt.Println("文件名:", info.Name())
//内容:
payload := adaptor.Transform(records)
if len(payload) > 0 {
the.dataCache <- payload
}
}
return nil
})
if err != nil {
fmt.Println("遍历目录时发生错误:", err)
}
//var needPush []byte
//
//adaptor := the.getAdaptor(matchTopic)
//if adaptor != nil {
// needPush = adaptor.Transform(Msg)
// if len(needPush) > 0 {
// the.dataCache <- needPush
// }
//}
}
func getGDGSIdMap(gdgsSensors []MYX.GDGSsensorNameMap) (IdMap map[string]MYX.CHInfo) {
IdMap = map[string]MYX.CHInfo{}
for _, gdgsSensor := range gdgsSensors {
for name, info := range gdgsSensor.Map {
IdMap[name] = MYX.CHInfo{
SensorInfo: info,
Type: gdgsSensor.Type,
Formula: gdgsSensor.Formula,
}
}
}
return IdMap
}
// 检查文件是否是UTF-8格式并带有BOM
func isUTF8BOM(path string) bool {
file, err := os.Open(path)
if err != nil {
return false
}
defer file.Close()
reader := bufio.NewReader(file)
bytes, err := reader.Peek(3) // 检查文件的前3个字节是否是UTF-8 BOM(0xEF,0xBB,0xBF)
if err != nil {
return false
}
if bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF {
return true // 是UTF-8 BOM,是UTF-8格式的文本文件
} else {
return false // 不是UTF-8 BOM,不是UTF-8格式的文本文件或不是文本文件(例如二进制文件)
}
}

27
consumers/consumerManage.go

@ -0,0 +1,27 @@
package consumers
func GetConsumer(name string) (consumer IConsumer) {
switch name {
case "consumerCQZG": //重庆资管
consumer = new(consumerCQZG)
case "consumerHTJC": //湖南湘潭
consumer = new(consumerHTJC)
case "consumerMYX": //明月峡
consumer = new(consumerMYX)
case "consumerCDJYSN": //明月峡
consumer = new(consumerCDJYSN)
case "consumerWJHP": //魏家滑坡-视觉位移(光电扰度)
consumer = new(consumerWJHP)
case "consumerGZGZM": //工迅-广州高支模平台
consumer = new(consumerGZGZM)
default:
consumer = nil
}
return consumer
}

104
consumers/consumerWJHP.go

@ -0,0 +1,104 @@
package consumers
import (
"encoding/json"
"goUpload/adaptors"
"goUpload/consumers/WJHP"
"goUpload/dbHelper"
"goUpload/monitors"
"log"
"strings"
"time"
)
type consumerWJHP struct {
//数据缓存管道
dataCache chan []byte
//具体配置
Info WJHP.ConfigFile
InMqtt *dbHelper.MqttHelper
InFileMonitor *monitors.FileMonitor
outHttpPost *dbHelper.HttpHelper
}
func (the *consumerWJHP) LoadConfigJson(cfgStr string) {
// 将 JSON 格式的数据解析到结构体中
err := json.Unmarshal([]byte(cfgStr), &the.Info)
if err != nil {
log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error())
panic(err)
}
}
func (the *consumerWJHP) Initial(cfg string) error {
the.LoadConfigJson(cfg)
err := the.InputInitial()
if err != nil {
return err
}
err = the.OutputInitial()
return err
}
func (the *consumerWJHP) InputInitial() error {
the.dataCache = make(chan []byte, 200)
//mqtt数据入口
the.InMqtt = dbHelper.MqttInitial(
the.Info.IOConfig.InMqtt.Host,
the.Info.IOConfig.InMqtt.Port,
the.Info.IOConfig.InMqtt.ClientId,
the.Info.IOConfig.InMqtt.UserName,
the.Info.IOConfig.InMqtt.Password,
false)
for _, inTopic := range the.Info.IOConfig.InMqtt.Topics {
the.InMqtt.Subscribe(inTopic, the.onData)
}
return nil
}
func (the *consumerWJHP) OutputInitial() error {
//数据出口
the.outHttpPost = &dbHelper.HttpHelper{
Url: the.Info.IOConfig.OutHttpPost.Url,
}
the.outHttpPost.Initial()
return nil
}
func (the *consumerWJHP) Work() {
go func() {
for {
pushBytes := <-the.dataCache
log.Printf("取出ch数据,剩余[%d]", len(the.dataCache))
log.Printf("准备推送=%s", pushBytes)
resp, err := the.outHttpPost.Publish(pushBytes)
log.Printf("推送[%s]%v\n结果[%s]: ", the.outHttpPost.Url, err, resp)
time.Sleep(50 * time.Millisecond)
}
}()
}
func (the *consumerWJHP) onData(Topic string, Msg string) {
if len(Msg) > 80 {
log.Printf("mqtt-recv:[%s]:%s ...", Topic, Msg[:100])
}
var needPush []byte
topicPrefixIndex := strings.LastIndex(Topic, "/")
matchTopic := Topic[:topicPrefixIndex]
deviceModule := Topic[topicPrefixIndex+1:]
adaptor := the.getAdaptor(matchTopic)
if adaptor != nil {
needPush = adaptor.Transform(deviceModule, Msg)
if len(needPush) > 0 {
the.dataCache <- needPush
}
}
}
func (the *consumerWJHP) getAdaptor(flag string) (adaptor adaptors.IAdaptor3) {
switch flag {
case "/fs-flexometer":
log.Printf("[视觉位移数据]-上报,准备处理")
adaptor = adaptors.Adaptor_SJWY_WJHP{IdMap: the.Info.SensorConfig}
default:
log.Printf("[无匹配 %s],不处理", flag)
}
return adaptor
}

262
consumers/consumer_test.go

@ -0,0 +1,262 @@
package consumers
import (
"fmt"
"goUpload/config"
"log"
"testing"
"time"
)
// 广州高支模 测点注册 --> 直接从config配置中读取数据,运行前执行一次 测试用例 即可全部注册
func Test_GzGZM_register(t *testing.T) {
log.Printf("广州高支模注册")
myConfigs := config.LoadConfigJsonByPath("../configFiles")
configBody := myConfigs["consumerGZGZM"]
_consumerGZGZM := new(consumerGZGZM)
_consumerGZGZM.Initial(configBody)
go _consumerGZGZM.RefreshTask()
time.Sleep(2 * time.Second)
sensorInfoMaps := _consumerGZGZM.ConfigInfo.SensorInfoMap
for s, info := range sensorInfoMaps {
log.Println(s, info)
_consumerGZGZM.RegisterPoint(s, info)
}
log.Println(_consumerGZGZM)
}
func Test_TYCJ_YB(t *testing.T) {
Msg := `{
"dtuInfo": {
"id": 0,
"code": "COM3"
},
"sensorData": {
"id": 24,
"name": "LHTDQ-RSG-L07-001-03",
"module": "2942",
"channel": "7",
"factorType": 23,
"productCode": "MD-BM15",
"structId": 0,
"data": {
"RawValues": [
880.98736572265625,
16.775247573852539,
784.51312255859375
],
"ThemeValues": [
-14.017531612697216
]
},
"time": "2023-11-27T14:32:44.355"
}
}`
topic := "upload/uds/23"
consumerCQZG := new(consumerCQZG)
consumerCQZG.onData(topic, Msg)
log.Println("===========")
}
func Test_CZ(t *testing.T) {
Msg := `
{
"roadno": 1,
"speed": 110,
"AxisCount": 2,
"AxleGrpNum": 2,
"AxieWeight1": 950,
"AxieWeight2": 640,
"AxieWeight3": 0,
"AxieWeight4": 0,
"AxieWeight5": 0,
"AxieWeight6": 0,
"AxieWeight7": 0,
"AxieWeight8": 0,
"AxieWeight9": 0,
"AxieWeight10": 0,
"GrossWeight": 1590,
"operDirec": 0,
"strTimeYear": "",
"carmodel": "A",
"carlen": 4.2,
"license": "",
"LimitWeight": 0,
"IP": "10.27.171.207",
"DataState": 0,
"atime": "2023-11-25 10:43:16"
}
`
topic := "upload/CZ/LHTDQ-HSD-L09-001-02"
consumerCQZG := new(consumerCQZG)
consumerCQZG.onData(topic, Msg)
}
func Test_ZD(t *testing.T) {
Msg := `
{
"Sensorid": 0,
"Module": "LHTDQ-VIB-L03-001-01",
"Channel": 0,
"ThemeValue": [
999.44390869140625
],
"RawValues": [
],
"AccValues": [
815.57,
454.898,
250.659,
656.155,
906.561,
764.857
],
"Ticks": 1700918326490
}
`
topic := "upload/ZD/LHTDQ-VIB-L03-001-01"
consumerCQZG := new(consumerCQZG)
consumerCQZG.onData(topic, Msg)
}
func Test_HTJCZD(t *testing.T) {
Msg := `{
"Sensorid":0,
"Module":"228-8",
"Channel":0,
"Frequency":32.0,
"ThemeValue":[1277.327880859375],
"RawValues":[],
"AccValues":[1274.202,1272.588,1274.735,1273.694,1273.741,1274.081,1272.76,1275.333,1274.674,1275.618,1274.765,1273.846,1273.83,1271.781,1271.843,1272.96,1272.593,1272.876,1271.364,1271.847,1270.14,1272.254,1270.792,1274.724,1273.793,1275.681,1274.63,1276.474,1273.812,1273.385,1274.161,1272.629,1275.019,1273.262,1273.861,1273.441,1273.591,1273.455,1273.573,1274.292,1274.525,1275.452,1275.644,1275.143,1274.517,1273.508,1272.987,1272.33,1274.151,1273.31,1274.475,1274.396,1274.982,1274.563,1273.806,1275.359,1273.595,1274.654,1274.842,1274.204,1273.618,1274.899,1272.473,1275.206,1273.523,1272.707,1274.964,1272.47,1276.61,1273.99,1275.635,1275.174,1273.962,1274.056,1274.415,1274.031,1274.727,1274.735,1274.71,1275.372,1273.487,1275.045,1271.584,1274.041,1273.093,1275.185,1275.094,1276.431,1274.467,1275.284,1272.375,1273.716,1272.426,1274.458,1274.489,1274.455,1274.188,1275.364,1272.934,1274.977,1272.731,1275.349,1275.43,1274.325,1275.898,1273.545,1275.811,1273.226,1273.627,1273.545,1271.535,1274.143,1274.231,1273.455,1277.328,1274.296,1275.641,1274.933,1273.315,1274.427,1273.6,1273.817,1275.024,1272.811,1276.174,1273.104,0.427,0.592,-2.423,1.284,0.393,0.879,2.123,-0.66,-0.298,0.232,-3.45,2.859,-2.743,1.91,0.237,-0.397,0.21,0.571,-1.613,1.649,-0.882,-0.604,1.622,-1.364,2.522,-0.627,1.355,-0.377,-1.372,0.501,-1.248,0.326,0.338,-0.228,0.823,-0.286,1.777,-1.052,1.214,-0.349,1.492,-1.053,1.208,-0.982,-1.017,0.332,-1.798,1.091,-0.956,2.485,0.427,0.859,2.411,-1.664,0.927,-0.616,-1.226,-0.475,-1.42,0.898,-0.562,0.331,0.444,0.292,-0.362,3.704,-2.178,2.721,-0.411,-2.145,-0.106,-1.515,1.028,-0.694,1.248,0.218,-0.999,-0.082,0.078,-1.325,2.022,0.124,-0.189,0.218,-0.417,-0.252,-0.081,1.39,-0.389,-0.264,0.732,-0.91,0.15,0.202,-1.423,-0.006,0.133,0.505,1.383,0.786,2.051,-0.872,0.108,-0.198,-2.258,0.431,-1.086,-0.829,-0.096,-0.321,1.506,0.884,2.05,0.451,-0.383,0.122,-1.149,-0.363,0.557,-1.259,0.013,-1.308,-0.316,0.302,0.922,2.34,0.229,1.074,-0.144,-1.089,-0.342,-1.129,-0.993,0.593,-0.322,0.978,-0.356,0.619,-0.438,-0.251,0.356,0.031,0.175,1.056,-0.624,-0.369,-0.244,-0.04,1.088,-0.45,0.801,-0.767,-0.595,-0.334,-0.689,-0.045,-0.254,0.082,0.763,0.773,0.714,1.03,0.732,0.486,-0.352,-1.01,-0.33,-1.051,-0.029,-0.328,0.719,0.667,1.02,1.493,0.328,0.752,-0.372,-0.524,-0.385,-0.375,-0.221,0.052,-0.965,0.326,0.368,1.273,1.314,0.702,0.856,-0.107,0.109,0.243,-0.896,-0.207],
"Ticks":1711335436533,
"ThemeItems":null}`
topic := "upload/ZD/228-8"
consumerCQZG := new(consumerHTJC)
consumerCQZG.onData(topic, Msg)
}
func Test_MYX_GDGS(t *testing.T) {
//初始化读取配置
myxConfig := `
{
"consumer": "consumerMYX",
"config": {
"inMqtt": {
"host": "10.8.30.160",
"port": 30883,
"userName": "xtjc-in",
"password": "123456",
"clientId": "xtjc-in-123",
"Topics": [
"upload/uds/+","upload/ZD/+"
]
},
"inFile": {
"directory": "G:\\工作记录\\每月任务需求\\202312需求\\明月峡数据接入influxDB\\光电光栅数据文件CSV",
"filenameExtension": "*.csv",
"cronStr": "0/1 * * * *"
},
"outHttp": {
"url": "http://127.0.0.1:4009/write?u=mingyuexia_wkd&p=mingyuexia_wkd&db=MingYueXia_Bridge&rp=autogen",
"method": "post"
}
},
"sensors": {
"TYCJsensorNameMap": {
"小里程-塔顶倾斜": "ZTWJC001",
"小里程-桥头测斜": "LDZJJC001",
"小里程-桥头伸缩缝磁滞位移": "SSFJC001",
"小里程-二层桥面中间温湿度": "WSDJC001",
"小里程-二层桥面中间风速风向": "FSFXJC001",
"大里程-塔顶倾斜": "ZTWJC002",
"大里程-桥头测斜": "LDZJJC002",
"大里程-桥头伸缩缝磁滞位移": "SSFJC002",
"大里程-塔顶风速风向": "FSFXJC002"
},
"ZDsensorM-CMap": {
"小里程船撞ZD0001": "CZDZJC001",
"小里程船撞ZD0002": "CZDZJC002",
"大里程船撞ZD0003": "CZDZJC003",
"大里程船撞ZD0004": "CZDZJC004",
"小里程主梁ZD0001": "ZLZDJC001",
"大里程主梁ZD0001": "ZLZDJC002"
},
"GDGSsensorNameMap": [
{
"type": "QLDYBJC",
"map": {
"CH0-1": {
"Label":"QLDYBJC001",
"params": {
"k":1.1
}
},
"CH0-2": {
"Label":"QLDYBJC002",
"params": {
"k":1.2
}
},
"CH0-3": {
"Label":"QLDYBJC003",
"params": {
"k":1.3
}
}
},
"formula": "v=( {{.phy}} +0.1 ) * {{.k}} + 2"
},
{
"type": "QLJYBJC",
"map": {
"CH3-1": {
"Label":"QLJYBJC001",
"params": {
"k":1.4
}
},
"CH3-2": {
"Label":"QLJYBJC002",
"params": {
"k":1.5
}
},
"CH3-3": {
"Label":"QLJYBJC003",
"params": {
"k":1.6
}
}
},
"formula": "v=( {{.phy}} +1000.1 )"
},
{
"type": "ZLWDJC",
"map": {
"CH4-1": {
"Label":"ZLWDJC001"
},
"CH4-2": {
"Label":"ZLWDJC002"
}
}
}
]
}
}`
consumerMyx := new(consumerMYX)
err := consumerMyx.Initial(myxConfig)
if err != nil {
log.Panic(fmt.Sprintf("[%s]初始化失败:%s", "consumerMyx", err.Error()))
}
consumerMyx.onFileData()
}

138
dbHelper/_kafka/consumerGroupHandler.go

@ -0,0 +1,138 @@
package _kafka
import (
"context"
"fmt"
"github.com/IBM/sarama"
"log"
)
type ConsumerGroupHandler struct {
brokers []string
topics []string
groupId string
onHandlersMap map[string]func(*sarama.ConsumerMessage) bool
}
func NewConsumerGroupHandler(Brokers []string, GroupId string) *ConsumerGroupHandler {
return &ConsumerGroupHandler{
brokers: Brokers,
groupId: GroupId,
topics: make([]string, 0),
onHandlersMap: make(map[string]func(*sarama.ConsumerMessage) bool),
}
}
func (h *ConsumerGroupHandler) Setup(_ sarama.ConsumerGroupSession) error {
// 在此执行任何必要的设置任务。
fmt.Println("_kafka Consumed start set")
return nil
}
func (h *ConsumerGroupHandler) Cleanup(_ sarama.ConsumerGroupSession) error {
// 在此执行任何必要的清理任务。
return nil
}
func (h *ConsumerGroupHandler) Subscribe(topic string, fun func(string, string) bool) {
h.topics = append(h.topics, topic)
h.onHandlersMap[topic] = h.decorateSubscribeString(fun)
}
func (h *ConsumerGroupHandler) SubscribeRaw(topic string, fun func(*sarama.ConsumerMessage) bool) {
h.topics = append(h.topics, topic)
h.onHandlersMap[topic] = fun
}
func (h *ConsumerGroupHandler) decorateSubscribeString(handler func(string, string) bool) func(*sarama.ConsumerMessage) bool {
f := func(cm *sarama.ConsumerMessage) bool {
msg := string(cm.Value)
log.Printf("处理topic[%s]数据 offset=[%d]", cm.Topic, cm.Offset)
return handler(cm.Topic, msg)
}
return f
}
func (h *ConsumerGroupHandler) ConsumeClaim(session sarama.ConsumerGroupSession, Claim sarama.ConsumerGroupClaim) error {
for message := range Claim.Messages() {
// 在这里处理消息。
topic := message.Topic
//log.Printf("[%s]Message: %s\n", topic, string(message.Value))
allOk := true
handlerFunc, isValid := h.onHandlersMap[topic]
if !isValid {
log.Printf("不存在 [%s]的解析", topic)
continue
}
allOk = handlerFunc(message)
if allOk {
// 将消息标记为在会话中已处理。
session.MarkMessage(message, "is handled")
}
}
return nil
}
func (h *ConsumerGroupHandler) Worker() {
config := sarama.NewConfig()
config.Consumer.Return.Errors = false
config.Version = sarama.V2_0_0_0
config.Consumer.Offsets.Initial = sarama.OffsetOldest
config.Consumer.Offsets.AutoCommit.Enable = true
config.Consumer.Group.Rebalance.GroupStrategies = []sarama.BalanceStrategy{sarama.NewBalanceStrategyRoundRobin()}
group, err := sarama.NewConsumerGroup(h.brokers, h.groupId, config)
if err != nil {
panic(err)
}
defer func() { _ = group.Close() }()
// Track errors
go func() {
for err := range group.Errors() {
fmt.Println("ERROR", err)
}
}()
// Iterate over consumer sessions.
ctx := context.Background()
for {
//topics := []string{"anxinyun_data"} //my_topic
//handler := consumerGroupHandler{}
// `Consume` should be called inside an infinite loop, when a
// server-side rebalance happens, the consumer session will need to be
// recreated to get the new claims
handler := h
err := group.Consume(ctx, h.topics, handler)
log.Printf("订阅 topics=%v", h.topics)
if err != nil {
log.Printf("订阅异常=%s", err.Error())
}
}
}
// 同步生产模式
func Send2Topic(brokers []string, topic, content string) {
producer, err := sarama.NewSyncProducer(brokers, nil)
if err != nil {
log.Fatalln(err)
}
defer func() {
if err := producer.Close(); err != nil {
log.Fatalln(err)
}
}()
msg := &sarama.ProducerMessage{Topic: topic, Value: sarama.StringEncoder(content)}
partition, offset, err := producer.SendMessage(msg)
if err != nil {
log.Printf("FAILED to send message: %s\n", err)
} else {
log.Printf("> message sent to partition %d at offset %d\n", partition, offset)
}
}

27
dbHelper/_kafka/kafkaHelper.go

@ -0,0 +1,27 @@
package _kafka
import (
"log"
)
type KafkaHelper struct {
Brokers []string
GroupId string
client *ConsumerGroupHandler
}
func (the *KafkaHelper) initialClient() *ConsumerGroupHandler {
the.client = NewConsumerGroupHandler(the.Brokers, the.GroupId)
return the.client
}
func (the *KafkaHelper) Initial() *ConsumerGroupHandler {
return the.initialClient()
}
func (the *KafkaHelper) Subscribe(topic string, callback func(topic string, msg string) bool) {
log.Printf("=================开始订阅 %s [%s]=================", the.Brokers, topic)
the.client.Subscribe(topic, callback)
}
func (the *KafkaHelper) Worker() {
go the.client.Worker()
}

52
dbHelper/_kafka/kafka_test.go

@ -0,0 +1,52 @@
package _kafka
import (
"log"
"os"
"strings"
"testing"
"time"
)
func TestInitial(t *testing.T) {
//"10.8.30.160:30092"
//
os.Setenv("kafkaBrokers", "10.8.30.72:29092,10.8.30.73:29092,10.8.30.74:29092")
//os.Setenv("kafkaTopics", "RawData2")
}
func TestConsumer(t *testing.T) {
TestInitial(t)
//消费者
brokers := strings.Split(os.Getenv("kafkaBrokers"), ",") //"10.8.30.160:30092"
//topics := strings.Split(os.Getenv("kafkaTopics"), ",")
groupID := "consumer_group_lk2"
cgh := NewConsumerGroupHandler(brokers, groupID)
cgh.Subscribe("testTopic01", handler1)
cgh.Subscribe("RawData11", handler2)
cgh.Worker()
println("=======")
}
func handler1(msg string) bool {
log.Printf("handler1 处理消息:%s", msg)
return true
}
func handler2(msg string) bool {
log.Printf("handler2 处理消息:%s", msg)
return true
}
func TestProductAsync(t *testing.T) {
layout := "2006-01-02T15:04:05.000+0800"
timeStr := "2024-02-02T00:00:01.001+0800"
startTime, err := time.ParseInLocation(layout, timeStr, time.Local)
if err != nil {
panic("时间异常")
}
msgs := getMsgs(2000, startTime, time.Millisecond)
topic := "go_RawData"
AsyncProductMsg(topic, msgs)
time.Sleep(time.Second * 2)
}

113
dbHelper/_kafka/producerHelper.go

@ -0,0 +1,113 @@
package _kafka
import (
"fmt"
"github.com/IBM/sarama"
"log"
"strings"
"time"
)
func getMsgs(count int, startTime time.Time, offsetTime time.Duration) []string {
msgs := make([]string, 0)
for i := 0; i < count; i++ {
t := startTime.Add(time.Duration(i) * offsetTime)
msgs = append(msgs, getMsg(t))
}
return msgs
}
func getMsg(collectTime time.Time) string {
collectTimeStr := collectTime.Format(time.RFC3339Nano)
rawDataMsg := fmt.Sprintf(`
{
"userId": "77804162-837d-4ff9-96c0-beb8e8888f8e",
"thingId": "8e3eec71-c924-47fd-ac8b-2f28c49ad4e9",
"dimensionId": "f65e5990-540d-40ff-9056-af775e5e4c56",
"dimCapId": "aaab627b-5a58-454b-a83f-e236a63930bb",
"capId": "35ec137a-ea04-4c81-bbaf-23ddae650c0e",
"deviceId": "9c94a305-dd18-4809-8fc6-4191c699e726",
"scheduleId": "c5559fbd-eaf4-4fd9-b667-30cc40607ea9",
"taskId": "c05ccef4-017c-48d5-a2e5-c01fac16f797",
"jobId": 1,
"jobRepeatId": 1,
"triggerTime": "%s",
"realTime": "%s",
"finishTime": "%s",
"seq": 0,
"released": false,
"data": {
"type": 1,
"data": {
"pressure": 17.186,
"temperature": 23.25
},
"result": {
"code": 0,
"msg": "",
"detail": null,
"errTimes": 0,
"dropped": false
}
}
}`, collectTimeStr, collectTimeStr, collectTimeStr)
return rawDataMsg
}
// AsyncProductMsg 是一个异步发送消息到Kafka的函数
// topic: 消息的主题
// msgs: 需要发送的消息的内容列表
func AsyncProductMsg(topic string, msgs []string) {
producer, err := sarama.NewAsyncProducer([]string{"10.8.30.160:30992"}, nil)
if err != nil {
log.Fatalln(err)
}
defer func() {
if err := producer.Close(); err != nil {
log.Fatalln(err)
}
}()
for i := 0; i < len(msgs); i++ {
content := msgs[i]
msg := &sarama.ProducerMessage{Topic: topic, Value: sarama.StringEncoder(content)}
producer.Input() <- msg
}
if err != nil {
log.Printf("FAILED to send message: %s\n", err)
}
}
type KafkaAsyncProducer struct {
producer sarama.AsyncProducer
}
func (p *KafkaAsyncProducer) Publish(topic string, messageBytes []byte) {
//由于kafka topic 无法分级 需要特殊处理
topic = strings.Split(topic, "/")[0]
msg := &sarama.ProducerMessage{Topic: topic, Value: sarama.ByteEncoder(messageBytes)}
p.producer.Input() <- msg
}
func (p *KafkaAsyncProducer) Close() {
if err := p.producer.Close(); err != nil {
log.Fatalln(err)
}
}
func NewKafkaAsyncProducer(brokers []string) *KafkaAsyncProducer {
config := sarama.NewConfig()
config.ClientID = "et-go-push"
config.Net.DialTimeout = time.Second * 10
config.Net.ReadTimeout = time.Second * 10
config.Net.WriteTimeout = time.Second * 10
producer, err := sarama.NewAsyncProducer(brokers, config)
if err != nil {
log.Printf("_kafka 生产者[%v] 初始化异常 %s", brokers, err.Error())
return nil
}
//[]string{"10.8.30.160:30092"} //etpush/3/197
return &KafkaAsyncProducer{
producer: producer,
}
}

38
dbHelper/apiServer.go

@ -0,0 +1,38 @@
package dbHelper
import (
"fmt"
"github.com/gin-gonic/gin"
"log"
"net/http"
"time"
)
type RouterFunc struct {
relativePath string //相对路由 如/gzm/data/upload
funcType string // 方法类型 如 post ,get
fun func(c *gin.Context) //方法
}
type ApiServerHelper struct {
Port uint16
RoutFun map[string]RouterFunc
}
func (the *ApiServerHelper) Initial() {
router := gin.Default()
for name, routerFunc := range the.RoutFun {
switch routerFunc.funcType {
case http.MethodGet:
router.GET(routerFunc.relativePath, routerFunc.fun)
case http.MethodPost:
router.GET(routerFunc.relativePath, routerFunc.fun)
default:
log.Printf("不支持的 [%s]方法类型 %s", routerFunc.relativePath, routerFunc.funcType)
continue
}
log.Printf("注册路由 %s,监听地址=%s", name, routerFunc.relativePath)
}
router.Run(fmt.Sprintf("0.0.0.0:%d", the.Port))
time.Sleep(time.Second * 1)
}

30
dbHelper/fileSaveHelper.go

@ -0,0 +1,30 @@
package dbHelper
import (
"io"
"log"
"os"
"strings"
)
type FileSaveHelper struct {
Directory string
FilenameExtension string
}
func (the *FileSaveHelper) Initial() {
}
func (the *FileSaveHelper) Save(filePath, fileContent string) {
File, errC := os.Create(filePath)
defer File.Close()
if errC != nil {
log.Printf("创建文件失败 path=%s,err=%s", filePath, errC.Error())
}
_, err := io.Copy(File, strings.NewReader(fileContent))
if err != nil {
log.Printf("文件写入失败 path=%s,err=%s", filePath, err.Error())
}
log.Printf("[%v]存储文件 长度=%d ", filePath, len(fileContent))
}

257
dbHelper/httpHelper.go

@ -0,0 +1,257 @@
package dbHelper
import (
"bytes"
"crypto/tls"
"fmt"
"io"
"log"
"mime/multipart"
"net/http"
"os"
"strings"
"time"
)
type HttpHelper struct {
Url string
Token string
client http.Client
}
func (the *HttpHelper) Initial() {
the.client = http.Client{}
time.Sleep(time.Second * 1)
}
func (the *HttpHelper) HttpGet(queryBody string) string {
url := the.Url
client := the.client
req, err := http.NewRequest("GET", url, strings.NewReader(queryBody))
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
fmt.Println("http get 请求,url", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
return string(body)
}
func (the *HttpHelper) HttpGetWithHeader(queryBody string, headerMap map[string]string) string {
url := the.Url
client := the.client
req, err := http.NewRequest("GET", url, strings.NewReader(queryBody))
req.Header.Set("Content-Type", "application/json")
for k, v := range headerMap {
req.Header.Set(k, v)
}
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer func(resp *http.Response) {
if resp != nil && resp.Body != nil {
errClose := resp.Body.Close()
if errClose != nil {
log.Printf("关闭异常")
}
}
}(resp)
fmt.Println("http get 请求,url", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
return string(body)
}
func (the *HttpHelper) Publish(messageBytes []byte) (string, error) {
url := the.Url
client := the.client
req, err := http.NewRequest("POST", url, bytes.NewReader(messageBytes))
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
log.Println("请求POST异常 ", err, resp)
return "", err
}
defer resp.Body.Close()
log.Println("http post 请求,url", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Println("请求ReadAll异常 ", err, resp)
return "", err
}
return string(body), err
}
func (the *HttpHelper) PublishWithHeader(messageBytes []byte, headers map[string]string) (string, error) {
resp, err := HttpPostWithHeader(the.Url, string(messageBytes), headers)
if err != nil {
log.Printf("数据推送异常 err=%s,resp=%s", err.Error(), resp)
}
return resp, err
}
// 静态方法
func HttpGet(url string, queryBody string) string {
client := &http.Client{}
req, err := http.NewRequest("GET", url, strings.NewReader(queryBody))
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
fmt.Println("http get 请求,url", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
return string(body)
}
func HttpPost(url string, queryBody string) (string, error) {
client := &http.Client{}
req, err := http.NewRequest("POST", url, strings.NewReader(queryBody))
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求POST异常 ", err, resp)
return "", err
}
defer resp.Body.Close()
fmt.Println("http post 请求,url", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("请求ReadAll异常 ", err, resp)
return "", err
}
return string(body), err
}
func HttpPostWithHeader(url string, queryBody string, headers map[string]string) (string, error) {
tr := &http.Transport{
DisableKeepAlives: true,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
req, err := http.NewRequest("POST", url, strings.NewReader(queryBody))
req.Header.Set("Content-Type", "application/json")
for k, v := range headers {
req.Header.Add(k, v)
}
fmt.Printf("http post 开始请求,%s,\n,%v \n", url, req)
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求POST异常 ", err, resp)
return "", err
}
defer resp.Body.Close()
//fmt.Println("http post 请求,url=", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("请求ReadAll异常 ", err, resp)
return "", err
}
return string(body), err
}
func HttpPostFormDataWithHeader(url string, queryBody string, headers map[string]string) (string, error) {
tr := &http.Transport{
DisableKeepAlives: true,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
req, err := http.NewRequest("POST", url, strings.NewReader(queryBody))
req.Header.Set("Content-Type", "application/json")
for k, v := range headers {
req.Header.Add(k, v)
}
fmt.Printf("http post 开始请求,%s,\n,%s \n", url, req)
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求POST异常 ", err, resp)
return "", err
}
defer resp.Body.Close()
fmt.Println("http post 请求,url=", url, " <- code=", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("请求ReadAll异常 ", err, resp)
return "", err
}
return string(body), err
}
func UploadFile(url string, headers map[string]string, bodyParams map[string]string, fileName string) ([]byte, error) {
body := new(bytes.Buffer)
// 创建 multipart writer
mpWriter := multipart.NewWriter(body)
for key, val := range bodyParams {
_ = mpWriter.WriteField(key, val)
}
file, err := os.Open(fileName)
fileInfo, err := file.Stat()
// 添加文件字段
formFile, err := mpWriter.CreateFormFile("File", fileInfo.Name())
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
if err != nil {
log.Printf("无法打开文件[%s]: err=%s", file.Name(), err.Error())
return nil, err
}
//读取文件并写入请求体
_, err = io.Copy(formFile, file)
if err != nil {
return nil, err
}
err = mpWriter.Close()
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", url, body)
//req.Header.Set("Content-Type", "application/json")
//req.Header.Set("Content-Type","multipart/form-data")
req.Header.Add("Content-Type", mpWriter.FormDataContentType())
for k, v := range headers {
req.Header.Add(k, v)
}
if err != nil {
return nil, err
}
//tr := &http.Transport{
// DisableKeepAlives: true,
// TLSClientConfig: &tls.IOConfig{InsecureSkipVerify: true},
//}
//HttpClient := &http.Client{Transport: tr}
HttpClient := &http.Client{}
resp, err := HttpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
content, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return content, nil
}

136
dbHelper/influxDBHelper.go

@ -0,0 +1,136 @@
package dbHelper
import (
"context"
"fmt"
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
"log"
"net/http"
"time"
)
type InfluxDBHelper struct {
Url string
Token string
Bucket string
Org string
client influxdb2.Client
}
func (the *InfluxDBHelper) GetClient() influxdb2.Client {
return the.client
}
func (the *InfluxDBHelper) Initial() {
//the.Token = "t4YoDtUT1Hi3-1COJ2xxJbKnBGHyLYxt9SQ2MpZ_5EskMaKyKaU-IiSQRJnFm7y66t80M3AKH7TzF3tBksL5EA=="
//the.Bucket = "dynamic"
//the.Org = "shandong"
//the.Url = "http://172.26.103.10:30086"
// 创建HTTP客户端并设置请求超时
httpClient := &http.Client{
Timeout: 60 * time.Second, // 设置超时时间为60秒
}
the.client = influxdb2.NewClientWithOptions(the.Url, the.Token, influxdb2.DefaultOptions().SetHTTPClient(httpClient))
// always close client at the end
//defer the.client.Close()
log.Println("influxDB 客户端初始化完成")
}
func (the *InfluxDBHelper) Close() {
defer the.client.Close()
log.Println("influxDB 客户端关闭")
}
func (the *InfluxDBHelper) Write() {
// get non-blocking write client
writeAPI := the.client.WriteAPI(the.Org, the.Bucket)
// write line protocol
writeAPI.WriteRecord(fmt.Sprintf("stat,unit=temperature avg=%f,max=%f", 23.5, 45.0))
writeAPI.WriteRecord(fmt.Sprintf("stat,unit=temperature avg=%f,max=%f", 22.5, 45.0))
// Flush writes
writeAPI.Flush()
}
func (the *InfluxDBHelper) QueryByOfflineGap(measurement string, offlineGap string) map[string]time.Time {
sh, _ := time.LoadLocation("Asia/Shanghai")
data := make(map[string]time.Time)
query := fmt.Sprintf(`
from(bucket:"%v")
|> range(start: -%sm)
|> filter(fn: (r) => r["_measurement"] == "%s")
|> group(columns: ["sensor_id"])
|> last()
`, the.Bucket, offlineGap, measurement)
// Get query client
queryAPI := the.client.QueryAPI(the.Org)
// get QueryTableResult
result, err := queryAPI.Query(context.Background(), query)
if err == nil {
// Iterate over query response
for result.Next() {
// Notice when group key has changed
if result.TableChanged() {
fmt.Printf("table: %s\n", result.TableMetadata().String())
}
// Access data
values := result.Record().Values()
sensorId := values["sensor_id"].(string)
recordTime := result.Record().Time().In(sh)
data[sensorId] = recordTime
fmt.Printf("station:[%v] value:[%v] %v \n", sensorId, recordTime, values)
}
// check for an error
if result.Err() != nil {
fmt.Printf("query parsing error: %\n", result.Err().Error())
}
} else {
log.Printf("influxDB 查询异常 %s", err.Error())
}
return data
}
func (the *InfluxDBHelper) Query() map[string]time.Time {
sh, _ := time.LoadLocation("Asia/Shanghai")
data := make(map[string]time.Time)
query := fmt.Sprintf(`
from(bucket:"%v")
|> range(start: -1)
|> filter(fn: (r) => r["_measurement"] == "factor_11" or r["_measurement"] == "factor_18" or r["_measurement"] == "factor_24")
|> group(columns: ["sensor_id"])
|> last()
`, the.Bucket)
// Get query client
queryAPI := the.client.QueryAPI(the.Org)
// get QueryTableResult
result, err := queryAPI.Query(context.Background(), query)
if err == nil {
// Iterate over query response
for result.Next() {
// Notice when group key has changed
if result.TableChanged() {
fmt.Printf("table: %s\n", result.TableMetadata().String())
}
// Access data
values := result.Record().Values()
sensorId := values["sensor_id"].(string)
recordTime := result.Record().Time().In(sh)
data[sensorId] = recordTime
//fmt.Printf("station:[%v] value:[%v] %v \n", sensorId, recordTime, values)
}
// check for an error
if result.Err() != nil {
fmt.Printf("query parsing error: %v \n", result.Err().Error())
}
} else {
log.Printf("[QueryAllLast] influxDB 查询异常 %s", err.Error())
}
return data
}

134
dbHelper/mqttHelper.go

@ -0,0 +1,134 @@
package dbHelper
import (
"crypto/tls"
"crypto/x509"
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"log"
"os"
"time"
)
type MqttHelper struct {
Host string
Port int
ClientId string
UserName string
Password string
client mqtt.Client
subscribeCalls []subscribeCall //纪录 重连订阅
}
type subscribeCall struct {
topic string
f func(topic string, callMsg string)
}
func (the *MqttHelper) reConn2Subscribe(client mqtt.Client) {
log.Println("mqtt触发重连后的重订阅")
for _, call := range the.subscribeCalls {
the.Subscribe(call.topic, call.f)
}
}
func (the *MqttHelper) initialClient(sslEnable bool, caPath string) {
maxReConnCount := 3
ReConnDurationSec := 30
reConn:
mqttConnectStr := fmt.Sprintf("tcp://%v:%d", the.Host, the.Port)
opts := mqtt.NewClientOptions().AddBroker(mqttConnectStr)
opts.SetUsername(the.UserName)
opts.SetPassword(the.Password)
opts.SetClientID(the.ClientId)
opts.SetOnConnectHandler(the.reConn2Subscribe)
if sslEnable {
opts.SetTLSConfig(NewTlsConfig(caPath))
}
the.client = mqtt.NewClient(opts)
if token := the.client.Connect(); token.Wait() && token.Error() != nil {
log.Printf("mqtt连接状态异常 %v(u:%v,p:%v,cid:%v) [err=%s]", mqttConnectStr, the.UserName, the.Password, the.ClientId, token.Error())
log.Printf("mqtt重连,%ds后尝试,剩余次数=%d", ReConnDurationSec, maxReConnCount)
if maxReConnCount > 0 {
maxReConnCount--
time.Sleep(time.Duration(ReConnDurationSec) * time.Second)
goto reConn
}
os.Exit(1)
}
time.Sleep(time.Second * 1)
}
func (the *MqttHelper) Initial() {
the.initialClient(false, "")
}
func (the *MqttHelper) InitialWithSSL(caPath string) {
the.initialClient(true, caPath)
}
func NewTlsConfig(sslPath string) *tls.Config {
//"ssl/centerCA.crt"
certpool := x509.NewCertPool()
ca, err := os.ReadFile(sslPath)
if err != nil {
log.Fatalln(err.Error())
}
certpool.AppendCertsFromPEM(ca)
return &tls.Config{
//RootCAs: certpool,
InsecureSkipVerify: true,
}
}
func (the *MqttHelper) Publish(topic string, messageBytes []byte) {
if the.client != nil {
token := the.client.Publish(topic, 0, false, messageBytes)
token.Wait()
//the.client.Disconnect(200)
fmt.Printf("[%s] -[%v]推送Msg 长度=%d \n", topic, the.client.IsConnected(), len(messageBytes))
}
}
func (the *MqttHelper) Subscribe(topic string, myCallback func(topic string, callMsg string)) {
var callback mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
log.Printf("收到数据 [%v] TOPIC: %s,MSGLen: %v", msg.MessageID(), msg.Topic(), len(msg.Payload()))
Msg := string(msg.Payload())
myCallback(msg.Topic(), Msg)
//log.Println("消息处理结束")
}
log.Printf("=================开始订阅 %s [%s]=================", the.Host, topic)
t := the.client.Subscribe(topic, 1, callback)
f := func() {
_ = t.Wait() // Can also use '<-t.Done()' in releases > 1.2.0
if t.Error() != nil {
log.Println(t.Error()) // Use your preferred logging technique (or just fmt.Printf)
}
}
go f()
//纪录需要重连的 callback
the.subscribeCalls = append(the.subscribeCalls, subscribeCall{
topic: topic,
f: myCallback,
})
}
func MqttInitial(host string, port int, clientId string, userName string, password string, isSSL bool, caPtah ...string) *MqttHelper {
mqHelpers := MqttHelper{
Host: host,
Port: port,
ClientId: clientId,
UserName: userName,
Password: password,
}
if isSSL && len(caPtah) > 0 {
log.Println("SSL mqHelpers初始化")
mqHelpers.InitialWithSSL(caPtah[0])
} else {
mqHelpers.Initial()
}
//topic = "t/500103" //龙河桥
time.Sleep(time.Second * 1)
return &mqHelpers
}

51
dbHelper/udpHelper.go

@ -0,0 +1,51 @@
package dbHelper
import (
"fmt"
"log"
"net"
"time"
)
type UdpHelper struct {
Host string
Port int
client *net.UDPConn
}
func (the *UdpHelper) Initial() {
addrStr := fmt.Sprintf("%s:%d", the.Host, the.Port)
serverAddr, err := net.ResolveUDPAddr("udp", addrStr)
if err != nil {
log.Println("解析地址失败:", err)
panic(err)
}
// 创建UDP连接
the.client, err = net.DialUDP("udp", nil, serverAddr)
if err != nil {
log.Println("连接服务器失败:", err)
panic(err)
}
time.Sleep(time.Second * 1)
}
func (the *UdpHelper) Publish(messageBytes []byte) {
if the.client != nil {
// 发送数据
_, err := the.client.Write(messageBytes)
if err != nil {
log.Println("发送数据失败:", err)
return
}
log.Printf("[%v]推送Msg 长度=%d ", the.client.RemoteAddr(), len(messageBytes))
}
}
func (the *UdpHelper) Close() {
err := the.client.Close()
if err != nil {
log.Printf("[%v] udp 链接 关闭出现异常 %s", the.client.RemoteAddr(), err.Error())
return
}
}

64
go.mod

@ -0,0 +1,64 @@
module goUpload
go 1.21
require (
github.com/IBM/sarama v1.43.3
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/gin-gonic/gin v1.9.1
github.com/influxdata/influxdb-client-go/v2 v2.13.0
github.com/robfig/cron/v3 v3.0.1
golang.org/x/text v0.17.0
google.golang.org/protobuf v1.31.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
require (
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/bytedance/sonic v1.10.0-rc3 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/eapache/go-resiliency v1.7.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/oapi-codegen/runtime v1.0.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.4.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

196
go.sum

@ -0,0 +1,196 @@
github.com/IBM/sarama v1.43.3 h1:Yj6L2IaNvb2mRBop39N7mmJAHBVY3dTPncr3qGVkxPA=
github.com/IBM/sarama v1.43.3/go.mod h1:FVIRaLrhK3Cla/9FfRF5X9Zua2KpS3SYIXxhac1H+FQ=
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0=
github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA=
github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws=
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/influxdata/influxdb-client-go/v2 v2.13.0 h1:ioBbLmR5NMbAjP4UVA5r9b5xGjpABD7j65pI8kFphDM=
github.com/influxdata/influxdb-client-go/v2 v2.13.0/go.mod h1:k+spCbt9hcvqvUiz0sr5D8LolXHqAAOfPw9v/RIRHl4=
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo=
github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A=
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

24
logSet.go

@ -0,0 +1,24 @@
package main
import (
"gopkg.in/natefinch/lumberjack.v2"
"io"
"log"
"os"
)
// 日志生成文件,配置初始化
func logInitial() {
multiWriter := io.MultiWriter(os.Stdout, &lumberjack.Logger{
Filename: "./logs/logInfo.log",
MaxSize: 1, // megabytes
MaxBackups: 10,
MaxAge: 30, //days
//Compress: true,
})
log.SetFlags(log.LstdFlags | log.Lshortfile)
log.SetOutput(multiWriter)
log.Println("=================log start=================")
log.Println("==>")
}

18
logs/logInfo.log

@ -0,0 +1,18 @@
2024/10/17 11:33:20.528503 main.go:24: =================log start=================
2024/10/17 11:33:20.540075 main.go:25: ==>
2024/10/17 11:33:20.540075 main.go:30: 进程启动
2024/10/17 11:33:20.540075 init.go:20: 加载配置文件:config_魏家滑坡_视觉位移.json
2024/10/17 11:33:20.540592 init.go:20: 加载配置文件:弃用备份
2024/10/17 11:33:20.540592 init.go:22: 非文件[弃用备份]跳过
2024/10/17 11:33:22.546148 mqttHelper.go:48: mqtt连接状态异常 tcp://10.8.30.160:1883(u:wjhp-sjwy-upload,p:123456,cid:wjhp-sjwy-upload) [err=network Error : dial tcp 10.8.30.160:1883: connectex: No connection could be made because the target machine actively refused it.]
2024/10/17 11:33:22.546148 mqttHelper.go:49: mqtt重连,30s后尝试,剩余次数=3
2024/10/17 11:33:53.265276 main.go:24: =================log start=================
2024/10/17 11:33:53.285624 main.go:25: ==>
2024/10/17 11:33:53.285624 main.go:30: 进程启动
2024/10/17 11:33:53.286127 init.go:20: 加载配置文件:config_魏家滑坡_视觉位移.json
2024/10/17 11:33:53.286698 init.go:20: 加载配置文件:弃用备份
2024/10/17 11:33:53.286698 init.go:22: 非文件[弃用备份]跳过
2024/10/17 11:33:53.289208 mqttHelper.go:28: mqtt触发重连后的重订阅
2024/10/17 11:33:55.290027 mqttHelper.go:100: =================开始订阅 10.8.30.160 [/fs-flexometer/admin123]=================
2024/10/17 11:34:12.251376 mqttHelper.go:28: mqtt触发重连后的重订阅
2024/10/17 11:34:12.251376 mqttHelper.go:100: =================开始订阅 10.8.30.160 [/fs-flexometer/admin123]=================

51
main.go

@ -0,0 +1,51 @@
package main
import (
"fmt"
"goUpload/config"
"goUpload/consumers"
"gopkg.in/natefinch/lumberjack.v2"
"io"
"log"
"os"
"time"
)
func init() {
multiWriter := io.MultiWriter(os.Stdout, &lumberjack.Logger{
Filename: "./logs/logInfo.log",
MaxSize: 1, // megabytes
MaxBackups: 10,
MaxAge: 30, //days
//Compress: true,
})
log.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds)
log.SetOutput(multiWriter)
log.Println("=================log start=================")
log.Println("==>")
}
func main() {
log.Println("进程启动")
//初始化读取配置
myConfigs := config.LoadConfigJson() //数据存储
for consumerName, consumerConfig := range myConfigs {
consumer := consumers.GetConsumer(consumerName)
if consumer == nil {
log.Printf("无匹配的consumer [%s] 请检查", consumerName)
continue
}
err := consumer.Initial(consumerConfig)
if err != nil {
log.Panic(fmt.Sprintf("[%s]初始化失败:%s", consumerName, err.Error()))
}
consumer.Work()
}
for {
time.Sleep(time.Hour)
}
}

52
main_test.go

@ -0,0 +1,52 @@
package main
import (
"bytes"
"crypto/rc4"
"encoding/hex"
"goUpload/utils"
"log"
"testing"
"text/template"
"time"
)
func TestCRC16CCITT(t *testing.T) {
hexs := "0a16080718a8ea8fab06620c0a0471bd54c11204e01d8641"
hexs = "0a2f080210f8b6d5d01218b395bffec3313a1e0a08a75fed41a75fed41120892c5d64292c5d6421a08f6c8a74379c9a743"
Hexdata, _ := hex.DecodeString(hexs)
crc := utils.NewCRC16CCITT().GetWCRCin(Hexdata)
log.Println(hex.EncodeToString(crc))
log.Println("===1==")
needRC4 := append(Hexdata, crc...)
rc4Key := []byte("t/500101")
dest1 := make([]byte, len(needRC4))
cipher1, _ := rc4.NewCipher(rc4Key)
cipher1.XORKeyStream(dest1, needRC4)
log.Printf("最终报文 dest1=%s", hex.EncodeToString(dest1))
}
func TestRC4(t *testing.T) {
rc4Key := []byte("t/500101")
log.Println("===2 test RC4==")
cipher2, _ := rc4.NewCipher(rc4Key)
raw := "0a2f080210f8b6d5d01218b395bffec3313a1e0a08a75fed41a75fed41120892c5d64292c5d6421a08f6c8a74379c9a743864c"
needRC4New, _ := hex.DecodeString(raw)
dest2 := make([]byte, len(needRC4New))
cipher2.XORKeyStream(dest2, needRC4New)
log.Printf("最终报文 dest1=%s", hex.EncodeToString(dest2))
}
func TestTemplate(t *testing.T) {
Create := func(name, t string) *template.Template {
return template.Must(template.New(name).Parse(t))
}
t2 := Create("t2", "什么是快乐星球-Name: {{.Name}}\n")
b := &bytes.Buffer{}
t2.Execute(b, struct {
Name string
}{"Jane Doe"})
time.Sleep(time.Second * 1)
bs := b.String()
log.Println(bs)
}

81
models/EsAggTop.go

@ -0,0 +1,81 @@
package models
import "time"
const (
// AXY_FactorType_YL 雨量监测
AXY_FactorType_Rain = 3
// AXY_FactorType_Rain_New 雨量新
AXY_FactorType_Rain_New = 422
// AXY_FactorType_BMWY 表面斜监测(GNSS)
AXY_FactorType_BMWY = 13
// AXY_FactorType_NBWY 深部水平位移(双轴倾角转位移)
AXY_FactorType_SBSPWY = 116
// AXY_FactorType_DXSW 地下水位 (m) (马冲20240515确认 不传地下水位和裂缝)
AXY_FactorType_DXSW = 546
//大斜阳
AXY_StructId_DXY = "4570"
//太平堡
AXY_StructId_TPB = "4571"
//唐山冀东
AXY_StructId_TSJD = "3676"
)
type EsAggTop struct {
Took int `json:"took"`
TimedOut bool `json:"timed_out"`
Shards struct {
Total int `json:"total"`
Successful int `json:"successful"`
Skipped int `json:"skipped"`
Failed int `json:"failed"`
} `json:"_shards"`
Hits struct {
Total int `json:"total"`
MaxScore float64 `json:"max_score"`
} `json:"hits"`
Aggregations struct {
SensorId struct {
DocCountErrorUpperBound int `json:"doc_count_error_upper_bound"`
SumOtherDocCount int `json:"sum_other_doc_count"`
Buckets []Bucket `json:"buckets"`
} `json:"gpBySensorId"`
} `json:"aggregations"`
}
type Bucket struct {
Key int `json:"key"`
DocCount int `json:"doc_count"`
Last struct {
Hits struct {
Total int `json:"total"`
Hits []struct {
Index string `json:"_index"`
Type string `json:"_type"`
Id string `json:"_id"`
Score interface{} `json:"_score"`
Source Source `json:"_source"`
Sort []int64 `json:"sort"`
} `json:"hits"`
} `json:"hits"`
} `json:"last"`
}
type Source struct {
SensorName string `json:"sensor_name"`
FactorName string `json:"factor_name"`
FactorProtoCode string `json:"factor_proto_code"`
Data map[string]float64 `json:"data"`
FactorProtoName string `json:"factor_proto_name"`
Factor int `json:"factor"`
CollectTime time.Time `json:"collect_time"`
Sensor int `json:"sensor"`
Structure int `json:"structure"`
IotaDevice []string `json:"iota_device"`
CreateTime time.Time `json:"create_time"`
}

28
models/OLCZ.go

@ -0,0 +1,28 @@
package models
type OLCZ struct {
Roadno int32 `json:"roadno"`
Speed int32 `json:"speed"`
AxisCount int32 `json:"AxisCount"`
AxleGrpNum int32 `json:"AxleGrpNum"`
AxieWeight1 int `json:"AxieWeight1"`
AxieWeight2 int `json:"AxieWeight2"`
AxieWeight3 int `json:"AxieWeight3"`
AxieWeight4 int `json:"AxieWeight4"`
AxieWeight5 int `json:"AxieWeight5"`
AxieWeight6 int `json:"AxieWeight6"`
AxieWeight7 int `json:"AxieWeight7"`
AxieWeight8 int `json:"AxieWeight8"`
AxieWeight9 int `json:"AxieWeight9"`
AxieWeight10 int `json:"AxieWeight10"`
GrossWeight int32 `json:"GrossWeight"`
StrTimeYear string `json:"strTimeYear"`
Carmodel string `json:"carmodel"`
OperDirec int32 `json:"operDirec"`
Carlen int `json:"carlen"`
License string `json:"license"`
LimitWeight int `json:"LimitWeight"`
IP string `json:"IP"`
DataState int `json:"DataState"`
Atime string `json:"atime"`
}

44
models/TYCJ.go

@ -0,0 +1,44 @@
package models
const (
//温湿度监测
TYCJ_FactorType_WSD = 5
//档土墙应变监测
TYCJ_FactorType_DTQYB = 13
//桥墩倾斜监测
TYCJ_FactorType_QDQX = 20
//桥梁伸缩缝监测
TYCJ_FactorType_QLSSF = 22
//应力应变监测
TYCJ_FactorType_YLYB = 23
//裂缝监测
TYCJ_FactorType_LF = 28
//挠度监测
TYCJ_FactorType_RD = 31
)
type TYCJ struct {
DtuInfo struct {
Id int `json:"id"`
Code string `json:"code"`
} `json:"dtuInfo"`
SensorData struct {
Id int `json:"id"`
Name string `json:"name"`
Module string `json:"module"`
Channel string `json:"channel"`
FactorType int `json:"factorType"`
ProductCode string `json:"productCode"`
StructId int `json:"structId"`
Time string `json:"time"`
Data struct {
RawValues []float32 `json:"RawValues"`
ThemeValues []float32 `json:"ThemeValues"`
} `json:"data"`
} `json:"sensorData"`
}

12
models/ZD.go

@ -0,0 +1,12 @@
package models
type ZD struct {
SensorId int `json:"Sensorid"`
Module string `json:"Module"`
Channel int `json:"Channel"`
Frequency int `json:"Frequency,omitempty"`
ThemeValue []float32 `json:"ThemeValue"`
RawValues []float32 `json:"RawValues"`
AccValues []float32 `json:"AccValues"`
Ticks int64 `json:"Ticks"` //毫秒级
}

20
models/dx.go

@ -0,0 +1,20 @@
package models
type dx struct {
S int `json:"S"`
M int `json:"M"`
C int `json:"C"`
R int `json:"R"`
N int `json:"N"`
T int64 `json:"T"`
Q []string `json:"Q"`
A []string `json:"A"`
FI int `json:"FI"`
RV []float64 `json:"RV"`
LV []float64 `json:"LV"`
PV []float64 `json:"PV"`
TV []float64 `json:"TV"`
//DT interface{} `json:"DT"`
SR []string `json:"SR"`
SRT []string `json:"SRT"`
}

57
models/savoirTheme.go

@ -0,0 +1,57 @@
package models
const (
//立杆倾斜与立杆轴力
Savoir_FactorType_QX_ZL = 285
//倾斜与支架水平位移
Savoir_FactorType_QX_SP = 286
//立杆倾斜与模板沉降
Savoir_FactorType_QX_CZ = 287
//savoir_FactorType_立杆水平位移 = 1084
)
type SavoirTheme struct {
Station struct {
Name string `json:"name"`
Id int `json:"id"`
Structure Structure `json:"structure"`
Factor struct {
Id int `json:"id"`
Name string `json:"name"`
ProtoCode string `json:"protoCode"`
ProtoName string `json:"protoName"`
Items []struct {
Id int `json:"id"`
Name string `json:"name"`
FieldName string `json:"field_name"`
UnitName string `json:"unit_name"`
Precision interface{} `json:"precision"`
} `json:"items"`
Units struct {
Strain string `json:"strain"`
} `json:"units"`
} `json:"factor"`
ManualData bool `json:"manual_data"`
Formula interface{} `json:"formula"`
Params interface{} `json:"params"`
Group interface{} `json:"group"`
Labels string `json:"labels"`
GroupParam interface{} `json:"groupParam"`
} `json:"station"`
AcqTime string `json:"acqTime"`
TaskId string `json:"taskId"`
Data map[string]float64 `json:"data"`
State int `json:"state"`
DataEmpty bool `json:"dataEmpty"`
RawAgg bool `json:"rawAgg"`
}
type Structure struct {
ThingId string `json:"thingId"`
Id int `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
OrgId int `json:"orgId"`
}

40
monitors/fileMonitor.go

@ -0,0 +1,40 @@
package monitors
import (
"github.com/robfig/cron/v3"
"log"
)
type FileMonitor struct {
Directory string
FilenameExtension string
MonitorHelper
}
func (the *FileMonitor) Initial() {
the.Cron = cron.New()
log.Printf("文件目录监听 cronStr=%s", the.CronStr)
}
func (the *FileMonitor) Subscribe(task func()) {
entryID, err := the.Cron.AddFunc(the.CronStr, task)
if err != nil {
log.Printf("cron 定时任务[%v]添加异常:%s", entryID, err.Error())
}
the.Cron.Start()
}
func FileMonitorInitial(Directory string, FilenameExtension string, cron string) *FileMonitor {
fileMonitorHelper := FileMonitor{
Directory: Directory,
FilenameExtension: FilenameExtension,
MonitorHelper: MonitorHelper{
CronStr: cron,
},
}
fileMonitorHelper.Initial()
return &fileMonitorHelper
}

18
monitors/httpMonitor.go

@ -0,0 +1,18 @@
package monitors
import "goUpload/dbHelper"
type HttpMonitor struct {
HttpClient *dbHelper.HttpHelper
*MonitorHelper
}
func (the *HttpMonitor) RegisterFun(fun func()) {
the.registerFun(fun)
}
func (the *HttpMonitor) Start() {
the.HttpClient.Initial()
the.initial()
the.monitorStart()
}

28
monitors/monitorHelper.go

@ -0,0 +1,28 @@
package monitors
import (
"github.com/robfig/cron/v3"
"log"
)
type MonitorHelper struct {
CronStr string
Cron *cron.Cron
}
func (the *MonitorHelper) initial() {
the.Cron = cron.New()
log.Printf("cronStr=%s", the.CronStr)
}
// RegisterFun 注册定时器方法
func (the *MonitorHelper) registerFun(task func()) {
entryID, err := the.Cron.AddFunc(the.CronStr, task)
if err != nil {
log.Printf("cron 定时任务[%v]添加异常:%s", entryID, err.Error())
}
}
func (the *MonitorHelper) monitorStart() {
the.Cron.Start()
}

139
testUnit/httpPost_test.go

@ -0,0 +1,139 @@
package testUnit
import (
"bytes"
"crypto/md5"
"fmt"
"io"
"math/rand"
"mime/multipart"
"net/http"
"os"
"testing"
"time"
)
func TestPOST(t *testing.T) {
url := "http://example.com/upload" // 替换为你的目标URL
filePath := "path/to/file.txt" // 替换为你的文件路径
file, err := os.Open(filePath)
if err != nil {
fmt.Println("无法打开文件:", err)
return
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filePath)
if err != nil {
fmt.Println("创建表单文件失败:", err)
return
}
_, err = io.Copy(part, file)
if err != nil {
fmt.Println("复制文件内容失败:", err)
return
}
writer.Close()
request, err := http.NewRequest("POST", url, body)
if err != nil {
fmt.Println("创建HTTP请求失败:", err)
return
}
request.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
fmt.Println("执行HTTP请求失败:", err)
return
}
defer response.Body.Close()
fmt.Println("HTTP响应码:", response.StatusCode)
}
const (
KC_RAND_KIND_NUM = 0 // 纯数字
KC_RAND_KIND_LOWER = 1 // 小写字母
KC_RAND_KIND_UPPER = 2 // 大写字母
KC_RAND_KIND_ALL = 3 // 数字、大小写字母
)
// 随机字符串
func Krand(size int, kind int) []byte {
ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
is_all := kind > 2 || kind < 0
rand.Seed(time.Now().UnixNano())
for i := 0; i < size; i++ {
if is_all { // random ikind
ikind = rand.Intn(3)
}
scope, base := kinds[ikind][0], kinds[ikind][1]
result[i] = uint8(base + rand.Intn(scope))
}
return result
}
func TestGzGZMToken(t *testing.T) {
AppKey := "gykj"
AppSecret := "gykj"
randomStr16 := string(Krand(16, KC_RAND_KIND_NUM))
timestamp := time.Now().UnixMilli()
secretRaw := fmt.Sprintf("%s%s%s%d", AppKey, AppSecret, randomStr16, timestamp)
println(secretRaw)
h := md5.New()
io.WriteString(h, secretRaw)
secret := fmt.Sprintf("%x", h.Sum(nil))
println(randomStr16, timestamp, secret)
url := "http://example.com/upload" // 替换为你的目标URL
filePath := "path/to/file.txt" // 替换为你的文件路径
file, err := os.Open(filePath)
if err != nil {
fmt.Println("无法打开文件:", err)
return
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filePath)
if err != nil {
fmt.Println("创建表单文件失败:", err)
return
}
_, err = io.Copy(part, file)
if err != nil {
fmt.Println("复制文件内容失败:", err)
return
}
writer.Close()
request, err := http.NewRequest("POST", url, body)
if err != nil {
fmt.Println("创建HTTP请求失败:", err)
return
}
request.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
fmt.Println("执行HTTP请求失败:", err)
return
}
defer response.Body.Close()
fmt.Println("HTTP响应码:", response.StatusCode)
}

51
testUnit/mqttPush_test.go

@ -0,0 +1,51 @@
package testUnit
import (
"encoding/hex"
"goUpload/consumers/CQZG/protoFiles"
"goUpload/dbHelper"
"google.golang.org/protobuf/proto"
"log"
"testing"
"time"
)
func TestMqttUpload(t *testing.T) {
//测试上报-实时的温湿度 数据
a09Request := &protoFiles.ComplexData{
SensorData: make([]*protoFiles.SensorData, 1),
}
sensorData := &protoFiles.SensorData{
MonitorType: 0, //监测类型
SensorID: 5000100001,
EventTime: time.Now().Unix(),
ChannelCode: "",
DataBody: &protoFiles.SensorData_Gnss{
Gnss: &protoFiles.GNSSRealTime{
X: []float32{-0.030051423, -0.030051423},
Y: []float32{-0.041311406, -0.041311406},
Z: []float32{-0.05905144, -0.05905144},
},
},
}
a09Request.SensorData = append(a09Request.SensorData, sensorData)
dataStr, err := proto.Marshal(a09Request)
hexStr := hex.EncodeToString(dataStr)
log.Println(err, hexStr)
mqHelpers := dbHelper.MqttHelper{
Host: "mqtt.datahub.anxinyun.cn",
Port: 1883,
ClientId: "lzwjdq500101-lk",
UserName: "lzwjdq500101",
Password: "lzwjdq500101p",
}
mqHelpers.Initial()
topic := "t/500101" //荔枝乌江大桥
//topic = "t/500103" //龙河桥
time.Sleep(time.Second * 1)
mqHelpers.Publish(topic, dataStr)
log.Println("=====推送完毕=====")
}

34
testUnit/mqttRecv_test.go

@ -0,0 +1,34 @@
package testUnit
import (
"goUpload/dbHelper"
"log"
"testing"
"time"
)
func TestMqttRecv(t *testing.T) {
mqHelpers := dbHelper.MqttHelper{
Host: "10.8.30.160",
Port: 30883,
ClientId: "lzwjdq500101-lk",
UserName: "lzwjdq500101",
Password: "lzwjdq500101p",
}
mqHelpers.Initial()
topic := "udasUpload/#" //荔枝乌江大桥
//topic = "t/500103" //龙河桥
time.Sleep(time.Second * 1)
mqHelpers.Subscribe(topic, myHandle)
log.Println("=====开始订阅=====")
for {
time.Sleep(1 * time.Minute)
}
}
func myHandle(Topic string, Msg string) {
log.Printf("mqtt-recv:[%s]:%s", Topic, Msg)
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save