github.com/enbility/spine-go@v0.7.0/spine/feature_remote.go (about) 1 package spine 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/enbility/ship-go/logging" 8 "github.com/enbility/spine-go/api" 9 "github.com/enbility/spine-go/model" 10 "github.com/enbility/spine-go/util" 11 "github.com/rickb777/date/period" 12 ) 13 14 const defaultMaxResponseDelay = time.Duration(time.Second * 10) 15 16 type FeatureRemote struct { 17 *Feature 18 19 entity api.EntityRemoteInterface 20 functionDataMap map[model.FunctionType]api.FunctionDataInterface 21 maxResponseDelay *time.Duration 22 23 mux sync.Mutex 24 } 25 26 func NewFeatureRemote(id uint, entity api.EntityRemoteInterface, ftype model.FeatureTypeType, role model.RoleType) *FeatureRemote { 27 res := &FeatureRemote{ 28 Feature: NewFeature( 29 featureAddressType(id, entity.Address()), 30 ftype, 31 role), 32 entity: entity, 33 functionDataMap: make(map[model.FunctionType]api.FunctionDataInterface), 34 } 35 for _, fd := range CreateFunctionData[api.FunctionDataInterface](ftype) { 36 res.functionDataMap[fd.FunctionType()] = fd 37 } 38 39 res.operations = make(map[model.FunctionType]api.OperationsInterface) 40 41 return res 42 } 43 44 var _ api.FeatureRemoteInterface = (*FeatureRemote)(nil) 45 46 /* FeatureRemoteInterface */ 47 48 func (r *FeatureRemote) Device() api.DeviceRemoteInterface { 49 return r.entity.Device() 50 } 51 52 func (r *FeatureRemote) Entity() api.EntityRemoteInterface { 53 return r.entity 54 } 55 func (r *FeatureRemote) DataCopy(function model.FunctionType) any { 56 r.mux.Lock() 57 defer r.mux.Unlock() 58 59 fd := r.functionData(function) 60 if fd == nil { 61 return nil 62 } 63 64 return r.functionData(function).DataCopyAny() 65 } 66 67 func (r *FeatureRemote) UpdateData(persist bool, function model.FunctionType, data any, filterPartial *model.FilterType, filterDelete *model.FilterType) (any, *model.ErrorType) { 68 r.mux.Lock() 69 defer r.mux.Unlock() 70 71 fd := r.functionData(function) 72 if fd == nil { 73 return nil, model.NewErrorTypeFromString("function data not found") 74 } 75 76 return fd.UpdateDataAny(false, persist, data, filterPartial, filterDelete) 77 } 78 79 func (r *FeatureRemote) SetOperations(functions []model.FunctionPropertyType) { 80 r.operations = make(map[model.FunctionType]api.OperationsInterface) 81 for _, sf := range functions { 82 if sf.PossibleOperations == nil { 83 continue 84 } 85 r.operations[*sf.Function] = NewOperations( 86 sf.PossibleOperations.Read != nil, 87 sf.PossibleOperations.Read != nil && sf.PossibleOperations.Read.Partial != nil, 88 sf.PossibleOperations.Write != nil, 89 sf.PossibleOperations.Write != nil && sf.PossibleOperations.Write.Partial != nil, 90 ) 91 } 92 } 93 94 func (r *FeatureRemote) SetMaxResponseDelay(delay *model.MaxResponseDelayType) { 95 if delay == nil { 96 return 97 } 98 p, err := period.Parse(string(*delay)) 99 if err != nil { 100 r.maxResponseDelay = util.Ptr(p.DurationApprox()) 101 } else { 102 logging.Log().Debug(err) 103 } 104 } 105 106 func (r *FeatureRemote) MaxResponseDelayDuration() time.Duration { 107 if r.maxResponseDelay != nil { 108 return *r.maxResponseDelay 109 } 110 return defaultMaxResponseDelay 111 } 112 113 func (r *FeatureRemote) functionData(function model.FunctionType) api.FunctionDataInterface { 114 fd, found := r.functionDataMap[function] 115 if !found { 116 logging.Log().Errorf("Data was not found for function '%s'", function) 117 return nil 118 } 119 return fd 120 }