/******************************************************************************* * Copyright 2017 Dell Inc. * Copyright (c) 2019 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. *******************************************************************************/ package dtos import ( "encoding/json" "github.com/winc-link/hummingbird/internal/models" "github.com/winc-link/hummingbird/internal/pkg/constants" "github.com/winc-link/hummingbird/internal/pkg/utils" "strconv" "strings" "time" ) type ThingModelTemplate struct { Properties []ThingModelTemplateProperties `json:"properties"` Events []ThingModelTemplateEvents `json:"events"` Services []ThingModelTemplateServices `json:"services"` } //------------------------------------------------------------ //array //{ //"childDataType":"TEXT", //"customFlag":true, //"dataType":"ARRAY", //"size":128 //} type ThingModelTemplateArray struct { ChildDataType string `json:"childDataType"` Size int `json:"size"` } //------------------------------------------------------------ //{ // "dataType":"DOUBLE", // "max":"23", // "min":"16", // "precise":7, // "step":"0.01", // "unit":"°C", // "unitName":"摄氏度" //} type ThingModelTemplateIntOrFloat struct { Max string `json:"max"` Min string `json:"min"` Step string `json:"step"` Unit string `json:"unit"` UnitName string `json:"unitName"` } //------------------------------------------------------------ //[ //{ //"dataType":"BOOL", //"name":"未查询", //"value":0 //}, //{ //"dataType":"BOOL", //"name":"查询", //"value":1 //} //] type ThingModelTemplateBool struct { Name string `json:"name"` Value int `json:"value"` } //------------------------------------------------------------ //{ //"dataType":"TEXT", //"length":255 //} type ThingModelTemplateText struct { Length int `json:"length"` } //------------------------------------------------------------ //{ //"dataType":"Date", //"length":255 //} type ThingModelTemplateDate struct { Length string `json:"length"` } //------------------------------------------------------------ //[ //{ //"dataType":"ENUM", //"name":"电源", //"value":0 //}, //{ //"dataType":"ENUM", //"name":"电池", //"value":1 //} //] type ThingModelTemplateEnum struct { Name string `json:"name"` Value int `json:"value"` } type ThingModelTemplateStruct struct { ChildDataType string `json:"childDataType"` ChildName string `json:"childName"` Identifier string `json:"identifier"` ChildSpecsDTO interface{} `json:"childSpecsDTO"` } //------------------------------------------------------------ // INT DOUBLE FLOAT TEXT ARRAY=> dataSpecs //BOOL ENUM STRUCT=> dataSpecsList type ThingModelTemplateProperties struct { Name string `json:"name"` Identifier string `json:"identifier"` DataType string `json:"dataType"` Description string `json:"description"` Required bool `json:"required"` RwFlag string `json:"rwFlag"` DataSpecs interface{} `json:"dataSpecs"` DataSpecsList interface{} `json:"dataSpecsList"` } func (t *ThingModelTemplateProperties) TransformModelTypeSpec() (typeSpec models.TypeSpec) { return getThingModelTemplateTypeSpec(t.DataType, t.DataSpecs, t.DataSpecsList) } func getModelSpecByDataType(specType constants.SpecsType, dto interface{}) string { switch specType { case constants.SpecsTypeInt, constants.SpecsTypeFloat: thingModelTemplateIntOrFloat := new(ThingModelTemplateIntOrFloat) b, _ := json.Marshal(dto) err := json.Unmarshal(b, thingModelTemplateIntOrFloat) if err != nil { return "" } var modelTypeSpecIntOrFloat models.TypeSpecIntOrFloat modelTypeSpecIntOrFloat.Max = thingModelTemplateIntOrFloat.Max modelTypeSpecIntOrFloat.Min = thingModelTemplateIntOrFloat.Min modelTypeSpecIntOrFloat.Step = thingModelTemplateIntOrFloat.Step modelTypeSpecIntOrFloat.Unit = thingModelTemplateIntOrFloat.Unit modelTypeSpecIntOrFloat.UnitName = thingModelTemplateIntOrFloat.UnitName return modelTypeSpecIntOrFloat.TransformTostring() case constants.SpecsTypeText: thingModelTemplateText := new(ThingModelTemplateText) b, _ := json.Marshal(dto) err := json.Unmarshal(b, thingModelTemplateText) if err != nil { return "" } var modelTypeSpecText models.TypeSpecText modelTypeSpecText.Length = strconv.Itoa(thingModelTemplateText.Length) return modelTypeSpecText.TransformTostring() case constants.SpecsTypeDate: var modelTypeSpecText models.TypeSpecDate return modelTypeSpecText.TransformTostring() case constants.SpecsTypeBool: thingModelTemplateBool := new([]ThingModelTemplateBool) b, _ := json.Marshal(dto) err := json.Unmarshal(b, thingModelTemplateBool) if err != nil { return "" } var modelTypeSpecBool models.TypeSpecBool modelTypeSpecBool = make(map[string]string) if thingModelTemplateBool != nil { for _, templateBool := range *thingModelTemplateBool { modelTypeSpecBool[strconv.Itoa(templateBool.Value)] = templateBool.Name } } return modelTypeSpecBool.TransformTostring() case constants.SpecsTypeEnum: thingModelTemplateEnum := new([]ThingModelTemplateEnum) b, _ := json.Marshal(dto) err := json.Unmarshal(b, thingModelTemplateEnum) if err != nil { return "" } var modelTypeSpecEunm models.TypeSpecEnum modelTypeSpecEunm = make(map[string]string) if thingModelTemplateEnum != nil { for _, templateEunm := range *thingModelTemplateEnum { modelTypeSpecEunm[strconv.Itoa(templateEunm.Value)] = templateEunm.Name } } return modelTypeSpecEunm.TransformTostring() case constants.SpecsTypeArray: thingModelTemplateArray := new(ThingModelTemplateArray) b, _ := json.Marshal(dto) err := json.Unmarshal(b, thingModelTemplateArray) if err != nil { return "" } var modelTypeSpecArray models.TypeSpecArray modelTypeSpecArray.Size = strconv.Itoa(thingModelTemplateArray.Size) modelTypeSpecArray.Item = models.Item{ Type: thingModelTemplateArray.ChildDataType, } return modelTypeSpecArray.TransformTostring() } return "" } func transformSpecType(specType string) constants.SpecsType { var specs constants.SpecsType switch specType { case "INT": specs = constants.SpecsTypeInt case "DOUBLE", "FLOAT": specs = constants.SpecsTypeFloat case "TEXT": specs = constants.SpecsTypeText case "ARRAY": specs = constants.SpecsTypeArray case "BOOL": specs = constants.SpecsTypeBool case "ENUM": specs = constants.SpecsTypeEnum case "STRUCT": specs = constants.SpecsTypeStruct case "DATE": specs = constants.SpecsTypeDate } return specs } //ASYNC SYNC type ThingModelTemplateServices struct { ServiceName string `json:"serviceName"` Identifier string `json:"identifier"` Description string `json:"description"` Required bool `json:"required"` CallType constants.CallType `json:"callType"` InputParams []ThingModelTemplateServicesInputParam `json:"inputParams"` OutParams []ThingModelTemplateServicesOutParam `json:"outParams"` } type ThingModelTemplateServicesInputParam struct { Name string `json:"name"` Identifier string `json:"identifier"` DataType string `json:"dataType"` DataSpecs interface{} `json:"dataSpecs"` DataSpecsList interface{} `json:"dataSpecsList"` } type ThingModelTemplateServicesOutParam struct { Name string `json:"name"` Identifier string `json:"identifier"` DataType string `json:"dataType"` DataSpecs interface{} `json:"dataSpecs"` DataSpecsList interface{} `json:"dataSpecsList"` } func (t *ThingModelTemplateServices) TransformModelInPutParams() (inPutParams models.InPutParams) { for _, datum := range t.InputParams { var inputOutput models.InputOutput inputOutput.Code = datum.Identifier inputOutput.Name = datum.Name inputOutput.TypeSpec = getThingModelTemplateTypeSpec(datum.DataType, datum.DataSpecs, datum.DataSpecsList) inPutParams = append(inPutParams, inputOutput) } return } func (t *ThingModelTemplateServices) TransformModelOutPutParams() (outPutParams models.OutPutParams) { for _, datum := range t.OutParams { var inputOutput models.InputOutput inputOutput.Code = datum.Identifier inputOutput.Name = datum.Name inputOutput.TypeSpec = getThingModelTemplateTypeSpec(datum.DataType, datum.DataSpecs, datum.DataSpecsList) outPutParams = append(outPutParams, inputOutput) } return } type ThingModelTemplateEvents struct { EventName string `json:"eventName"` EventType string `json:"eventType"` Identifier string `json:"identifier"` Description string `json:"description"` Required bool `json:"required"` OutputData []ThingModelTemplateEventsOutputData `json:"outputData"` } type ThingModelTemplateEventsOutputData struct { Name string `json:"name"` Identifier string `json:"identifier"` DataType string `json:"dataType"` Required bool `json:"required"` DataSpecs interface{} `json:"dataSpecs"` DataSpecsList interface{} `json:"dataSpecsList"` } func (t *ThingModelTemplateEvents) TransformModelOutputParams() (outPutParams models.OutPutParams) { for _, datum := range t.OutputData { var inputOutput models.InputOutput inputOutput.Code = datum.Identifier inputOutput.Name = datum.Name inputOutput.TypeSpec = getThingModelTemplateTypeSpec(datum.DataType, datum.DataSpecs, datum.DataSpecsList) outPutParams = append(outPutParams, inputOutput) } return outPutParams } func getThingModelTemplateTypeSpec(dataType string, dataSpecs, dataSpecsList interface{}) (typeSpec models.TypeSpec) { typeSpec.Type = transformSpecType(dataType) switch typeSpec.Type { case constants.SpecsTypeInt, constants.SpecsTypeFloat: thingModelTemplateIntOrFloat := new(ThingModelTemplateIntOrFloat) b, _ := json.Marshal(dataSpecs) err := json.Unmarshal(b, thingModelTemplateIntOrFloat) if err != nil { return } var modelTypeSpecIntOrFloat models.TypeSpecIntOrFloat modelTypeSpecIntOrFloat.Max = thingModelTemplateIntOrFloat.Max modelTypeSpecIntOrFloat.Min = thingModelTemplateIntOrFloat.Min modelTypeSpecIntOrFloat.Step = thingModelTemplateIntOrFloat.Step modelTypeSpecIntOrFloat.Unit = thingModelTemplateIntOrFloat.Unit modelTypeSpecIntOrFloat.UnitName = thingModelTemplateIntOrFloat.UnitName typeSpec.Specs = modelTypeSpecIntOrFloat.TransformTostring() case constants.SpecsTypeText: thingModelTemplateText := new(ThingModelTemplateText) b, _ := json.Marshal(dataSpecs) err := json.Unmarshal(b, thingModelTemplateText) if err != nil { return } var modelTypeSpecText models.TypeSpecText modelTypeSpecText.Length = strconv.Itoa(thingModelTemplateText.Length) typeSpec.Specs = modelTypeSpecText.TransformTostring() case constants.SpecsTypeDate: var modelTypeSpecText models.TypeSpecDate typeSpec.Specs = modelTypeSpecText.TransformTostring() case constants.SpecsTypeBool: thingModelTemplateBool := new([]ThingModelTemplateBool) b, _ := json.Marshal(dataSpecsList) err := json.Unmarshal(b, thingModelTemplateBool) if err != nil { return } var modelTypeSpecBool models.TypeSpecBool modelTypeSpecBool = make(map[string]string) if thingModelTemplateBool != nil { for _, templateBool := range *thingModelTemplateBool { modelTypeSpecBool[strconv.Itoa(templateBool.Value)] = templateBool.Name } } typeSpec.Specs = modelTypeSpecBool.TransformTostring() case constants.SpecsTypeEnum: thingModelTemplateEnum := new([]ThingModelTemplateEnum) b, _ := json.Marshal(dataSpecsList) err := json.Unmarshal(b, thingModelTemplateEnum) if err != nil { return } var modelTypeSpecEunm models.TypeSpecEnum modelTypeSpecEunm = make(map[string]string) if thingModelTemplateEnum != nil { for _, templateEunm := range *thingModelTemplateEnum { modelTypeSpecEunm[strconv.Itoa(templateEunm.Value)] = templateEunm.Name } } typeSpec.Specs = modelTypeSpecEunm.TransformTostring() case constants.SpecsTypeArray: thingModelTemplateArray := new(ThingModelTemplateArray) b, _ := json.Marshal(dataSpecs) err := json.Unmarshal(b, thingModelTemplateArray) if err != nil { return } var modelTypeSpecArray models.TypeSpecArray modelTypeSpecArray.Size = strconv.Itoa(thingModelTemplateArray.Size) modelTypeSpecArray.Item = models.Item{ Type: strings.ToLower(thingModelTemplateArray.ChildDataType), } typeSpec.Specs = modelTypeSpecArray.TransformTostring() case constants.SpecsTypeStruct: thingModelTemplateStruct := new([]ThingModelTemplateStruct) b, _ := json.Marshal(dataSpecsList) err := json.Unmarshal(b, thingModelTemplateStruct) if err != nil { return } var modelTypeSpecStruct []models.TypeSpecStruct if thingModelTemplateStruct != nil { for _, templateStruct := range *thingModelTemplateStruct { modelTypeSpecStruct = append(modelTypeSpecStruct, models.TypeSpecStruct{ Code: templateStruct.Identifier, Name: templateStruct.ChildName, DataType: models.TypeSpec{ Type: transformSpecType(templateStruct.ChildDataType), Specs: getModelSpecByDataType(transformSpecType(templateStruct.ChildDataType), templateStruct.ChildSpecsDTO), }, }) } } bm, _ := json.Marshal(modelTypeSpecStruct) typeSpec.Specs = string(bm) } return } func GetModelPropertyEventActionByThingModelTemplate(thingModelJSON string) (properties []models.Properties, events []models.Events, actions []models.Actions) { thingModelTemplate := new(ThingModelTemplate) err := json.Unmarshal([]byte(thingModelJSON), thingModelTemplate) if err == nil { for _, property := range thingModelTemplate.Properties { var accessMode string if property.RwFlag == "READ_ONLY" { accessMode = "R" } else if property.RwFlag == "READ_WRITE" { accessMode = "RW" } else if property.RwFlag == "WRITE_ONLY" { accessMode = "W" } properties = append(properties, models.Properties{ Id: utils.RandomNum(), Name: property.Name, Code: property.Identifier, AccessMode: accessMode, Require: property.Required, Description: property.Description, TypeSpec: property.TransformModelTypeSpec(), Tag: string(constants.TagNameSystem), Timestamps: models.Timestamps{ Created: time.Now().UnixMilli(), }, }) } for _, event := range thingModelTemplate.Events { var eventType constants.EventType if event.EventType == "ALERT_EVENT_TYPE" { eventType = constants.EventTypeAlert } else if event.EventType == "INFO_EVENT_TYPE" { eventType = constants.EventTypeInfo } else if event.EventType == "ERROR_EVENT_TYPE" { eventType = constants.EventTypeError } events = append(events, models.Events{ Id: utils.RandomNum(), Name: event.EventName, EventType: string(eventType), Code: event.Identifier, Require: event.Required, Description: event.Description, OutputParams: event.TransformModelOutputParams(), Tag: string(constants.TagNameSystem), Timestamps: models.Timestamps{ Created: time.Now().UnixMilli(), }, }) } for _, service := range thingModelTemplate.Services { actions = append(actions, models.Actions{ Id: utils.RandomNum(), Name: service.ServiceName, Code: service.Identifier, CallType: service.CallType, Require: service.Required, Description: service.Description, InputParams: service.TransformModelInPutParams(), OutputParams: service.TransformModelOutPutParams(), Tag: string(constants.TagNameSystem), Timestamps: models.Timestamps{ Created: time.Now().UnixMilli(), }, }) } } return } //func OpenApiGetModelPropertyEventActionByThingModelTemplate(req OpenApiAddRequest) (properties []models.Properties, events []models.Events, actions []models.Actions) { // for _, property := range req.Properties { // properties = append(properties, models.Properties{ // Id: utils.RandomNum(), // Name: property.Name, // Code: property.Code, // AccessMode: property.AccessMode, // Require: property.Required, // Description: property.Description, // TypeSpec: models.TypeSpec(property.TypeSpec), // Tag: string(constants.TagNameCustom), // Timestamps: models.Timestamps{ // Created: time.Now().UnixMilli(), // }, // }) // } // // for _, event := range req.Events { // var outPutParams models.OutPutParams // for _, param := range event.OutputParams { // outPutParams = append(outPutParams, models.InputOutput{ // Code: param.Code, // Name: param.Name, // TypeSpec: models.TypeSpec{ // Type: param.TypeSpec.Type, // Specs: param.TypeSpec.Specs, // }, // }) // } // events = append(events, models.Events{ // Id: utils.RandomNum(), // Name: event.Name, // EventType: event.EventType, // Code: event.Code, // Require: event.Required, // Description: event.Description, // OutputParams: outPutParams, // Tag: string(constants.TagNameCustom), // Timestamps: models.Timestamps{ // Created: time.Now().UnixMilli(), // }, // }) // } // // for _, action := range req.Actions { // var inPutParams models.InPutParams // var outPutParams models.OutPutParams // for _, param := range action.InputParams { // inPutParams = append(inPutParams, models.InputOutput{ // Code: param.Code, // Name: param.Name, // TypeSpec: models.TypeSpec{ // Type: param.TypeSpec.Type, // Specs: param.TypeSpec.Specs, // }, // }) // } // for _, param := range action.OutputParams { // outPutParams = append(outPutParams, models.InputOutput{ // Code: param.Code, // Name: param.Name, // TypeSpec: models.TypeSpec{ // Type: param.TypeSpec.Type, // Specs: param.TypeSpec.Specs, // }, // }) // } // actions = append(actions, models.Actions{ // Id: utils.RandomNum(), // Name: action.Name, // Code: action.Code, // CallType: action.CallType, // Require: action.Required, // Description: action.Description, // InputParams: inPutParams, // OutputParams: outPutParams, // Tag: string(constants.TagNameCustom), // Timestamps: models.Timestamps{ // Created: time.Now().UnixMilli(), // }, // }) // } // return //}