Using Subjects to extra measurements from Cumulocity

I have created an Angular service for my component to extract a list object measurements from my Cumulocity Inventory using the InventoryService. The service needs to extract one of two types of objects based on the following SmartREST template:

Mode

To do so, I have created a method that uses an instance of InventoryService to call the list() method to extract the relevant measurements from a given date range.

  async getModeMeasurements(startDate: string, endDate: string){
    try {
      const filter = {
        dateFrom: startDate,
        dateTo: endDate,
        valueFragmentType: 'mode',
      }
    const response = await this.inventoryService.list(filter);

    return response.data;

    } catch (error){
      console.error('Error occured while loading insufflator mode measurements: ', error);
    }
  }

To capture this data on the component side of the code, I created a model based on the SmartREST Template.

export interface IModeUsage {
    time: string;
    mode: string;
    value: number;
    unit: string;
}

Next, I am using a Subject of type IModeUsage from my custom Angular service to subscribe to the response stream; however, I am unsure how I am supposed to proceed from here.

modeMeasurements: Subject<IModeUsage> = new Subject<IModeUsage>();
[ . . . ]

private subscribeToModeUsageData() {
  this.[service].modeMeasurements.subscribe((data: any) => {
   [ ? ? ? ]
    }
  })
}

From what I glimpsed usingVS code’s intellisense, the response.data is a structure of IManagedObjects, so I am not exactly sure what the Subject is subscribing to. Is it subscribing to a single IManagedObject or to the entire data structure?

Also, how would I go about transferring the data from one of the IManagedObject to an instance of IModeUsage if the data comes as a data structure?

Hi Lucas,

it sounds like you are mixing up different things here…
I’m assuming you are creating a measurement via your SmartREST template. If so, you should use the MeasurementService instead of the InventoryService as these are two completely different APIs.

Also it sounds like you are unable to test the code you are developing against an actual tenant? Are you missing a device sending the data from the SmartREST template? If so, you could define a Simulator that sends this data to your Cumulocity tenant.

Transforming the data from one data structure (IManagedObject or actually IMeasurement) to another one (IModeUsage) is pretty basic JavaScript/TypeScript knowledge that we do not plan to teach in this forum. If you do not know how the objects you are going to receive via API look like, why do you not just take a look at the responses you are receiving from the API (e.g. via Postman) or via the services above?

Regards,
Tristan

Hi Tristan,

I did what you suggested and created a new method that incorporates MeasurementService to retrieve temperature measurements from C8Y.

Angular Service

  async getTemperatureMeasurements(startDate: string, endDate: string){
    const filter = {
      dateFrom: startDate,
      dateTo: endDate,
      type: 'c8y_Temperature',
      pageSize: 2000,
      revert:true
    }

    const response = await this.measurementService.list(filter);

    return response;
  }

Angular Component

  private getTemperatureMeasurement(startDate: string, endDate: string):void{
    this.liveDashboardService
        .getTemperatureMeasurements(startDate, endDate)
               .then((result)=> {
          console.log(result);
        })
  }

The method successfully prints the response data on the console.

My next challenge, however, is extracting the information from each element in the array.

The method returns a Promise<IResultList<IMeasurement> object but whenever I try to sequence through each array element I am unable to access any of the properties.

  private getTemperatureMeasurement(startDate: string, endDate: string):void{
    this.liveDashboardService
        .getTemperatureMeasurements(startDate, endDate)
        .then((result)=> {
          for(let element in result.data){
            console.log(element[0]);
          }
        })
  }

Instead, it just returns strings:

Okay, now I am getting somewhere…

So, I looked up the documentation in the developer’s Web SDK for the MeasurementService and modified by getTemperatureMeasurements as follows:

async getTemperatureMeasurements(startDate: string, endDate: string){
    try{
      const filter = {
        dateFrom: startDate,
        dateTo: endDate,
        type: 'c8y_Temperature',
        pageSize: 2000,
        revert:true
      }
  
      const {data, res, paging} = await this.measurementService.list(filter);
      console.log({data, res, paging});
      return {data, res, paging};
    }
    catch (error){
      console.error('Error occurred while loading the device description: ', error)
    }
    
  }

Now, on the component side, I can retrieve the type of data from the measurement and display it on my log.

private getTemperatureMeasurement(startDate: string, endDate: string):void{
    this.liveDashboardService
        .getTemperatureMeasurements(startDate, endDate)
        .then((result)=> {
          var len: number = result.data.length;
          console.log(len);
          for(let i = 0; i < len; i++){
            console.log(result.data[i]);
          }
        })
  }

Now the only task is to find a way to retrieve the value from the data structure.

As said this is really basic code.

private getTemperatureMeasurement(startDate: string, endDate: string):void{
    this.liveDashboardService
        .getTemperatureMeasurements(startDate, endDate)
        .then((result)=> {
          var len: number = result.data.length;
          console.log(len);
          const fragment = 'c8y_Temperature';
          const series = 'T';
          for(let i = 0; i < len; i++){
            const measurement = result.data[i];
            const valueUnitTuple = measurement[fragment][series];
            console.log(measurement.time, valueUnitTuple.value, valueUnitTuple.unit);
          }
        })
  }

If you need help in writing this kind of code, I would highly recommend to get in touch with our Professional Services to get some support.
This forum is at least not meant to teach writing basic JavaScript code.

Regards,
Tristan

Hi Tristan,

This did not quite answer my question, but I have a better idea of what I have to do.

Thanks,

Lucas

You were asking how to retrieve the value from the data structure and tristan posted an working example. If this is not answering your question, what is your question?

I agree with Tristan, that we cannot answer basic typescript/javascript questions here. When developing Web Application you should have basic knowledge about that.

I would also suggest that you have a deeper look in our data structure: Cumulocity IoT - OpenAPI Specification
This will help to understand what is meant with fragments, series and values in measurements and how navigate in one document.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.