Browse Source

完成相机模块后台服务代码编写

niujiuru 1 week ago
parent
commit
6a58a77f40
3 changed files with 220 additions and 8 deletions
  1. 18 8
      camera-capture.service/main.go
  2. 168 0
      camera-capture.service/rpc_handler.go
  3. 34 0
      camera-capture.service/test.txt

+ 18 - 8
camera-capture.service/main.go

@@ -24,8 +24,9 @@ var (
 )
 
 const (
-	network    = "tcp" // http -> tcp
-	listenAddr = "127.0.0.1:7003"
+	eth1AddrCIDR = "192.168.100.1/24"
+	network      = "tcp" // http -> tcp
+	listenAddr   = "127.0.0.1:7003"
 )
 
 type program struct {
@@ -44,13 +45,15 @@ func (p *program) Start(s service.Service) error {
 	baseapp.InitLogger(logCfgFile)
 	baseapp.Logger.Infof("App Version: %s, Build Time: %s", Version, BuildTime)
 
-	if !hk_takephoto.ModuleInit() || !dh_takephoto.ModuleInit() {
-		return errors.New("photo module init failed")
+	if !hk_takephoto.ModuleInit() {
+		return errors.New("hk camera module init failed")
 	}
 
-	camera.SetWaitAEDoneForTakePhoto(0)
+	if !dh_takephoto.ModuleInit() {
+		return errors.New("dh camera module init failed")
+	}
 
-	if err := camera.SetupEth1ForGigeCamera("192.168.100.1/24"); err != nil {
+	if err := camera.SetupEth1ForGigeCamera(eth1AddrCIDR); err != nil {
 		return errors.New("failed to setup eth1 address")
 	}
 
@@ -61,7 +64,7 @@ func (p *program) Start(s service.Service) error {
 
 	methods := make(jsonrpc2.MethodMap)
 
-	//////////////////////////////////////////////////////////
+	//////////////////////////基础功能//////////////////////////
 	_getBuildVer := servicelib.MakeGetBuildVer(
 		Version, BuildTime)
 	methods["basic.getBuildVer"] = _getBuildVer // 获取软件版本
@@ -71,7 +74,14 @@ func (p *program) Start(s service.Service) error {
 	methods["basic.setLogLevel"] = _setLogLevel // 设置日志级别
 	_saveLogConf := servicelib.SaveLogConf
 	methods["basic.saveLogConf"] = _saveLogConf // 保存日志设置
-	//////////////////////////////////////////////////////////
+	//////////////////////////网口相机//////////////////////////
+	methods["core.setGigeCameraPower"] = setGigeCameraPower
+	methods["core.checkGigeCamera"] = checkGigeCamera
+	//////////////////////////相机数量//////////////////////////
+	methods["core.getSupportedCameraCount"] = getSupportedCameraCount
+	//////////////////////////拍照取图//////////////////////////
+	methods["core.setWaitAEDoneForTakePhoto"] = setWaitAEDoneForTakePhoto
+	methods["core.takePhoto"] = takePhoto
 
 	err = p.core_server.RegisterMethods(methods)
 	if err != nil {

+ 168 - 0
camera-capture.service/rpc_handler.go

@@ -1 +1,169 @@
 package main
+
+import (
+	"context"
+	"encoding/json"
+	"strconv"
+	"strings"
+
+	"hnyfkj.com.cn/rtu/linux/camera"
+	"hnyfkj.com.cn/rtu/linux/dh_takephoto"
+	"hnyfkj.com.cn/rtu/linux/hk_takephoto"
+	"hnyfkj.com.cn/rtu/linux/utils/jsonrpc2"
+)
+
+func setGigeCameraPower(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
+	var params map[string]string
+	if err := json.Unmarshal(req.Params, &params); err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
+	}
+
+	enable, ok := params["enable"]
+	if !ok || enable == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'enable' parameter")
+	}
+
+	var on bool
+	switch {
+	case strings.EqualFold(enable, "true"), enable == "1":
+		on = true
+	case strings.EqualFold(enable, "false"), enable == "0":
+		on = false
+	default:
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "invalid 'enable' value")
+	}
+
+	if err := camera.PowerOnGigeCamera(on); err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInternal, err.Error())
+	}
+
+	return jsonrpc2.BuildResponse(req, "success", nil)
+}
+
+func checkGigeCamera(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
+	var params map[string]string
+	if err := json.Unmarshal(req.Params, &params); err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
+	}
+
+	ip, ok := params["ip"]
+	if !ok || ip == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'ip' parameter")
+	}
+
+	prefix, ok := params["prefix"]
+	if !ok || prefix == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'prefix' parameter")
+	}
+
+	gigeAddrCIDR := ip + "/" + prefix
+	equal, err := camera.CidrEqualSemantic(eth1AddrCIDR, gigeAddrCIDR)
+	if err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
+	}
+
+	if !equal {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "gige camera ip not in network")
+	}
+
+	if err := camera.PingOnce(ip, 1); err != nil {
+		return jsonrpc2.BuildError(req, -32001, err.Error())
+	}
+
+	return jsonrpc2.BuildResponse(req, "success", nil)
+}
+
+func getSupportedCameraCount(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
+	var params map[string]string
+	if err := json.Unmarshal(req.Params, &params); err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
+	}
+
+	cameraType, ok := params["type"]
+	if !ok || cameraType == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'type' parameter")
+	}
+
+	var count int
+
+	switch strings.ToLower(cameraType) {
+	case "all":
+		count = camera.GetSupportedCameraCount()
+	case "hk":
+		count = hk_takephoto.GetHKCameraCount()
+	case "dh":
+		count = dh_takephoto.GetDHCameraCount()
+	default:
+		return jsonrpc2.BuildError(req, -32001, "unsupported camera type")
+	}
+
+	return jsonrpc2.BuildResponse(req, strconv.Itoa(count), nil)
+}
+
+func setWaitAEDoneForTakePhoto(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
+	var params map[string]string
+	if err := json.Unmarshal(req.Params, &params); err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
+	}
+
+	waitAE, ok := params["waitAE"]
+	if !ok || waitAE == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'waitAE' parameter")
+	}
+
+	switch waitAE {
+	case "0":
+		camera.SetWaitAEDoneForTakePhoto(0)
+	case "1":
+		camera.SetWaitAEDoneForTakePhoto(1)
+	default:
+		return jsonrpc2.BuildError(req, -32001, "invalid 'waitAE' value")
+	}
+
+	return jsonrpc2.BuildResponse(req, "success", nil)
+}
+
+func takePhoto(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
+	var params map[string]string
+	if err := json.Unmarshal(req.Params, &params); err != nil {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
+	}
+
+	format, ok := params["format"]
+	if !ok || format == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'format' parameter")
+	}
+
+	outFilename, ok := params["outFilename"]
+	if !ok || outFilename == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'outFilename' parameter")
+	}
+
+	timeoutMs, ok := params["timeoutMs"]
+	if !ok || timeoutMs == "" {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'timeoutMs' parameter")
+	}
+
+	if !strings.EqualFold(format, "jpg") {
+		return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "unsupported format")
+	}
+
+	timeout, err := strconv.Atoi(timeoutMs)
+	if err != nil || timeout <= 0 {
+		timeout = 300
+	}
+
+	imgMark, err := camera.TakePhoto(
+		camera.IMG_TYPE_JPG,
+		outFilename,
+		timeout,
+	)
+	if err != nil {
+		return jsonrpc2.BuildError(req, -32001, err.Error())
+	}
+
+	return jsonrpc2.BuildResponse(req, map[string]interface{}{
+		"status": "success",
+		"mark":   imgMark,
+	}, nil)
+}

+ 34 - 0
camera-capture.service/test.txt

@@ -0,0 +1,34 @@
+接口测试:
+
+// ping联通测试
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"ping","params":{},"id":1}'
+
+// 获取软件版本
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"basic.getBuildVer","params":{},"id":2}'
+
+// 获取日志级别
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"basic.getLogLevel","params":{},"id":3}'
+
+// 设置日志级别
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"basic.setLogLevel","params":{"log_level":"trace"},"id":4}'
+
+// 保存日志设置
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"basic.saveLogConf","params":{},"id":5}'
+
+// 打开网口相机
+// 参数: "true"-网口相机供电; "false"-网口相机断电
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"core.setGigeCameraPower","params":{"enable":"true"},"id":6}'
+
+// PING网口相机
+// 参数:目前固定网口相机的IP地址: 192.168.100.100/24
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"core.checkGigeCamera","params":{"ip":"192.168.100.100", "prefix": "24"},"id":7}'
+
+// 得到相机数量
+// 参数: 海康-"hk"; 大华-"dh"; 所有-"all"
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"core.getSupportedCameraCount","params":{"type":"all"},"id":8}'
+
+// 相机处于自动曝光模式时, 设置是否等待曝光稳定后再拍照, 参数: waitAE: 0=不等待, 1=等待(默认)
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"core.setWaitAEDoneForTakePhoto","params":{"waitAE":"1"},"id":9}'
+
+// 请求相机拍照
+curl -s -X POST http://127.0.0.1:7003/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"core.takePhoto","params":{"format":"jpg", "outFilename":"./test.jpg", "timeoutMs":"300"},"id":10}'