| | |
| | | return |
| | | } |
| | | |
| | | params.DeviceID = conf.Conf.System.DeviceId |
| | | params.DeviceID = conf.Conf.CurrentDeviceID |
| | | if params.Method == constvar.PlcMethodModbusTCP && (params.Address == "" || params.Port == 0) { |
| | | ctx.FailWithMsg(ecode.ParamsErr, "当接口方式为modbusTCP时,地址和端口号不能为空") |
| | | return |
New file |
| | |
| | | package v1 |
| | | |
| | | import ( |
| | | "apsClient/conf" |
| | | "apsClient/constvar" |
| | | "apsClient/crontask" |
| | | "apsClient/model/request" |
| | | "apsClient/model/response" |
| | | _ "apsClient/model/response" |
| | | "apsClient/pkg/contextx" |
| | | "apsClient/pkg/ecode" |
| | | "apsClient/pkg/logx" |
| | | "apsClient/service" |
| | | "github.com/gin-gonic/gin" |
| | | ) |
| | | |
| | | type DeviceApi struct{} |
| | | |
| | | // Set |
| | | // @Tags 设备 |
| | | // @Summary 设置当前设备id |
| | | // @Produce application/json |
| | | // @Param object body request.SetCurrentDevice true "查询参数" |
| | | // @Success 200 {object} contextx.Response{} "成功" |
| | | // @Router /v1/device/set [post] |
| | | func (slf *DeviceApi) Set(c *gin.Context) { |
| | | var params request.SetCurrentDevice |
| | | ctx, ok := contextx.NewContext(c, ¶ms) |
| | | if !ok { |
| | | return |
| | | } |
| | | if params.CurrentDeviceID != "" { |
| | | ctx.Fail(ecode.ParamsErr) |
| | | return |
| | | } |
| | | list, err := service.GetDeviceIDList() |
| | | findFlag := false |
| | | for _, item := range list { |
| | | if item == params.CurrentDeviceID { |
| | | findFlag = true |
| | | } |
| | | } |
| | | if !findFlag { |
| | | ctx.Fail(ecode.ParamsErr) |
| | | return |
| | | } |
| | | service.SetDeviceIDToFile(params.CurrentDeviceID) |
| | | conf.Conf.SerfClusterStatus = params.CurrentDeviceID |
| | | err = crontask.RestartTask(conf.Conf.SerfClusterStatus != constvar.SerfClusterStatusSlave) |
| | | if err != nil { |
| | | logx.Errorf("restart task failed:%v", err) |
| | | ctx.Fail(ecode.UnknownErr) |
| | | return |
| | | } |
| | | |
| | | ctx.Ok() |
| | | } |
| | | |
| | | // DeviceList |
| | | // @Tags Device |
| | | // @Summary 获取当前面板绑定的设备列表 |
| | | // @Produce application/json |
| | | // @Success 200 {object} contextx.Response{data=response.DeviceListResponse} "成功" |
| | | // @Router /v1/device/list [post] |
| | | func (slf *DeviceApi) DeviceList(c *gin.Context) { |
| | | ctx, ok := contextx.NewContext(c, nil) |
| | | if !ok { |
| | | return |
| | | } |
| | | list, err := service.GetDeviceIDList() |
| | | if err != nil { |
| | | ctx.Fail(ecode.DBErr) |
| | | return |
| | | } |
| | | resp := response.DeviceListResponse{ |
| | | SystemDeviceID: conf.Conf.System.DeviceId, |
| | | CurrentDeviceID: conf.Conf.CurrentDeviceID, |
| | | DeviceIDList: list, |
| | | } |
| | | ctx.OkWithDetailed(resp) |
| | | } |
| | |
| | | ctx.FailWithMsg(ecode.NeedConfirmedErr, err.Error()) |
| | | return |
| | | } |
| | | |
| | | taskCount := service.NewTaskService().NewTaskCount() |
| | | taskCount := service.NewTaskService().NewTaskCount(conf.Conf.CurrentDeviceID) |
| | | params.Page = 1 |
| | | if params.PageSize <= 0 { |
| | | if params.TaskMode == constvar.TaskModeUnStarted { |
| | |
| | | taskMode = params.TaskMode |
| | | } |
| | | |
| | | taskResponse, code := service.NewTaskService().GetTask(params.Page, params.PageSize, taskMode, nil) //取进行中的或未开始的 |
| | | taskResponse, code := service.NewTaskService().GetTask(params.DeviceID, params.Page, params.PageSize, taskMode, nil) //取进行中的或未开始的 |
| | | if code != ecode.OK { |
| | | ctx.Fail(code) |
| | | return |
| | |
| | | if existsChannel[int32(i)] { |
| | | continue |
| | | } |
| | | taskResponseTemp, code := service.NewTaskService().GetTask(params.Page, 1, constvar.TaskModeLastFinished, []int32{int32(i)}) //取上一个完成的 |
| | | taskResponseTemp, code := service.NewTaskService().GetTask(params.DeviceID, params.Page, 1, constvar.TaskModeLastFinished, []int32{int32(i)}) //取上一个完成的 |
| | | if code != ecode.OK { |
| | | ctx.Fail(code) |
| | | return |
| | |
| | | ctx.FailWithMsg(ecode.NeedConfirmedErr, err.Error()) |
| | | return |
| | | } |
| | | params.DeviceID = conf.Conf.CurrentDeviceID |
| | | |
| | | dataMap := make(map[int32]*response.TaskResponse, channelAmount) |
| | | if params.Channel != nil { |
| | |
| | | } |
| | | |
| | | func getTaskResponseByChannel(params request.TaskListByChannel, channel int32) (taskResponse *response.TaskResponse, err error) { |
| | | taskResponse, err = service.NewTaskService().GetTask2(params.Offset, params.Limit, []int32{channel}, params.Type) //取进行中的或未开始的 |
| | | taskResponse, err = service.NewTaskService().GetTask2(params.DeviceID, params.Offset, params.Limit, []int32{channel}, params.Type) //取进行中的或未开始的 |
| | | if err != nil { |
| | | return |
| | | } |
| | |
| | | PLC plc |
| | | |
| | | Prompt Prompt |
| | | |
| | | CurrentDeviceID string //设置当前面板控制的设备 |
| | | |
| | | SerfClusterStatus string |
| | | } |
| | | ) |
| | | |
| | |
| | | } |
| | | return "" |
| | | } |
| | | |
| | | const ( |
| | | SerfClusterStatusNull = "" //未加入集群 |
| | | SerfClusterStatusMaster = "master" //集群master |
| | | SerfClusterStatusSlave = "slave" //集群slave |
| | | ) |
| | |
| | | |
| | | import ( |
| | | "apsClient/conf" |
| | | "apsClient/constvar" |
| | | "apsClient/crontask" |
| | | "apsClient/model" |
| | | "apsClient/nsq" |
| | |
| | | "apsClient/pkg/sqlitex" |
| | | "apsClient/router" |
| | | "apsClient/serf" |
| | | "apsClient/service" |
| | | "apsClient/service/plc_address" |
| | | "fmt" |
| | | "log" |
| | |
| | | return |
| | | } |
| | | |
| | | //从文件里读取当前生产设备id |
| | | conf.Conf.CurrentDeviceID = service.ReadDeviceIDFromFile() |
| | | if conf.Conf.CurrentDeviceID == "" { |
| | | conf.Conf.CurrentDeviceID = conf.Conf.System.DeviceId |
| | | } |
| | | |
| | | // 判断当前集群状态 |
| | | logx.Infof("current agent.ClusterStatus:%v", agent.ClusterStatus) |
| | | log.Println("current agent.ClusterStatus:", agent.ClusterStatus) |
| | | |
| | | conf.Conf.SerfClusterStatus = agent.ClusterStatus |
| | | |
| | | if agent.ClusterStatus != "slave" { |
| | | if err := nsq.Init(); err != nil { |
| | | logx.Errorf("nsq Init err:%v", err) |
| | |
| | | } |
| | | |
| | | func serfClusterEvent(stat int) { |
| | | ChangeClusterStatus(stat) |
| | | switch stat { |
| | | case serf.EventCreateCluster, serf.EventSlave2Master, serf.EventLeaveCluster: |
| | | if err := nsq.Init(); err != nil { //开启nsq |
| | |
| | | |
| | | logx.Infof("serf cluster event: %v", stat) |
| | | } |
| | | |
| | | func ChangeClusterStatus(stat int) { |
| | | switch stat { |
| | | case serf.EventSlave2Master, serf.EventCreateCluster: |
| | | conf.Conf.SerfClusterStatus = constvar.SerfClusterStatusMaster |
| | | case serf.EventLeaveCluster: |
| | | conf.Conf.SerfClusterStatus = constvar.SerfClusterStatusNull |
| | | case serf.EventJoinCluster, serf.EventMaster2Slave: |
| | | conf.Conf.SerfClusterStatus = constvar.SerfClusterStatusSlave |
| | | } |
| | | } |
| | |
| | | DeviceID string `gorm:"column:device_id;type:varchar(255);not null;unique" json:"deviceID"` //设备编号 |
| | | ExtChannelAmount int `gorm:"type:tinyint;default:0" json:"extChannelAmount"` |
| | | Procedures string `gorm:"column:procedure;type:varchar(255);not null;default ''" json:"procedures"` //设备支持的工序,用逗号分隔 |
| | | DeviceMac string `gorm:"type:varchar(255);" json:"deviceMac"` //绑定的工控机设备ID |
| | | ProceduresArr []string `gorm:"-" json:"procedureAdd"` //设备支持的工序切片 |
| | | } |
| | | |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *DeviceSearch) SetDeviceMac(deviceMac string) *DeviceSearch { |
| | | slf.DeviceMac = deviceMac |
| | | return slf |
| | | } |
| | | |
| | | func (slf *DeviceSearch) SetDeviceIds(deviceIds []string) *DeviceSearch { |
| | | slf.DeviceIDs = deviceIds |
| | | return slf |
| | |
| | | db = db.Where("device_id = ?", slf.DeviceID) |
| | | } |
| | | |
| | | if slf.DeviceMac != "" { |
| | | db = db.Where("device_mac = ?", slf.DeviceMac) |
| | | } |
| | | |
| | | if len(slf.DeviceIDs) != 0 { |
| | | db = db.Where("device_id in (?)", slf.DeviceIDs) |
| | | } |
| | |
| | | type GetById struct { |
| | | ID uint `json:"id"` // 主键ID |
| | | } |
| | | |
| | | type SetCurrentDevice struct { |
| | | CurrentDeviceID string `json:"currentDeviceID,omitempty"` //当前选定的生产设备 |
| | | } |
| | |
| | | type TaskList struct { |
| | | PageInfo |
| | | TaskMode constvar.TaskMode `json:"taskMode" form:"taskMode"` |
| | | DeviceID string `json:"deviceID"` |
| | | } |
| | | |
| | | type SendProcessParams struct { |
| | |
| | | |
| | | // TaskListByChannel 按channel返回任务列表请求参数 |
| | | type TaskListByChannel struct { |
| | | Offset int `json:"offset,omitempty" form:"offset"` //默认0 |
| | | Limit int `json:"limit,omitempty" form:"limit"` //默认3 |
| | | Type QueryType `json:"type,omitempty" form:"type"` //1 未完成 2 今天未完成 3 已完成 |
| | | Channel *int32 `json:"channel" form:"channel"` //通道号。不传取全部的 |
| | | Offset int `json:"offset,omitempty" form:"offset"` //默认0 |
| | | Limit int `json:"limit,omitempty" form:"limit"` //默认3 |
| | | Type QueryType `json:"type,omitempty" form:"type"` //1 未完成 2 今天未完成 3 已完成 |
| | | Channel *int32 `json:"channel" form:"channel"` //通道号。不传取全部的 |
| | | DeviceID string `json:"deviceID"` |
| | | } |
| | | |
| | | type QueryType int |
| | |
| | | Event string |
| | | Data interface{} |
| | | } |
| | | |
| | | type DeviceListResponse struct { |
| | | SystemDeviceID string `json:"systemDeviceID,omitempty"` //工控机设备ID |
| | | CurrentDeviceID string `json:"currentDeviceID,omitempty"` //当前选定的生产设备 |
| | | DeviceIDList []string `json:"deviceIDList,omitempty"` //生产设备id列表 |
| | | } |
| | |
| | | if v, ok := defaultCacheStore.Get(fmt.Sprintf(CurrentTaskCacheKey, channel)); ok { |
| | | return v.(bool) |
| | | } |
| | | _, err := model.NewProceduresSearch(nil).SetDeviceId(conf.Conf.System.DeviceId).SetStatus(model.ProcedureStatusProcessing).SetChannels([]int32{channel}).First() |
| | | _, err := model.NewProceduresSearch(nil).SetDeviceId(conf.Conf.CurrentDeviceID).SetStatus(model.ProcedureStatusProcessing).SetChannels([]int32{channel}).First() |
| | | if err == gorm.ErrRecordNotFound { |
| | | defaultCacheStore.Add(fmt.Sprintf(CurrentTaskCacheKey, channel), false) |
| | | return false |
New file |
| | |
| | | package service |
| | | |
| | | import ( |
| | | "apsClient/conf" |
| | | "apsClient/model" |
| | | "fmt" |
| | | "os" |
| | | ) |
| | | |
| | | func GetDeviceIDList() (deviceIds []string, err error) { |
| | | devices, err := model.NewDeviceSearch().SetDeviceMac(conf.Conf.System.DeviceId).FindNotTotal() |
| | | if err != nil { |
| | | return nil, err |
| | | } |
| | | deviceIds = make([]string, 0, len(devices)) |
| | | for _, device := range devices { |
| | | deviceIds = append(deviceIds, device.DeviceID) |
| | | } |
| | | return deviceIds, nil |
| | | } |
| | | |
| | | const deviceIDFile = "currentDeviceID.txt" |
| | | |
| | | func SetDeviceIDToFile(deviceID string) { |
| | | err := os.WriteFile(deviceIDFile, []byte(deviceID), 0644) |
| | | if err != nil { |
| | | fmt.Printf("无法写入设备ID到文件: %v\n", err) |
| | | } else { |
| | | fmt.Println("设备ID已写入文件") |
| | | } |
| | | } |
| | | |
| | | func ReadDeviceIDFromFile() string { |
| | | data, err := os.ReadFile(deviceIDFile) |
| | | if err != nil { |
| | | fmt.Printf("无法读取设备ID文件: %v\n", err) |
| | | return "" |
| | | } |
| | | return string(data) |
| | | } |
| | |
| | | } |
| | | |
| | | func (slf DevicePlcService) GetDevicePlc() (*model.DevicePlc, int) { |
| | | DevicePlc, err := model.NewDevicePlcSearch().SetDeviceId(conf.Conf.System.DeviceId).First() |
| | | DevicePlc, err := model.NewDevicePlcSearch().SetDeviceId(conf.Conf.CurrentDeviceID).First() |
| | | if err == gorm.ErrRecordNotFound { |
| | | return &model.DevicePlc{ |
| | | DeviceID: "", |
| | |
| | | ) |
| | | |
| | | func GetProcessModelList(offset, limit int, currentNumber string) (list []*model.ProcessModel, total int64, err error) { |
| | | device, err := model.NewDeviceSearch().SetDeviceId(conf.Conf.System.DeviceId).First() |
| | | device, err := model.NewDeviceSearch().SetDeviceId(conf.Conf.CurrentDeviceID).First() |
| | | if err != nil { |
| | | return |
| | | } |
| | |
| | | var ok bool |
| | | progressCache, ok = ProgressCacheGet(channel) |
| | | if !ok { |
| | | progressCache, err = model.NewProductionProgressSearch(nil).SetDeviceId(conf.Conf.System.DeviceId).SetChannel(channel).SetOrder("id desc").First() |
| | | progressCache, err = model.NewProductionProgressSearch(nil).SetDeviceId(conf.Conf.CurrentDeviceID).SetChannel(channel).SetOrder("id desc").First() |
| | | if err == gorm.ErrRecordNotFound { |
| | | return nil, errors.New("progress not found") |
| | | } |
| | |
| | | package service |
| | | |
| | | import ( |
| | | "apsClient/conf" |
| | | "apsClient/constvar" |
| | | "apsClient/model" |
| | | "apsClient/model/common" |
| | |
| | | } |
| | | |
| | | // GetTask 获取任务,未完成的开始时间小于等于当前时间,结束时间大于当前时间的任务 |
| | | func (slf TaskService) GetTask(page, pageSize int, mode constvar.TaskMode, channels []int32) (taskResp *response.TaskResponse, code int) { |
| | | func (slf TaskService) GetTask(deviceID string, page, pageSize int, mode constvar.TaskMode, channels []int32) (taskResp *response.TaskResponse, code int) { |
| | | var taskList []*response.TaskData |
| | | var count int64 |
| | | var workers []*common.ProcedureWorker |
| | |
| | | workOrderIds []string |
| | | ) |
| | | search := model.NewProceduresSearch(nil). |
| | | SetDeviceId(conf.Conf.System.DeviceId). |
| | | SetDeviceId(deviceID). |
| | | SetPage(page, pageSize) |
| | | |
| | | if mode == constvar.TaskModeUnStarted { |
| | |
| | | } |
| | | return taskResp, ecode.OK |
| | | } |
| | | func (slf TaskService) NewTaskCount() (count int64) { |
| | | count, _ = model.NewProceduresSearch(nil).SetDeviceId(conf.Conf.System.DeviceId).SetStatus(model.ProcedureStatusWaitProcess).Count() |
| | | func (slf TaskService) NewTaskCount(deviceId string) (count int64) { |
| | | count, _ = model.NewProceduresSearch(nil).SetDeviceId(deviceId).SetStatus(model.ProcedureStatusWaitProcess).Count() |
| | | return count |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // GetTask2 获取任务列表2 |
| | | func (slf TaskService) GetTask2(offset, limit int, channels []int32, queryType request.QueryType) (taskResp *response.TaskResponse, err error) { |
| | | func (slf TaskService) GetTask2(deviceID string, offset, limit int, channels []int32, queryType request.QueryType) (taskResp *response.TaskResponse, err error) { |
| | | var taskList []*response.TaskData |
| | | var count int64 |
| | | var workers []*common.ProcedureWorker |
| | |
| | | workOrderIds []string |
| | | ) |
| | | search := model.NewProceduresSearch(nil). |
| | | SetDeviceId(conf.Conf.System.DeviceId). |
| | | SetDeviceId(deviceID). |
| | | SetOffset(offset, limit).SetChannels(channels) |
| | | nowTs := time.Now().Unix() |
| | | switch queryType { |