diff --git a/README.md b/README.md index 7c0c1a90..812dd7a9 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ Here is the current set of supported services. For low-level access use the clie | MonitoredItems Service Set | CreateMonitoredItems | Yes | | | | DeleteMonitoredItems | Yes | | | | ModifyMonitoredItems | Yes | | -| | SetMonitoringMode | | | +| | SetMonitoringMode | Yes | | | | SetTriggering | | | | Subscription Service Set | CreateSubscription | Yes | | | | ModifySubscription | | | diff --git a/subscription.go b/subscription.go index f08a81f6..5436856d 100644 --- a/subscription.go +++ b/subscription.go @@ -177,22 +177,28 @@ func (s *Subscription) ModifyMonitoredItems(ctx context.Context, ts ua.Timestamp stats.Subscription().Add("ModifyMonitoredItems", 1) stats.Subscription().Add("ModifiedMonitoredItems", int64(len(items))) + var err error s.itemsMu.Lock() for _, item := range items { id := item.MonitoredItemID if _, exists := s.items[id]; !exists { - return nil, fmt.Errorf("sub %d: cannot modify unknown monitored item id: %d", s.SubscriptionID, id) + err = fmt.Errorf("sub %d: cannot modify unknown monitored item id: %d", s.SubscriptionID, id) + break } } s.itemsMu.Unlock() + if err != nil { + return nil, err + } + req := &ua.ModifyMonitoredItemsRequest{ SubscriptionID: s.SubscriptionID, TimestampsToReturn: ts, ItemsToModify: items, } var res *ua.ModifyMonitoredItemsResponse - err := s.c.Send(ctx, req, func(v interface{}) error { + err = s.c.Send(ctx, req, func(v interface{}) error { return safeAssign(v, &res) }) if err != nil { @@ -220,6 +226,40 @@ func (s *Subscription) ModifyMonitoredItems(ctx context.Context, ts ua.Timestamp return res, nil } +func (s *Subscription) SetMonitoringMode(ctx context.Context, monitoringMode ua.MonitoringMode, monitoredItemIDs ...uint32) (*ua.SetMonitoringModeResponse, error) { + stats.Subscription().Add("SetMonitoringMode", 1) + stats.Subscription().Add("SetMonitoringModeMonitoredItems", int64(len(monitoredItemIDs))) + + var err error + s.itemsMu.Lock() + for _, id := range monitoredItemIDs { + if _, exists := s.items[id]; !exists { + err = fmt.Errorf("sub %d: cannot set monitoring mode for unknown monitored item id: %d", s.SubscriptionID, id) + break + } + } + s.itemsMu.Unlock() + + if err != nil { + return nil, err + } + + req := &ua.SetMonitoringModeRequest{ + SubscriptionID: s.SubscriptionID, + MonitoringMode: monitoringMode, + MonitoredItemIDs: monitoredItemIDs, + } + var res *ua.SetMonitoringModeResponse + err = s.c.Send(ctx, req, func(v interface{}) error { + return safeAssign(v, &res) + }) + if err != nil { + return nil, err + } + + return res, nil +} + // SetTriggering sends a request to the server to add and/or remove triggering links from a triggering item. // To add links from a triggering item to an item to report provide the server assigned ID(s) in the `add` argument. // To remove links from a triggering item to an item to report provide the server assigned ID(s) in the `remove` argument.