Quellcode durchsuchen

Update 20240327

YueYunyun vor 2 Jahren
Ursprung
Commit
c134b5e5e4

+ 92 - 6
SERVER/Lamp_Server/src/basic/basic.go

@@ -8,12 +8,55 @@ import (
 	"unicode/utf8"
 )
 
+type ElectDataFront struct {
+	Result int     `json:"result"`
+	P      float32 `json:"p"`
+	Pa     float32 `json:"pa"`
+	Pb     float32 `json:"pb"`
+	Pc     float32 `json:"pc"`
+	Q      float32 `json:"q"`
+	Qa     float32 `json:"qa"`
+	Qb     float32 `json:"qb"`
+	Qc     float32 `json:"qc"`
+	Pf     float32 `json:"pf"`
+	Pfa    float32 `json:"pfa"`
+	Pfb    float32 `json:"pfb"`
+	Pfc    float32 `json:"pfc"`
+	Ia     float32 `json:"ia"`
+	Ib     float32 `json:"ib"`
+	Ic     float32 `json:"ic"`
+	Iz     float32 `json:"iz"`
+	Ua     float32 `json:"ua"`
+	Ub     float32 `json:"ub"`
+	Uc     float32 `json:"uc"`
+	Uab    float32 `json:"uab"`
+	Ubc    float32 `json:"ubc"`
+	Uca    float32 `json:"uca"`
+	Uaw    float32 `json:"uaw"`
+	Ubw    float32 `json:"ubw"`
+	Ucw    float32 `json:"ucw"`
+	Uabw   float32 `json:"uabw"`
+	Ubcw   float32 `json:"ubcw"`
+	Ucaw   float32 `json:"ucaw"`
+	Pv     float32 `json:"pv"`
+	Freq   float32 `json:"freq"`
+	Fw     float32 `json:"fw"`
+	Tps    float32 `json:"tps"`
+	Tqs    float32 `json:"tqs"`
+	Fps    float32 `json:"fps"`
+	Fqs    float32 `json:"fqs"`
+	Tpe    float32 `json:"tpe"`
+	Tqe    float32 `json:"tqe"`
+	Fpe    float32 `json:"fpe"`
+	Fqe    float32 `json:"fqe"`
+}
+
 type USRPower_K struct {
-	Bmyz string //电表编码
-	CT   int
-	PT   int
-	//电表参数
-	P         float32
+	Bmyz      string //电表编码
+	Cn        string
+	CT        int
+	PT        int
+	P         float32 //电表参数
 	Pa        float32
 	Pb        float32
 	Pc        float32
@@ -88,7 +131,8 @@ var (
 	Dtumap_state   *dt.DMAP_ClientState //DTU连接列表:网关TCP连接上来的状态列表,SN为key
 	IPMapSN        *dt.DmapStringKV     //网关IP与SN对应关系列表
 	OnlineSN       *dt.DMAP_ClientState //DTU注册列表:已注册网关SN列表,SN为key
-	CalcParam      *dt.DMAP_Interface
+	CalcParam      *dt.DMAP_Interface   //电表电量计算
+	DeviceStatus   *dt.DMAP_Interface   //平台和电表采集状态
 	TranSN         chan dt.DtuRegistChanMsg
 	//DevmapState  *syncmap.SyncMap
 )
@@ -168,3 +212,45 @@ func ParseDtuReport(data []byte, dev *dt.DTUMangCmd) (err error) {
 	dev.SN = string(data[1:])
 	return
 }
+
+func Usrpower2Electdata(s *USRPower_K, d *ElectDataFront) {
+	d.P = s.P
+	d.Pa = s.Pa
+	d.Pb = s.Pb
+	d.Pc = s.Pc
+	d.Q = s.Q
+	d.Qa = s.Qa
+	d.Qb = s.Qb
+	d.Qc = s.Qc
+	d.Pf = s.Pf
+	d.Pfa = s.Pfa
+	d.Pfb = s.Pfb
+	d.Pfc = s.Pfc
+	d.Ia = s.Ia
+	d.Ib = s.Ib
+	d.Ic = s.Ic
+	d.Iz = s.Iz
+	d.Ua = s.Ua
+	d.Ub = s.Ub
+	d.Uc = s.Uc
+	d.Uab = s.Uab
+	d.Ubc = s.Ubc
+	d.Uca = s.Uca
+	d.Uaw = s.Uaw
+	d.Ubw = s.Ubw
+	d.Ucw = s.Ucw
+	d.Uabw = s.Uabw
+	d.Ubcw = s.Ubcw
+	d.Ucaw = s.Ucaw
+	d.Pv = s.Pv
+	d.Freq = s.Freq
+	d.Fw = s.Fw
+	d.Tps = s.Tps
+	d.Tqs = s.Tqs
+	d.Fps = s.Fps
+	d.Fqs = s.Fqs
+	d.Tpe = s.Tpe
+	d.Tqe = s.Tqe
+	d.Fpe = s.Fpe
+	d.Fqe = s.Fqe
+}

+ 6 - 0
SERVER/Lamp_Server/src/config.ini

@@ -0,0 +1,6 @@
+[common]
+server_addr = 11
+server_port = 2.4
+
+
+db_string = 11

+ 2 - 2
SERVER/Lamp_Server/src/config.yaml

@@ -7,8 +7,8 @@ mysql:
   #account: root:DingCheng@2020
   #host : 192.168.0.101
   account: root:123456
-  host : 47.112.30.247
-  port : 23306
+  host : localhost
+  port : 3306
   database : hj212configprj
   #dtudeviceconf
 redis:

+ 0 - 50
SERVER/Lamp_Server/src/config/config.go

@@ -173,59 +173,9 @@ func ParaseClientConfFromIni(content string) (cfg LocalConf, err error) {
 			}
 		}
 	}
-
-	if cfg.Type == 4040 {
-		if tmpStr, ok = conf.Get("ftp", "user"); ok {
-			cfg.FtpUsr = tmpStr
-		}
-		if tmpStr, ok = conf.Get("ftp", "passwd"); ok {
-			cfg.FtpPwd = tmpStr
-		}
-		if tmpStr, ok = conf.Get("ftp", "ip"); ok {
-			cfg.FtpIP = tmpStr
-		}
-		if tmpStr, ok = conf.Get("ftp", "port"); ok {
-			v, err = strconv.ParseInt(tmpStr, 10, 64)
-			if err == nil {
-				cfg.FtpPort = int(v)
-			}
-		}
-	}
 	return
 }
 
-//检查SN是否正确,正确为true,长度=13校验,=12不校验,其他的错误
-func SerialVerify(sn string) bool {
-	if len(sn) == int(dt.LengthSNAct+1) {
-		arr := []byte(sn)
-		if v, r := serialNumCheckSumCal(arr[:12]); r && v == arr[12] {
-			return true
-		}
-	}
-	return false
-}
-
-func serialNumCheckSumCal(sn []byte) (byte, bool) {
-	mu := []byte{7, 9, 10, 5, 8, 4, 2, 1, 6, 2, 1, 6}
-	val := 0
-	if len(sn) != dt.LengthSNAct {
-		return byte(0), false
-	}
-	for k, v := range sn {
-		if v > 0x39 || v < 0x30 {
-			return byte(0), false
-		}
-		val = val + int((v-0x30)*mu[k])
-	}
-	val %= 11
-	if val > 9 {
-		val = 0x58
-	} else {
-		val += 0x30
-	}
-	return byte(val), true
-}
-
 func MatchArgsParam(args []string) bool {
 	r := false
 	if len(args) > 1 {

+ 16 - 306
SERVER/Lamp_Server/src/connsql/connsql.go

@@ -11,22 +11,14 @@ import (
 	"hello/mcryp"
 	"io/ioutil"
 	"log"
-	"strconv"
 	"strings"
 	"time"
 
-	"github.com/astaxie/beego/orm"
-	"github.com/boltdb/bolt"
 	_ "github.com/go-sql-driver/mysql"
 	yaml "gopkg.in/yaml.v2"
 )
 
 var (
-	dbredis = dt.ConnSqlInfo{
-		IP:     "localhost",
-		Port:   "6379",
-		NameDB: "2",
-	}
 	dtuinfo = dt.ConnSqlInfo{
 		Usr:     "root",
 		Pwd:     "123456",
@@ -59,10 +51,6 @@ func ParaseYamlFile() error {
 	dtuinfo.IP = conf.Mysql.Host
 	dtuinfo.Port = conf.Mysql.Port
 	dtuinfo.NameDB = conf.Mysql.Database
-	dbredis.IP = conf.Redis.Host
-	dbredis.Port = conf.Redis.Port
-	dbredis.Pwd = conf.Redis.Passwd
-	dbredis.NameDB = conf.Redis.Database
 	return nil
 }
 
@@ -137,8 +125,8 @@ func DTUManage_GetCompanyList(dmap *dt.DMAP_DtuDev) error {
 /*********************************数据库操作*************************************/
 
 /*********************************数据库操作end*************************************/
-var boltuser, boltacc *bolt.DB
-
+//var boltuser, boltacc *bolt.DB
+/*
 func BoltInit() {
 	boltuser, _ = bolt.Open("db/user.db", 0666, nil)
 	err := boltuser.Update(func(tx *bolt.Tx) error {
@@ -165,9 +153,9 @@ func BoltInit() {
 	if err != nil {
 		log.Println(err) //更新数据库失败
 	}
-}
+}*/
 
-/*获取代理商列表*/
+/*获取代理商列表
 func GetAllAgent() error {
 	var user []*dt.TAgent
 	o := orm.NewOrm()
@@ -185,9 +173,9 @@ func GetAllAgent() error {
 		return nil
 	})
 	return nil
-}
+}*/
 
-/*获取代理商*/
+/*获取代理商
 func GetOneAgent(key string) string {
 	val := ""
 	boltuser.View(func(tx *bolt.Tx) error {
@@ -199,7 +187,7 @@ func GetOneAgent(key string) string {
 		return nil
 	})
 	return val
-}
+}*/
 
 /*
 func GetAllPermis() error {
@@ -217,7 +205,7 @@ func GetAllPermis() error {
 		return nil
 	})
 	return nil
-}*/
+}
 
 func GetOnePerm(key string) string {
 	val := ""
@@ -230,13 +218,13 @@ func GetOnePerm(key string) string {
 		return nil
 	})
 	return val
-}
+}*/
 
 /*获取代理商列表*/
 func DTUManage_GetAgentList(m map[int]string, n map[string]int) error {
 	rows, err := dtudb.Query("select `id`,`name` from t_agent")
 	if err != nil {
-		log.Println("GetAgentList failed:", err.Error()) //panic(err) //
+		//log.Println("GetAgentList failed:", err.Error()) //panic(err) //
 		return err
 	}
 	defer rows.Close()
@@ -246,9 +234,7 @@ func DTUManage_GetAgentList(m map[int]string, n map[string]int) error {
 			name string
 		)
 		err = rows.Scan(&id, &name)
-		if err != nil {
-			fmt.Printf("scan failed, err:%v\n", err)
-		} else {
+		if err == nil {
 			m[id] = name
 			n[name] = id
 		}
@@ -280,62 +266,16 @@ func getIdNameDict(table string) (map[int]string, error) {
 /*获取项目*/
 func DTUManage_GetProjectDict() (map[int]string, error) {
 	return getIdNameDict("t_project")
-	/*var (
-		id   int
-		name string
-	)
-	rows, err := dtudb.Query("select `id`,`name` from t_project")
-	if err != nil {
-		//log.Println("GetProDict failed:", err.Error())
-		return err
-	}
-	defer rows.Close()
-	for rows.Next() {
-		if err = rows.Scan(&id, &name); err == nil {
-			m[id] = name
-		}
-	}
-	return nil*/
 }
 
 /*获取权限*/
 func DTUManage_GetPermissionDict() (map[int]string, error) {
 	return getIdNameDict("t_permission")
-	/*var (
-		id   int
-		name string
-	)
-	rows, err := dtudb.Query("select `id`,`name` from t_permission")
-	if err != nil {
-		return err
-	}
-	defer rows.Close()
-	for rows.Next() {
-		if err = rows.Scan(&id, &name); err == nil {
-			m[id] = name
-		}
-	}
-	return nil*/
 }
 
 /*获取代理*/
 func DTUManage_GetAgentDict() (map[int]string, error) {
 	return getIdNameDict("t_agent")
-	/*var (
-		id   int
-		name string
-	)
-	rows, err := dtudb.Query("select `id`,`name` from t_agent")
-	if err != nil {
-		return err
-	}
-	defer rows.Close()
-	for rows.Next() {
-		if err = rows.Scan(&id, &name); err == nil {
-			m[id] = name
-		}
-	}
-	return nil*/
 }
 
 /*添加公司*/
@@ -371,27 +311,11 @@ func DTUManage_ModifyCompanyInfo(info dt.EditItemCompany) error {
 	if info.Unique == "" {
 		return errors.New("Unique is null")
 	}
-	//agents := 1
-	//ag, ok := Map_AgentId[info.Agent]
-	//if ok {
-	//	agents = ag
-	//} else {
-	//	stc := "Can't found Agent: " + info.Agent
-	//	log.Println(stc)
-	//return errors.New(stc)
-	//}
 	_, err := dtudb.Exec(str, info.Sn, info.Name, info.Agent, info.ProID, info.AreaID, info.Unique)
-	/*lastInsertID, _ := ret.LastInsertId()
-	fmt.Println("LastInsertID:", lastInsertID)
-	//影响行数
-	rowsaffected, _ := ret.RowsAffected()
-	fmt.Println("RowsAffected:", rowsaffected)*/
-	if err != nil {
-		log.Println(err.Error())
-	}
 	return err
 }
 
+/*
 //更新停上电时间,onoff=true上电
 func DTUManage_UpdateDTUPOWFTime(sn string, time string, onoff bool) error {
 	str := ""
@@ -441,7 +365,7 @@ func DTUManage_UpdateDTUVersion(sn string, version string) bool {
 	//rowsaffected, _ := ret.RowsAffected()
 	//fmt.Println("RowsAffected:", rowsaffected)
 	return true
-}
+}*/
 
 //添加ConfigfsJson记录
 func addConfigfsJson(info dt.ConfigJson) error {
@@ -452,11 +376,6 @@ func addConfigfsJson(info dt.ConfigJson) error {
 		log.Println(err.Error())
 		return err
 	}
-	//lastInsertID, _ := ret.LastInsertId()
-	//fmt.Println("LastInsertID:", lastInsertID)
-	//影响行数
-	//rowsaffected, _ := ret.RowsAffected()
-	//fmt.Println("RowsAffected:", rowsaffected)
 	return nil
 }
 
@@ -553,32 +472,6 @@ func QueryConfigJsonByUID(uid string) (dt.ConfigJson, error) {
 	return dtc, err
 }
 
-/*
-func DTUManage_GetAreaList() (dt.AreaNodeList, error) {
-	node := dt.AreaNode{}
-	st := dt.AreaNodeList{List: make([]dt.AreaNode, 0)}
-	str := "select `code`,`name`,`parent_code` from area"
-	info := dt.ConnSqlInfo{}
-	info = dtuinfo
-	info.NameDB = "cems_sysbase"
-	qdb, err := openSqlDB(info)
-	if err != nil {
-		return st, err
-	}
-	defer qdb.Close()
-	rows, err := qdb.Query(str)
-	if err != nil {
-		return st, err
-	}
-	defer rows.Close()
-	for rows.Next() {
-		if err = rows.Scan(&node.Code, &node.Name, &node.Parent); err == nil {
-			st.List = append(st.List, node)
-		}
-	}
-	return st, nil
-}*/
-
 func DTUManage_GetAreaList() (dt.AreaNodeList, error) {
 	node := dt.AreaNode{}
 	st := dt.AreaNodeList{List: make([]dt.AreaNode, 0)}
@@ -617,98 +510,6 @@ func getIdProtocolDict(it int) (map[int]string, error) {
 
 //==========================================
 
-//通过编码因子、时间段查询当日最后时间
-/*func record_Query_Power_MAXTime(bmyz string, min, max int64) (value int64, err error) {
-	if min > max {
-		tmp := min
-		min = max
-		max = tmp
-	}
-	sql := "SELECT MAX(`uptime`) FROM stat_electricity WHERE `bmyz` = ? AND `uptime` >= ? AND `uptime` <= ? LIMIT 1"
-	rows, flag := dtudb.Query(sql, bmyz, min, max)
-	if flag != nil {
-		err = flag
-		return
-	}
-	defer rows.Close()
-	for rows.Next() {
-		err = rows.Scan(&value)
-		return
-	}
-	return
-}*/
-/*
-//通过编码因子、时间戳查询电量
-func record_Query_Section_Energy(bmyz string, min, max int64) (value dt.CalcOriginEnergy, err error) {
-	if min > max {
-		tmp := min
-		min = max
-		max = tmp
-	}
-	sql := "SELECT `tps`,`tqs`,`fps`,`fqs` FROM stat_electricity WHERE `bmyz` = ? AND `uptime` >= ? AND `uptime` <= ? LIMIT 1"
-	rows, flag := dtudb.Query(sql, bmyz, min, max)
-	if flag != nil {
-		err = flag
-		return
-	}
-	defer rows.Close()
-	for rows.Next() {
-		err = rows.Scan(&value.OriginTps, &value.OriginTqs, &value.OriginFps, &value.OriginFqs)
-		return
-	}
-	return
-}
-
-//通过编码因子、时间段查询功率
-func record_Query_Section_Power(bmyz string, min, max int64) (list []float32, err error) {
-	if min > max {
-		tmp := min
-		min = max
-		max = tmp
-	}
-	sql := "SELECT `power` FROM stat_electricity WHERE `bmyz` = ? AND `uptime` >= ? AND `uptime` <= ? ORDER BY `uptime` ASC LIMIT 1440"
-	rows, flag := dtudb.Query(sql, bmyz, min, max)
-	if flag != nil {
-		err = flag
-		return
-	}
-	defer rows.Close()
-	for rows.Next() {
-		v := float32(0)
-		if e := rows.Scan(&v); e == nil {
-			list = append(list, v)
-			err = nil
-		}
-	}
-	return
-}
-
-
-//通过编码因子、时间段查询
-func Record_Query_Section(bmyz string, min, max int64) (list []dt.SqlQueryElectData, err error) {
-	if min > max {
-		tmp := min
-		min = max
-		max = tmp
-	}
-	sql := "SELECT `id`,`uptime`,`power`,`power_max`,`count`,`tps`,`tqs`,`fps`,`fqs` FROM stat_electricity WHERE `bmyz` = ? AND `uptime` >= ? AND `uptime` <= ? ORDER BY `uptime` ASC LIMIT 1440"
-	rows, flag := dtudb.Query(sql, bmyz, min, max)
-	if flag != nil {
-		err = flag
-		return
-	}
-	defer rows.Close()
-	for rows.Next() {
-		v := dt.SqlQueryElectData{}
-		if e := rows.Scan(&v.Id, &v.Time, &v.SumPower, &v.MaxPower, &v.Count, &v.Tps, &v.Tqs, &v.Fps, &v.Fqs); e == nil {
-			v.Bmyz = bmyz
-			list = append(list, v)
-			err = nil
-		}
-	}
-	return
-}*/
-
 //通过编码因子、时间段查询统计功率
 func record_Query_Section_StatPower(bmyz string, min, max int64) (result dt.CalcLoadRate, err error) {
 	if min > max {
@@ -754,101 +555,20 @@ func Record_Calcute_Energy(pm dt.SqlQueryElectData, tms int64) (val dt.CalcDataE
 	tmp.Minute = 0
 	tmp.Second = 0
 	min := basic.DataToTimeStamp(tmp) //当日0点时间戳
+	log.Printf("Calcute_Energy:pm.Time=%v;min=%v", pm.Time, min)
 	//数据库记录时间大于等于当日0点时间,表示为当日记录
 	if pm.Time >= min {
 		//当日的起始电量有效
 		val = pm.OriginEgy
+		log.Println("Calcute_Energy:pm.OriginEgy=", pm.OriginEgy)
 	} else {
 		//初始化起始电能为以前的当日电能
 		val = pm.Energy
+		log.Println("Calcute_Energy:pm.Energy=", pm.Energy)
 	}
 	return
 }
 
-// //通过时间戳查询当日记录
-// func Record_Query_Powers(pm basic.USRPower_K, tms int64) (result dt.SqlQueryElectData, ok bool) {
-// 	init_pw := true  //初始化功率标记
-// 	init_egy := true //初始化起始电能标记
-// 	tmp := basic.TimeStampToData(tms)
-// 	result = dt.CalcLoadRate{0, 0, 0}
-// 	tmp.Hour = 0
-// 	tmp.Minute = 0
-// 	tmp.Second = 0
-// 	min := basic.DataToTimeStamp(tmp)
-// 	ok = false
-// 	if dtudb == nil {
-// 		return
-// 	}
-// 	if w, err := Record_Query_ByBmyz(pm.Bmyz); err == nil {
-// 		ok = true
-// 		//数据库记录时间大于等于当日零点时间,表示为当日记录
-// 		if w.Time >= min {
-// 			result = w
-// 			init_pw = false
-// 			init_egy = false
-// 		} else { //否则为昨日或以前记录
-// 			//功率初始化
-// 			result.LRate.Count = 1
-// 			result.LRate.MaxPower = pm.P
-// 			result.LRate.SumPower = pm.P
-// 			//初始化起始电能为以前的当日电能
-// 			result.OriginEgy = w.Energy
-// 		}
-// 		return
-// 	}
-// 	//设置当前电能
-// 	result.Energy.Tps = pm.Tps
-// 	result.Energy.Tqs = pm.Tqs
-// 	result.Energy.Fps = pm.Fps
-// 	result.Energy.Fqs = pm.Fqs
-// 	if init_pw {
-// 		//功率初始化
-// 		result.LRate.Count = 1
-// 		result.LRate.MaxPower = pm.P
-// 		result.LRate.SumPower = pm.P
-// 	}
-// 	if init_egy {
-// 		//初始化起始电能为当前电能
-// 		result.OriginEgy = result.Energy
-// 	}
-// 	return
-// }
-/*
-//通过时间戳查询前日最后一次电能
-func Record_Query_EnergyLastDay(bmyz string, tms int64) (result dt.CalcOriginEnergy, ok bool) {
-	var (
-		max int64 = 0
-		min int64 = 0
-		//		cur int64 = 0
-	)
-	ok = false
-	if dtudb == nil {
-		return
-	}
-	//前一日时间戳
-	tmp := basic.TimeStampToData(tms - 86400)
-	result = dt.CalcOriginEnergy{0, 0, 0, 0}
-	//当日23:59
-	tmp.Hour = 23
-	tmp.Minute = 59
-	tmp.Second = 0
-	max = basic.DataToTimeStamp(tmp)
-	//当日00:00
-	tmp.Hour = 0
-	tmp.Minute = 0
-	min = basic.DataToTimeStamp(tmp)
-	// if t, err := record_Query_Power_MAXTime(bmyz, min, max); err == nil {
-	// 	cur = t
-	// } else {
-	// 	return
-	// }
-	if w, err := record_Query_Section_Energy(bmyz, min, max); err == nil {
-		result = w
-		ok = true
-	}
-	return
-}*/
-
 //通过编码因子查询
 func Record_Query_ByBmyz(bmyz string) (val dt.SqlQueryElectData, err error) {
 	if dtudb == nil {
@@ -905,13 +625,3 @@ func Record_InsertElectricity(v dt.SqlQueryElectData) (err error) {
 	}
 	return
 }
-
-/*获取支持的电表协议表*/
-// func DTUManage_GetMeterProtocol() (map[int]string, error) {
-// 	return getIdProtocolDict(0)
-// }
-
-/*获取支持的上报协议表*/
-// func DTUManage_GetPlatformProtocol() (map[int]string, error) {
-// 	return getIdProtocolDict(2)
-// }

+ 72 - 5
SERVER/Lamp_Server/src/connsql/dbaccount.go

@@ -10,7 +10,6 @@ import (
 	"time"
 
 	"github.com/astaxie/beego/orm"
-	"github.com/boltdb/bolt"
 	//"github.com/appleboy/gin-jwt"
 )
 
@@ -92,6 +91,17 @@ func GetAccountList() (dt.DBAccountArray, error) {
 	return obj, nil
 }
 
+//修改账户密码
+func ModifyAccountPasswd(info dt.AccountRegistMod) error {
+	lg := dt.HtmlLogin{}
+	lg.Usr = info.Usr
+	lg.Pwd = info.Pwd
+	info.Pwd = checkAccount(lg)
+	str := "update t_account set pwd=? where `id`=? and `usr`=?"
+	_, err := dtudb.Exec(str, info.Pwd, info.Id, info.Usr)
+	return err
+}
+
 //修改账户
 func ModifyAccountInfo(info dt.HtmlRegist) error {
 	str := "update t_account set projectid=?,agentid=?,perm=? where `id`=? and `usr`=?"
@@ -102,13 +112,69 @@ func ModifyAccountInfo(info dt.HtmlRegist) error {
 	return err
 }
 
+func GetAgentList(table string) (dt.DBAgentArray, error) {
+	obj := dt.DBAgentArray{Array: make([]dt.DBAgentMg, 0)}
+	str := "select `id`,`name` from " + table
+	rows, err := dtudb.Query(str)
+	if err != nil {
+		return obj, err
+	}
+	defer rows.Close()
+	for rows.Next() {
+		var t dt.DBAgentMg
+		if err := rows.Scan(&t.Id, &t.Name); err == nil {
+			if t.Id != 1 || table != "t_project" {
+				obj.Array = append(obj.Array, t)
+			}
+		}
+	}
+	return obj, nil
+}
+
+//增加代理商
+func AddAgentInfo(name string) error {
+	str := "insert into t_agent (`name`) values(?)"
+	_, err := dtudb.Exec(str, name)
+	return err
+}
+
+func UpdateAgentInfo(id int, name string) error {
+	str := "update t_agent set name=? where `id`=?"
+	_, err := dtudb.Exec(str, name, id)
+	return err
+}
+
+//删除代理商
+func DeleteAgentInfo(id int, name string) error {
+	str := "delete from t_agent where `id`=? and `name`=?"
+	_, err := dtudb.Exec(str, id, name)
+	return err
+}
+
+//增加项目
+func AddProjectInfo(name string) error {
+	str := "insert into t_project (`name`) values(?)"
+	_, err := dtudb.Exec(str, name)
+	return err
+}
+
+func UpdateProjectInfo(id int, name string) error {
+	str := "update t_project set name=? where `id`=?"
+	_, err := dtudb.Exec(str, name, id)
+	return err
+}
+
+//删除项目
+func DeleteProjectInfo(id int, name string) error {
+	str := "delete from t_project where `id`=? and `name`=?"
+	_, err := dtudb.Exec(str, id, name)
+	return err
+}
+
 //删除账户
 func DeleteAccountInfo(id int, usr string) error {
 	str := "delete from t_account where `id`=? and `usr`=?"
 	_, err := dtudb.Exec(str, id, usr)
-	if err != nil {
-		//log.Println("exec ", err.Error())
-	}
 	return err
 }
 
@@ -232,6 +298,7 @@ func CreatePermKv() {
 	//GetAllPerKv()
 }
 
+/*
 func GetAllPerKv() error {
 	boltuser.Update(func(tx *bolt.Tx) error {
 		b := tx.Bucket([]byte(BlNameAccount))
@@ -247,7 +314,7 @@ func GetAllPerKv() error {
 		return nil
 	})
 	return nil
-}
+}*/
 
 /*
 func FilterAccount(token string) {

+ 160 - 974
SERVER/Lamp_Server/src/controller/controller.go

@@ -10,19 +10,12 @@ import (
 	"hello/connsql"
 	dt "hello/datastruct"
 	fwd "hello/forwardmode"
-	"hello/mcryp"
 	"hello/model"
-	"io"
 	"log"
 	"net/http"
-	"net/url"
-	"os"
-	"path/filepath"
 
 	//	"sort"
 	"strconv"
-	"strings"
-	"sync"
 
 	"github.com/gin-gonic/gin"
 	//	"github.com/imroc/biu"
@@ -203,10 +196,6 @@ func GetSNList(c *gin.Context) {
 			cli, ok := basic.Dtumap_state.Get(v)
 			if ok {
 				node.Online = cli.Online
-				// if cli.Online {
-				// 	node.Relay3 = cli.PurifiDO3
-				// 	node.Relay2 = cli.PurifiDO2
-				// }
 			}
 			node.Sn = v
 			res.Array = append(res.Array, node)
@@ -369,80 +358,185 @@ func updateCompanyList() {
 	connsql.DTUManage_GetCompanyList(basic.Dtumap_sn)
 }
 
-/*****************************通信机相关操作********************************************/
-func optDTUCtrl(c *gin.Context, cmd string, data string) bool {
-	if sn, ok := c.GetQuery("sn"); !ok {
+func SetMeterAddress(c *gin.Context) {
+	value := dt.SetMeterAddressRes{}
+	cpid := c.Request.URL.Query().Get("sn")
+	if len(cpid) < 1 {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn null")
+		return
+	}
+	if err := c.BindJSON(&value); err != nil {
+		AckHTML_ErrJsonFmt(c, err.Error())
+	} else {
+		state := fwd.API_SetMeterAddress(cpid, value)
+		AckHTML_OKWithData(c, state)
+	}
+}
+
+func SetMeterRatio(c *gin.Context) {
+	value := dt.SetMeterRatioRes{}
+	cpid := c.Request.URL.Query().Get("sn")
+	if len(cpid) < 1 {
 		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn null")
-		return false
+		return
+	}
+	if err := c.BindJSON(&value); err != nil {
+		AckHTML_ErrJsonFmt(c, err.Error())
 	} else {
-		if len(sn) < 10 {
-			AckHTML_AbNormal(c, dt.HTC_SNLENGTH, "sn err")
-			return false
+		if len(value.SerData) < 1 {
+			AckHTML_ErrJsonFmt(c, "json format err")
+			return
 		}
-		res, ok := model.ModelDTUCtrl(sn, cmd, data)
-		if !ok {
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
+		state := fwd.API_SetMeterRatio(cpid, value)
+		AckHTML_OKWithData(c, state)
+	}
+}
+
+func GetElectricData(c *gin.Context) {
+	cpid := ""
+	mtype := ""
+	addr := 0
+	if val := c.Request.URL.Query().Get("sn"); len(val) < 1 {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn null")
+		return
+	} else {
+		cpid = val
+	}
+	if val := c.Request.URL.Query().Get("type"); len(val) < 1 {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "type null")
+		return
+	} else {
+		mtype = val
+	}
+	if val := c.Request.URL.Query().Get("addr"); len(val) < 1 {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "addr null")
+		return
+	} else {
+		if n, err := strconv.Atoi(val); err != nil {
+			AckHTML_AbNormal(c, dt.HTC_HtmlParam, "addr error")
+			return
 		} else {
-			AckHTML_OKWithData(c, res)
+			addr = n
 		}
-		return ok
 	}
+	state := fwd.API_QueryElectricData(cpid, addr, mtype)
+	AckHTML_OKWithData(c, state)
 }
 
-func optDTUCtrlWithSN(c *gin.Context, sn, cmd, data string) bool {
-	if len(sn) < 10 {
-		AckHTML_AbNormal(c, dt.HTC_SNLENGTH, "sn err")
-		return false
+func GetMeterRatio(c *gin.Context) {
+	cpid := ""
+	mtype := ""
+	addr := 0
+	if val, ok := c.GetQuery("sn"); !ok {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn null")
+		return
+	} else {
+		cpid = val
 	}
-	res, ok := model.ModelDTUCtrl(sn, cmd, data)
-	if !ok {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
+	if val := c.Request.URL.Query().Get("type"); len(val) < 1 {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "type null")
+		return
 	} else {
-		AckHTML_OKWithData(c, res)
+		mtype = val
+	}
+	if val, ok := c.GetQuery("addr"); !ok {
+		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "addr null")
+		return
+	} else {
+		n, er := strconv.Atoi(val)
+		if er != nil {
+			AckHTML_AbNormal(c, dt.HTC_HtmlParam, "addr error")
+			return
+		}
+		addr = n
 	}
-	return ok
+	state := fwd.API_QueryMeterRatio(cpid, addr, mtype)
+	AckHTML_OKWithData(c, state)
 }
 
-func DTUReRun(c *gin.Context) {
-	optDTUCtrl(c, dt.CMD_RERUN, "")
+func DTUGetProjectList(c *gin.Context) {
+	obj, _ := connsql.GetAgentList("t_project")
+	AckHTML_OKWithData(c, obj)
 }
 
-func DTUReboot(c *gin.Context) {
-	if !cfg.ParamConf.Mode {
-		AckHTML_OK(c)
+func DTUGetAgentList(c *gin.Context) {
+	obj, _ := connsql.GetAgentList("t_agent")
+	AckHTML_OKWithData(c, obj)
+}
+
+func DTUAddAgent(c *gin.Context) {
+	var info dt.DictIntStr
+	if err := c.BindJSON(&info); err != nil {
+		AckHTML_ErrJsonFmt(c, "json fmt err")
 		return
 	}
-	optDTUCtrl(c, dt.CMD_REBOOT, "")
+	name := info.Value
+	if len([]rune(name)) < 2 || len([]rune(name)) > 50 {
+		AckHTML_AbNormal(c, dt.HTC_DTUErr, "name error")
+		return
+	}
+	connsql.AddAgentInfo(name)
+	AckHTML_OK(c)
 }
 
-func GetDTUVersion(c *gin.Context) {
-	optDTUCtrl(c, dt.CMD_GETVERSION, "")
+func DTUDeleteAgent(c *gin.Context) {
+	var info dt.DictIntStr
+	if err := c.BindJSON(&info); err != nil {
+		AckHTML_ErrJsonFmt(c, "json fmt err")
+		return
+	}
+	connsql.DeleteAgentInfo(info.Key, info.Value)
+	AckHTML_OK(c)
 }
 
-/*解析压缩格式的data数据
-出于降低流量开销目的,与通信机传输数据如果data长度大于512字节则会使用自定义压缩格式
-格式内容见文档,此处是对data按照自定义压缩格式解析
-返回:int状态码,string内容
-*/
-func paraseCompressData(str string) (int, string, error) {
-	var info dt.CfgFileInfo
-	//json格式检查
-	if err := json.Unmarshal([]byte(str), &info); err != nil {
-		//不符合压缩格式
-		return dt.HTC_JSONFormat, "", errors.New("json format error")
+func DTUModifyAgent(c *gin.Context) {
+	var info dt.DictIntStr
+	if err := c.BindJSON(&info); err != nil {
+		AckHTML_ErrJsonFmt(c, "json fmt err")
+		return
+	}
+	if err := connsql.UpdateAgentInfo(info.Key, info.Value); err != nil {
+		AckHTML_AbNormal(c, dt.HTC_EditCompany, "fail")
+	} else {
+		AckHTML_OK(c)
+	}
+}
+
+func DTUAddProject(c *gin.Context) {
+	var info dt.DictIntStr
+	if err := c.BindJSON(&info); err != nil {
+		AckHTML_ErrJsonFmt(c, "json fmt err")
+		return
+	}
+	name := info.Value
+	if len([]rune(name)) < 2 || len([]rune(name)) > 50 {
+		AckHTML_AbNormal(c, dt.HTC_DTUErr, "name error")
+		return
 	}
-	//数据检查
-	if !info.Res {
-		//通信机那边读取数据失败
-		return dt.HTC_DTUErr, "", errors.New(info.CryData)
+	connsql.AddProjectInfo(name)
+	AckHTML_OK(c)
+}
+
+func DTUDeleteProject(c *gin.Context) {
+	var info dt.DictIntStr
+	if err := c.BindJSON(&info); err != nil {
+		AckHTML_ErrJsonFmt(c, "json fmt err")
+		return
 	}
-	//解压
-	if str, err := mcryp.ParaseRemoteFile(info); err != nil {
-		//解压/校验失败
-		return dt.HTC_UnCPR, "", err
+	connsql.DeleteProjectInfo(info.Key, info.Value)
+	AckHTML_OK(c)
+}
+
+func DTUModifyProject(c *gin.Context) {
+	var info dt.DictIntStr
+	if err := c.BindJSON(&info); err != nil {
+		AckHTML_ErrJsonFmt(c, "json fmt err")
+		return
+	}
+	if err := connsql.UpdateProjectInfo(info.Key, info.Value); err != nil {
+		AckHTML_AbNormal(c, dt.HTC_EditCompany, "fail")
 	} else {
-		//正确获取数据
-		return dt.HTC_OK, str, nil
+		AckHTML_OK(c)
 	}
 }
 
@@ -479,180 +573,6 @@ func DTUGetConfig(c *gin.Context) {
 	}
 }
 
-func Testdtu(c *gin.Context) {
-	if sn := c.Request.URL.Query().Get("sn"); sn == "" {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn is null")
-	} else {
-		res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETSYSCFG, "")
-		if !ok {
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-		} else {
-			if co, cdata, err := paraseCompressData(res); err != nil {
-				AckHTML_AbNormal(c, co, err.Error())
-			} else {
-				AckHTML_OKWithData(c, cdata)
-			}
-		}
-	}
-}
-
-func GetDTUGetSyscfg(c *gin.Context) {
-	if sn := c.Request.URL.Query().Get("sn"); sn == "" {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn is null")
-	} else {
-		res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETSYSCFG, "")
-		if !ok {
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-		} else {
-			if co, cdata, err := paraseCompressData(res); err != nil {
-				AckHTML_AbNormal(c, co, err.Error())
-			} else {
-				AckHTML_OKWithData(c, cdata)
-			}
-		}
-	}
-}
-
-//读取指定文件
-func GetAssigntxtFile(c *gin.Context) {
-	if sn := c.Request.URL.Query().Get("sn"); sn == "" {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn is null")
-	} else {
-		path := c.Request.Header.Get("FilePath")
-		if len(path) < 1 {
-			AckHTML_AbNormal(c, dt.HTC_HtmlParam, "miss path")
-			return
-		}
-		//log.Println("GetAssigntxtFile path ", path)
-		res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETXTFILE, path)
-		if !ok {
-			//log.Println("GetAssigntxtFile Err ", res)
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-		} else {
-			//log.Println("GetAssigntxtFile OK ")
-			if co, cdata, err := paraseCompressData(res); err != nil {
-				AckHTML_AbNormal(c, co, err.Error())
-				//log.Println("GetAssigntxtFile Err ", err.Error())
-			} else {
-				//log.Println("GetAssigntxtFile Sucess ")
-				AckHTML_OKWithData(c, cdata)
-			}
-		}
-	}
-}
-
-//设置指定文件
-func SetAssigntxtFile(c *gin.Context) {
-	var (
-		te     dt.RmtTxtFile
-		dtudev dt.ConfigSystem
-	)
-	if err := c.BindJSON(&dtudev); err != nil {
-		log.Println(err.Error())
-		AckHTML_ErrJsonFmt(c, err.Error())
-	} else {
-		path := c.Request.Header.Get("FilePath")
-		if len(path) < 1 {
-			AckHTML_AbNormal(c, dt.HTC_HtmlParam, "miss path")
-			return
-		}
-		cfg := mcryp.PackRemoteFile(dtudev.Conf, false)
-		te.Path = path
-		te.Context = dt.JsonToString(cfg)
-		if ok := optDTUCtrl(c, dt.CMD_SETXTFILE, dt.JsonToString(te)); ok {
-			log.Println("SetAssigntxtFile ", "OK")
-			//AckHTML_OK(c)
-		} else {
-			AckHTML_AbNormal(c, dt.HTC_HtmlParam, "set to dtu fail")
-			log.Println("SetAssigntxtFile ", "set to dtu fail")
-		}
-	}
-}
-
-func GetDTUGetExtShell(c *gin.Context) {
-	if sn := c.Request.URL.Query().Get("sn"); sn == "" {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "sn is null")
-	} else {
-		res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETXTFILE, "/usr/ext.sh")
-		if !ok {
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-		} else {
-			if co, cdata, err := paraseCompressData(res); err != nil {
-				AckHTML_AbNormal(c, co, err.Error())
-			} else {
-				AckHTML_OKWithData(c, cdata)
-			}
-		}
-	}
-}
-
-func getFileMD5(sn string, file string) (string, error) {
-	res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETFILEMD5, file)
-	if !ok {
-		return "", errors.New("get md5 error")
-	} else {
-		return res, nil
-	}
-}
-
-func chkThresholdConfig(cfg *dt.ConfigThreshold) error {
-	if len([]rune(cfg.Name)) > 24 {
-		return errors.New("Range[0,12], Name is too longer : " + cfg.Name)
-	}
-	if cfg.Voc > 100 || cfg.Voc < 1 {
-		return errors.New("Voc is Invalid, Range[1,100]")
-	}
-	if cfg.Pm > 100 || cfg.Pm < 1 {
-		return errors.New("Pm is Invalid, Range[1,100]")
-	}
-
-	if cfg.Lamp > 100 || cfg.Lamp < 1 {
-		return errors.New("Lamp is Invalid, Range[1,100]")
-	}
-	if cfg.Flow > 100000 || cfg.Flow < 1 {
-		return errors.New("Flow is Invalid, Range[1,100000]")
-	}
-	if cfg.Ifan > 10 || cfg.Ifan < 0.0 {
-		return errors.New("Ifan is Invalid, Range[0.0,10]")
-	}
-	if cfg.Ipur > 10 || cfg.Ipur < 0.0 {
-		return errors.New("Ipur is Invalid, Range[0.0,10]")
-	}
-
-	if cfg.VocA > 10 || cfg.VocA < -10 {
-		return errors.New("VocA is Invalid, Range[-10,10]")
-	}
-	if cfg.PmA > 10 || cfg.PmA < -10 {
-		return errors.New("PmA is Invalid, Range[-10,10]")
-	}
-	if cfg.LampA > 10 || cfg.LampA < -10 {
-		return errors.New("LampA is Invalid, Range[-10,10]")
-	}
-	if cfg.IfanA > 10 || cfg.IfanA < -10 {
-		return errors.New("IfanA is Invalid, Range[-10,10]")
-	}
-	if cfg.IpurA > 10 || cfg.IpurA < -10 {
-		return errors.New("IpurA is Invalid, Range[-10,10]")
-	}
-
-	if cfg.VocB > 10 || cfg.VocB < -10 {
-		return errors.New("VocB is Invalid, Range[-10,10]")
-	}
-	if cfg.PmB > 10 || cfg.PmB < -10 {
-		return errors.New("PmB is Invalid, Range[-10,10]")
-	}
-	if cfg.LampB > 10 || cfg.LampB < -10 {
-		return errors.New("LampB is Invalid, Range[-10,10]")
-	}
-	if cfg.IfanB > 10 || cfg.IfanB < -10 {
-		return errors.New("IfanB is Invalid, Range[-10,10]")
-	}
-	if cfg.IpurB > 10 || cfg.IpurB < -10 {
-		return errors.New("IpurB is Invalid, Range[-10,10]")
-	}
-	return nil
-}
-
 func checkCfgJsonItem(item dt.ConfigfsJSONItem) error {
 	if len(item.Name) > dt.LenName-1 {
 		return errors.New("Platform Name is too longer : " + item.Name)
@@ -685,19 +605,6 @@ func chkConfigfsJSON(cfg *dt.ConfigfsJSON) error {
 		if err := checkCfgJsonItem(cfg.Platform[i]); err != nil {
 			return err
 		}
-		/*if len(cfg.Platform[i].Name) > dt.LenName-1 {
-			return errors.New("Platform Name is too longer : " + cfg.Platform[i].Name)
-		}
-		if len(cfg.Platform[i].Pw) > dt.LenPW-1 {
-			return errors.New("Platform PW is too longer : " + cfg.Platform[i].Pw)
-		}
-		if len(cfg.Platform[i].Mn) > dt.LenMN-1 {
-			return errors.New("Platform MN is too longer : " + cfg.Platform[i].Mn)
-		}
-		pe := cfg.Platform[i].Secs
-		if pe < 1 || pe > 60 {
-			return errors.New("Platform Interval is Invalid : " + cfg.Platform[i].Name + " ( n > 60min)")
-		}*/
 	}
 	return nil
 }
@@ -713,12 +620,6 @@ func update_to_map(sn string, val dt.ConfigfsJSON) {
 		cli.Conf = val
 		basic.OnlineSN.Add(sn, cli)
 	}
-	// if cli, ok := basic.Dtumap_state.Get(sn); ok {
-	// 	log.Println("Dtumap_state:", cli.Conf)
-	// }
-	// if cli, ok := basic.OnlineSN.Get(sn); ok {
-	// 	log.Println("OnlineSN:", cli.Conf)
-	// }
 }
 
 func DTUSetConfig(c *gin.Context) {
@@ -767,339 +668,17 @@ func DTUAddItemConfig(c *gin.Context) {
 			AckHTML_OK(c)
 			//AckHTML_OKWithData(c, cfg)
 		}
-
-		//cfg := mcryp.PackRemoteFile(dt.JsonToString(dtudev), false)
-		/*if md5, err := getFileMD5(sn, dt.CMD_GETCFGCFG); err == nil {
-			if cfg.Md5 == md5 {
-				log.Println("tag: No Change")
-				AckHTML_OK(c)
-				return
-			}
-		}*/
-		//		optDTUCtrl(c, dt.CMD_ADDCFGCFG, dt.JsonToString(cfg))
-	}
-}
-
-func GetDTUSetSyscfg(c *gin.Context) {
-	var dtudev dt.ConfigSystem
-	sn := c.Request.URL.Query().Get("sn")
-	if err := c.BindJSON(&dtudev); err != nil {
-		log.Println(err.Error())
-		AckHTML_ErrJsonFmt(c, err.Error())
-	} else {
-		res := mcryp.PackRemoteFile(dtudev.Conf, false)
-		if md5, err := getFileMD5(sn, dt.CMD_SETSYSCFG); err == nil {
-			if res.Md5 == md5 {
-				log.Println("tag: No Change")
-				AckHTML_OK(c)
-				return
-			}
-		}
-		if err := cfg.CheckSystemConf(dtudev.Conf); err != nil {
-			AckHTML_AbNormal(c, dt.HTC_Undefine, err.Error())
-			return
-		}
-		//AckHTML_OK(c)
-		if ok := optDTUCtrl(c, dt.CMD_SETSYSCFG, dt.JsonToString(res)); ok {
-			//connsql.SaveConfigfsToDB(sn, dt.JsonToString(dtudev))
-		}
 	}
 }
 
-func GetDTUSetExtShell(c *gin.Context) {
-	var (
-		te     dt.RmtTxtFile
-		dtudev dt.ConfigSystem
-	)
-	//sn := c.Request.URL.Query().Get("sn")
-	if err := c.BindJSON(&dtudev); err != nil {
-		log.Println(err.Error())
-		AckHTML_ErrJsonFmt(c, err.Error())
-	} else {
-		/*if err := cfg.CheckSystemConf(dtudev.Conf); err != nil {
-			AckHTML_AbNormal(c, dt.HTC_Undefine, err.Error())
-			return
-		}*/
-		cfg := mcryp.PackRemoteFile(dtudev.Conf, false)
-		/*if md5, err := getFileMD5(sn, dt.CMD_SETSYSCFG); err == nil {
-			if cfg.Md5 == md5 {
-				log.Println("tag: No Change")
-				AckHTML_OK(c)
-				return
-			}
-		}*/
-		te.Path = "/usr/ext.sh"
-		te.Context = dt.JsonToString(cfg)
-		if ok := optDTUCtrl(c, dt.CMD_SETXTFILE, dt.JsonToString(te)); ok {
-			//connsql.SaveConfigfsToDB(sn, dt.JsonToString(dtudev))
-		}
-	}
-}
-
-/*
-func GetDTUGetState(c *gin.Context) {
-	optDTUCtrl(c, dt.CMD_GETSTATE, "")
-}*/
 //以json格式获取运行状态
-func DTUGetStateJson(c *gin.Context) {
-	var (
-		reo dt.RunStateDTU
-	//	to  dt.RunStateDTU
-	)
+func GetDTUState(c *gin.Context) {
 	sn := c.Request.URL.Query().Get("sn")
-	res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETSTATE, "")
-	if !ok {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-	} else {
-		if len(res) < 5 {
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-			return
-		}
-		d := mcryp.BASE64DecodeStr(res)
-		if d == "" {
-			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-			return
-		}
-		err := json.Unmarshal([]byte(d), &reo)
-		if err != nil {
-			res = "json format error"
-			AckHTML_ErrJsonFmt(c, "")
-		} else {
-			AckHTML_OKWithData(c, reo)
-		}
-	}
+	val := fwd.API_QueryDeviceStatus(sn)
+	AckHTML_OKWithData(c, val)
 	return
 }
 
-/*
-func GetDTUpgradeRctool(c *gin.Context) {
-	optDTUCtrl(c, dt.CMD_UPRCTOOL, "")
-}
-func GetDTUpgradeHJ212(c *gin.Context) {
-	optDTUCtrl(c, dt.CMD_UPHJ212, "")
-}
-
-func SetDTUpgradeRctool(c *gin.Context) {
-	optDTUCtrl(c, dt.CMD_UPRCTOOL, "")
-}*/
-
-//生成DTU端HTTP下载信息包
-func makeHttpDTU_Down(n dt.RmtURLInfo) string {
-	var (
-		pack dt.RmtFilePack
-		info dt.RmtFileInfo
-	)
-	info.Type = "http"
-	if n.IsZip {
-		info.Encode = "gzip"
-	} else {
-		info.Encode = ""
-	}
-	//info.Auth
-	info.URL = "http://" + cfg.ParamConf.Htip + ":" + strconv.Itoa(cfg.ParamConf.HtPort) + "/file/download"
-	info.HPath = encUrl(n)
-	info.DIR = true
-	pack.Info = dt.JsonToString(info)
-	pack.MD5 = mcryp.MD5Str(pack.Info)
-	str := dt.JsonToString(pack)
-	_, bp := mcryp.EncypAESEncode([]byte(str), []byte(rmtDileKey))
-	return bp
-}
-func makeFtpDTU_Down(n dt.FtpFileInfo) string {
-	var (
-		pack dt.RmtFilePack
-		info dt.RmtFileInfo
-	)
-	info.Type = "ftp"
-	if n.IsZip {
-		info.Encode = "gzip"
-	} else {
-		info.Encode = ""
-	}
-	info.IP = cfg.ParamConf.FtpIP
-	info.Port = strconv.Itoa(cfg.ParamConf.FtpPort)
-	info.Usr = cfg.ParamConf.FtpUsr
-	info.Pwd = cfg.ParamConf.FtpPwd
-	info.Src = n.Src
-	info.Dst = n.Dst
-	info.DIR = n.DIR
-	if info.DIR {
-		info.Reboot = n.IsRbt
-	} else {
-		info.Reboot = false
-	}
-	pack.Info = dt.JsonToString(info)
-	pack.MD5 = mcryp.MD5Str(pack.Info)
-	str := dt.JsonToString(pack)
-	_, bp := mcryp.EncypAESEncode([]byte(str), []byte(rmtDileKey))
-	return bp
-}
-
-func SetDTUpgradeHJ212(c *gin.Context) {
-	sn := c.Query("sn")
-	key := c.Query("key")
-	if sn == "" || key == "" {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "miss param")
-		return
-	}
-	err, info := decUrl(key)
-	if err != nil {
-		log.Println(err)
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "key err")
-		return
-	}
-	info.Sn = sn
-	info.Time = dt.GetNowTime()
-	data := makeHttpDTU_Down(info)
-	res, ok := model.ModelDTUCtrl(sn, dt.CMD_FILEDOWNLOAD, data)
-	if !ok {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-	} else {
-		AckHTML_OKWithData(c, res)
-	}
-	//optDTUCtrl(c, dt.CMD_FILEDOWNLOAD, CrypeToRmtFile("./app", "./app"))
-}
-
-func taskUpgradeBatch(c *gin.Context, info dt.UpgradeBatchInfo, flag string) {
-	var (
-		wg     sync.WaitGroup
-		mt     sync.Mutex
-		result = ""
-	)
-	model.FlagsCache.Add(flag, "")
-	data := makeFtpDTU_Down(info.FtpInfo)
-	for _, v := range info.DevList {
-		wg.Add(1)
-		go func(sn string) {
-			str := ""
-			if res, ok := model.ModelDTUCtrl(sn, dt.CMD_FILEDOWNLOAD, data); ok && res == "ok" {
-				str = sn + "-ok"
-			} else {
-				str = sn + "-" + res
-			}
-			mt.Lock()
-			result += str + ";"
-			mt.Unlock()
-			wg.Done()
-		}(v)
-	}
-	wg.Wait()
-	//log.Println("OptionUpgradeBatch:", result)
-	if len(result) == 0 {
-		result = "unknow error"
-		//AckHTML_OKWithData(c, result)
-	} // else {
-	//AckHTML_AbNormal(c, dt.HTC_DTUErr, "null")
-	//}
-	model.FlagsCache.Add(flag, result)
-}
-
-func OptionUpgradeBatch(c *gin.Context) {
-	var (
-		//wg     sync.WaitGroup
-		//mt     sync.Mutex
-		info dt.UpgradeBatchInfo
-		//result []string
-	)
-	flag, ok := c.GetQuery("flag")
-	if !ok {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "miss param")
-		return
-	}
-	if err := c.BindJSON(&info); err != nil {
-		AckHTML_ErrJsonFmt(c, "")
-		return
-	}
-	AckHTML_OK(c)
-	go taskUpgradeBatch(c, info, flag)
-	/*data := makeFtpDTU_Down(info.FtpInfo)
-	for _, v := range info.DevList {
-		wg.Add(1)
-		go func(sn string) {
-			str := ""
-			if res, ok := model.ModelDTUCtrl(sn, dt.CMD_FILEDOWNLOAD, data); ok && res == "ok" {
-				str = sn + " ok"
-			} else {
-				str = sn + " " + res
-			}
-			mt.Lock()
-			result = append(result, str)
-			mt.Unlock()
-			wg.Done()
-		}(v)
-	}
-	wg.Wait()
-	//log.Println("OptionUpgradeBatch:", result)
-	if len(result) > 0 {
-		AckHTML_OKWithData(c, result)
-	} else {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, "null")
-	}*/
-}
-
-func GetUpBatchResult(c *gin.Context) {
-	flag, ok := c.GetQuery("flag")
-	if !ok {
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "miss param")
-		return
-	}
-	if val, ok := model.FlagsCache.Get(flag); ok {
-		//var obj = dt.OBJString{Obj: ""}
-		if len(val) > 0 {
-			model.FlagsCache.Remove(flag)
-		}
-		//obj.Obj = val
-		AckHTML_OKWithData(c, val)
-	} else {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, "")
-	}
-}
-
-func OptionUpgradeRmtf(c *gin.Context) {
-	var info dt.FtpFileInfo
-	sn, ok := c.GetQuery("sn")
-	if !ok {
-		//fmt.Println("OptionUpgradeRmtf : ", "miss param")
-		AckHTML_AbNormal(c, dt.HTC_HtmlParam, "miss param")
-		return
-	}
-	if err := c.BindJSON(&info); err != nil {
-		//fmt.Println("json format error")
-		AckHTML_ErrJsonFmt(c, "")
-		return
-	}
-	data := makeFtpDTU_Down(info)
-	if res, ok := model.ModelDTUCtrl(sn, dt.CMD_FILEDOWNLOAD, data); ok && res == "ok" {
-		AckHTML_OKWithData(c, res)
-	} else {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-	}
-}
-
-var (
-	rmtDileKey string
-	keyEnUrl   = "u98(-NHigdbpa-=0"
-)
-
-func SetRmtDileKey(n string) {
-	rmtDileKey = n
-}
-func packRmtFileStr(src, dst string) string {
-	var (
-		pack dt.RmtFilePack
-		info dt.RmtFileInfo
-	)
-	info.Port = strconv.Itoa(cfg.ParamConf.HtPort)
-	info.IP = cfg.ParamConf.Htip
-	info.Src = src
-	info.Dst = dst
-	str := dt.JsonToString(info)
-	pack.Info = str
-	pack.MD5 = mcryp.MD5Str(str)
-	log.Println(pack)
-	return dt.JsonToString(pack)
-}
-
 /*
 
 func packHttpRmtFile(name, dst string, zip bool) dt.RmtFileInfo {
@@ -1113,146 +692,12 @@ func packHttpRmtFile(name, dst string, zip bool) dt.RmtFileInfo {
 	return info
 }*/
 
-//对远程更新文件信息加密
-func CrypeToRmtFile(src, dst string) string {
-	str := packRmtFileStr(src, dst)
-	//log.Println("CrypeToRmtFile : " + str)
-	_, bp := mcryp.EncypAESEncode([]byte(str), []byte(rmtDileKey))
-	return bp
-}
-
-var (
-	uploadSave   = "./file/down/"
-	downloadSave = "./file/upload/"
-)
-
-func GetFileFromHtml(c *gin.Context) {
-	fileDir := "." //c.Query("fileDir")
-	fileName := c.Query("fileName")
-	path := fileDir + "/" + fileName
-	fmt.Println(path)
-	is, _ := dt.PathExists(path)
-	if !is {
-		c.Redirect(http.StatusFound, "/404")
-		return
-	}
-	c.Header("Content-Type", "application/octet-stream")
-	c.Header("Content-Disposition", "attachment; filename="+fileName)
-	c.Header("Content-Transfer-Encoding", "binary")
-	c.File(path)
-}
-
-func StartFrpc(c *gin.Context) {
-	if !cfg.ParamConf.Mode {
-		AckHTML_OK(c)
-		return
-	}
-	optDTUCtrl(c, dt.CMD_STARTFRP, "")
-}
-
-func SetFileFromHtml(c *gin.Context) {
-	var ck = dt.RmtURLInfo{IsZip: false}
-	//获取文件头
-	file, err := c.FormFile("file")
-	if err != nil {
-		fmt.Println("ERROR: upload file failed. ", err)
-		AckHTML_AbNormal(c, 90, "Request fail") //c.String(http.StatusBadRequest, "请求失败")
-		return
-	}
-	//获取文件名
-	fileName := uploadSave + filepath.Base(file.Filename) //"./file/" + file.Filename
-	//保存文件到服务器本地
-	//SaveUploadedFile(文件头,保存路径)
-	if err := c.SaveUploadedFile(file, fileName); err != nil {
-		AckHTML_AbNormal(c, 91, "Save fail") //c.String(http.StatusBadRequest, "保存失败 Error:%s", err.Error())
-		return
-	}
-	//tarFile(fileName)
-	//c.String(http.StatusOK, "上传文件成功")
-	fmt.Println("fileName : " + fileName)
-	new_name := fileName
-	er, size := dt.GetFileSize(fileName)
-	if er == nil && size > int64(1*1024*1024) {
-		err, name := mcryp.NewTarGz(fileName)
-		if err == nil {
-			fmt.Println("new fileName : " + name)
-			os.Remove(fileName)
-			new_name = uploadSave + filepath.Base(name)
-			ck.IsZip = true
-		}
-	}
-	ck.Path = new_name
-	//fmt.Println("ck : ", ck)
-	re := encUrl(ck)
-	AckHTML_OKWithMsg(c, re)
-}
-
-func SetPurifierState(c *gin.Context) {
-	var (
-		opt   = ""
-		onoff = ""
-	)
-	if !cfg.ParamConf.Mode {
-		AckHTML_OK(c)
-		return
-	}
-	sn := c.Request.URL.Query().Get("sn")
-	st := c.Request.URL.Query().Get("state")
-	mode := c.Request.URL.Query().Get("mode")
-	if sn == "" || st == "" || mode == "" {
-		ackHTML_ErrHtml(c, "sn state or mode is null")
-		return
-	}
-	switch mode {
-	case "0":
-		opt = dt.CMD_PURIFIERSTATE
-		break
-	case "1":
-		opt = dt.CMD_PURIFIERSTATEDO2
-		break
-	default:
-		ackHTML_ErrHtml(c, "illegal mode")
-		return
-	}
-	//fmt.Println(c.Request.URL.Query())
-	if st == "on" {
-		onoff = "on"
-	} else {
-		onoff = "off"
-	}
-	if res, ok := model.ModelDTUCtrl(sn, opt, onoff); !ok {
-		AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
-	} else {
-		AckHTML_OK(c)
-	}
-}
-
 /*
-var staticHandler http.Handler
-// 静态文件处理
-func StaticServer(w http.ResponseWriter, req *http.Request) {
-	fmt.Println("path:" + req.URL.Path)
-	staticHandler.ServeHTTP(w, req)
-}
-func init() {
-	staticHandler = http.StripPrefix("/assets/", http.FileServer(http.Dir("radio")))
-}
-
-func CreateHTTPFileServer() { //已经有静态文件了
-	http.HandleFunc("/assets/", StaticServer)
-	err := http.ListenAndServe(":3000", nil)
-	if err != nil {
-		log.Fatal("ListenAndServe: ", err)
-	}
-}*/
-
 //获取通信机基本参数
 func GetDTUBaseInfo(c *gin.Context) {
-	sn := c.Request.URL.Query().Get("sn") //sn := c.Param("sn")
+	sn := c.Request.URL.Query().Get("sn")
 	if sn == "" {
-		ackHTML_ErrHtml(c, "sn is null") //
-		//c.JSON(http.StatusForbidden, dt.JsonToString(cerr))
-		//c.String(http.StatusForbidden, "sn is null")
+		ackHTML_ErrHtml(c, "sn is null")
 	} else {
 		if res, ok := model.ModelDTUCtrl(sn, dt.CMD_GETDTUBASEINFO, ""); !ok {
 			AckHTML_AbNormal(c, dt.HTC_DTUErr, res)
@@ -1262,13 +707,9 @@ func GetDTUBaseInfo(c *gin.Context) {
 				loginfo dt.Loginfo
 				binfo   dt.DTUBaseInfo
 			)
-
 			err := json.Unmarshal([]byte(res), &loginfo)
 			if err != nil {
 				AckHTML_AbNormal(c, dt.HTC_JSONFormat, err.Error())
-				//c.JSON(http.StatusForbidden, dt.JsonToString(cerr))
-				//log.Println("", err)
-				//c.String(http.StatusForbidden, "json format error:", err.Error())
 			} else {
 				binfo.Version = loginfo.Version
 				binfo.Verplat = loginfo.Verplat
@@ -1283,259 +724,4 @@ func GetDTUBaseInfo(c *gin.Context) {
 			}
 		}
 	}
-}
-
-func upload(w http.ResponseWriter, req *http.Request) {
-	maxsize := int64(10 * 1024 * 1024)
-	contentType := req.Header.Get("content-type")
-	sha256 := req.Header.Get("Content-SHA256") //req.PostFormValue("Content-SHA256")
-	contentLen := req.ContentLength
-	fmt.Printf("upload content-type:%s,content-length:%d,sha:%s\n", contentType, contentLen, sha256)
-	if !strings.Contains(contentType, "multipart/form-data") {
-		w.Write([]byte("content-type must be multipart/form-data"))
-		return
-	}
-	if contentLen >= maxsize { // 10 MB
-		w.Write([]byte("file to large,limit 10MB"))
-		return
-	}
-
-	err := req.ParseMultipartForm(maxsize)
-	if err != nil {
-		//http.Error(w, err.Error(), http.StatusInternalServerError)
-		w.Write([]byte("ParseMultipartForm error:" + err.Error()))
-		return
-	}
-
-	if len(req.MultipartForm.File) == 0 {
-		w.Write([]byte("not have any file"))
-		return
-	}
-
-	for name, files := range req.MultipartForm.File {
-		fmt.Printf("req.MultipartForm.File,name=%s", name)
-
-		if len(files) != 1 {
-			w.Write([]byte("too many files"))
-			return
-		}
-		if name == "" {
-			w.Write([]byte("is not FileData"))
-			return
-		}
-
-		for _, f := range files {
-			handle, err := f.Open()
-			if err != nil {
-				w.Write([]byte(fmt.Sprintf("unknown error,fileName=%s,fileSize=%d,err:%s", f.Filename, f.Size, err.Error())))
-				return
-			}
-
-			path := "./" + f.Filename
-			dst, _ := os.Create(path)
-			io.Copy(dst, handle)
-			dst.Close()
-			fmt.Printf("successful uploaded,fileName=%s,fileSize=%.2f MB,savePath=%s \n", f.Filename, float64(contentLen)/1024/1024, path)
-
-			err, cal := mcryp.GetFileSHA256Str(path)
-			if err == nil {
-				if cal != sha256 {
-					log.Println("sha256 no match : " + sha256 + " " + cal)
-					os.Remove(path)
-				} else {
-					log.Println("sha256 is match")
-				}
-			}
-			w.Write([]byte("successful,url=" + url.QueryEscape(f.Filename)))
-		}
-	}
-}
-
-func Dealupload(w http.ResponseWriter, req *http.Request, c *gin.Context) {
-	maxsize := int64(10 * 1024 * 1024)
-	contentType := req.Header.Get("content-type")
-	sha256 := req.Header.Get("Content-SHA256") //req.PostFormValue("Content-SHA256")
-	contentLen := req.ContentLength
-	fmt.Printf("upload content-type:%s,content-length:%d,sha:%s\n", contentType, contentLen, sha256)
-	if !strings.Contains(contentType, "multipart/form-data") {
-		w.Write([]byte("content-type must be multipart/form-data"))
-		return
-	}
-
-	if contentLen >= maxsize { // 10 MB
-		w.Write([]byte("file to large,limit 10MB"))
-		return
-	}
-
-	err := req.ParseMultipartForm(maxsize)
-	if err != nil {
-		//http.Error(w, err.Error(), http.StatusInternalServerError)
-		w.Write([]byte("ParseMultipartForm error:" + err.Error()))
-		return
-	}
-
-	if len(req.MultipartForm.File) == 0 {
-		w.Write([]byte("not have any file"))
-		return
-	}
-
-	for name, files := range req.MultipartForm.File {
-		fmt.Printf("req.MultipartForm.File,name=%s", name)
-
-		if len(files) != 1 {
-			w.Write([]byte("too many files"))
-			return
-		}
-		if name == "" {
-			w.Write([]byte("is not FileData"))
-			return
-		}
-
-		for _, f := range files {
-			handle, err := f.Open()
-			if err != nil {
-				w.Write([]byte(fmt.Sprintf("unknown error,fileName=%s,fileSize=%d,err:%s", f.Filename, f.Size, err.Error())))
-				return
-			}
-
-			path := "./" + f.Filename
-			dst, _ := os.Create(path)
-			io.Copy(dst, handle)
-			dst.Close()
-			fmt.Printf("successful uploaded,fileName=%s,fileSize=%.2f MB,savePath=%s \n", f.Filename, float64(contentLen)/1024/1024, path)
-
-			err, cal := mcryp.GetFileSHA256Str(path)
-			if err == nil {
-				if cal != sha256 {
-					log.Println("sha256 no match : " + sha256 + " " + cal)
-					os.Remove(path)
-				} else {
-					log.Println("sha256 is match")
-				}
-			}
-			w.Write([]byte("successful,url=" + url.QueryEscape(f.Filename)))
-		}
-	}
-}
-
-func getContentType(fileName string) (extension, contentType string) {
-	arr := strings.Split(fileName, ".")
-	contentType = ""
-	// see: https://tool.oschina.net/commons/
-	if len(arr) >= 2 {
-		extension = arr[len(arr)-1]
-		switch extension {
-		case "jpeg", "jpe", "jpg":
-			contentType = "image/jpeg"
-		case "png":
-			contentType = "image/png"
-		case "gif":
-			contentType = "image/gif"
-		case "mp4":
-			contentType = "video/mpeg4"
-		case "mp3":
-			contentType = "audio/mp3"
-		case "wav":
-			contentType = "audio/wav"
-		case "pdf":
-			contentType = "application/pdf"
-		case "doc", "":
-			contentType = "application/msword"
-		}
-	}
-	if contentType == "" {
-		// .*( 二进制流,不知道下载文件类型)
-		contentType = "application/octet-stream"
-	}
-	return
-}
-
-//加密URL信息
-func encUrl(n dt.RmtURLInfo) string {
-	var t dt.RmtFilePack
-	t.Info = dt.JsonToString(n)
-	t.MD5 = mcryp.MD5Str(t.Info)
-	r := dt.JsonToString(t)
-	err, ret := mcryp.EncypAESEncode([]byte(r), []byte(keyEnUrl))
-	if err != nil {
-		return ""
-	}
-	return ret
-}
-
-//解密URL信息
-func decUrl(n string) (error, dt.RmtURLInfo) {
-	var (
-		t   dt.RmtURLInfo
-		c   dt.RmtFilePack
-		str = ""
-	)
-	if n == "" {
-		return errors.New("null"), t
-	}
-	if err, ret := mcryp.DecypAESEncode(n, []byte(keyEnUrl)); err != nil {
-		return errors.New("dec err"), t
-	} else {
-		str = string(ret)
-	}
-	if str == "" {
-		return errors.New("null"), t
-	}
-	if err := json.Unmarshal([]byte(str), &c); err != nil {
-		return errors.New("json err"), t
-	}
-	md5 := mcryp.MD5Str(c.Info)
-	if md5 != c.MD5 {
-		return errors.New("chech err"), t
-	}
-	if err := json.Unmarshal([]byte(c.Info), &t); err != nil {
-		return errors.New("json err"), t
-	}
-	return nil, t
-}
-
-/*
-func download(w http.ResponseWriter, req *http.Request) {
-	//if req.RequestURI == "/favicon.ico" {
-	//return
-	//}
-	fmt.Println("download url : " + req.RequestURI)
-	filename := filepath.Base(req.RequestURI) //req.RequestURI[1:]
-	fmt.Println(filename)
-	enEscapeUrl, err := url.QueryUnescape(filename)
-	if err != nil {
-		w.Write([]byte(err.Error()))
-		return
-	}
-
-	f, err := os.Open("./" + enEscapeUrl)
-	if err != nil {
-		w.Write([]byte(err.Error()))
-		return
-	}
-
-	info, err := f.Stat()
-	if err != nil {
-		w.Write([]byte(err.Error()))
-		return
-	}
-
-	_, contentType := getContentType(filename)
-	w.Header().Set("Content-Disposition", "attachment; filename="+filename)
-	//w.Header().Set("Content-Type", http.DetectContentType(fileHeader))
-	w.Header().Set("Content-Type", contentType)
-	w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
-	err, sha := mcryp.GetFileSHA256Str(filename)
-	w.Header().Set("Content-SHA256", sha)
-	if err != nil {
-
-	}
-	f.Seek(0, 0)
-	io.Copy(w, f)
 }*/
-
-func CreateHTTPFileServer_2() {
-	http.HandleFunc("/file/upload", upload)
-	//http.HandleFunc("/", download)
-	http.ListenAndServe(fmt.Sprintf(":%d", cfg.ParamConf.HtPort), nil)
-}

+ 47 - 0
SERVER/Lamp_Server/src/datastruct/crc16.go

@@ -0,0 +1,47 @@
+// hello
+package datastruct
+
+//HJ212 计算crc
+func CalCRC16HJ212(data []byte) uint16 {
+	var (
+		crc  uint16 = 0xFFFF
+		inum uint16 = 0
+	)
+	length := len(data)
+	for i := 0; i < length; i++ {
+		inum = uint16(data[i])
+		crc = (crc >> 8) & 0x00FF
+		crc = crc ^ inum
+		for j := 0; j < 8; j++ {
+			flag := crc % 2
+			crc = crc >> 1
+			if flag == 1 {
+				crc = crc ^ 0xA001
+			}
+		}
+	}
+	return crc
+}
+
+
+
+func CalCRC16ModbusRTU(data []byte) uint16 {
+	var (
+		crc  uint16 = 0xFFFF
+		inum uint16 = 0
+	)
+	length := len(data)
+	for i := 0; i < length; i++ {
+		inum = uint16(data[i])
+		//crc = (crc >> 8) & 0x00FF
+		crc ^= inum & 0x00FF
+		for j := 0; j < 8; j++ {
+			flag := crc % 2
+			crc = crc >> 1
+			if flag == 1 {
+				crc = crc ^ 0xA001
+			}
+		}
+	}
+	return crc
+}

+ 94 - 76
SERVER/Lamp_Server/src/datastruct/datastruct.go

@@ -6,7 +6,9 @@ import (
 	"hello/tcpserver"
 	"os"
 	"sync"
+	"sync/atomic"
 	"time"
+	"unsafe"
 )
 
 const (
@@ -17,7 +19,7 @@ const (
 
 var (
 	//CONFIGFS_JSON = "/usr/RunConfig.json"
-	Version              = "1.3.0"
+	Version              = "1.4.0"
 	TYPE_REQUST          = "request"
 	TYPE_RESPONSE        = "response"
 	CMD_GETTHRESCFG      = "gethrescfg"
@@ -491,6 +493,7 @@ type ClientState struct {
 	Info   Loginfo
 	Times  int64 //心跳计时器
 	Online bool  //在线状态
+	MLock  Mutex
 	Conf   ConfigfsJSON
 	// PwrOff    bool  //掉电状态
 	// PurifiDO3 bool  //净化器状态
@@ -499,6 +502,34 @@ type ClientState struct {
 	TmOffline string
 }
 
+type SetMeterRatioReply struct {
+	Result int `json:"result"`
+}
+
+type SetMeterRatioRes struct {
+	Addr int `json:"addr"`
+	//Ct      int    `json:"ct"`
+	//Pt      int    `json:"pt"`
+	Type    string `json:"type"`
+	SerData string `json:"serdata"`
+}
+
+type SetMeterAddressRes struct {
+	AddrOld int    `json:"addr_old"`
+	AddrNew int    `json:"addr_new"`
+	Type    string `json:"type"`
+}
+
+//读取电表变比
+type GetMeterRatioRes struct {
+	Result  int    `json:"result"`
+	SerData string `json:"serdata"`
+	// Addr   int    `json:"addr"`
+	// Ct     int    `json:"ct"`
+	// Pt     int    `json:"pt"`
+	// Type   string `json:"type"`
+}
+
 type DtuRegistChanMsg struct {
 	Sn    string
 	Value ClientState
@@ -550,13 +581,14 @@ type CalcDataEnergy struct {
 	Fqs float32
 }
 
-//起始电量
-// type CalcOriginEnergy struct {
-// 	OriginTps float32
-// 	OriginTqs float32
-// 	OriginFps float32
-// 	OriginFqs float32
-// }
+//上行设备状态信息
+type PlatReportCount struct {
+	Info    string `json:"info"`
+	CntSend int    `json:"cnt_send"`
+	CntAck  int    `json:"cnt_ack"`
+	ErrConn int    `json:"err_conn"`
+	Time    string `json:"time"`
+}
 
 type MeterSampleCount struct {
 	Addr     int    `json:"addr"`
@@ -565,13 +597,18 @@ type MeterSampleCount struct {
 	Lastime  string `json:"lastime"`
 }
 
+type DeviceSampleCount struct {
+	Meter map[int]MeterSampleCount
+	Plat  map[string]PlatReportCount
+}
+
 type CalcMeterParm struct {
 	Init        int
 	Time        int64 //计算的日期
 	LRate       CalcLoadRate
 	LastEnergy  CalcDataEnergy //最近一次电能
 	OrginEnergy CalcDataEnergy //起始电能
-	MtSample    MeterSampleCount
+	//MtSample    MeterSampleCount
 }
 
 type SimpleStat struct {
@@ -627,11 +664,11 @@ type RunstatePlat struct { //上行设备状态信息
 	Time    string `json:"time"`
 }
 
-//dtu运行状态
+//运行状态
 type RunStateDTU struct {
-	Runtime int `json:"runtime"` //Runtime string `json:"runtime"` //运行时间(分钟)
-	//Device  []RunstateDev  `json:"device"`
-	Plat []RunstatePlat `json:"plat"`
+	Result int                `json:"result"`
+	Meter  []MeterSampleCount `json:"meter"`
+	Plat   []PlatReportCount  `json:"plat"`
 }
 
 type CfgFileInfo struct { //
@@ -664,21 +701,6 @@ type EditItemCompany struct {
 }
 
 /*
-//dtu基本信息
-type DTUBasicInfo struct {
-	Version string `json:"version"`
-	Lora    struct {
-		Type   string `json:"type"`
-		Rate   int    `json:"rate"`
-		Freq   int    `json:"freq"`
-		Frequp int    `json:"frequp"`
-		Freqdw int    `json:"freqdw"`
-	} `json:"lora"`
-	Devpro  []string `json:"devpro"`
-	Platpro []string `json:"platpro"`
-	Idlist  []int    `json:"idlist"`
-}*/
-
 type ConfigThreshold struct {
 	Name  string  `json:"name"`
 	Voc   float64 `json:"voc"`
@@ -697,7 +719,7 @@ type ConfigThreshold struct {
 	LampB float64 `json:"lamp_b"`
 	IfanB float64 `json:"ifan_b"`
 	IpurB float64 `json:"ipur_b"`
-}
+}*/
 
 type ConfigSystem struct {
 	Conf string `json:"config"`
@@ -750,6 +772,8 @@ type ConfigfsJSONItem struct {
 		LVref int    `json:"lvref"` //线电压基准(380)
 		Bmyz  string `json:"bmyz"`
 		Mtype string `json:"mtype"`
+		MCn   string `json:"mcn"`
+		Extra string `json:"extra"`
 	} `json:"slave"`
 }
 
@@ -777,53 +801,6 @@ type ConfigfsJSON struct {
 	// } `json:"platform"`
 }
 
-/***************通信机配置步骤**********************
-//下行配置文件
-type DeviceProcess struct {
-	ListAgent []string `json:"list_agent"` //供应商列表
-	ListPro   []string `json:"list_pro"`   //协议列表 指定device.Protocol内容
-	Device    []struct {
-		Ch       int     `json:"ch"`
-		Addr     int     `json:"addr"`
-		ID       int     `json:"id"`
-		Name     string  `json:"name"`
-		Protocol string  `json:"protocol"`
-		Ct       float64 `json:"ct"`
-		Pt       float64 `json:"pt"`
-	} `json:"device"`
-}
-
-//上行配置文件
-type PlatProcess struct {
-	PlatNum int      //Platform数组最大数量
-	ListPro []string `json:"list_pro"` //协议列表
-	ListDev []struct {
-		ID   int    `json:"id"`
-		Name string `json:"name"`
-	} `json:"list_dev"`
-	Platform []struct {
-		Enable   bool   `json:"enable"` //上报使能
-		Name     string `json:"name"`
-		IP       string `json:"ip"`
-		Port     int    `json:"port"`
-		Protocol string `json:"protocol"`
-		Pw       string `json:"pw"`
-		Mn       string `json:"mn"`
-		Interval int    `json:"interval"`
-		St       int    `json:"st"`
-		Dev      []struct {
-			ID   int    `json:"id"`
-			Name string `json:"name"`
-			Bmyz string `json:"bmyz"`
-		} `json:"dev"`
-	} `json:"platform"`
-}*/
-
-/*// html:登陆后台反馈的信息
-type HtmlRespondLogin struct {
-	Res  string `json:"result"`
-	Data string `json:"note"`
-}*/
 // html:网页传递过来的用户登陆信息
 type HtmlLogin struct {
 	Usr string `json:"usr"`
@@ -854,6 +831,12 @@ type YamlCFG struct {
 	}
 }
 
+type AccountRegistMod struct {
+	Id  int    `json:"id"`
+	Usr string `json:"usr"` //用户名
+	Pwd string `json:"pwd"` //密码
+} //账号信息
+
 // html:网页传递过来的用户注册信息
 type HtmlRegist struct {
 	Id    int    `json:"id"`
@@ -882,6 +865,15 @@ type DBAccountArray struct {
 	Array []DBAccountMg `json:"array"`
 }
 
+type DBAgentMg struct {
+	Id   int    `json:"id"`
+	Name string `json:"name"` //代理商
+} //管理账号信息
+
+type DBAgentArray struct {
+	Array []DBAgentMg `json:"array"`
+}
+
 //数据库账号信息
 type DbAccount struct {
 	ID      int
@@ -910,6 +902,24 @@ type UsrAccount struct {
 	Agent int //`json:"agent"` //代理商
 } //账号信息*/
 
+// type GetMeterPMC350BRes struct {
+// 	Result int               `json:"result"`
+// 	Value  MeterPMC350BParam `json:"value"`
+// }
+
+type MeterCTPT struct {
+	Ct int `json:"ct"`
+	Pt int `json:"pt"`
+}
+
+type MeterPMC350BParam struct {
+	PrimaryVolt    int `json:"primary_volt"`
+	SecondVolt     int `json:"second_volt"`
+	PrimaryCurrent int `json:"primary_current"`
+	SecondCurrent  int `json:"second_current"`
+	CType          int `json:"ct_type"`
+}
+
 type OBJNewAccount struct {
 	Usr   string `json:"usr"`
 	Pwd   string `json:"pwd"`
@@ -1150,6 +1160,14 @@ func ConnTimeoutJudge(tm int64) bool {
 	return tmDiff(tm, int64(TCPTimeoutTime))
 }
 
+type Mutex struct {
+	sync.Mutex
+}
+
+func (m *Mutex) TryLock() bool {
+	return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), 0, 1)
+}
+
 /*
 //心跳检测   每秒遍历一次 查看所有sess 上次接收消息时间  如果超过 num 就删除该 sess
 func (this *DMAP_ClientState) HeartBeat(num int64) {

+ 43 - 0
SERVER/Lamp_Server/src/datastruct/dmap.go

@@ -50,3 +50,46 @@ func (cm *DmapKv) Clean() {
 	}
 	cm.RWLock.Unlock()
 }
+
+//===================================================================
+type SliceLock struct {
+	rwLock sync.RWMutex
+	Mem    []interface{}
+}
+
+func NewSliceLock() *SliceLock {
+	m := &SliceLock{
+		Mem: make([]interface{}, 0),
+	}
+	return m
+}
+
+func (m *SliceLock) Add(val interface{}) {
+	m.rwLock.Lock()
+	defer m.rwLock.Unlock()
+	m.Mem = append(m.Mem, val)
+}
+
+func (m *SliceLock) Exist(val interface{}) bool {
+	m.rwLock.Lock()
+	defer m.rwLock.Unlock()
+	for _, v := range m.Mem {
+		if v == val {
+			return true
+		}
+	}
+	return false
+}
+
+func (m *SliceLock) All() (list []interface{}) {
+	list = make([]interface{}, 0)
+	if len(m.Mem) < 1 {
+		return
+	}
+	m.rwLock.Lock()
+	defer m.rwLock.Unlock()
+	for _, v := range m.Mem {
+		list = append(list, v)
+	}
+	return
+}

BIN
SERVER/Lamp_Server/src/db/account.db


BIN
SERVER/Lamp_Server/src/db/user.db


+ 52 - 11
SERVER/Lamp_Server/src/downstream_service/downstream_service.go

@@ -10,6 +10,10 @@ import (
 	"hello/tcpserver"
 	"log"
 	"time"
+	//simplejson "github.com/bitly/go-simplejson"
+	//"github.com/DeanThompson/syncmap"
+	//"github.com/zyx4843/gojson"
+	//"github.com/buger/jsonparser"
 )
 
 func dealDTUdisconnect(c *tcpserver.Client) {
@@ -19,9 +23,6 @@ func dealDTUdisconnect(c *tcpserver.Client) {
 		if cli, ok := basic.Dtumap_state.Get(sn); ok {
 			if naddr == cli.FD.GetClientHost() {
 				cli.Online = false
-				// if !cli.PwrOff {
-				// 	cli.TmOffline = dt.GetNowTime()
-				// }
 				basic.Dtumap_state.Add(sn, cli)
 				log.Println("Client Closed:", sn, "-", c.GetClientHost())
 			}
@@ -98,10 +99,6 @@ func dealDTUpack(c *tcpserver.Client, msg []byte) tcpserver.RestResult {
 		dev    dt.DTUMangCmd
 		result = tcpserver.RestResult{Sucess: false, Message: "er..."}
 	)
-	// if len(msg) < 8 {
-	// 	result.Message = "length error"
-	// 	return result
-	// }
 	err := basic.ParseDtuReport(msg, &dev)
 	//err := json.Unmarshal(msg, &dev)
 	if err != nil {
@@ -111,6 +108,16 @@ func dealDTUpack(c *tcpserver.Client, msg []byte) tcpserver.RestResult {
 		cli, ok := basic.Dtumap_state.Get(dev.SN)
 		if ok {
 			cli.Online = true
+			//cli.UpdateTime()
+			//basic.Dtumap_state.Add(dev.SN, cli)
+
+			//DevmapState.Set(cmd.SN, cli)
+			//log.Println("Get SN Tag1.2")
+			//cli, ok = basic.Dtumap_state.Get(dev.SN)
+			//log.Println("Get SN Tag1.3")
+			//if ok && cfg.ParamConf.Debug {
+			//log.Println(cmd.SN, " is Online")
+			//}
 		} else {
 			cli.Online = false
 		}
@@ -122,9 +129,21 @@ func dealDTUpack(c *tcpserver.Client, msg []byte) tcpserver.RestResult {
 			basic.Dtumap_state.Add(dev.SN, cli)
 			basic.IPMapSN.Add(c.GetClientHost(), dev.SN)
 			if tmp, find := basic.OnlineSN.Get(dev.SN); !find {
+				/*df := dt.ConfigfsJSON{}
+				log.Println(dev.SN, "Dtumap_state cli ", cli.Conf)
+				if du, e := basic.Dtumap_sn.Get(dev.SN); e {
+					//这里不管json解析成功或失败,都要更新给cli.Conf
+					//解析失败说明还没配置上报平台
+					json.Unmarshal([]byte(du.Info.Configs), &df)
+					cli.Conf = df
+					log.Println(dev.SN, "Dtumap_sn Get ", du.Info.Configs)
+				} else {
+					log.Println(dev.SN, "Dtumap_sn Get fail")
+				}*/
 				msg := dt.DtuRegistChanMsg{}
 				msg.Sn = dev.SN
 				msg.Value = cli
+				//basic.OnlineSN.Add(dev.SN, cli)
 				basic.TranSN <- msg //dev.SN
 			} else {
 				if tmp.FD.GetClientHost() != cli.FD.GetClientHost() {
@@ -158,15 +177,15 @@ func NewDownStreamService() {
 	})
 	server.OnNewMessage(func(c *tcpserver.Client, msg []byte) {
 		if cfg.ParamConf.Debug {
-			log.Println(c.GetClientHost(), " receive string:", string(msg))
-			log.Println(c.GetClientHost(), " receive byte:", msg)
+			//log.Println(c.GetClientHost(), "receive string:", string(msg))
+			log.Println(c.GetClientHost(), "receive byte:", msg)
 		}
 		res := dealDTUpack(c, msg)
 		if res.Sucess {
 			c.PutRawRes(msg)
 			//c.PutRestRes(res)
 		} else {
-			log.Println("is bin:", res.Message)
+			log.Println("is str:", string(msg))
 		}
 	})
 	server.OnClientConnectionClosed(func(c *tcpserver.Client, err error) {
@@ -179,5 +198,27 @@ func NewDownStreamService() {
 }
 
 func NewDownStreamServiceTLS() {
-
+	/*	server := tcpserver.NewWithTLS(fmt.Sprintf(":%d", cfg.ParamConf.PortCmd), "./certs/server.crt", "./certs/server.key") //"192.168.1.200:19999"
+		basic.Dtumap_state = dt.NewDMAP_ClientState()
+		//DevmapState = syncmap.New()
+		//m := syncmap.New()
+		//m.Set("one", "")
+		basic.IPMapSN = dt.NewDMAP_StringKV()
+		//go Dtumap_state.HeartBeat(300)
+		server.OnNewClient(func(c *tcpserver.Client) {
+			log.Println(c.GetClientHost())
+		})
+		server.OnNewMessage(func(c *tcpserver.Client, msg []byte) {
+			if cfg.ParamConf.Debug {
+				log.Println("receive:", string(msg))
+			}
+			res := dealDTUpack(c, msg)
+			if res.Sucess {
+				c.PutRestRes(res)
+			}
+		})
+		server.OnClientConnectionClosed(func(c *tcpserver.Client, err error) {
+			dealDTUdisconnect(c)
+		})
+		server.Listen()*/
 }

+ 11 - 0
SERVER/Lamp_Server/src/entry.go

@@ -14,9 +14,13 @@ import (
 	"syscall"
 	"time"
 
+	//_ "hello/forwardmode"
 	fwd "hello/forwardmode"
 	"log"
 	"os"
+	//"github.com/goburrow/modbus"
+	//	crypto "github.com/fatedier/golib/crypto"
+	//_ "github.com/go-sql-driver/mysql"
 )
 
 func Entry() {
@@ -38,9 +42,15 @@ func Entry() {
 		return
 	}
 	fwd.MeterProtocolInit()
+	// if cfg.ParamConf.Type == 4010 {
+	// 	go func() {
+	// 		log.Println(http.ListenAndServe(":30040", nil))
+	// 	}()
+	// }
 	if model.NewModelDTU() {
 		go dwt.NewDownStreamService()
 		go router.RouterJWT()
+		//go router.RouterJWTUpGrade()
 	} else {
 		err = errors.New("open db fail")
 		return
@@ -56,4 +66,5 @@ func Entry() {
 	for {
 		time.Sleep(5 * time.Minute)
 	}
+
 }

+ 638 - 0
SERVER/Lamp_Server/src/forwardmode/adw300_tables.go

@@ -0,0 +1,638 @@
+// hello
+package forwardmode
+
+import (
+	"encoding/json"
+	"fmt"
+	"hello/basic"
+	dt "hello/datastruct"
+	"log"
+)
+
+type adw300Packager struct {
+	name string
+}
+
+var (
+	meter_of_adw300 = []holdRegsData{
+		{regs: holdRegsDataUnit{0x0E, 56}, method: parse_04_56},
+		//regs: holdRegsDataUnit{0x0E, 23}, method: parse_0e_23},
+		//{regs: holdRegsDataUnit{0x26, 31}, method: parse_26_31},
+		{regs: holdRegsDataUnit{0x12E, 12}, method: parse_12E_12},
+		{regs: holdRegsDataUnit{0x7A, 60}, method: parse_7a_60},
+		{regs: holdRegsDataUnit{0xB6, 60}, method: parse_b6_60},
+		{regs: holdRegsDataUnit{0xF2, 60}, method: parse_f2_60},
+		{regs: holdRegsDataUnit{0x15A, 13}, method: parse_15a_13},
+	}
+)
+
+type ADW300Handler struct {
+	adw300Packager
+}
+
+func NewADW300Handler() *ADW300Handler {
+	handler := &ADW300Handler{}
+	handler.name = Meter_ADW300
+	return handler
+}
+
+func ADW300Client() MeterClient {
+	handler := NewADW300Handler()
+	return NewMeterClient(handler)
+}
+
+func (mb *adw300Packager) MeterName() (result string) {
+	result = mb.name
+	return
+}
+
+func (mb *adw300Packager) SetAddress(w RtuNetPgr, addr int) (result int) {
+	buf := []byte{}
+	buf = append(buf, basic.IntoByte(addr>>8))
+	buf = append(buf, basic.IntoByte(addr&0xFF))
+	if _, err := w.SetHoldingRegs(0, 1, buf); err != nil {
+		result = 4
+	} else {
+		result = 0
+	}
+	return
+}
+
+//查询电表变比
+func (mb *adw300Packager) QueryRatio(w RtuNetPgr) (data string, result int) {
+	pts := dt.MeterCTPT{}
+	if adu, err := w.GetHoldingRegs(0x0E, 2); err != nil {
+		result = 4
+	} else {
+		parse_ct_pt_regs(adu, &pts.Pt, &pts.Ct)
+		data = dt.JsonToString(pts)
+		result = 0
+	}
+	return
+}
+
+//设置电表变比
+func (mb *adw300Packager) SetRatio(w RtuNetPgr, data string) (result int) {
+	m := dt.MeterCTPT{}
+	if err := json.Unmarshal([]byte(data), &m); err != nil {
+		result = 7 //数据格式错误
+		return
+	}
+	buf := []byte{}
+	{
+		k := hfword2byte(m.Pt)
+		buf = append(buf, k...)
+	}
+	{
+		k := hfword2byte(m.Ct)
+		buf = append(buf, k...)
+	}
+	// buf = append(buf, basic.IntoByte(m.Pt>>8))
+	// buf = append(buf, basic.IntoByte(m.Pt&0xFF))
+	// buf = append(buf, basic.IntoByte(m.Ct>>8))
+	// buf = append(buf, basic.IntoByte(m.Ct&0xFF))
+	if _, err := w.SetHoldingRegs(0x0E, 2, buf); err != nil {
+		result = 4
+	} else {
+		result = 0
+		//log.Println("API_SetMeterRatio Rcv:", adu)
+	}
+	return
+}
+
+func (mb *adw300Packager) QueryElectricData(w RtuNetPgr, vref MeterVoltRef) (state basic.ElectDataFront) {
+	if k, err := mb.Query(w, vref); err != nil {
+		state.Result = 4
+	} else {
+		basic.Usrpower2Electdata(&k, &state)
+		state.Result = 0
+	}
+	return
+}
+
+func (mb *adw300Packager) Query(w RtuNetPgr, ref MeterVoltRef) (pm basic.USRPower_K, err error) {
+	var adu []byte
+	defer func() {
+		if r := recover(); r != nil {
+			log.Println(r)
+			err = fmt.Errorf("panic: %v", r)
+		}
+	}()
+	for _, v := range meter_of_adw300 {
+		if adu, err = w.GetHoldingRegs(v.regs.Origin, v.regs.Amount); err == nil {
+			v.method(adu, &pm, ref)
+		} else {
+			return
+		}
+	}
+	return
+}
+
+/*
+func read_adw300_meter(w RtuNetPgr, ref MeterVoltRef) (pm basic.USRPower_K, err error) {
+	var adu []byte
+	for _, v := range meter_of_adw300 {
+		if adu, err = w.GetHoldingRegs(v.regs.Origin, v.regs.Amount); err != nil {
+			return
+		} else {
+			v.method(adu, &pm, ref)
+		}
+	}
+	return
+}*/
+
+func parse_ct_pt_regs(adu []byte, pt *int, ct *int) {
+	index := 0
+	m := int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	*pt = int(m)
+	index += 2
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	*ct = int(m)
+}
+
+func parse_15a_13(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+		u     int32
+	)
+	s := meth.(*basic.USRPower_K)
+	//当前正向有功需量
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Dp = float32(int32(u)) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//当前反向有功需量
+	index += 4
+	//当前正向无功需量
+	index += 4
+	//当前反向无功需量
+	index += 4
+	//电压不平衡度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Unbalance = float32(m) * float32(0.01)
+	index += 2
+	//电流不平衡度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Inbalance = float32(m) * float32(0.01)
+	index += 2
+	//A相温度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Tempture[0] = float32(m) * float32(0.1)
+	index += 2
+	//B相温度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Tempture[1] = float32(m) * float32(0.1)
+	index += 2
+	//C相温度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Tempture[2] = float32(m) * float32(0.1)
+	index += 2
+}
+
+func parse_04_56(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+		u     int32
+	)
+	vf := ext.(MeterVoltRef)
+	s := meth.(*basic.USRPower_K)
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.PT = int(m)
+	index += 2
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.CT = int(m)
+	index += 2
+	//N相温度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Tempture[3] = float32(m) * float32(0.1)
+	index += 2
+	index += 6
+	//A相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ua = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//B相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ub = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//C相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Uc = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//AB线电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Uab = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//BC线电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ubc = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//CA相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Uca = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+
+	//A相电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ia = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//B相电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ib = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//C相电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ic = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//三相电流矢量和
+	index += 2
+
+	//A相有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Pa = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//B相有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Pb = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//C相有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Pc = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//总有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.P = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+
+	//A相无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Qa = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//B相无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Qb = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//C相无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Qc = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//总无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Q = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+
+	//A相视在功率
+	index += 4
+	//B相视在功率
+	index += 4
+	//C相视在功率
+	index += 4
+	//总视在功率
+	index += 4
+
+	//A相功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pfa = float32(m) * float32(0.001)
+	index += 2
+	//B相功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pfb = float32(m) * float32(0.001)
+	index += 2
+	//C相功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pfc = float32(m) * float32(0.001)
+	index += 2
+	//总功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pf = float32(m) * float32(0.001)
+	index += 2
+	//DI
+	index += 2
+	//频率
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Freq = float32(m) * float32(0.01)
+	index += 2
+	//组合有功总电能
+	index += 4
+	//正向有功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Tps = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//反向有功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Fps = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//正向无功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Tqs = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//反向无功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Fqs = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+
+	s.Fw = s.Freq - float32(50.0)
+	s.Uaw = (s.Ua - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Ubw = (s.Ub - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Ucw = (s.Uc - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Uabw = (s.Uab - vf.Lvref) * float32(100.0) / vf.Lvref
+	s.Ubcw = (s.Ubc - vf.Lvref) * float32(100.0) / vf.Lvref
+	s.Ucaw = (s.Uca - vf.Lvref) * float32(100.0) / vf.Lvref
+}
+
+func parse_0e_23(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+		u     int32
+	)
+	s := meth.(*basic.USRPower_K)
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.PT = int(m)
+	index += 2
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.CT = int(m)
+	index += 2
+	//N相温度
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Tempture[3] = float32(m) * float32(0.1)
+	index += 2
+	index += 6
+	//A相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ua = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//B相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ub = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//C相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Uc = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//AB线电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Uab = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//BC线电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ubc = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//CA相电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Uca = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+
+	//A相电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ia = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//B相电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ib = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//C相电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Ic = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//三相电流矢量和
+	index += 2
+
+	//A相有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Pa = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//B相有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Pb = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//C相有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Pc = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//总有功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.P = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+}
+
+func parse_26_31(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+		u     int32
+	)
+	vf := ext.(MeterVoltRef)
+	s := meth.(*basic.USRPower_K)
+
+	//A相无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Qa = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//B相无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Qb = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//C相无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Qc = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//总无功功率
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Q = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
+	index += 4
+
+	//A相视在功率
+	index += 4
+	//B相视在功率
+	index += 4
+	//C相视在功率
+	index += 4
+	//总视在功率
+	index += 4
+
+	//A相功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pfa = float32(m) * float32(0.001)
+	index += 2
+	//B相功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pfb = float32(m) * float32(0.001)
+	index += 2
+	//C相功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pfc = float32(m) * float32(0.001)
+	index += 2
+	//总功率因数
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Pf = float32(m) * float32(0.001)
+	index += 2
+	//DI
+	index += 2
+	//频率
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Freq = float32(m) * float32(0.01)
+	index += 2
+	//组合有功总电能
+	index += 4
+	//正向有功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Tps = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//反向有功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Fps = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//正向无功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Tqs = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+	//反向无功电能
+	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Fqs = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
+	index += 4
+
+	s.Fw = s.Freq - float32(50.0)
+	s.Uaw = (s.Ua - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Ubw = (s.Ub - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Ucw = (s.Uc - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Uabw = (s.Uab - vf.Lvref) * float32(100.0) / vf.Lvref
+	s.Ubcw = (s.Ubc - vf.Lvref) * float32(100.0) / vf.Lvref
+	s.Ucaw = (s.Uca - vf.Lvref) * float32(100.0) / vf.Lvref
+}
+
+//0x12E,12
+//基波、谐波
+func parse_12E_12(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+	)
+	s := meth.(*basic.USRPower_K)
+	//A相基波电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Baseua = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//B相基波电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Baseub = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//C相基波电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Baseuc = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+
+	//A相谐波电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Harua = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//B相谐波电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Harub = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+	//C相谐波电压
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Haruc = float32(m) * float32(0.1) * float32(s.PT)
+	index += 2
+
+	//A相基波电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Baseia = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//B相基波电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Baseib = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+	//C相基波电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Baseic = float32(m) * float32(0.01) * float32(s.CT)
+	index += 2
+
+	//A相谐波电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Haria = float32(m) * float32(0.1) * float32(s.CT)
+	index += 2
+	//B相谐波电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Harib = float32(m) * float32(0.1) * float32(s.CT)
+	index += 2
+	//C相谐波电流
+	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+	s.Haric = float32(m) * float32(0.1) * float32(s.CT)
+	index += 2
+}
+
+//0x7A,60
+//A相电压分次谐波(2-31次)
+//B相电压分次谐波(2-31次)
+func parse_7a_60(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+	)
+	s := meth.(*basic.USRPower_K)
+	//A相电压分次谐波(2-31次)
+	index = 2
+	for i := 0; i < 15; i++ {
+		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+		s.Hua[i] = float32(m) * float32(0.01)
+		index += 4
+	}
+	//B相电压分次谐波(2-31次)
+	index = 2*30 + 2
+	for i := 0; i < 15; i++ {
+		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+		s.Hub[i] = float32(m) * float32(0.01)
+		index += 4
+	}
+}
+
+//0xB6,60
+//C相电压分次谐波(2-31次)
+//A相电流分次谐波(2-31次)
+func parse_b6_60(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+	)
+	s := meth.(*basic.USRPower_K)
+	//C相电压分次谐波(2-31次)
+	index = 2
+	for i := 0; i < 15; i++ {
+		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+		s.Huc[i] = float32(m) * float32(0.01)
+		index += 4
+	}
+	//A相电流分次谐波(2-31次)
+	index = 2*30 + 2
+	for i := 0; i < 15; i++ {
+		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+		s.Hia[i] = float32(m) * float32(0.01)
+		index += 4
+	}
+}
+
+//0xF2,60
+//B相电流分次谐波(2-31次)
+//C相电流分次谐波(2-31次)
+func parse_f2_60(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
+	var (
+		index = 0
+		m     int16
+	)
+	s := meth.(*basic.USRPower_K)
+	//B相电流分次谐波(2-31次)
+	index = 2
+	for i := 0; i < 15; i++ {
+		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+		s.Hub[i] = float32(m) * float32(0.01)
+		index += 4
+	}
+	//C相电流分次谐波(2-31次)
+	index = 2*30 + 2
+	for i := 0; i < 15; i++ {
+		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
+		s.Hic[i] = float32(m) * float32(0.01)
+		index += 4
+	}
+}

+ 448 - 554
SERVER/Lamp_Server/src/forwardmode/forwardmode.go

@@ -15,425 +15,104 @@ type MeterVoltRef struct {
 	Lvref float32
 }
 
-var (
-	meterProt = make([]string, 0) //电表协议列表
-	platProt  = make([]string, 0) //上报协议列表
-)
-
-//
-func MeterProtocolInit() {
-	//在这里添加支持的电表协议列表
-	meterProt = append(meterProt, "ADW300")
-
-	//在这里添加支持的上报协议列表
-	platProt = append(platProt, "YC-HJ212")
+type holdRegsDataUnit struct {
+	Origin uint16 //起始地址
+	Amount uint16 //寄存器数量
 }
 
-//获取电表协议列表
-func GetMeterProtList() []string {
-	return meterProt
-}
+type parseMethod func([]byte, interface{}, interface{})
 
-//获取上报协议列表
-func GetPlatProtList() []string {
-	return platProt
+type holdRegsData struct {
+	regs   holdRegsDataUnit
+	method parseMethod
 }
 
-func makeQN() string {
-	t := time.Now()
-	r := t.Format("20060102150405")
-	return r + "000"
+type MethodMeter interface {
+	MeterName() string
+	SetAddress(w RtuNetPgr, addr int) int
+	QueryRatio(w RtuNetPgr) (string, int)
+	SetRatio(w RtuNetPgr, data string) int
+	QueryElectricData(w RtuNetPgr, vref MeterVoltRef) basic.ElectDataFront
+	Query(w RtuNetPgr, ref MeterVoltRef) (basic.USRPower_K, error)
 }
 
-func parse_15a_13(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
-	var (
-		index = 0
-		m     int16
-		u     int32
-	)
-	s := meth.(*basic.USRPower_K)
-	//当前正向有功需量
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Dp = float32(int32(u)) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//当前反向有功需量
-	index += 4
-	//当前正向无功需量
-	index += 4
-	//当前反向无功需量
-	index += 4
-	//电压不平衡度
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Unbalance = float32(m) * float32(0.01)
-	index += 2
-	//电流不平衡度
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Inbalance = float32(m) * float32(0.01)
-	index += 2
-	//A相温度
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Tempture[0] = float32(m) * float32(0.1)
-	index += 2
-	//B相温度
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Tempture[1] = float32(m) * float32(0.1)
-	index += 2
-	//C相温度
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Tempture[2] = float32(m) * float32(0.1)
-	index += 2
+type MeterClientHandler interface {
+	MethodMeter
 }
 
-func parse_04_56(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
-	var (
-		index = 0
-		m     int16
-		u     int32
-	)
-	vf := ext.(MeterVoltRef)
-	s := meth.(*basic.USRPower_K)
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.PT = int(m)
-	index += 2
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.CT = int(m)
-	index += 2
-	//N相温度
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Tempture[3] = float32(m) * float32(0.1)
-	index += 2
-	index += 6
-	//A相电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Ua = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//B相电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Ub = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//C相电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Uc = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//AB线电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Uab = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//BC线电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Ubc = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//CA相电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Uca = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-
-	//A相电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Ia = float32(m) * float32(0.01) * float32(s.CT)
-	index += 2
-	//B相电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Ib = float32(m) * float32(0.01) * float32(s.CT)
-	index += 2
-	//C相电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Ic = float32(m) * float32(0.01) * float32(s.CT)
-	index += 2
-	//三相电流矢量和
-	index += 2
-
-	//A相有功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Pa = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//B相有功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Pb = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//C相有功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Pc = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//总有功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.P = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-
-	//A相无功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Qa = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//B相无功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Qb = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//C相无功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Qc = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//总无功功率
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Q = float32(u) * float32(0.001) * float32(s.CT) * float32(s.PT)
-	index += 4
-
-	//A相视在功率
-	index += 4
-	//B相视在功率
-	index += 4
-	//C相视在功率
-	index += 4
-	//总视在功率
-	index += 4
-
-	//A相功率因数
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Pfa = float32(m) * float32(0.001)
-	index += 2
-	//B相功率因数
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Pfb = float32(m) * float32(0.001)
-	index += 2
-	//C相功率因数
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Pfc = float32(m) * float32(0.001)
-	index += 2
-	//总功率因数
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Pf = float32(m) * float32(0.001)
-	index += 2
-	//DI
-	index += 2
-	//频率
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Freq = float32(m) * float32(0.01)
-	index += 2
-	//组合有功总电能
-	index += 4
-	//正向有功电能
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Tps = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//反向有功电能
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Fps = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//正向无功电能
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Tqs = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
-	index += 4
-	//反向无功电能
-	u = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-	s.Fqs = float32(u) * float32(0.01) * float32(s.CT) * float32(s.PT)
-	index += 4
-
-	s.Fw = s.Freq - float32(50.0)
-	s.Uaw = (s.Ua - vf.Pvref) * float32(100.0) / vf.Pvref
-	s.Ubw = (s.Ub - vf.Pvref) * float32(100.0) / vf.Pvref
-	s.Ucw = (s.Uc - vf.Pvref) * float32(100.0) / vf.Pvref
-	s.Uabw = (s.Uab - vf.Lvref) * float32(100.0) / vf.Lvref
-	s.Ubcw = (s.Ubc - vf.Lvref) * float32(100.0) / vf.Lvref
-	s.Ucaw = (s.Uca - vf.Lvref) * float32(100.0) / vf.Lvref
+type MeterClient struct {
+	Manner MethodMeter
 }
 
-//0x12E,12
-//基波、谐波
-func parse_12E_12(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
-	var (
-		index = 0
-		m     int16
-	)
-	s := meth.(*basic.USRPower_K)
-	//A相基波电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Baseua = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//B相基波电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Baseub = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//C相基波电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Baseuc = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-
-	//A相谐波电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Harua = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//B相谐波电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Harub = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
-	//C相谐波电压
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Haruc = float32(m) * float32(0.1) * float32(s.PT)
-	index += 2
+var (
+	//meterProt = make([]string, 0) //电表协议列表
+	meterProt *dt.SliceLock
+	platProt  = make([]string, 0) //上报协议列表
+)
 
-	//A相基波电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Baseia = float32(m) * float32(0.01) * float32(s.CT)
-	index += 2
-	//B相基波电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Baseib = float32(m) * float32(0.01) * float32(s.CT)
-	index += 2
-	//C相基波电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Baseic = float32(m) * float32(0.01) * float32(s.CT)
-	index += 2
+func hfword2byte(obj int) (slice []byte) {
+	slice = append(slice, basic.IntoByte(obj>>8))
+	slice = append(slice, basic.IntoByte(obj&0xFF))
+	return
+}
 
-	//A相谐波电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Haria = float32(m) * float32(0.1) * float32(s.CT)
-	index += 2
-	//B相谐波电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Harib = float32(m) * float32(0.1) * float32(s.CT)
-	index += 2
-	//C相谐波电流
-	m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-	s.Haric = float32(m) * float32(0.1) * float32(s.CT)
-	index += 2
+func word2byte(obj int) (slice []byte) {
+	slice = append(slice, basic.IntoByte(obj>>24))
+	slice = append(slice, basic.IntoByte(obj>>16))
+	slice = append(slice, basic.IntoByte(obj>>8))
+	slice = append(slice, basic.IntoByte(obj&0xFF))
+	return
 }
 
-//0x7A,60
-//A相电压分次谐波(2-31次)
-//B相电压分次谐波(2-31次)
-func parse_7a_60(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
-	var (
-		index = 0
-		m     int16
-	)
-	s := meth.(*basic.USRPower_K)
-	//A相电压分次谐波(2-31次)
-	index = 2
-	for i := 0; i < 15; i++ {
-		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		s.Hua[i] = float32(m) * float32(0.01)
-		index += 4
-	}
-	//B相电压分次谐波(2-31次)
-	index = 2*30 + 2
-	for i := 0; i < 15; i++ {
-		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		s.Hub[i] = float32(m) * float32(0.01)
-		index += 4
-	}
+func NewMeterClient(handler MeterClientHandler) MeterClient {
+	return MeterClient{Manner: handler}
 }
 
-//0xB6,60
-//C相电压分次谐波(2-31次)
-//A相电流分次谐波(2-31次)
-func parse_b6_60(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
-	var (
-		index = 0
-		m     int16
-	)
-	s := meth.(*basic.USRPower_K)
-	//C相电压分次谐波(2-31次)
-	index = 2
-	for i := 0; i < 15; i++ {
-		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		s.Huc[i] = float32(m) * float32(0.01)
-		index += 4
-	}
-	//A相电流分次谐波(2-31次)
-	index = 2*30 + 2
-	for i := 0; i < 15; i++ {
-		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		s.Hia[i] = float32(m) * float32(0.01)
-		index += 4
-	}
+//
+func MeterProtocolInit() {
+	//在这里添加支持的电表协议列表
+	meterProt = dt.NewSliceLock()
+	meterProt.Add(Meter_ADW300)
+	meterProt.Add(Meter_PMC350B)
+	//meterProt = append(meterProt, Meter_ADW300)
+	//meterProt = append(meterProt, Meter_PMC350B)
+
+	//在这里添加支持的上报协议列表
+	platProt = append(platProt, Plat_YC_HJ212)
 }
 
-//0xF2,60
-//B相电流分次谐波(2-31次)
-//C相电流分次谐波(2-31次)
-func parse_f2_60(adu []byte, meth interface{}, ext interface{}) { //s *USRPower_K) {
-	var (
-		index = 0
-		m     int16
-	)
-	s := meth.(*basic.USRPower_K)
-	//B相电流分次谐波(2-31次)
-	index = 2
-	for i := 0; i < 15; i++ {
-		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		s.Hub[i] = float32(m) * float32(0.01)
-		index += 4
-	}
-	//C相电流分次谐波(2-31次)
-	index = 2*30 + 2
-	for i := 0; i < 15; i++ {
-		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		s.Hic[i] = float32(m) * float32(0.01)
-		index += 4
+//获取电表协议列表
+func GetMeterProtList() []string {
+	list := make([]string, 0)
+	if meterProt != nil {
+		sl := meterProt.All()
+		if len(sl) > 0 {
+			for _, v := range sl {
+				list = append(list, v.(string))
+			}
+		}
 	}
+	return list
 }
 
-type holdRegsDataUnit struct {
-	Origin uint16 //起始地址
-	Amount uint16 //寄存器数量
+//判断电表协议合法
+func VerifyMeterProt(val string) (result bool) {
+	result = false
+	if meterProt != nil {
+		result = meterProt.Exist(val)
+	}
+	return
 }
 
-type parseMethod func([]byte, interface{}, interface{})
-
-type holdRegsData struct {
-	regs   holdRegsDataUnit
-	method parseMethod
+//获取上报协议列表
+func GetPlatProtList() []string {
+	return platProt
 }
 
-var (
-	meter_of_adw300 = []holdRegsData{
-		{regs: holdRegsDataUnit{0x0E, 56}, method: parse_04_56},
-		{regs: holdRegsDataUnit{0x12E, 12}, method: parse_12E_12},
-		{regs: holdRegsDataUnit{0x7A, 60}, method: parse_7a_60},
-		{regs: holdRegsDataUnit{0xB6, 60}, method: parse_b6_60},
-		{regs: holdRegsDataUnit{0xF2, 60}, method: parse_f2_60},
-		{regs: holdRegsDataUnit{0x15A, 13}, method: parse_15a_13},
-	}
-)
-
-func read_adw300_meter(w RtuNetPgr, ref MeterVoltRef) (pm basic.USRPower_K, err error) {
-	var adu []byte
-	for _, v := range meter_of_adw300 {
-		if adu, err = w.GetHoldingRegs(v.regs.Origin, v.regs.Amount); err != nil {
-			return
-		} else {
-			v.method(adu, &pm, ref)
-		}
-	}
-	/*
-		if adu, err = w.GetHoldingRegs(0x0E, 56); err != nil {
-			return
-		}
-		parse_04_56(adu, &pm)
-		//
-		if adu, err = w.GetHoldingRegs(0x12E, 12); err != nil {
-			return
-		}
-		parse_12E_12(adu, &pm)
-		//
-		if adu, err = w.GetHoldingRegs(0x7A, 60); err != nil {
-			return
-		}
-		parse_7a_60(adu, &pm)
-		//
-		if adu, err = w.GetHoldingRegs(0xB6, 60); err != nil {
-			return
-		}
-		parse_b6_60(adu, &pm)
-		//
-		if adu, err = w.GetHoldingRegs(0xF2, 60); err != nil {
-			return
-		}
-		parse_f2_60(adu, &pm)
-		if adu, err = w.GetHoldingRegs(0x162, 5); err != nil {
-			return
-		}
-		parse_162_5(adu, &pm)*/
-	return
+func makeQN() string {
+	t := time.Now()
+	r := t.Format("20060102150405")
+	return r + "000"
 }
 
 func calc_fps_origin(val, origin float32) (result float32) {
@@ -520,9 +199,274 @@ func Record_meter_data(bmyz string, cal dt.CalcMeterParm) error {
 	return connsql.Record_InsertElectricity(v)
 }
 
+//设置电表地址
+func API_SetMeterAddress(cpid string, value dt.SetMeterAddressRes) (state dt.SetMeterRatioReply) {
+	state.Result = 0
+	mtype := value.Type
+	mclient := MeterClient{}
+	if !VerifyMeterProt(mtype) {
+		state.Result = 5 //协议不支持
+		return
+	}
+	//有电表协议
+	hasprot := true
+	address := basic.IntoByte(value.AddrOld)
+	if address < 1 || address > 254 || value.AddrNew < 1 || value.AddrNew > 254 {
+		state.Result = 3
+		return
+	}
+	if value.AddrNew == value.AddrOld {
+		return
+	}
+	client, ok := basic.Dtumap_state.Get(cpid)
+	if !ok {
+		state.Result = 1
+		return
+	}
+	if !client.Online {
+		state.Result = 2
+		return
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	w := NewRtuNetPgr(address)
+	w.SetClientState(&client)
+	w.SetSerialNumber(cpid)
+	// if value.Type == Meter_ADW300 {
+	// 	buf = append(buf, basic.IntoByte(value.AddrNew>>8))
+	// 	buf = append(buf, basic.IntoByte(value.AddrNew&0xFF))
+	// 	if _, err := w.SetHoldingRegs(0, 1, buf); err != nil {
+	// 		state.Result = 4
+	// 	} else {
+	// 		state.Result = 0
+	// 		//log.Println("API_SetMeterRatio Rcv:", adu)
+	// 	}
+	// 	return
+	// }
+	//电表协议判断
+	switch mtype {
+	case Meter_ADW300:
+		mclient = ADW300Client()
+	case Meter_PMC350B:
+		mclient = PMC350BClient()
+	default:
+		hasprot = false
+	}
+	if hasprot {
+		state.Result = mclient.Manner.SetAddress(w, value.AddrNew)
+		return
+	}
+	state.Result = 5 //协议不支持
+	return
+}
+
+type tmpNofmt struct {
+	fmt interface{}
+}
+
+//设置电表变比
+func API_SetMeterRatio(cpid string, value dt.SetMeterRatioRes) (state dt.SetMeterRatioReply) {
+	state.Result = 0
+	mclient := MeterClient{}
+	mtype := value.Type
+	//有电表协议
+	hasprot := true
+	if !VerifyMeterProt(mtype) {
+		state.Result = 5 //协议不支持
+		return
+	}
+	address := basic.IntoByte(value.Addr)
+	if address < 1 || address > 254 {
+		state.Result = 3
+		return
+	}
+	client, ok := basic.Dtumap_state.Get(cpid)
+	if !ok {
+		state.Result = 1
+		return
+	}
+	if !client.Online {
+		state.Result = 2
+		return
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	w := NewRtuNetPgr(address)
+	w.SetClientState(&client)
+	w.SetSerialNumber(cpid)
+	/*if value.Type == Meter_ADW300 {
+		buf = append(buf, basic.IntoByte(value.Pt>>8))
+		buf = append(buf, basic.IntoByte(value.Pt&0xFF))
+		buf = append(buf, basic.IntoByte(value.Ct>>8))
+		buf = append(buf, basic.IntoByte(value.Ct&0xFF))
+		if adu, err := w.SetHoldingRegs(0x0E, 2, buf); err != nil {
+			state.Result = 4
+		} else {
+			state.Result = 0
+			//log.Println("API_SetMeterRatio Rcv:", adu)
+		}
+		return
+	}*/
+	//vars := tmpNofmt{}
+	//电表协议判断
+	switch mtype {
+	case Meter_ADW300:
+		mclient = ADW300Client()
+	case Meter_PMC350B:
+		mclient = PMC350BClient()
+		/*pm := dt.MeterPMC350BParam{}
+		if err := json.Unmarshal([]byte(value.SerData), &pm); err != nil {
+			state.Result = 7 //数据格式错误
+			return
+		}
+		ops = pm*/
+	default:
+		hasprot = false
+	}
+	if hasprot {
+		state.Result = mclient.Manner.SetRatio(w, value.SerData)
+		return
+	}
+	state.Result = 5 //协议不支持
+	return
+}
+
+//查询电力数据
+func API_QueryElectricData(cpid string, addr int, mtype string) (state basic.ElectDataFront) {
+	state.Result = 0
+	mclient := MeterClient{}
+	//有电表协议
+	hasprot := true
+	if !VerifyMeterProt(mtype) {
+		state.Result = 5 //协议不支持
+		return
+	}
+	address := basic.IntoByte(addr)
+	vref := MeterVoltRef{}
+	if address < 1 || address > 254 {
+		state.Result = 3
+		return
+	}
+	client, ok := basic.Dtumap_state.Get(cpid)
+	if !ok {
+		state.Result = 1
+		return
+	}
+	if !client.Online {
+		state.Result = 2
+		return
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	w := NewRtuNetPgr(address)
+	w.SetClientState(&client)
+	w.SetSerialNumber(cpid)
+	vref.Lvref = float32(380)
+	vref.Pvref = float32(220)
+	/*if mtype == Meter_ADW300 {
+		if k, err := read_adw300_meter(w, vref); err != nil {
+			state.Result = 4
+			return
+		} else {
+			state.Result = 0
+			basic.Usrpower2Electdata(&k, &state)
+		}
+		return
+	}*/
+	//电表协议判断
+	switch mtype {
+	case Meter_ADW300:
+		mclient = ADW300Client()
+	case Meter_PMC350B:
+		mclient = PMC350BClient()
+	default:
+		hasprot = false
+	}
+	if hasprot {
+		state = mclient.Manner.QueryElectricData(w, vref)
+		return
+	}
+	state.Result = 5 //协议不支持
+	return
+}
+
+//查询电表变比
+func API_QueryMeterRatio(cpid string, addr int, mtype string) (state dt.GetMeterRatioRes) {
+	state.Result = 0
+	mclient := MeterClient{}
+	//有电表协议
+	hasprot := true
+	if !VerifyMeterProt(mtype) {
+		state.Result = 5 //协议不支持
+		return
+	}
+	address := basic.IntoByte(addr)
+	if address < 1 || address > 254 {
+		state.Result = 3
+		return
+	}
+	client, ok := basic.Dtumap_state.Get(cpid)
+	if !ok {
+		state.Result = 1
+		return
+	}
+	if !client.Online {
+		state.Result = 2
+		return
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	w := NewRtuNetPgr(address)
+	w.SetClientState(&client)
+	w.SetSerialNumber(cpid)
+	// if mtype == Meter_ADW300 {
+	// 	if adu, err := w.GetHoldingRegs(0x0E, 2); err != nil {
+	// 		state.Result = 4
+	// 		return
+	// 	} else {
+	// 		parse_ct_pt_regs(adu, &state.Pt, &state.Ct)
+	// 		state.Result = 0
+	// 	}
+	// 	return
+	// }
+	//电表协议判断
+	switch mtype {
+	case Meter_ADW300:
+		mclient = ADW300Client()
+	case Meter_PMC350B:
+		mclient = PMC350BClient()
+	default:
+		hasprot = false
+	}
+	if hasprot {
+		state.SerData, state.Result = mclient.Manner.QueryRatio(w)
+		return
+	}
+	state.Result = 5 //协议不支持
+	return
+}
+
+func API_QueryDeviceStatus(cpid string) (state dt.RunStateDTU) {
+	//先查询列表是否存在
+	if x, ok := basic.DeviceStatus.Get(cpid); ok {
+		val := x.(dt.DeviceSampleCount)
+		for _, v := range val.Meter {
+			state.Meter = append(state.Meter, v)
+		}
+		for _, v := range val.Plat {
+			state.Plat = append(state.Plat, v)
+		}
+		state.Result = 0
+		return
+	}
+	state.Result = 1 //不存在
+	return
+}
+
 //采集并上报
 func CollectAndReport(cpid string, item dt.ConfigfsJSONItem) {
 	array := make([]basic.USRPower_K, 0)
+	mt_state := make(map[int]dt.MeterSampleCount)
 	vref := MeterVoltRef{}
 	info := item
 	calc := dt.CalcMeterParm{Init: 0}
@@ -546,20 +490,39 @@ func CollectAndReport(cpid string, item dt.ConfigfsJSONItem) {
 	}
 	client, ok := basic.Dtumap_state.Get(cpid)
 	if !ok {
-		log.Fatalln("Can't find ", cpid)
+		log.Println("Can't find ", cpid)
 		return
 	}
 	if !client.Online {
-		log.Fatalln(cpid, " is offline")
+		log.Println(cpid, " is offline")
 		return
 	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	//获取电表通信状态
+	if x, ok := basic.DeviceStatus.Get(cpid); ok {
+		if len(x.(dt.DeviceSampleCount).Meter) > 0 {
+			mt_state = x.(dt.DeviceSampleCount).Meter
+		}
+	}
 	for _, val := range info.Slave {
+		//var merror error
+		mtSample := dt.MeterSampleCount{
+			Sumcount: 0,
+			Sucess:   0,
+		}
+		mclient := MeterClient{}
+		//pm := basic.USRPower_K{}
 		baddr := basic.IntoByte(val.Addr)
 		w := NewRtuNetPgr(baddr)
+		isexist := false
 		//判断地址是否合法
 		if val.Addr < 1 || val.Addr > 254 {
 			continue
 		}
+		if v, r := mt_state[val.Addr]; r {
+			mtSample = v
+		}
 		w.SetClientState(&client)
 		w.SetSerialNumber(cpid)
 		vref.Lvref = float32(380)
@@ -570,23 +533,83 @@ func CollectAndReport(cpid string, item dt.ConfigfsJSONItem) {
 		if val.PVref > 0 {
 			vref.Pvref = float32(val.PVref)
 		}
+		//先查询参数列表是否存在
+		if x, ok := basic.CalcParam.Get(val.Bmyz); ok {
+			//存在则直接计算
+			calc = x.(dt.CalcMeterParm)
+			isexist = true
+		}
+		//有电表协议
+		hasprot := true
+		//电表协议判断
+		switch val.Mtype {
+		case Meter_ADW300:
+			mclient = ADW300Client()
+			//pm, merror = read_adw300_meter(w, vref)
+		case Meter_PMC350B:
+			mclient = PMC350BClient()
+		default:
+			hasprot = false
+		}
+		if hasprot {
+			if pm, err := mclient.Manner.Query(w, vref); err != nil {
+				log.Printf("read %s[%d] %s\n", val.Mtype, val.Addr, err.Error())
+			} else {
+				pm.Bmyz = val.Bmyz
+				pm.Cn = val.MCn
+				if !isexist {
+					log.Println("Meter", val.Addr, "CalcParam not exist")
+					//先初始化
+					calc.LRate.Count = 1
+					calc.LRate.MaxPower = pm.P
+					calc.LRate.SumPower = pm.P
+					//不存在则从数据库读取
+					if w, err := connsql.Record_Query_ByBmyz(val.Bmyz); err == nil {
+						if m, ok := connsql.Record_Calcute_Power(w, tms); ok {
+							calc.LRate = m
+						}
+						//计算起始电能
+						calc.OrginEnergy = connsql.Record_Calcute_Energy(w, tms)
+					} else {
+						log.Printf("Record_Query_ByBmyz:", err)
+						//数据库也没有则初始化
+						calc.OrginEnergy.Tps = pm.Tps
+						calc.OrginEnergy.Tqs = pm.Tqs
+						calc.OrginEnergy.Fps = pm.Fps
+						calc.OrginEnergy.Fqs = pm.Fqs
+					}
+				}
+				//计算负荷率
+				//calc_meter_loadrate(&calc.LRate, &k, tms)
+				//计算电量、负荷率
+				calc_meter_energy(&calc, &pm, tms)
+				if calc.Init != 1 {
+					calc.OrginEnergy = calc.LastEnergy
+				}
+				calc.Init = 1
+				calc.Time = tms
+				//插入电表数据
+				Record_meter_data(val.Bmyz, calc)
+				array = append(array, pm)
+				mtSample.Sucess++
+				mtSample.Lastime = time.Unix(tms, 0).Format("2006-01-02 15:04:05")
+				log.Println("Meter", val.Addr, "CalcParam", calc)
+				log.Println(val.Mtype, "[", val.Addr, "]CT=", pm.CT, ";PT=", pm.PT)
+				//info.Slave[i].Addr = 0 //读取成功的则地址清零
+			}
+			mtSample.Addr = val.Addr
+			mtSample.Sumcount++
+			mt_state[val.Addr] = mtSample
+			//插入参数计算列表
+			basic.CalcParam.Add(val.Bmyz, calc)
+		}
 		//电表协议判断
-		if val.Mtype == "ADW300" {
+		/*if val.Mtype == Meter_ADW300 {
 			if k, err := read_adw300_meter(w, vref); err != nil {
-				log.Println("read ADW300 fail")
-				log.Println(err.Error())
+				log.Printf("read ADW300[%d]:%s\n", val.Addr, err.Error())
 			} else {
 				k.Bmyz = val.Bmyz
-				// if err := Record_meter_data(&k, tms); err == nil {
-				// 	log.Println("Meter", val.Addr, "Record data ok")
-				// } else {
-				// 	log.Println("Meter", val.Addr, "Record data fail:", err)
-				// }
-				//先查询参数计算列表
-				if x, ok := basic.CalcParam.Get(val.Bmyz); ok {
-					//存在则直接计算
-					calc = x.(dt.CalcMeterParm)
-				} else {
+				if !isexist {
 					log.Println("Meter", val.Addr, "CalcParam not exist")
 					//先初始化
 					calc.LRate.Count = 1
@@ -600,6 +623,7 @@ func CollectAndReport(cpid string, item dt.ConfigfsJSONItem) {
 						//计算起始电能
 						calc.OrginEnergy = connsql.Record_Calcute_Energy(w, tms)
 					} else {
+						log.Printf("Record_Query_ByBmyz:", err)
 						//数据库也没有则初始化
 						calc.OrginEnergy.Tps = k.Tps
 						calc.OrginEnergy.Tqs = k.Tqs
@@ -619,162 +643,32 @@ func CollectAndReport(cpid string, item dt.ConfigfsJSONItem) {
 				//插入电表数据
 				Record_meter_data(val.Bmyz, calc)
 				array = append(array, k)
-				calc.MtSample.Sucess++
-				calc.MtSample.Lastime = time.Unix(tms, 0).Format("2006-01-02 15:04:05")
+				mtSample.Sucess++
+				mtSample.Lastime = time.Unix(tms, 0).Format("2006-01-02 15:04:05")
 				log.Println("Meter", val.Addr, "CalcParam", calc)
 				log.Println("ADW300[", val.Addr, "]CT=", k.CT, ";PT=", k.PT)
 				//info.Slave[i].Addr = 0 //读取成功的则地址清零
 			}
-			calc.MtSample.Addr = val.Addr
-			calc.MtSample.Sumcount++
+			mtSample.Addr = val.Addr
+			mtSample.Sumcount++
+			mt_state[val.Addr] = mtSample
 			//插入参数计算列表
 			basic.CalcParam.Add(val.Bmyz, calc)
+		}*/
+		if len(mt_state) > 0 {
+			calc := dt.DeviceSampleCount{}
+			if x, ok := basic.DeviceStatus.Get(cpid); ok {
+				calc = x.(dt.DeviceSampleCount)
+			}
+			calc.Meter = make(map[int]dt.MeterSampleCount)
+			calc.Meter = mt_state
+			basic.DeviceStatus.Add(cpid, calc)
 		}
 	}
 	if len(array) > 0 {
 		//上报协议判断
-		if info.Protocol == "YC-HJ212" {
-			go report_yc_hj212(plt, array)
-		}
-	}
-	/*for {
-		select {
-		case <-time.After(time.Second * 5):
-			if len(cpid) < 1 {
-				cpid = c.GetClientRegistID()
-				w.SetSerialNumber(cpid)
-				log.Println("TetMeter sn=", cpid)
-			} else {
-				if err := readADW300(w, pw); err != nil {
-					log.Println("TetMeter readADW300 fail")
-				}
-			}
-			// case <-out:
-			// 	log.Println("handleTaskTimer exit")
-			// 	return
-		}
-	}*/
-}
-
-/*
-//yc_hj212协议上报
-func report_yc_hj212(bs dt.HJBaseInfo, cs []USRPower_K) {
-	if ck, ok := pack_yc_hj212(bs, cs); ok {
-		for _, v := range ck {
-			receive, err := sendtoServer(bs.Host, bs.Port, v)
-			if err != nil {
-				log.Println("Send fail->", receive, ":", err)
-			} else {
-				log.Println("Send->", v)
-				log.Println("Receive<-", receive)
-			}
-		}
-	}
-}
-
-//yc_hj212温度数据打包
-func pack_yc_hj212_temp(val [8]float32) string {
-	ret := ""
-	for i, v := range val {
-		if i == 0 {
-			ret += "t=" + strconv.FormatFloat(float64(v), 'f', 3, 32) + "&"
-		} else {
-			ret += "t" + strconv.Itoa(i+1) + "=" +
-				strconv.FormatFloat(float64(v), 'f', 3, 32) + "&"
+		if info.Protocol == Plat_YC_HJ212 {
+			go report_yc_hj212(cpid, plt, array)
 		}
 	}
-	return ret
-}
-
-//yc_hj212电压谐波数据打包
-func pack_yc_hj212_hux(val [15]float32, hall, bu float32) string {
-	ret := ""
-	for i, v := range val {
-		ret += "h" + strconv.Itoa(i*2+3) + ":" +
-			strconv.FormatFloat(float64(v), 'f', 3, 32) + ","
-	}
-	ret += "hall:" + strconv.FormatFloat(float64(hall), 'f', 3, 32) +
-		",baseu:" + strconv.FormatFloat(float64(bu), 'f', 3, 32) + "&"
-	return ret
-}
-
-//yc_hj212电流谐波数据打包
-func pack_yc_hj212_hix(val [15]float32, hall, bu float32) string {
-	ret := ""
-	for i, v := range val {
-		ret += "h" + strconv.Itoa(i*2+3) + ":" +
-			strconv.FormatFloat(float64(v), 'f', 3, 32) + ","
-	}
-	ret += "hall:" + strconv.FormatFloat(float64(hall), 'f', 3, 32) +
-		",basei:" + strconv.FormatFloat(float64(bu), 'f', 3, 32) + "&"
-	return ret
-}
-
-//yc_hj212协议打包
-func pack_yc_hj212(bs dt.HJBaseInfo, array []USRPower_K) ([]string, bool) {
-	nt := time.Now()
-	//	var key [len(KeyHJ212)]string
-	//	var i int
-	arr := make([]string, 0)
-	if len(array) == 0 {
-		return arr, false
-	}
-	ntime := fmt.Sprintf("%04d%02d%02d%02d%02d00", nt.Year(), nt.Month(),
-		nt.Day(), nt.Hour(), nt.Minute())
-	for _, cs := range array {
-		body := "p=" + strconv.FormatFloat(float64(cs.P), 'f', 3, 32) + "&" +
-			"pa=" + strconv.FormatFloat(float64(cs.Pa), 'f', 3, 32) + "&" +
-			"pb=" + strconv.FormatFloat(float64(cs.Pb), 'f', 3, 32) + "&" +
-			"pc=" + strconv.FormatFloat(float64(cs.Pc), 'f', 3, 32) + "&" +
-			"q=" + strconv.FormatFloat(float64(cs.Q), 'f', 3, 32) + "&" +
-			"qa=" + strconv.FormatFloat(float64(cs.Qa), 'f', 3, 32) + "&" +
-			"qb=" + strconv.FormatFloat(float64(cs.Qb), 'f', 3, 32) + "&" +
-			"qc=" + strconv.FormatFloat(float64(cs.Qc), 'f', 3, 32) + "&" +
-			"pf=" + strconv.FormatFloat(float64(cs.Pf), 'f', 3, 32) + "&" +
-			"pfa=" + strconv.FormatFloat(float64(cs.Pfa), 'f', 3, 32) + "&" +
-			"pfb=" + strconv.FormatFloat(float64(cs.Pfb), 'f', 3, 32) + "&" +
-			"pfc=" + strconv.FormatFloat(float64(cs.Pfc), 'f', 3, 32) + "&" +
-			"ia=" + strconv.FormatFloat(float64(cs.Ia), 'f', 3, 32) + "&" +
-			"ib=" + strconv.FormatFloat(float64(cs.Ib), 'f', 3, 32) + "&" +
-			"ic=" + strconv.FormatFloat(float64(cs.Ic), 'f', 3, 32) + "&" +
-			"iz=" + strconv.FormatFloat(float64(cs.Iz), 'f', 3, 32) + "&" +
-			"ua=" + strconv.FormatFloat(float64(cs.Ua), 'f', 3, 32) + "&" +
-			"ub=" + strconv.FormatFloat(float64(cs.Ub), 'f', 3, 32) + "&" +
-			"uc=" + strconv.FormatFloat(float64(cs.Uc), 'f', 3, 32) + "&" +
-			"uab=" + strconv.FormatFloat(float64(cs.Uab), 'f', 3, 32) + "&" +
-			"ubc=" + strconv.FormatFloat(float64(cs.Ubc), 'f', 3, 32) + "&" +
-			"uca=" + strconv.FormatFloat(float64(cs.Uca), 'f', 3, 32) + "&" +
-			"pv=" + strconv.FormatFloat(float64(cs.Pv), 'f', 3, 32) + "&" +
-			"tps=" + strconv.FormatFloat(float64(cs.Tps), 'f', 3, 32) + "&" +
-			"tqs=" + strconv.FormatFloat(float64(cs.Tqs), 'f', 3, 32) + "&" +
-			"fps=" + strconv.FormatFloat(float64(cs.Fps), 'f', 3, 32) + "&" +
-			"fqs=" + strconv.FormatFloat(float64(cs.Fqs), 'f', 3, 32) + "&" +
-			"tpe=" + strconv.FormatFloat(float64(cs.Tpe), 'f', 3, 32) + "&" +
-			"tqe=" + strconv.FormatFloat(float64(cs.Tqe), 'f', 3, 32) + "&" +
-			"fpe=" + strconv.FormatFloat(float64(cs.Fpe), 'f', 3, 32) + "&" +
-			"fqe=" + strconv.FormatFloat(float64(cs.Fqe), 'f', 3, 32) + "&" +
-			"uaw=" + strconv.FormatFloat(float64(cs.Uaw), 'f', 3, 32) + "&" +
-			"ubw=" + strconv.FormatFloat(float64(cs.Ubw), 'f', 3, 32) + "&" +
-			"ucw=" + strconv.FormatFloat(float64(cs.Ucw), 'f', 3, 32) + "&" +
-			"uabw=" + strconv.FormatFloat(float64(cs.Uabw), 'f', 3, 32) + "&" +
-			"ubcw=" + strconv.FormatFloat(float64(cs.Ubcw), 'f', 3, 32) + "&" +
-			"ucaw=" + strconv.FormatFloat(float64(cs.Ucaw), 'f', 3, 32) + "&" +
-			"inbalance=" + strconv.FormatFloat(float64(cs.Inbalance), 'f', 3, 32) + "&" +
-			"unbalance=" + strconv.FormatFloat(float64(cs.Unbalance), 'f', 3, 32) + "&"
-
-		body += pack_yc_hj212_temp(cs.Tempture)
-		body += "hua=" + pack_yc_hj212_hux(cs.Hua, cs.Harua, cs.Baseua)
-		body += "hub=" + pack_yc_hj212_hux(cs.Hub, cs.Harub, cs.Baseub)
-		body += "huc=" + pack_yc_hj212_hux(cs.Huc, cs.Haruc, cs.Baseuc)
-		body += "hia=" + pack_yc_hj212_hix(cs.Hia, cs.Haria, cs.Baseia)
-		body += "hib=" + pack_yc_hj212_hix(cs.Hib, cs.Harib, cs.Baseib)
-		body += "hic=" + pack_yc_hj212_hix(cs.Hic, cs.Haric, cs.Baseic)
-		loader := "st=" + bs.ST + ";cn=" + bs.CN +
-			";datatime=" + ntime + ";cphh=&&tid=" + cs.Bmyz + "&" + body
-		crc16 := gocrc.CalCRC16HJ212([]byte(loader))
-		pstr := fmt.Sprintf("##00%04d", len(loader)) + loader + fmt.Sprintf("%04X", crc16) + "\r\n"
-		arr = append(arr, pstr)
-	}
-	return arr, true
 }
-*/

+ 417 - 0
SERVER/Lamp_Server/src/forwardmode/pmc350b_tables.go

@@ -0,0 +1,417 @@
+// hello
+package forwardmode
+
+import (
+	"encoding/json"
+	"hello/basic"
+	dt "hello/datastruct"
+	"math"
+)
+
+type pmc350bPackager struct {
+	name string
+}
+
+type PMC350BHandler struct {
+	pmc350bPackager
+}
+
+var (
+	meter_of_pmc350b = []holdRegsData{
+		{regs: holdRegsDataUnit{0, 32}, method: parse_volt_0_32},
+		{regs: holdRegsDataUnit{32, 26}, method: parse_power_32_26},
+		{regs: holdRegsDataUnit{86, 8}, method: parse_tempture_86_8},
+		{regs: holdRegsDataUnit{500, 12}, method: parse_energy_500_12},
+		{regs: holdRegsDataUnit{1600, 6}, method: parse_dist_Uabc},
+		{regs: holdRegsDataUnit{1400, 6}, method: parse_dist_Iabc},
+		{regs: holdRegsDataUnit{1330, 4}, method: parse_dist_UIbalance},
+		{regs: holdRegsDataUnit{1400 + 24, 54}, method: parse_harmIabc_3_11},
+		{regs: holdRegsDataUnit{1400 + 84, 54}, method: parse_harmIabc_13_21},
+		{regs: holdRegsDataUnit{1400 + 144, 54}, method: parse_harmIabc_23_31},
+		{regs: holdRegsDataUnit{1600 + 24, 54}, method: parse_harmUabc_3_11},
+		{regs: holdRegsDataUnit{1600 + 84, 54}, method: parse_harmUabc_13_21},
+		{regs: holdRegsDataUnit{1600 + 144, 54}, method: parse_harmUabc_23_31},
+	}
+)
+
+func NewPMC350BHandler() *PMC350BHandler {
+	handler := &PMC350BHandler{}
+	handler.name = Meter_PMC350B
+	return handler
+}
+
+func PMC350BClient() MeterClient {
+	handler := NewPMC350BHandler()
+	return NewMeterClient(handler)
+}
+
+func (mb *pmc350bPackager) MeterName() (result string) {
+	result = mb.name
+	return
+}
+
+func (mb *pmc350bPackager) SetAddress(w RtuNetPgr, addr int) (result int) {
+	buf := []byte{}
+	buf = append(buf, basic.IntoByte(addr>>8))
+	buf = append(buf, basic.IntoByte(addr&0xFF))
+	if _, err := w.SetHoldingRegs(6401, 1, buf); err != nil {
+		result = 4
+	} else {
+		result = 0
+	}
+	return
+}
+
+//查询电表变比
+func (mb *pmc350bPackager) QueryRatio(w RtuNetPgr) (data string, result int) {
+	param := dt.MeterPMC350BParam{}
+	if adu, err := w.GetHoldingRegs(6000, 10); err != nil {
+		result = 4
+	} else {
+		parse_rated_ratio(adu, &param)
+		result = 0
+	}
+	data = dt.JsonToString(param)
+	return
+}
+
+//设置电表变比
+func (mb *pmc350bPackager) SetRatio(w RtuNetPgr, data string) (result int) {
+	m := dt.MeterPMC350BParam{}
+	if err := json.Unmarshal([]byte(data), &m); err != nil {
+		result = 7 //数据格式错误
+		return
+	}
+	buf := []byte{}
+	{
+		k := word2byte(m.PrimaryVolt)
+		buf = append(buf, k...)
+	}
+	{
+		k := word2byte(m.SecondVolt)
+		buf = append(buf, k...)
+	}
+	{
+		k := word2byte(m.PrimaryCurrent)
+		buf = append(buf, k...)
+	}
+	{
+		k := word2byte(m.SecondCurrent)
+		buf = append(buf, k...)
+	}
+	{
+		k := word2byte(m.CType)
+		buf = append(buf, k...)
+	}
+	if _, err := w.SetHoldingRegs(6000, 10, buf); err != nil {
+		result = 4
+	} else {
+		result = 0
+		// 	//log.Println("API_SetMeterRatio Rcv:", adu)
+	}
+	return
+}
+
+func (mb *pmc350bPackager) QueryElectricData(w RtuNetPgr, vref MeterVoltRef) (state basic.ElectDataFront) {
+	if k, err := mb.Query(w, vref); err != nil {
+		state.Result = 4
+	} else {
+		basic.Usrpower2Electdata(&k, &state)
+		state.Result = 0
+	}
+	return
+}
+
+func (mb *pmc350bPackager) Query(w RtuNetPgr, ref MeterVoltRef) (pm basic.USRPower_K, err error) {
+	var adu []byte
+	for _, v := range meter_of_pmc350b {
+		if adu, err = w.GetHoldingRegs(v.regs.Origin, v.regs.Amount); err == nil {
+			v.method(adu, &pm, ref)
+		} else {
+			return
+		}
+	}
+	return
+}
+
+//==================================================================
+//6000
+func parse_rated_ratio(adu []byte, meth interface{}) {
+	var (
+		index = 0
+		m     int32
+	)
+	s := meth.(*dt.MeterPMC350BParam)
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.PrimaryVolt = int(m)
+	index += 4
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.SecondVolt = int(m)
+	index += 4
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.PrimaryCurrent = int(m)
+	index += 4
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.SecondCurrent = int(m)
+	index += 4
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.CType = int(m)
+	index += 4
+}
+
+//0,32
+func parse_volt_0_32(adu []byte, meth interface{}, ext interface{}) {
+	var (
+		index = 0
+		m     uint32
+	)
+	vf := ext.(MeterVoltRef)
+	s := meth.(*basic.USRPower_K)
+	//ABC相电压
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	s.Ua = math.Float32frombits(m)
+	index += 4
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	s.Ub = math.Float32frombits(m)
+	index += 4
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	s.Uc = math.Float32frombits(m)
+	index += 4
+
+	index += 4
+	//ABC线电压
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Uab = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Ubc = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Uca = math.Float32frombits(m)
+	index += 4
+	//ABC电流
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Ia = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Ib = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Ic = math.Float32frombits(m)
+	index += 4
+	//ABC、总有功
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pa = math.Float32frombits(m) * float32(0.001)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pb = math.Float32frombits(m) * float32(0.001)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pc = math.Float32frombits(m) * float32(0.001)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.P = math.Float32frombits(m) * float32(0.001)
+
+	s.Uaw = (s.Ua - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Ubw = (s.Ub - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Ucw = (s.Uc - vf.Pvref) * float32(100.0) / vf.Pvref
+	s.Uabw = (s.Uab - vf.Lvref) * float32(100.0) / vf.Lvref
+	s.Ubcw = (s.Ubc - vf.Lvref) * float32(100.0) / vf.Lvref
+	s.Ucaw = (s.Uca - vf.Lvref) * float32(100.0) / vf.Lvref
+}
+
+//32,26
+func parse_power_32_26(adu []byte, meth interface{}, ext interface{}) {
+	var (
+		index = 0
+		m     uint32
+	)
+	s := meth.(*basic.USRPower_K)
+	//ABC、总无功
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Qa = math.Float32frombits(m) * float32(0.001)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Qb = math.Float32frombits(m) * float32(0.001)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Qc = math.Float32frombits(m) * float32(0.001)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Q = math.Float32frombits(m) * float32(0.001)
+	//视在功率
+	index += 16
+	//ABC、总功率因素
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pfa = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pfb = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pfc = math.Float32frombits(m)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Pf = math.Float32frombits(m)
+	//频率
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	index += 4
+	s.Freq = math.Float32frombits(m)
+	s.Fw = s.Freq - float32(50.0)
+}
+
+//500,12
+func parse_energy_500_12(adu []byte, meth interface{}, ext interface{}) {
+	var (
+		index = 0
+		m     int32
+	)
+	s := meth.(*basic.USRPower_K)
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Tps = float32(m) * float32(0.01)
+	index += 4
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Fps = float32(m) * float32(0.01)
+	index += 4
+	index += 8
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Tqs = float32(m) * float32(0.01)
+	index += 4
+	m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
+	s.Fqs = float32(m) * float32(0.01)
+	index += 4
+}
+
+//86,8
+func parse_tempture_86_8(adu []byte, meth interface{}, ext interface{}) {
+	var (
+		index = 0
+		m     uint32
+		f     float32
+	)
+	s := meth.(*basic.USRPower_K)
+	//温度
+	for i := 0; i < 4; i++ {
+		m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+		f = math.Float32frombits(m)
+		if math.IsNaN(float64(f)) {
+			s.Tempture[i] = float32(0)
+		} else {
+			s.Tempture[i] = f
+		}
+		index += 4
+	}
+}
+
+//ABC相畸变
+func sub_dist_abc(adu []byte, fa *float32, fb *float32, fc *float32) {
+	var (
+		index = 0
+		m     uint32
+	)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	*fa = math.Float32frombits(m) * float32(10)
+	index += 4
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	*fb = math.Float32frombits(m) * float32(10)
+	index += 4
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	*fc = math.Float32frombits(m) * float32(10)
+	index += 4
+}
+
+//3-11次谐波
+func sub_harm_3_11(orig int, adu []byte, fa *[15]float32, fb *[15]float32, fc *[15]float32) {
+	var (
+		index = 0
+		m     uint32
+	)
+	//ABC相3-11次谐波
+	for i := 0; i < 5; i++ {
+		m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+		index += 4
+		fa[i+orig] = math.Float32frombits(m) * float32(10)
+		m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+		index += 4
+		fb[i+orig] = math.Float32frombits(m) * float32(10)
+		m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+		index += 4
+		fc[i+orig] = math.Float32frombits(m) * float32(10)
+		index += 12 //跳过偶次谐波
+	}
+}
+
+//1600
+func parse_dist_Uabc(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_dist_abc(adu, &s.Uahar, &s.Ubhar, &s.Uchar)
+}
+
+//1400
+func parse_dist_Iabc(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_dist_abc(adu, &s.Iahar, &s.Ibhar, &s.Ichar)
+}
+
+//1330
+func parse_dist_UIbalance(adu []byte, meth interface{}, ext interface{}) {
+	var (
+		index = 0
+		m     uint32
+	)
+	s := meth.(*basic.USRPower_K)
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	s.Unbalance = math.Float32frombits(m)
+	index += 4
+	m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
+	s.Inbalance = math.Float32frombits(m)
+	index += 4
+}
+
+//(n-2)*6+18
+//1400+24,6*9
+//ABC相电流分次谐波(3-11次)
+func parse_harmIabc_3_11(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_harm_3_11(0, adu, &s.Hia, &s.Hib, &s.Hic)
+}
+
+//1400+24+6*9,6*9
+//ABC相电流分次谐波(13-21次)
+func parse_harmIabc_13_21(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_harm_3_11(5, adu, &s.Hia, &s.Hib, &s.Hic)
+}
+
+//1400+24+2*6*9,6*9
+//ABC相电流分次谐波(23-31次)
+func parse_harmIabc_23_31(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_harm_3_11(10, adu, &s.Hia, &s.Hib, &s.Hic)
+}
+
+//1600+24,6*9
+//ABC相电压分次谐波(3-11次)
+func parse_harmUabc_3_11(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_harm_3_11(0, adu, &s.Hua, &s.Hub, &s.Huc)
+}
+
+//1600+24+6*9,6*9
+//ABC相电压分次谐波(13-21次)
+func parse_harmUabc_13_21(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_harm_3_11(5, adu, &s.Hua, &s.Hub, &s.Huc)
+}
+
+//1600+24+2*6*9,6*9
+//ABC相电压分次谐波(23-31次)
+func parse_harmUabc_23_31(adu []byte, meth interface{}, ext interface{}) {
+	s := meth.(*basic.USRPower_K)
+	sub_harm_3_11(10, adu, &s.Hua, &s.Hub, &s.Huc)
+}

+ 23 - 19
SERVER/Lamp_Server/src/forwardmode/rtu_tcp.go

@@ -18,6 +18,7 @@ type rtuNetPackager struct {
 
 type RtuNetPgr interface {
 	GetHoldingRegs(address, quantity uint16) (adu []byte, err error)
+	SetHoldingRegs(address, quantity uint16, value []byte) (adu []byte, err error)
 	SetAddress(Id int)
 	SetSerialNumber(sn string)
 	SetClientState(sta *dt.ClientState)
@@ -46,18 +47,7 @@ func (mb *rtuNetPackager) SetClientState(sta *dt.ClientState) {
 //adu []byte, err error
 //发送modbus rtu报文并解析
 func (mb *rtuNetPackager) GetHoldingRegs(address, quantity uint16) (adu []byte, err error) {
-	//retbool := false
-	//cstring := "er..."
 	var result []byte
-	// dev, ok := basic.Dtumap_state.Get(mb.Sn)
-	// if !ok {
-	// 	err = fmt.Errorf("Can't find device")
-	// 	return
-	// }
-	// if !dev.Online {
-	// 	err = fmt.Errorf("Device is offline")
-	// 	return
-	// }
 	if mb.Sta == nil {
 		err = fmt.Errorf("Client FD is null")
 		return
@@ -66,22 +56,36 @@ func (mb *rtuNetPackager) GetHoldingRegs(address, quantity uint16) (adu []byte,
 	if err != nil {
 		return
 	}
-	//res, bok := tcpserver.Sendto(dev.FD, result)
 	res, bok := tcpserver.Sendto(mb.Sta.FD, result)
 	if !bok {
-		//if dt.ConnTimeoutJudge(dev.Times) {
 		if dt.ConnTimeoutJudge(mb.Sta.Times) {
-			//dev.Online = false
-			//dws.Dtumap_state.Add(sn, dev)
 			log.Println("Timeout Judge...")
 		}
 		err = fmt.Errorf("Send failed")
 		return
 	}
 	adu, err = mb.Clt.DePackRegisters(res)
-	// if res.Message == opt {
-	// 	retbool = true
-	// 	cstring = res.Data
-	// }
+	return
+}
+
+func (mb *rtuNetPackager) SetHoldingRegs(address, quantity uint16, value []byte) (adu []byte, err error) {
+	var result []byte
+	if mb.Sta == nil {
+		err = fmt.Errorf("Client FD is null")
+		return
+	}
+	result, err = mb.Clt.PackWriteMultipleRegisters(address, quantity, value)
+	if err != nil {
+		return
+	}
+	res, bok := tcpserver.Sendto(mb.Sta.FD, result)
+	if !bok {
+		if dt.ConnTimeoutJudge(mb.Sta.Times) {
+			log.Println("Timeout Judge...")
+		}
+		err = fmt.Errorf("Send failed")
+		return
+	}
+	adu, err = mb.Clt.DePackSetRegs(res)
 	return
 }

+ 15 - 143
SERVER/Lamp_Server/src/forwardmode/server.go

@@ -6,7 +6,15 @@ import (
 	"time"
 )
 
-func sendtoServer(host, port, date string) (res string, err error) {
+const (
+	//电表类型
+	Meter_ADW300  = "ADW300"
+	Meter_PMC350B = "PMC350B"
+	//上报平台协议
+	Plat_YC_HJ212 = "YC-HJ212"
+)
+
+func sendtoServer(host, port, date string) (res string, err error, state int) {
 	var (
 		mConn   *net.TCPConn
 		tcpAddr *net.TCPAddr
@@ -24,15 +32,16 @@ func sendtoServer(host, port, date string) (res string, err error) {
 	tcpAddr, err = net.ResolveTCPAddr("tcp", info)
 	if err != nil {
 		//fmt.Println("ResolveTCPAddr err")
+		state = 1
 		return
 	}
-
 	mConn, err = net.DialTCP("tcp", nil, tcpAddr)
 	if err != nil {
+		state = 2 //连接失败
 		return
 	}
+	state = 5
 	defer mConn.Close()
-	//fmt.Println("myConn :")
 	err = mConn.SetReadDeadline(time.Now().Add(readTimeout)) // timeout
 	if err != nil {
 		return
@@ -43,154 +52,17 @@ func sendtoServer(host, port, date string) (res string, err error) {
 	}
 	_, err = mConn.Write([]byte(date))
 	if err != nil {
+		state = 3 //发送失败
 		return
 	}
-
 	_, err = mConn.Read(rxd)
 	if err != nil {
 		//tcp send ok but no replay
 		err = nil
+		state = 4 //无响应
 		return
 	}
+	state = 0 //成功
 	res = string(rxd)
 	return
 }
-
-/*
-import (
-	"fmt"
-	"gocrc"
-	cfg "hello/config"
-	"hello/datastruct"
-	"hello/tcpserver"
-	"log"
-)
-
-//	"convtype"
-//	"encoding/json"
-//
-//
-var (
-	clientState *datastruct.DmapKv
-	rateResult  *datastruct.DmapKv
-)
-
-//
-
-//type LoraCmd byte
-
-const (
-	fmtHead  uint16 = 0xFF65
-	fmtKeep  uint16 = 0x0002
-	fmtLogin uint16 = 0x0001
-)
-
-func deal_pack(c *tcpserver.Client, msg []byte) ([]byte, bool) {
-	var (
-		result []byte = make([]byte, 128)
-		cli    datastruct.ClientState
-		//		rcvstr string = ""
-	)
-	respond := []byte{0xFF, 0x65, 0, 0, 0x20, 0x2F}
-	LogPrintHex("Receive Bytes", msg)
-	msglen := len(msg)
-	//打印收到的字节流
-	//rcvstr = fmt.Sprintf("rcv byte %d:", msglen)
-	//for _, v := range msg {
-	//	rcvstr += fmt.Sprintf("%02x ", v)
-	//}
-	//log.Println(rcvstr)
-
-	if msglen < 5 {
-		return result, false
-	}
-	crca := uint16(msg[msglen-1])<<8 + uint16(msg[msglen-2])
-	crcb := gocrc.CalCRC16ModbusRTU(msg[:msglen-2])
-	if crca != crcb {
-		fmt.Printf("deal_pack crc err:%04x;%04x", crca, crcb)
-		return result, false
-	}
-	if msg[0] == 0xFF && msg[1] == 0x65 && msglen == 18 {
-		sn := string(msg[4:16])
-		fmt.Println("sn=", sn)
-		v, ok := clientState.Get(sn)
-		if ok {
-			cli = v.(datastruct.ClientState)
-			cli.Online = true
-			cli.UpdateTime()
-			clientState.Add(sn, cli)
-			_, ok = clientState.Get(sn)
-			if ok {
-				if cli.Online {
-					log.Println(sn, " forward is Online")
-				} else {
-					log.Println(sn, " forward is Offline")
-				}
-			}
-			//log.Println("found SN=", cmd.SN)
-			//log.Println("time.Now().Unix():", cli.Times)
-		} else {
-			log.Println("forward can not found SN=", sn)
-		}
-		if msg[3] == 0x01 { //Login
-			//FF 65 00 01 31 31 31 31 31 31 31 31 31 31 31 31 46 B7
-			var rmsg string = ""
-			c.SetClientRegistID(sn)
-			cli.FD = c
-			cli.Online = true
-			cli.UpdateTime()
-			clientState.Add(sn, cli)
-			_, find := clientState.Get(sn)
-			if !find {
-				rmsg = "deal_pack SN = " + sn + " no found"
-				log.Println(rmsg)
-			} else {
-				rmsg = "deal_pack SN = " + sn + " login"
-				log.Println(rmsg)
-				c.ChanWrtie(respond)
-			}
-
-		}
-		if msg[3] == 0x02 { //Keep
-			c.ChanWrtie(respond)
-		}
-		return result, false
-	}
-	return msg, true
-}
-
-func NewForwardService() {
-	server := tcpserver.New(fmt.Sprintf(":%d", cfg.ParamConf.PortFwd)) //":10003"
-	clientState = datastruct.NewDmap()
-	rateResult = datastruct.NewDmap()
-	//go Dtumap_state.HeartBeat(40)
-	server.OnNewClient(func(c *tcpserver.Client) {
-		log.Println(c.Conn().RemoteAddr().String())
-	})
-	server.OnNewMessage(func(c *tcpserver.Client, msg []byte) {
-		//log.Println("receive:", string(msg))
-		res, ok := deal_pack(c, msg)
-		if ok {
-			if c.GetWaitRawRes() {
-				c.PutRawRes(res)
-			}
-		}
-	})
-	server.OnClientConnectionClosed(func(c *tcpserver.Client, err error) {
-		deal_disconnect(c)
-	})
-	server.Listen()
-}
-
-func deal_disconnect(c *tcpserver.Client) {
-	sn := c.GetClientRegistID()
-	if sn != "" {
-		v, ok := clientState.Get(sn)
-		if ok {
-			cli := v.(datastruct.ClientState)
-			cli.Online = false
-			clientState.Add(sn, cli)
-		}
-		log.Println("Client Closed:", sn)
-	}
-}*/

+ 52 - 15
SERVER/Lamp_Server/src/forwardmode/yc_hj212.go

@@ -3,10 +3,6 @@ package forwardmode
 
 import (
 	"fmt"
-	gocrc "hello/crc16"
-
-	//"gocrc"
-
 	"hello/basic"
 	dt "hello/datastruct"
 	"log"
@@ -14,22 +10,59 @@ import (
 	"time"
 )
 
-// yc_hj212协议上报
-func report_yc_hj212(bs dt.HJBaseInfo, cs []basic.USRPower_K) {
+//yc_hj212协议上报
+func report_yc_hj212(cpid string, bs dt.HJBaseInfo, cs []basic.USRPower_K) {
+	val := dt.PlatReportCount{
+		CntSend: 0,
+		CntAck:  0,
+		ErrConn: 0,
+	}
+	val.Info = bs.Host + ":" + bs.Port
+	//先查询参数列表是否存在
+	if x, ok := basic.DeviceStatus.Get(cpid); ok {
+		//存在则直接计算
+		calc := x.(dt.DeviceSampleCount)
+		if len(calc.Plat) > 0 {
+			if v, r := calc.Plat[val.Info]; r {
+				val = v
+			}
+		}
+	}
 	if ck, ok := pack_yc_hj212(bs, cs); ok {
 		for _, v := range ck {
-			receive, err := sendtoServer(bs.Host, bs.Port, v)
+			receive, err, state := sendtoServer(bs.Host, bs.Port, v)
 			if err != nil {
 				log.Println("Send fail->", receive, ":", err)
+				if state == 2 {
+					val.ErrConn++
+				}
 			} else {
+				if state != 4 {
+					val.CntAck++
+				}
 				log.Println("Send->", v)
 				log.Println("Receive<-", receive)
+				val.Time = time.Now().Format("2006-01-02 15:04:05")
 			}
+			val.CntSend++
+		}
+		if val.CntSend > 0 {
+			calc := dt.DeviceSampleCount{}
+			//先查询参数列表是否存在
+			if x, ok := basic.DeviceStatus.Get(cpid); ok {
+				//存在则直接计算
+				calc = x.(dt.DeviceSampleCount)
+			}
+			if len(calc.Plat) < 1 {
+				calc.Plat = make(map[string]dt.PlatReportCount)
+			}
+			calc.Plat[val.Info] = val
+			basic.DeviceStatus.Add(cpid, calc)
 		}
 	}
 }
 
-// yc_hj212温度数据打包
+//yc_hj212温度数据打包
 func pack_yc_hj212_temp(val [8]float32) string {
 	ret := ""
 	for i, v := range val {
@@ -43,7 +76,7 @@ func pack_yc_hj212_temp(val [8]float32) string {
 	return ret
 }
 
-// yc_hj212电压谐波数据打包
+//yc_hj212电压谐波数据打包
 func pack_yc_hj212_hux(val [15]float32, hall, bu float32) string {
 	ret := ""
 	for i, v := range val {
@@ -55,7 +88,7 @@ func pack_yc_hj212_hux(val [15]float32, hall, bu float32) string {
 	return ret
 }
 
-// yc_hj212电流谐波数据打包
+//yc_hj212电流谐波数据打包
 func pack_yc_hj212_hix(val [15]float32, hall, bu float32) string {
 	ret := ""
 	for i, v := range val {
@@ -67,11 +100,10 @@ func pack_yc_hj212_hix(val [15]float32, hall, bu float32) string {
 	return ret
 }
 
-// yc_hj212协议打包
+//yc_hj212协议打包
 func pack_yc_hj212(bs dt.HJBaseInfo, array []basic.USRPower_K) ([]string, bool) {
 	nt := time.Now()
-	//	var key [len(KeyHJ212)]string
-	//	var i int
+	cn := ""
 	arr := make([]string, 0)
 	if len(array) == 0 {
 		return arr, false
@@ -79,6 +111,11 @@ func pack_yc_hj212(bs dt.HJBaseInfo, array []basic.USRPower_K) ([]string, bool)
 	ntime := fmt.Sprintf("%04d%02d%02d%02d%02d00", nt.Year(), nt.Month(),
 		nt.Day(), nt.Hour(), nt.Minute())
 	for _, cs := range array {
+		if len(cs.Cn) > 0 {
+			cn = cs.Cn
+		} else {
+			cn = bs.CN
+		}
 		body := "p=" + strconv.FormatFloat(float64(cs.P), 'f', 3, 32) + "&" +
 			"pa=" + strconv.FormatFloat(float64(cs.Pa), 'f', 3, 32) + "&" +
 			"pb=" + strconv.FormatFloat(float64(cs.Pb), 'f', 3, 32) + "&" +
@@ -129,9 +166,9 @@ func pack_yc_hj212(bs dt.HJBaseInfo, array []basic.USRPower_K) ([]string, bool)
 		body += "hia=" + pack_yc_hj212_hix(cs.Hia, cs.Haria, cs.Baseia)
 		body += "hib=" + pack_yc_hj212_hix(cs.Hib, cs.Harib, cs.Baseib)
 		body += "hic=" + pack_yc_hj212_hix(cs.Hic, cs.Haric, cs.Baseic)
-		loader := "st=" + bs.ST + ";cn=" + bs.CN +
+		loader := "st=" + bs.ST + ";cn=" + cn +
 			";datatime=" + ntime + ";cphh=&&tid=" + cs.Bmyz + "&" + body
-		crc16 := gocrc.CalCRC16HJ212([]byte(loader))
+		crc16 := dt.CalCRC16HJ212([]byte(loader))
 		pstr := fmt.Sprintf("##00%04d", len(loader)) + loader + fmt.Sprintf("%04X", crc16) + "\r\n"
 		arr = append(arr, pstr)
 	}

+ 4 - 1
SERVER/Lamp_Server/src/modbus/api.go

@@ -25,9 +25,12 @@ type Client interface {
 	// ReadInputRegisters reads from 1 to 125 contiguous input registers in
 	// a remote device and returns input registers.
 	ReadInputRegisters(address, quantity uint16) (results []byte, err error)
-
+	//自定义函数
 	PackReadHoldingRegisters(address, quantity uint16) (results []byte, err error)
 	DePackRegisters(aduResponse []byte) (results []byte, err error)
+	PackWriteMultipleRegisters(address, quantity uint16, value []byte) (results []byte, err error)
+	DePackSetRegs(aduResponse []byte) (results []byte, err error)
+
 	// ReadHoldingRegisters reads the contents of a contiguous block of
 	// holding registers in a remote device and returns register value.
 	ReadHoldingRegisters(address, quantity uint16) (results []byte, err error)

+ 67 - 4
SERVER/Lamp_Server/src/modbus/client.go

@@ -18,7 +18,11 @@ type ClientHandler interface {
 type client struct {
 	packager    Packager
 	transporter Transporter
-	aduRequest  []byte
+	//发送后存储的数据
+	aduRequest   []byte
+	quantity     uint16
+	address      uint16
+	functionCode byte
 }
 
 // NewClient creates a new modbus client with given backend handler.
@@ -116,10 +120,69 @@ func (mb *client) PackReadHoldingRegisters(address, quantity uint16) (results []
 	}
 	//存储要发送的字节数组,用于接收数据时验证
 	mb.aduRequest = response
+	mb.quantity = quantity
+	mb.address = address
+	mb.functionCode = request.FunctionCode
 	results = response
 	return
 }
 
+// Request:
+//  Function code         : 1 byte (0x10)
+//  Starting address      : 2 bytes
+//  Quantity of outputs   : 2 bytes
+//  Byte count            : 1 byte
+//  Registers value       : N* bytes
+// Response:
+//  Function code         : 1 byte (0x10)
+//  Starting address      : 2 bytes
+//  Quantity of registers : 2 bytes
+func (mb *client) PackWriteMultipleRegisters(address, quantity uint16, value []byte) (results []byte, err error) {
+	if quantity < 1 || quantity > 123 {
+		err = fmt.Errorf("modbus: quantity '%v' must be between '%v' and '%v',", quantity, 1, 123)
+		return
+	}
+	request := ProtocolDataUnit{
+		FunctionCode: FuncCodeWriteMultipleRegisters,
+		Data:         dataBlockSuffix(value, address, quantity),
+	}
+	response, err := mb.pack_post(&request)
+	if err != nil {
+		return
+	}
+	//存储要发送的字节数组,用于接收数据时验证
+	mb.aduRequest = response
+	mb.quantity = quantity
+	mb.address = address
+	mb.functionCode = request.FunctionCode
+	results = response
+	return
+}
+
+func (mb *client) DePackSetRegs(aduResponse []byte) (results []byte, err error) {
+	response, err := mb.depack_rcv(mb.aduRequest, aduResponse)
+	if err != nil {
+		return
+	}
+	// Fixed response length
+	if len(response.Data) != 4 {
+		err = fmt.Errorf("modbus: response data size '%v' does not match expected '%v'", len(response.Data), 4)
+		return
+	}
+	respValue := binary.BigEndian.Uint16(response.Data)
+	if mb.address != respValue {
+		err = fmt.Errorf("modbus: response address '%v' does not match request '%v'", respValue, mb.address)
+		return
+	}
+	results = response.Data[2:]
+	respValue = binary.BigEndian.Uint16(results)
+	if mb.quantity != respValue {
+		err = fmt.Errorf("modbus: response quantity '%v' does not match request '%v'", respValue, mb.quantity)
+		return
+	}
+	return
+}
+
 func (mb *client) DePackRegisters(aduResponse []byte) (results []byte, err error) {
 	response, err := mb.depack_rcv(mb.aduRequest, aduResponse)
 	if err != nil {
@@ -483,7 +546,7 @@ func (mb *client) pack_post(request *ProtocolDataUnit) (aduRequest []byte, err e
 }
 
 func (mb *client) depack_rcv(aduRequest, aduResponse []byte) (response *ProtocolDataUnit, err error) {
-	var functionCode byte
+	//var functionCode byte
 	if err = mb.packager.Verify(aduRequest, aduResponse); err != nil {
 		return
 	}
@@ -492,9 +555,9 @@ func (mb *client) depack_rcv(aduRequest, aduResponse []byte) (response *Protocol
 	if err != nil {
 		return
 	}
-	functionCode = aduRequest[1]
+	//functionCode = aduRequest[1]
 	// Check correct function code returned (exception)
-	if response.FunctionCode != functionCode {
+	if response.FunctionCode != mb.functionCode {
 		err = responseError(response)
 		return
 	}

+ 1 - 1
SERVER/Lamp_Server/src/modbus/rtuclient.go

@@ -94,8 +94,8 @@ func (mb *rtuPackager) Decode(adu []byte) (pdu *ProtocolDataUnit, err error) {
 	var crc crc
 	crc.reset().pushBytes(adu[0 : length-2])
 	checksum := uint16(adu[length-1])<<8 | uint16(adu[length-2])
-	//fmt.Println("Decode:", adu, ";length=", length)
 	if checksum != crc.value() {
+		fmt.Println("Decode Err:", adu, ";length=", length)
 		err = fmt.Errorf("modbus-rtu: response crc '%v' does not match expected '%v'", checksum, crc.value())
 		return
 	}

+ 2 - 263
SERVER/Lamp_Server/src/model/model.go

@@ -1,14 +1,10 @@
 package model
 
 import (
-	"encoding/json"
 	"fmt"
 	"hello/basic"
 	"hello/connsql"
 	dt "hello/datastruct"
-	"hello/tcpserver"
-	"log"
-	"time"
 	//	"github.com/astaxie/beego/orm"
 )
 
@@ -23,11 +19,12 @@ var (
 func NewModelDTU() bool {
 	basic.Dtumap_sn = dt.NewDMAP_DtuDev()
 	basic.CalcParam = dt.NewDMAP_Interface()
+	basic.DeviceStatus = dt.NewDMAP_Interface()
 	FlagsCache = dt.NewDMAP_StringKV()
 	//ProDictCache = dt.NewDMAP_IntStringKV()
 	connsql.Map_IdAgent = make(map[int]string)
 	connsql.Map_AgentId = make(map[string]int)
-	connsql.BoltInit()
+	//connsql.BoltInit()
 	if err := connsql.DTUManage_OpenDB(); err != nil {
 		panic(err)
 	}
@@ -41,38 +38,6 @@ func NewModelDTU() bool {
 		return false
 	}
 	fmt.Println("Read SQL is Sucess")
-
-	// k := fwd.USRPower_K{}
-	// k.Bmyz = "123"
-	// err := fwd.Record_meter_data(&k, basic.NowDataToTimeStamp())
-	// fmt.Println("Record_meter_data", err)
-
-	// if r, err := connsql.Record_Query_ByBmyz("234"); err != nil {
-	// 	fmt.Println(err)
-	// } else {
-	// 	fmt.Println("Record_Query_ofBmyz", r)
-	// }
-	// calc := dt.CalcMeterParm{Init: 0}
-	// calc.Time = 897654
-	// fwd.Record_meter_data("7777777", calc)
-	// if r, err := connsql.Record_Query_Power("234", 1709445526); !err {
-	// 	fmt.Println(err)
-	// } else {
-	// 	fmt.Println(r.Count)
-	// 	fmt.Println(r.MaxPower)
-	// 	fmt.Println(r.SumPower)
-	// }
-
-	// if r, err := connsql.Record_Query_EnergyLastDay("234", 1709445526); !err {
-	// 	fmt.Println(err)
-	// } else {
-	// 	fmt.Println(r.OriginFps)
-	// 	fmt.Println(r.OriginFqs)
-	// 	fmt.Println(r.OriginTps)
-	// 	fmt.Println(r.OriginTqs)
-	// }
-
-	//fmt.Println("Open Record is Sucess")
 	return true
 }
 
@@ -102,229 +67,3 @@ func UpdateAgentDict() (dt.MapIntStr, bool) {
 		return m, false
 	}
 }
-
-//更新电表协议字典
-// func UpdateMeterProtDict() (dt.MapIntStr, bool) {
-// 	if m, err := connsql.DTUManage_GetMeterProtocol(); err == nil {
-// 		return m, true
-// 	} else {
-// 		return m, false
-// 	}
-// }
-
-// //更新平台协议字典
-// func UpdatePlatProtDict() (dt.MapIntStr, bool) {
-// 	if m, err := connsql.DTUManage_GetPlatformProtocol(); err == nil {
-// 		return m, true
-// 	} else {
-// 		return m, false
-// 	}
-// }
-
-func packRequestData(sn string, cmd string, dat string) string {
-	p := &dt.DTUCmd{}
-	p.SN = sn
-	p.Type = dt.TYPE_REQUST
-	p.Cmd = cmd
-	p.Data = dat
-	data, _ := json.Marshal(p)
-	return "[JSON]" + string(data)
-}
-
-/*
-func packRequestData(sn string, cmd string, dat string) string {
-	var comd dt.ComdHead
-	p := &dt.DTUCmd{}
-	p.SN = sn
-	p.Type = dt.TYPE_REQUST
-	p.Cmd = cmd
-	p.Data = dat
-	data, _ := json.Marshal(p)
-
-	comd.Head = uint8(0xAA)
-	comd.Code = dt.Cmd2Code(cmd)
-	comd.Len = uint16(len(data))
-	comd.Crc32 = crc32.ChecksumIEEE(data)
-	return "[JSON]" + string(data)
-}*/
-/*
-type rtuNetPackager struct {
-	Sn  string
-	Id  byte
-	Clt modbus.Client
-}
-
-type RtuNetPgr interface {
-	GetHoldingRegs(address, quantity uint16) (adu []byte, err error)
-	SetAddress(Id byte)
-	SetSerialNumber(sn string)
-}
-
-func NewRtuNetPgr(sn string) RtuNetPgr {
-	handler := modbus.NewRTUClientHandler("")
-	return &rtuNetPackager{Sn: sn, Id: 1, Clt: modbus.NewClient(handler)}
-}
-
-func (mb *rtuNetPackager) SetAddress(Id byte) {
-	if Id > 0 && Id < 255 {
-		mb.Id = Id
-	}
-}
-
-func (mb *rtuNetPackager) SetSerialNumber(sn string) {
-	mb.Sn = sn
-}
-
-//adu []byte, err error
-//发送modbus rtu报文并解析
-func (mb *rtuNetPackager) GetHoldingRegs(address, quantity uint16) (adu []byte, err error) {
-	//retbool := false
-	//cstring := "er..."
-	var result []byte
-	dev, ok := dws.Dtumap_state.Get(mb.Sn)
-	if !ok {
-		err = fmt.Errorf("Can't find device")
-		return
-	}
-	if !dev.Online {
-		err = fmt.Errorf("Device is offline")
-		return
-	}
-	// if opt == dt.CMD_GETDTUBASEINFO {
-	// 	return dt.JsonToString(dev.Info), true
-	// }
-	result, err = mb.Clt.PackReadHoldingRegisters(address, quantity)
-	if err != nil {
-		return
-	}
-	res, bok := tcpSendto(dev.FD, result)
-	if !bok {
-		if dt.ConnTimeoutJudge(dev.Times) {
-			//dev.Online = false
-			//dws.Dtumap_state.Add(sn, dev)
-			log.Println("Timeout Judge...")
-		}
-		err = fmt.Errorf("Send failed")
-		return
-	}
-	adu, err = mb.Clt.DePackRegisters(res)
-	// if res.Message == opt {
-	// 	retbool = true
-	// 	cstring = res.Data
-	// }
-	return
-}*/
-
-//=============================================================
-func ModelDTUCtrl(sn, opt, data string) (string, bool) {
-	retbool := false
-	cstring := "er..."
-	client, ok := basic.Dtumap_state.Get(sn)
-	if !ok {
-		return "can not find device", false
-	}
-	if !client.Online {
-		return "device offline", false
-	}
-	if opt == dt.CMD_GETDTUBASEINFO {
-		return dt.JsonToString(client.Info), true
-	}
-	frm := packRequestData(sn, opt, data)
-	res, bok := tcpSendtoDTU(client.FD, frm)
-	if !bok {
-		if dt.ConnTimeoutJudge(client.Times) {
-			client.Online = false
-			basic.Dtumap_state.Add(sn, client)
-			log.Println("Timeout Judge...")
-		}
-		return "send failed", false
-	}
-	if res.Message == opt {
-		retbool = true
-		cstring = res.Data
-	}
-	return cstring, retbool
-}
-
-/*
-func tcpSendto(cli *tcpserver.Client, date []byte) (res []byte, ok bool) {
-	var (
-		en = false
-	)
-	ok = true
-	cli.LockClient()
-	cnt := cli.ChanWrtie(date)
-	select {
-	case <-time.After(time.Millisecond * 800):
-	}
-	for {
-		res, ok = cli.GetRawRes()
-		ncnt := cli.GetRestCnt()
-		if !ok {
-			//log.Println("Over Time...")
-			break
-		}
-		if ncnt == cnt+1 {
-			break
-		}
-		if ncnt > cnt+1 {
-			ok = false
-			break
-		}
-		if en {
-			break
-		}
-		en = true
-	}
-	cli.UnLockClient()
-	return
-}*/
-
-func tcpSendtoDTU(cli *tcpserver.Client, date string) (tcpserver.RestResult, bool) {
-	var (
-		en  = false
-		ok  = false
-		res tcpserver.RestResult
-	)
-	cli.LockClient()
-	cnt := cli.ChanWrtie([]byte(date))
-	select {
-	case <-time.After(time.Millisecond * 1200):
-	}
-	for {
-		res, ok = cli.GetRestRes()
-		ncnt := cli.GetRestCnt()
-		if !ok {
-			//log.Println("Over Time...")
-			break
-		}
-		if ncnt == cnt+1 {
-			break
-		}
-		if ncnt > cnt+1 {
-			ok = false
-			break
-		}
-		if en {
-			break
-		}
-		en = true
-	}
-	cli.UnLockClient()
-	return res, ok
-}
-
-/*
-func tcpSendtoDTU(cli *tcpserver.Client, date []byte) (tcpserver.RestResult, bool) {
-	cli.LockClient()
-	cli.ChanWrtie(date)
-	select {
-	case <-time.After(time.Millisecond * 100):
-	}
-	res, ok := cli.GetRestRes()
-	cli.UnLockClient()
-	if !ok {
-		log.Println("Over Time...")
-	}
-	return res, ok
-}*/

+ 51 - 53
SERVER/Lamp_Server/src/router/jwtauth.go

@@ -1,14 +1,12 @@
 package router
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	cfg "hello/config"
 	"hello/connsql"
 	ctrl "hello/controller"
 	dt "hello/datastruct"
-	"hello/mcryp"
 	"net/http"
 	"time"
 
@@ -91,10 +89,7 @@ func setOwneAgent(c *gin.Context) {
 			return
 		}
 	}
-	/*if !permiAgent(c.GetString(dt.RSauthority)) {
-		resUsrLmt(c)
-		return
-	}*/
+
 }
 
 //访客权限
@@ -114,34 +109,7 @@ func setOwneVisiter(c *gin.Context) {
 			return
 		}
 	}
-	//if !permiVisiter(c.GetString(dt.RSauthority)) {
-	//	resUsrLmt(c)
-	//	return
-	//}
-}
 
-/*
-type CollAgentInfo struct {
-	Appid     string `json:"appid"`
-	Nonce     string `json:"nonce"`
-	Timestamp string `json:"timestamp"`
-	Sign      string `json:"sign"`
-}
-*/
-func calCollAgentInfo(auth string) (ok bool, info dt.CollAgentInfo) {
-	ok = false
-	//fmt.Println("calCollAgentInfo : ", auth)
-	if err := json.Unmarshal([]byte(auth), &info); err != nil {
-		//fmt.Println("json err")
-		return
-	}
-	//app_key:=
-	str := mcryp.SHA1Str(mcryp.MD5Str(privkey) + info.Noce + info.Timestamp)
-	if str == info.Sign {
-		ok = true
-		return
-	}
-	return
 }
 
 func matchLocalTime(str string) bool {
@@ -165,7 +133,7 @@ func matchLocalTime(str string) bool {
 func RouterJWT() {
 	gin.SetMode(gin.ReleaseMode)
 	r := gin.New()
-	ctrl.SetRmtDileKey("q1DSjGk+K5kJdFwq")
+	//	ctrl.SetRmtDileKey("q1DSjGk+K5kJdFwq")
 	r.GET("/", func(c *gin.Context) {
 		res := dt.HtmlResultErr{Err: dt.LoginErrTokenMiss, Note: "No Authtoken!"}
 		c.AbortWithStatusJSON(http.StatusUnauthorized, res)
@@ -174,16 +142,30 @@ func RouterJWT() {
 	admin := r.Group("/")
 	admin.Use(jwtAuth())
 	{
+		//admin.GET("/verify", setOwneroot, verify)
+		//admin.POST("/regist", setOwneAgent, new_account)
 		admin.GET("/refreshtoken", refresh)
-		if cfg.ParamConf.Type == 4040 {
-			dts := admin.Group("account")
-			{
-				dts.POST("/new", setOwneroot, new_account)
-				dts.POST("/modify", setOwneroot, modify_account)
-				dts.POST("/delete", setOwneroot, ctrl.DTUDeleteAccount)
-				dts.GET("/get", setOwneroot, ctrl.DTUGetAccountInfo)
-			}
+		//账户管理接口
+		dts := admin.Group("account")
+		{
+			dts.POST("/new", setOwneroot, new_account)
+			dts.POST("/modify", setOwneroot, modify_account)
+			dts.POST("/delete", setOwneroot, ctrl.DTUDeleteAccount)
+			dts.GET("/get", setOwneVisiter, ctrl.DTUGetAccountInfo)
+			//代理商
+			dts.POST("/agent/new", setOwneroot, ctrl.DTUAddAgent)
+			dts.POST("/agent/delete", setOwneroot, ctrl.DTUDeleteAgent)
+			dts.POST("/agent/modify", setOwneroot, ctrl.DTUModifyAgent)
+			dts.GET("/agent/all", setOwneroot, ctrl.DTUGetAgentList)
+			//项目
+			dts.POST("/project/new", setOwneroot, ctrl.DTUAddProject)
+			dts.POST("/project/delete", setOwneroot, ctrl.DTUDeleteProject)
+			dts.POST("/project/modify", setOwneroot, ctrl.DTUModifyProject)
+			dts.GET("/project/all", setOwneroot, ctrl.DTUGetProjectList)
+			//密码管理
+			dts.POST("/passwd/modify", setOwneVisiter, modify_account_passwd)
 		}
+		//DTU设备管理接口
 		dtu := admin.Group("dtucompany")
 		{
 			dtu.GET("/getbaseinfo", setOwneVisiter, ctrl.GetBaseInfo)
@@ -195,14 +177,16 @@ func RouterJWT() {
 			dtu.GET("/state/all", setOwneVisiter, ctrl.GetDeviceStateList) //获取所有设备状态
 			dtu.GET("/delete", setOwneroot, ctrl.DeleteCompany)
 			dtu.GET("/getcompany/all", setOwneVisiter, ctrl.GetCompanyListFromDB) //获取所有公司
+
 			/*网关配置操作*/
-			dtu.GET("/state", setOwneAgent, ctrl.DTUGetStateJson)       //考虑删除
-			dtu.GET("/rerun", setOwneAgent, ctrl.DTUReRun)              //需要通信机在线
-			dtu.GET("/reboot", setOwneAgent, ctrl.DTUReboot)            //需要通信机在线
-			dtu.GET("/version", setOwneAgent, ctrl.GetDTUVersion)       //需要通信机在线
-			dtu.POST("/set/config", setOwneAgent, ctrl.DTUSetConfig)    //已完成改造
-			dtu.GET("/get/config", setOwneAgent, ctrl.DTUGetConfig)     //已完成改造
-			dtu.GET("/get/baseinfo", setOwneAgent, ctrl.GetDTUBaseInfo) //获取通信机参数
+			dtu.GET("/state", setOwneAgent, ctrl.GetDTUState)
+			dtu.GET("/meter_ratio", setOwneAgent, ctrl.GetMeterRatio)      //获取电表变比
+			dtu.POST("/meter_ratio", setOwneAgent, ctrl.SetMeterRatio)     //设置电表变比
+			dtu.POST("/meter_address", setOwneAgent, ctrl.SetMeterAddress) //设置电表地址
+			dtu.GET("/electric_data", setOwneAgent, ctrl.GetElectricData)  //获取电力参数
+			dtu.POST("/set/config", setOwneAgent, ctrl.DTUSetConfig)
+			dtu.GET("/get/config", setOwneAgent, ctrl.DTUGetConfig)
+			//dtu.GET("/get/baseinfo", setOwneAgent, ctrl.GetDTUBaseInfo) //获取参数
 			dtu.POST("/additem/config", setOwneAgent, ctrl.DTUAddItemConfig)
 		}
 	}
@@ -252,10 +236,9 @@ func loginHandle(c *gin.Context) {
 	} else {
 		loginer.Pwd = v
 	}
-
 	act, err := connsql.LoginAccount(loginer)
 	if err != nil {
-		fmt.Println("t1", err)
+		//fmt.Println("t1", err)
 		ctrl.AckHTML_AbNormal(c, -1, err.Error()) //c.String(http.StatusNotFound, err.Error())
 		return
 	}
@@ -278,8 +261,8 @@ func loginHandle(c *gin.Context) {
 	}
 	tok := dt.HtmlTokenInfo{
 		Token:   signedToken,
-		Agentid: act.Agentid, //connsql.Map_IdAgent[out],//
-		Actype:  act.Perm,    //act.Type,    //"rwx",     //账号类型
+		Agentid: act.Agentid,
+		Actype:  act.Perm, //act.Type,    //"rwx",     //账号类型
 		ProID:   act.Proid,
 	}
 	ctrl.AckHTML_OKWithData(c, tok) //c.JSON(http.StatusOK, tok)
@@ -321,6 +304,21 @@ func modify_account(c *gin.Context) {
 	ctrl.AckHTML_OK(c)
 }
 
+func modify_account_passwd(c *gin.Context) {
+	var (
+		val dt.AccountRegistMod
+	)
+	if err := c.BindJSON(&val); err != nil {
+		ctrl.AckHTML_ErrJsonFmt(c, "")
+		return
+	}
+	if err := connsql.ModifyAccountPasswd(val); err != nil {
+		ctrl.AckHTML_AbNormal(c, dt.LoginErrUsrExsit, "")
+		return
+	}
+	ctrl.AckHTML_OK(c)
+}
+
 func refresh(c *gin.Context) {
 	authtoken := c.Request.Header.Get("Authorization")
 	if authtoken == "" {

+ 131 - 3
SERVER/Lamp_Server/src/tcpserver/tcpserver.go

@@ -124,13 +124,41 @@ func (c *Client) GetRawRes() ([]byte, bool) {
 	select {
 	case res = <-c.buffRawRes:
 		ret = true
-	case <-time.After(time.Second * 5):
+	case <-time.After(time.Second * 3):
 		ret = false
 	}
 	c.restcnt++
 	return res, ret
 }
 
+//清除读取通道数据
+func (c *Client) clrRawRes() {
+	select {
+	case <-c.buffRawRes:
+
+	case <-time.After(time.Millisecond * 100):
+
+	}
+}
+
+//以原始格式获取
+// func (c *Client) GetRawRes() ([]byte, bool) {
+// 	//sync_lock
+// 	var (
+// 		ret bool   = false
+// 		res []byte = make([]byte, 0) //256)
+// 	)
+// 	select {
+// 	case str := <-c.buffRawRes:
+// 		res = []byte(str)
+// 		//fmt.Printf("GetRawRes:%d\n", len(res))
+// 		return res, true
+// 	case <-time.After(time.Second * 10):
+// 		ret = false
+// 	}
+// 	return res, ret
+// }
+
 // 将数据写给User端
 func (c *Client) ChanWrtie(b []byte) int {
 	//sync_lock
@@ -139,6 +167,19 @@ func (c *Client) ChanWrtie(b []byte) int {
 	return c.restcnt
 }
 
+/*
+func (c *Client) ChanRead() ([]byte, bool) {
+	//sync_lock
+	var ret bool = false
+	var res []byte
+	select {
+	case res = <-c.channel_rd:
+		ret = true
+	case <-time.After(time.Second * 5):
+		ret = false
+	}
+	return res, ret
+}*/
 func (c *Client) GetClientHost() string {
 	return c.clientaddr
 }
@@ -154,6 +195,50 @@ func (c *Client) GetGRunFlag() bool {
 	return c.grunflag
 }
 
+// func (c *Client) handleTaskTimer(out <-chan int) {
+// 	//
+// 	cpid := ""
+// 	date := []byte{0x02, 0x03, 0x00, 0x0E, 0x00, 0x02, 0xA5, 0xFB}
+// 	for {
+// 		select {
+// 		case <-time.After(time.Second * 5):
+// 			if len(cpid) < 1 {
+// 				cpid = c.GetClientRegistID()
+// 				log.Println("handleTaskTimer sn=", cpid)
+// 			} else {
+// 				en := false
+// 				cnt := c.ChanWrtie(date)
+// 				select {
+// 				case <-time.After(time.Millisecond * 800):
+// 				}
+// 				for {
+// 					res, ok := c.GetRawRes()
+// 					ncnt := c.GetRestCnt()
+// 					if !ok {
+// 						log.Println("Over Time...")
+// 						break
+// 					}
+// 					log.Println("handleTaskTimer rcv=", res)
+// 					if ncnt == cnt+1 {
+// 						break
+// 					}
+// 					if ncnt > cnt+1 {
+// 						break
+// 					}
+// 					if en {
+// 						break
+// 					}
+
+// 					en = true
+// 				}
+// 			}
+// 		case <-out:
+// 			log.Println("handleTaskTimer exit")
+// 			return
+// 		}
+// 	}
+// }
+
 func (c *Client) handleClient() {
 	res := ""
 	//	exit := false
@@ -201,6 +286,15 @@ func (c *Client) handleClient() {
 				c.Server.onNewMessage(c, rddata)
 			}
 		}
+		/*if exit {
+			//log.Println("client is exit due to ", res)
+			//cancel()
+			c.closeClient() //conn.Close()
+			if res != "ro" {
+				<-ro
+			}
+			break
+		}*/
 	}
 }
 
@@ -209,6 +303,13 @@ func (c *Client) closeClient() {
 	defer c.conn.Close()
 	c.grunflag = false
 	c.Server.onClientConnectionClosed(c, err)
+	//close(c.towr)
+	/*close(c.buffRestRes)
+	close(c.channel_err)
+	close(c.buffRawRes)
+	close(c.channel_wr)
+	close(c.tord)
+	*/
 }
 
 func (c *Client) ExitClient() {
@@ -240,9 +341,11 @@ func Sendto(cli *Client, date []byte) (res []byte, ok bool) {
 	)
 	ok = true
 	cli.LockClient()
+	defer cli.UnLockClient()
+	cli.clrRawRes()
 	cnt := cli.ChanWrtie(date)
 	select {
-	case <-time.After(time.Millisecond * 800):
+	case <-time.After(time.Millisecond * 1000):
 	}
 	for {
 		res, ok = cli.GetRawRes()
@@ -263,10 +366,27 @@ func Sendto(cli *Client, date []byte) (res []byte, ok bool) {
 		}
 		en = true
 	}
-	cli.UnLockClient()
 	return
 }
 
+/*
+// 将数据写给User端
+func (c *Client) gowrite(buff <-chan []byte, out chan<- int) {
+	for {
+		select {
+		case data, ok := <-buff: //c.towr:
+			if !ok {
+				runtime.Goexit() //return
+			}
+			_, err := c.conn.Write(data)
+			if err != nil { // && err != io.EOF {
+				out <- 0 //c.channel_err <- err
+				//fmt.Println("gowrite is err")
+			}
+		}
+	}
+}*/
+
 func (c *Client) Send(msg string) error {
 	_, err := c.conn.Write([]byte(msg))
 	return err
@@ -355,6 +475,14 @@ func New(address string) *server {
 
 func NewWithTLS(address, certFile, keyFile string) *server {
 	log.Println("creating server with address:", address)
+
+	/*cert, _ := tls.LoadX509KeyPair(certFile, keyFile)
+	config := tls.Config{
+		Certificates:             []tls.Certificate{cert},
+		PreferServerCipherSuites: true,
+		//ClientAuth:   tls.RequireAndVerifyClientCert,
+		//ClientCAs: pool,
+	}*/
 	conf, err := serverTLSConf(certFile, keyFile)
 	// sconf.ClientAuth = tls.RequireAndVerifyClientCert
 	if err != nil {