Giter Site home page Giter Site logo

Comments (3)

ffa500 avatar ffa500 commented on August 11, 2024

The SensorThings example in its current state has some deficiencies as you describe, regarding, for example, late joining producer agents and assignment of UUIDs to Things/Sensor objects.

Our recommendation is to not use this example as a template for your own SensorThings application, but follow the guidelines given in the SensorThings API Guide: Use SensorSourceController on the producer side and ThingSensorObservationObserverController on the consumer side. This combination supports late joining Things/Sensors by not only observing advertised Things/Sensors but also actively discovering them on start up. On the consumer side you can detect changes to registered sensors/things by the registeredSensorsChangeInfo$ method. A basic usage example of this combination can be found in the Coaty OPC UA Connector example.

Your issue with things going off and on again and thereby getting new UUIDs must always be solved on application level: In a real application use case, a specific thing/sensor should not be assigned a newly generated UUID at runtime, but have a specific constant UUID generated at configuration time. You can generate such UUIDs manually using an Online Version 4 UUID generator and configure the UUIDs as objectIds of your things/sensors, e.g. in a config JSON file. Alternatively, you could maintain a persistent mapping from a known external thing/sensor hardware asset ID to a UUID that is generated just once, the first time a thing/sensor is registered and reused afterwards. The SensorThings example simply doesn't care about this point.

BTW, the Sensor Things example also doesn't properly handle producer agents that go offline during operation. To detect and handle such states, follow the guidelines described in the SensorThings API Guide.

from coaty-examples.

bnouhanna avatar bnouhanna commented on August 11, 2024

The combination of SensorSourceController and ThingSensorObservationObserverController doesn't provide late joining Things/Sensors and actively discovering them on startup. I might be doing something wrong. Here is a snapshot of the code.

The producer side:


export class SensorThingsController extends SensorSourceController {

    private _thing: Thing;
    private _sensorsArray: Sensor[] = [];

    onCommunicationManagerStarting() {
        super.onCommunicationManagerStarting();
        this._createObjects();

    }
    onCommunicationManagerStopping() {
        super.onCommunicationManagerStopping();
        this.unregisterSensor(this._sensorsArray[0].objectId);
    }
    private _createObjects() {
        this._sensorsArray = [];
        this._thing = {
            // Thing description code here
        };
        this.communicationManager.publishAdvertise(AdvertiseEvent.withObject(this._thing));

        const sensor: Sensor = {
            // sesnor description code here
        };
        this._dataStore.set(sensor.objectId, sensor);
        this._sensorsArray.push(sensor);
        this.registerSensor(sensor, new MockSensorIo(), "channel", this.options.monitoringInterval);
    }

on the consumer side


export class SensorController extends ThingSensorObservationObserverController {
     private _sensorsSubscription: Subscription;
     onCommunicationManagerStarting() {
        super.onCommunicationManagerStarting();

        // Observe sensors
        this._sensorsSubscription = this.observeSensors();
    }

    observeSensors() {
        // Monitor information about changes in the currently registered sensors.
        return this.registeredSensorsChangeInfo$.subscribe(changeInfo => {
            changeInfo.changed.forEach(sensor => console.log("Changed sensor ", sensor["thing"] as Thing));
            changeInfo.added.forEach(sensor => console.log("New sensor ", sensor["thing"] as Thing));
            changeInfo.total.forEach(sensor => console.log("Total sensor ", sensor["thing"] as Thing));
            changeInfo.removed.forEach(sensor => console.log("Removed sensor ", sensor["thing"] as Thing));
        });
    }
}

The behavior I get is:

  • The consumer can discover newly registered Sensors and Things only if the consumer is connected first
  • If the consumer is disconnected and connected again none of the already connected sensors are discovered again.
  • The consumer can't print/see removed sensors
  • When a sensor is disconnected and connected again, the changed sensor is printed multiple times; however, the total sensor value is correct.

Any idea, why this behavior?

from coaty-examples.

ffa500 avatar ffa500 commented on August 11, 2024

Your SensorThingsController on the producer side does not support discovery of Things issued by the ThingSensorObservationObserverController on the consumer side as this functionality is not part of the base SensorSourceController class. The counter-operative functionality only covers Sensor objects, not Things, as described here.

The missing counterpart functionality you have to implement on the producer side is described here. Currently, your SensorThingsController only realizes the second requirement: advertising a Thing object when it is created on start up. Things are not discoverable (and not queryable) in your implementation. I recommend to take a look at the implementation of the OpcuaSensorThingsController. It supports a registerThings method and a method to respond to Discover Thing events by consumers. You don't need to implement the counterpart of queryThingsAtLocation if you don't use this functionality on the consumer side.

Implementing both advertisements and discovery of Things provides late joining consumer agents.

Detecting online/offline state of Things (and its related Sensors) is yet another part of the game. You have to implement it explicitely as described here. You should use the ObjectLifecycleController to keep track of Things (and its sensors) on the consumer side. A usage example can be found in the Coaty developer guide. On the producer side, just set the parentObjectId of your Thing objects to the agent's Identity UUID to make them lifecycle aware. For an example, see OpcuaSensorThingsController.registerThing() method: thing.parentObjectId = this.container.identity.objectId;

from coaty-examples.

Related Issues (2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.