• Recent
    • Tags
    • Popular
    • Register
    • Login

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

    node-mango-client to update datasource properties on Mango 2.8

    Mango Automation general Discussion
    3
    8
    1.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E
      etantonio
      last edited by

      Hi,
      I want try to use node-mango-client to update some Mango 2.8 datasource properties from outside Mango user interface. Mango instance is running on a RPI3B+.

      To achieve this I've done the following:

      sudo apt install -y nodejs
      node -v
      v8.11.1
      
      sudo apt install npm
      npm -v
      1.4.21
      (node:4528) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
      
      
      cd /home/solergy/MANGO/NODE-JS/
      npm install mango-client --save
      (node:2363) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
      mango-client@0.4.0 node_modules/mango-client
      ├── uuid@3.1.0
      ├── moment-timezone@0.5.27
      └── moment@2.24.0
      

      after this I've tried this little sample:

      const MangoClient = require('mango-client');
      
      const client = new MangoClient({
          protocol: 'http',
          host: 'localhost',
          port: 8810,
          rejectUnauthorized: false
      });
      
      const DataPoint = client.DataPoint;
      const User = client.User;
      
      
      User.login('myUsername', 'myPassword').then(data => {
          console.log(`Logged in as '${data.username}'.`);
          return DataPoint.getValue('internal_mango_num_data_points');
      }).then(data => {
          console.log(`There are ${data.value} data points.`);
      
          // you can perform any arbitrary rest request like this
          return client.restRequest({
              path: '/rest/v1/data-points/internal_mango_num_data_points',
              method: 'GET',
              //data: {object}
          });
      }).then(response => {
          console.log(`The data point's name is '${response.data.name}'`);
      });
      

      it is the same descripted here:
      https://github.com/infiniteautomation/node-mango-client

      but I've the following error:

      solergy@Tracker_0-1:~/MANGO/NODE-JS/node_modules/mango-client $ node example.js
      (node:4926) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token < in JSON at position 3
          at JSON.parse (<anonymous>)
          at IncomingMessage.response.on (/home/solergy/MANGO/NODE-JS/node_modules/mango-client/src/mangoClient.js:183:62)
          at emitNone (events.js:111:20)
          at IncomingMessage.emit (events.js:208:7)
          at endReadableNT (_stream_readable.js:1064:12)
          at _combinedTickCallback (internal/process/next_tick.js:138:11)
          at process._tickCallback (internal/process/next_tick.js:180:9)
      (node:4926) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
      (node:4926) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
      

      any idea about where's the problem?

      1 Reply Last reply Reply Quote 0
      • Jared WiltshireJ
        Jared Wiltshire
        last edited by

        I took at look at it is because the node client uses the REST V2 APIs to log in and they are not available on Mango 2.8. The actual error is because Mango 2.8 incorrectly returns the HTML error page instead of a JSON error response.

        I had a play with manually using client.restRequest() to login but that will not work either due to the CSRF protection changing.

        Otherwise this would work I would think...

        const MangoClient = require('@infinite-automation/mango-client');
        
        const client = new MangoClient({
            protocol: 'http',
            host: 'localhost',
            port: 8080,
            rejectUnauthorized: false
        });
        
        const DataPoint = client.DataPoint;
        const User = client.User;
        
        const username = 'admin';
        const password = 'admin';
        
        client.restRequest({
            path: `/rest/v1/login/${username}`,
            method: 'POST',
            params: {password}
        }).then(response => {
            const data = response.data;
            console.log(`Logged in as '${data.username}'.`);
            return DataPoint.getValue('internal_mango_num_data_points');
        }).then(data => {
            console.log(`There are ${data.value} data points.`);
        
            // you can perform any arbitrary rest request like this
            return client.restRequest({
                path: '/rest/v1/data-points/internal_mango_num_data_points',
                method: 'GET',
                //data: {object}
            });
        }).then(response => {
            console.log(`The data point's name is '${response.data.name}'`);
        });
        

        Developer at Radix IoT

        Jared WiltshireJ 1 Reply Last reply Reply Quote 0
        • E
          etantonio
          last edited by

          It seems there's still some problem:

          solergy@Tracker_0-1:~/MANGO/NODE-JS/node_modules/mango-client $ node example.js
          (node:3790) UnhandledPromiseRejectionWarning: Error: Mango HTTP error - 403 Forbidden
              at IncomingMessage.response.on (/home/solergy/MANGO/NODE-JS/node_modules/mango-client/src/mangoClient.js:194:35)
              at emitNone (events.js:111:20)
              at IncomingMessage.emit (events.js:208:7)
              at endReadableNT (_stream_readable.js:1064:12)
              at _combinedTickCallback (internal/process/next_tick.js:138:11)
              at process._tickCallback (internal/process/next_tick.js:180:9)
          (node:3790) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
          (node:3790) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
          
          1 Reply Last reply Reply Quote 0
          • Jared WiltshireJ
            Jared Wiltshire @Jared Wiltshire
            last edited by

            @jared-wiltshire said in node-mango-client to update datasource properties on Mango 2.8:

            I had a play with manually using client.restRequest() to login but that will not work either due to the CSRF protection changing.
            Otherwise this would work I would think...

            ^ as I said CSRF has changed since 2.8.

            Developer at Radix IoT

            1 Reply Last reply Reply Quote 0
            • E
              etantonio
              last edited by etantonio

              OK, thanks anyway, I will search for a different approach to change datasource properties from outside Mango 2.8. I've tried to read the blob with the following python script:

              #!/usr/bin/python3
              
              import pymysql
              import json
              
              def write_file(data, filename):
                  with open(filename, 'wb') as f:
                      f.write(data)
              
              
              def read_blob(filename):
                  # select photo column of a specific author
                  query = "SELECT data FROM mangoTerlizzi.dataSources where xid='FML01-main'"
              
                  try:
                      # Open database connection
                      db = pymysql.connect("localhost","user","pwd","mangoTerlizzi" )
              
                      # prepare a cursor object using cursor() method
                      cursor = db.cursor()
              
                      # execute SQL query using execute() method.
                      cursor.execute(query)
                      
                      # Fetch a single row using fetchone() method.
                      data = cursor.fetchone()[0]
                
                      # write blob data into a file
                      write_file(data, filename)
                      
                      with open(filename) as json_file:
                        data = json.load(json_file)
                 
                  except Error as e:
                      print(e)
               
                  finally:
                      cursor.close()
                      db.close()
                      
                              
              
              read_blob("datasourceDescription.json")
              

              but maybe it is not all the stuff, in fact I've the following error:

              solergy@Tracker_0-1:~ $ python3 dbConnection.py
              Traceback (most recent call last):
                File "dbConnection.py", line 34, in read_blob
                  data = json.load(json_file)
                File "/usr/lib/python3.5/json/__init__.py", line 265, in load
                  return loads(fp.read(),
                File "/usr/lib/python3.5/codecs.py", line 321, in decode
                  (result, consumed) = self._buffer_decode(data, self.errors, final)
              UnicodeDecodeError: 'utf-8' codec can't decode byte 0xac in position 0: invalid start byte
              
              1 Reply Last reply Reply Quote 0
              • E
                etantonio
                last edited by etantonio

                At the end I choose to use a scripting datasource to update datasource properties:

                var dsvoMain = com.serotonin.m2m2.db.dao.DataSourceDao.instance.getByXid("FML01-main");
                    dsvoMain.host = "172.16.0.12";
                    com.serotonin.m2m2.db.dao.DataSourceDao.instance.saveDataSource(dsvoMain);
                

                and the same for the publisher:

                var voPublisher = com.serotonin.m2m2.db.dao.PublisherDao.instance.getByXid("Pub_TRK-0.1")
                    voPublisher.port              = "8811";
                    com.serotonin.m2m2.db.dao.PublisherDao.instance.savePublisher(voPublisher);
                

                but I can't update instead systemSettings,
                I've tried with the following:

                com.serotonin.m2m2.db.dao.SystemSettingsDao.setValue("emailFromName", "Etantonio");
                

                but the result is:

                0_1572511885915_c97ce613-c790-42db-ab07-72ec0ef03a57-immagine.png

                but the method seems to be there in

                https://github.com/infiniteautomation/ma-core-public/blob/2.8.x/Core/src/com/serotonin/m2m2/db/dao/SystemSettingsDao.java

                0_1572511990311_1ce1aedf-d313-4853-bcbe-f25636247fd2-immagine.png

                do you have an idea about where's the problem?

                And also, there's a similar way to update excelReport properties on table excelReportTemplates?

                Thanks, Antonio

                1 Reply Last reply Reply Quote 0
                • terrypackerT
                  terrypacker
                  last edited by

                  @etantonio it looks like you have a syntax error. The other dao classes have a static instance member to access the methods but this dao is different in Mango 2.8,

                  The method you are using is not static so you need to first get a reference to the created dao. I believe there is a DaoRegistry class you may be able to use. Just be careful and make sure you understand why some methods are static and others are not.

                  1 Reply Last reply Reply Quote 0
                  • E
                    etantonio
                    last edited by etantonio

                    yes, you're right, the following code it's ok. thanks,

                    var ssdao = new com.serotonin.m2m2.db.dao.SystemSettingsDao();
                       ssdao.setValue("emailFromName", "Etantonio");
                    

                    instead for excelReport:

                    var voExcelReport = com.infiniteautomation.mango.excelreports.dao.ExcelReportTemplateDao.instance.getByXid("My_DailyReport")
                    voExcelReport.setName("Etantonio")
                    com.infiniteautomation.mango.excelreports.dao.ExcelReportTemplateDao.instance.save(voExcelReport);  
                    

                    Antonio

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post