作者 yangfu

feat:增加设备生产效率统计

... ... @@ -73,7 +73,7 @@ func AutoFlushDeviceDailyRunningRecordOEE(ctx context.Context) error {
device, err := deviceRepository.FindOne(map[string]interface{}{"deviceId": v.DeviceId})
if device != nil && err == nil {
if device.Ext.DeviceExt != nil {
pu = utils.Round(float64((v.DeviceRunningRecordInfo.Count*100.0)/(total/device.Ext.DeviceExt.UnitProductionSecTime)), 1)
pu = utils.Round((float64(v.DeviceRunningRecordInfo.Count)*100.0)/(float64(total)/device.Ext.DeviceExt.UnitProductionSecTime), 1)
}
}
// 工段对应二级品数据
... ...
... ... @@ -35,7 +35,7 @@ type CreateDeviceCommand struct {
RiskLevel int `cname:"风险等级 1:高 2:中 3:低" json:"riskLevel" valid:"Required"`
// 标准工时 生产单个产品的时间(单位:秒)
UnitProductionSecTime int `cname:"标准工时" json:"unitProductionSecTime"`
UnitProductionSecTime float64 `cname:"标准工时" json:"unitProductionSecTime"`
}
func (createDeviceCommand *CreateDeviceCommand) Valid(validation *validation.Validation) {
... ...
... ... @@ -2,6 +2,7 @@ package domain
import (
"fmt"
"strconv"
"time"
)
... ... @@ -111,7 +112,7 @@ func (device *Device) Update(data map[string]interface{}) error {
device.Ext.OrgName = orgName.(string)
}
if unitProductionSecTime, ok := data["unitProductionSecTime"]; ok {
device.Ext.DeviceExt.UnitProductionSecTime = unitProductionSecTime.(int)
device.Ext.DeviceExt.UnitProductionSecTime, _ = strconv.ParseFloat(fmt.Sprintf("%v", unitProductionSecTime), 64)
}
device.UpdatedAt = time.Now()
return nil
... ...
... ... @@ -138,7 +138,7 @@ func (d *DeviceRunningRecordInfo) AddDeviceRunningData(t time.Time, data *Device
d.AddTimeLineDeviceStatus(t, data)
//d.OEE (time.Now().Sub(utils.GetZeroTime(time.Now())).Minutes())
d.TimeUtilization = utils.Round((d.UpTime*100)/(24*60), 2)
//d.TimeUtilization = utils.Round((d.UpTime*100)/(24*60), 2)
//d.PerformanceUtilization
//d.QualificationUtilization
}
... ... @@ -173,6 +173,7 @@ func (d *DeviceRunningRecordInfo) ResetUpTime() float64 {
// 重置设备运行OEE
func (d *DeviceRunningRecordInfo) ResetOEE(pu, qu float64) float64 {
d.TimeUtilization = utils.Round((d.UpTime*100)/(24*60), 1)
d.PerformanceUtilization = pu
d.QualificationUtilization = qu
d.OEE = utils.Round((d.TimeUtilization*d.PerformanceUtilization*d.QualificationUtilization)/10000, 1)
... ...
... ... @@ -3,7 +3,7 @@ package domain
// DeviceExt 设备扩展
type DeviceExt struct {
// 生产单个产品的时间(单位:秒)
UnitProductionSecTime int `json:"unitProductionSecTime"`
UnitProductionSecTime float64 `json:"unitProductionSecTime"`
// 是否是车间设备,如果这个设备有上报过数据,标记 1 默认0
IsProductDevice int `json:"isProductDevice"`
}
... ...
... ... @@ -59,6 +59,7 @@ from ts_product_list
return nil
}
// 车间性能
func (dao *DeviceDailyRunningRecordDao) WorkshopProductionEfficiencyStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error {
tx := dao.transactionContext.PgTx
... ... @@ -84,6 +85,38 @@ select round(avg(oee),1) oee,round(avg(tu),1) tu,round(avg(pu),1)pu, round(avg(q
return nil
}
// 设备性能
func (dao *DeviceDailyRunningRecordDao) DeviceProductionEfficiencyStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error {
tx := dao.transactionContext.PgTx
sql := fmt.Sprintf(`
with device_running as(
select
cast(device_running_record_info->>'oee' as DECIMAL) oee,
cast(device_running_record_info->>'tu' as DECIMAL) tu,
cast(device_running_record_info->>'pu' as DECIMAL) pu,
cast(device_running_record_info->>'qu' as DECIMAL) qu,
cast(device_running_record_info->>'upTime' as DECIMAL) upTime,
device_id,
device_code
from manufacture.device_daily_running_record
where
company_id = ?
and org_id = ?
and work_station->>'workshopId'='?'
and created_at>=?
) ,device_running_oee as(
select round(avg(oee),1) oee,round(avg(tu),1) tu,round(avg(pu),1)pu, round(avg(qu),1) qu,round(sum(upTime)/60,0) up_time,count(0) t,device_id,max(device_code) device_code from device_running
GROUP BY device_id
)
select * from device_running_oee
`)
if _, err := tx.Query(result, sql, companyId, orgId, workshopId, beginTime); err != nil {
return err
}
return nil
}
// 时段产能
func (dao *DeviceDailyRunningRecordDao) TimeSectionProductRecord(companyId, orgId, workshopId int, lineId int, sectionName string, beginTime time.Time, result interface{}) error {
... ...
... ... @@ -109,3 +109,28 @@ func (dao *WorkshopProductRecordDao) SearchWorkshopProductRecord(queryOptions ma
return int64(count), employeeProductRecords, nil
}
}
// 设备性能
func (dao *WorkshopProductRecordDao) WorkStationProductionStatistics(companyId, orgId, workshopId int, beginTime time.Time, result interface{}) error {
tx := dao.transactionContext.PgTx
sql := fmt.Sprintf(`
with work_station_product as(
select work_station->>'workStationId' work_station_id,
COALESCE(cast(product_record_info ->>'inputWeight' as DECIMAL),0) input_weight,
COALESCE(cast(product_record_info ->>'secondLevelWeight' as DECIMAL),0) second_level_weight,
product_date
from manufacture.workshop_product_record
where company_id = ?
and org_id = ?
and work_station->>'workshopId'='?'
and created_at>=?
)
select work_station_id,sum(input_weight) input_weight,sum(second_level_weight) second_level_weight from work_station_product
group by work_station_id
`)
if _, err := tx.Query(result, sql, companyId, orgId, workshopId, beginTime); err != nil {
return err
}
return nil
}
... ...
... ... @@ -21,6 +21,8 @@ const (
ProportionOfSecondLevelStatistics = "ProportionOfSecondLevelStatistics"
// 车间生产效率
WorkshopProductionEfficiencyStatistics = "WorkshopProductionEfficiencyStatistics"
// 设备生产效率
DeviceProductionEfficiencyStatistics = "DeviceProductionEfficiencyStatistics"
// 设备运行统计
DeviceRunningStatistics = "DeviceRunningStatistics"
// 设备运行信息
... ... @@ -51,6 +53,9 @@ func (ptr *PGCommonStatisticsService) CommonStatistics(actionType string, queryO
case WorkshopProductionEfficiencyStatistics:
result, err = ptr.WorkshopProductionEfficiencyStatistics(queryOptions)
break
case DeviceProductionEfficiencyStatistics:
result, err = ptr.DeviceProductionEfficiencyStatistics(queryOptions)
break
case DeviceRunningStatistics:
result, err = ptr.DeviceRunningStatistics(queryOptions)
break
... ... @@ -415,6 +420,105 @@ type DeviceInfo struct {
TUptime int `json:"t_uptime"`
}
// 设备生产效率统计
func (ptr *PGCommonStatisticsService) DeviceProductionEfficiencyStatistics(queryOptions map[string]interface{}) (interface{}, error) {
var request = &HourProductiveStatisticsRequest{}
if err := utils.LoadQueryObject(queryOptions, request); err != nil {
return nil, err
}
if request.WorkshopId == 0 {
request.WorkshopId = constant.MANUFACTURE_DEFAULT_WORKSHOPID
}
deviceRepository, _ := repository.NewDeviceRepository(ptr.transactionContext)
deviceDailyRunningRecordDao, _ := dao.NewDeviceDailyRunningRecordDao(ptr.transactionContext)
/*
1.生产设备
2.设备本月运行数据
*/
_, devices, err := deviceRepository.Find(map[string]interface{}{
"companyId": request.CompanyId,
"orgId": request.OrgId,
"workshopId": request.WorkshopId,
"orderBy": "device_name asc"})
if err != nil {
return nil, err
}
type record struct {
Oee float64 `json:"oee"`
Pu float64 `json:"pu"`
Tu float64 `json:"tu"`
Qu float64 `json:"qu"`
UpTime int `json:"up_time"`
T int `json:"t"`
DeviceId int `json:"device_id"`
DeviceCode string `json:"device_code"`
DeviceName string `json:"device_name"`
// 生产单个产品的时间(单位:秒)
UnitProductionSecTime float64 `json:"unit_time"`
// 投入量
InputWeight float64 `json:"input_weight"`
// 二级品
SecondLevelWeight float64 `json:"second_level_weight"`
}
var records = make([]*record, 0)
if err := deviceDailyRunningRecordDao.DeviceProductionEfficiencyStatistics(request.CompanyId,
request.OrgId,
request.WorkshopId,
utils.GetCurrentMonthFirstDay(time.Now()), &records); err != nil {
log.Logger.Error(err.Error())
return nil, err
}
type production struct {
WorkStationId string `json:"work_station_id"`
InputWeight float64 `json:"input_weight"`
SecondLevelWeight float64 `json:"second_level_weight"`
}
var productions = make([]*production, 0)
workshopProductRecordDao, _ := dao.NewWorkshopProductRecordDao(ptr.transactionContext)
if err := workshopProductRecordDao.WorkStationProductionStatistics(request.CompanyId,
request.OrgId,
request.WorkshopId,
utils.GetCurrentMonthFirstDay(time.Now()), &productions); err != nil {
log.Logger.Error(err.Error())
return nil, err
}
var response = make([]interface{}, 0)
for i := 0; i < len(devices); i++ {
d := devices[i]
if d.Ext == nil || d.Ext.DeviceExt == nil || d.Ext.DeviceExt.IsProductDevice == 0 {
continue
}
var r *record
for j := 0; j < len(records); j++ {
if d.DeviceCode == records[j].DeviceCode {
r = records[j]
break
}
}
if r != nil {
r.DeviceName = d.DeviceName
if d.Ext.DeviceExt != nil {
r.UnitProductionSecTime = d.Ext.DeviceExt.UnitProductionSecTime
}
for k := 0; k < len(productions); k++ {
if productions[k].WorkStationId == d.WorkStation.WorkStationId {
r.InputWeight = productions[k].InputWeight
r.SecondLevelWeight = productions[k].SecondLevelWeight
break
}
}
response = append(response, r)
}
}
return map[string]interface{}{
"devices": response,
}, nil
}
func NewPGCommonStatisticsService(transactionContext *pgTransaction.TransactionContext) (*PGCommonStatisticsService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
... ...
... ... @@ -12,6 +12,7 @@ func init() {
web.Post("/statistics/daily-productive-statistics", c.CommonStatisticsHandler("DailyProductiveStatistics"))
web.Post("/statistics/proportion-of-second-level-statistics", c.CommonStatisticsHandler("ProportionOfSecondLevelStatistics"))
web.Post("/statistics/workshop-production-efficiency-statistics", c.CommonStatisticsHandler("WorkshopProductionEfficiencyStatistics"))
web.Post("/statistics/device-production-efficiency-statistics", c.CommonStatisticsHandler("DeviceProductionEfficiencyStatistics"))
web.Post("/statistics/device-running-statistics", c.CommonStatisticsHandler("DeviceRunningStatistics"))
web.Post("/statistics/device-running-info", c.CommonStatisticsHandler("DeviceRunningInfo"))
}
... ...