M2M Bridge

From AMTech WikiDocs
Revision as of 09:35, 22 April 2016 by Amarrero (Talk | contribs) (Edge Configuration)

Jump to: navigation, search

Functionality

  • Configurable edge intelligence
  • Bridges standard and proprietary protocols to AMTech IoT DAP.
    • MQTT, LLRP, CoAP, STOMP, SmartM2M, LWM2M, PLC, Zigbee, SNMP/MIB/TRAP and others
  • Device-to-device or device-to-cloud communications.
  • Allow remote and centralized administration of IoT devices and gateways.
  • Configurable auto-discover
  • Implements common functionality and orchestrates the execution of the protocols
  • Network failure detection and recovery
  • Get centralized configuration information at startup and real time modifications
  • Access control policies to manage observation production and consumption
  • The following diagram illustrates a M2MBrdige configuration:
    • Using LLRP protocol to get the data from EPC tags and send commands to the reader
    • Using SNMP to monitor the health o the readers
    • Implementing smoothing, decoding, grouping, access control and other edge intelligence

Example.jpg

Edge Configuration

bridgeConfig.json located at M2MBridge.js directory

{
    // Text to be assigned to M2MBridges description property
    "description": "AMTech M2M Bridge", 
    // If the description property will be assigned to M2MBridge's linked things
    "description:children" : true,
    "dap":{
        // Amtech IoT DAP ur
        "dapUrl": "https://dap.amtech.mx",     
        // userid for the m2mBridge instance bridgeId 
        "userId": "xxxxxxx@amtech.mx",
        // tenant where bridge been configured       
        "tenant" : "xxxxxxx",  
        // m2mBridge userId password  
        "password" :"xxxxxxxx"
    },
    // M2MBridge instance id to be cloned
    "templateId":"m2mCreator:m2mBridge",
    // Prefix to add to the unique M2MBridge identifier, the mac address of the device is use as unique id
    // In absence of the prefix just the mac address is used as identifier
    "bridgeIdPrefix":"tienda1",       
    // wkt location to set m2mBridge location overrides address
    "location": "{\"wkt\":\"POINT(-99.17125583 19.40501031)\",\"sContext\":\"geo\"}",  
    // if the location property will be assigned to M2MBridge's linked things
    "location:children" : true,
    // Address to be used to get m2mBridge's location
    "address" :{				 
        "country" : "usa",
        "city": "Las Vegas",
        "road": "Las Vegas Boulevard South",
        "number":"3960"
    },
}

Cloud Configuration

  • Create an amtechM2mBridge instance (See "/amtech/linkeddata/types/composite/entity/amtechM2mBridge")
  • Create an actor actorX with the polices required by the activity(s) (See Actors)
    • Add the things type polices the bridge needs to the actor actorX
  • Register a follower (See Roles)
    • Assign to follower actor actorX access
  • Activity observation configuration (See Observation production configuration)
  • Things instance creation
    • Configuring autoDiscover (See Edge Configuration)
      • The bridge will request the DAP to clone templateId instance with the name convention bridgeIdPrefix:(device mac address) from bridgeConfig.json
      • the things instances linked to the templateId property bridgeInstances will be cloned with the name convention bridgeIdPrefix:(device mac address):thing._name from bridgeConfig.json
      • cloned instance will be giving the access control owner to the follower user id of the bridge that requested it.
  • Monitoring M2MBridge status
    • Create an SNMPDevice instance and give access to your M2MBridge actor (See "/amtech/linkeddata/types/composite/entity/SNMPDevice")
      • Send observations to /m2mBridge/snmp/read a core activity /amtech/activities/monitorM2MBridgeStatus will analyze the data and notify to the user and guestusers of the M2MBridge instance.
        • This get done by setting at the observation production configuration /observationproductionconfig/SNMPDevice/observationsproducedconfig/snmpRead topic to value /m2mBridge/snmp/ (See Observation production configuration)

Implementation notes

  • M2MBridge is an open source stack developed by the AMTEch team; it discovers and loads nodes modules implementing "M2MBridge plugin interface"(See Thing types) tacking into account thing instances, activity(s) observation production configuration (See Observation production configuration) and M2MBridge credentials (See Actors and Edge Configuration).
    • It leverages AMTech IoT DAP (See Integration Guideline)
      • Clone configuration from exiting M2MBridge template configuration (See Edge Configuration)
      • Gets observation production configuration (See Observation production configuration API)
      • Gets thing types instances (See Observation instances API)
      • Creates a web socket to receive asynchronous commands and thing instances changes (crud operations) (See CRUD and Commands API)
        • Dispatch command observations to plugin instance leveraging thing type instance @id (See Thing types)
        • Restart instance when supported properties change by calling stop and star plugin interface
      • Creates configuration information by Thing type leveraging configuration information and client side M2MBridge placeholders (See Observation production configuration and Placeholders)
      • Load plugin nodes modules required by configuration
      • Creates an instance of plugin for each thing type instance using instance @id as identifier (See Thing types)
        • JavaScript object is extended with the properties values from the thing instance (See plugin example )
        • Properties and methods are injected: (See for details)
          • common logger
          • methods to send observations with and without enrichment
          • methods for restarting plugin
      • Creates a centralized observation dispatcher with persistence to ensure:
        • Observations delivery in the order that observations occurred.
      • Placeholders (See Placeholders)
        • #{deviceId} m2mBox Id set at bridgeConfig.json configuration file bridgeId property, or a unique id create in absence or this value
        • #{typeId} Unique id of the thingType that produces the event
        • #{thingId} Unique id of the instances that produces the event
        • #{tenantId} Tenant id used to authenticate the m2mBridge, defined at bridgeConfig.json tenant property
        • #{userId} User id used to authenticate the m2mBridge, defined at bridgeConfig.json userId property

How to implement a new plugin

  • Clone git repository (https://github.com/AMTechMX/M2MBridge.git)
    • at /.../M2MBridge/plugins create a directory that matched with the Thing type name to bridge example SNMPDevice (See Thing types)
  • Create a thing type XXXDevice (See Thing types)
  • Create the observations type the thing XXXDevice produces or consumes, example XXXDeviceObserv1 (See Observations and observation types)
  • Associate the observation XXXDeviceObserv1 type to the XXXDevice
  • Implement a nodejs module with the following interface
    function XXXThing() {
    }

    XXXThing.prototype.start = function ( complete) {
        try {
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    XXXThing.prototype.stop = function (complete) {
        try {
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    XXXThing.prototype.command = function (observation, complete) {
        try {
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    module.exports.XXXThing = XXXThing;

How to install

HelloWorld plugin

Create thing type HelloWorld

  • add supported property type string hwgreetingLabel (See Thing types)
    • string without space validation regexp ^[^\s]+$
  • add supported property type integer hwSayHelloFrequency

Create observation type obsrvHelloWorld

Define observation types produce or consume by the Thing

  • add obsrvHelloWorldobservation to Observation Production configuration list (See Thing types)
  • add commandHelloWorldobservation to Observation Production configuration list
  • add observationresourcecrud to Observation Production configuration list

Implement plugin HelloWorld interface

    function HelloWorld() {
    }

    HelloWorld.prototype.start = function (complete) {
        try {
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    HelloWorld.prototype.stop = function (complete) {
        try {
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    HelloWorld.prototype.command = function (observation, complete) {
        try {
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    module.exports.HelloWorld = HelloWorld;

Functionality

  • send an observation obsrvHelloWorldobservation with the frequency set by the property hwSayHelloFrequency
  • change hwgreetingLabel value when receive command obsrvHelloWorld observation
  • implement placeholder #{greetingLabel}
  • start method
    • create an observation type obsrvHelloWorld at /amtech/things/observations (See Simulator)
    • copy observation instance jsonld
    var clone = require('clone');
    var util = require('util');

    function HelloWorld() {
    }

    HelloWorld.prototype.start = function (complete) {
        var self = this;
        try {        
            self.sayHelloInterval = setInterval(function(){
                var obsrvHelloWorld = clone({
                    "proximityarea": "",
                    "topic": "",
                    "guestusers": [],
                    "targetthings": "[]",
                    "location": "",
                    "@type": "/amtech/linkeddata/types/composite/observation/obsrvHelloWorld",
                    "hwgreetingLabel": "",
                    "creationDate": "2016-04-20T03:24:54.099Z",
                    "guesttenants": [],
                    "description": "",
                    "producer": ""
                });
                obsrvHelloWorld.hwgreetingLabel = self.hwgreetingLabel;
                var ph = {'greetingLabel': self.hwgreetingLabel};
                self.sendObservation(self,obsrvHelloWorld, ph );            
            }, self.hwSayHelloFrequency);
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    HelloWorld.prototype.stop = function (complete) {
        try {
            if (this.sayHelloInterval) {
                clearInterval(this.sayHelloInterval);
            }
            complete(null);
        } catch (e) {
            complete(e);
        }
    };

    HelloWorld.prototype.command = function (observation, complete) {
        try {
            if(observation['@type'] === "/amtech/linkeddata/types/composite/observation/commandHelloWorld"){
                this.hwgreetingLabel = observation.hwgreetingLabel;
                complete(null);
            }else{
                complete(new Error(util.format("HelloWorld %s support commands of observations type commandHelloWorld", this._name)));
            }
        } catch (e) {
            complete(e);
        }
    };

    module.exports.HelloWorld = HelloWorld;

Configure amtechM2MBridge template

  • (See Cloud Configuration)
  • create activity helloWorld (See Activities)
  • create helloWord notification (See Notifications)
    • add subject with placeholder #{label}
    • add subject with placeholder #{producer} and #{label}
  • create helloWorld actor with access polices (See Actors)
    • amtechM2MBridge thing type
    • HelloWord thing type
    • helloWord notification
    • associate helloWorld actor with helloWorld activity
  • configure observation production (See Observation production configuration)
    • thing type HelloWorld
      • observation type obsrvHelloWorld
        • topic /helloWorld/#{greetingLabel}
        • producer #{thingId}
        • guestTeants add m2mcreator to shared the observation
      • observation type observationresourcecrud
        • topic /helloWorld/asynch
        • producer #{thingId}
    • thing type amtechM2mBridge
      • observation type observationresourcecrud
        • topic /helloWorld/asynch
        • producer #{thingId}
  • create observation simulation for observation type obsrvHelloWorld (to be used in observers)
  • create helloWorld observer (See Observers)
    • type observation obsrvHelloWorld
    • test observer
  • create helloWorld reazoner (See Reasoners)
    • add action send notification type helloWorld
    • add action send command
    • test and validate reasoner
  • publishing activity (See Publishing)
    • validate activity
    • deploy activity
  • invite a user as helloWorld actor (See Invite user)
    • user id smartsensor@amtech.mx
  • configure helloWorld m2mBridge template
    • create amtechM2MBridge instance with name helloWorld (See Instances)
    • create HelloWorld type instace with name helloWorld
    • associate HelloWorld instance to amtechM2MBridge instance
    • give guest access to helloWorld M2MBridge instance to tenant m2mfollower and user smartsensor@amtech.mx
  • add new action send Command to reasoner helloWorld
    • thing type HelloWorld
    • observation type commandHelloWorld
    • set topic to /helloWorld/asynch
    • set target uri to observation producer See targetthings)
    • set hwgreetingLabel holaFromCommand

bridgeConfig.json

    {
        "description": "AMTech M2M Bridge Helloworld demo",
        "description:children" : true,
        "dap":{
            "dapUrl": "https://dapdev.amtech.mx",
            "userId": "smartsensor@amtech.mx",
            "tenant" : "m2mfollower",
            "password" :"xxxxxxxx"
        }, 
        "templateId":"helloWorld",
        "bridgeIdPrefix":"helloWorldDemo",
        "location:children" : true,
        "address" :{
            "country" : "USA",
            "city": "New York City",
            "road" : "97th street transverse"
        }     
    }

Debug a plugin

Example plugins (See exiting plugins)

LLRPReader

Bridge EPC Low Level reader protocol to IoT DAP (See LLRPReader) and /amtech/linkeddata/types/composite/entity/LLRPReader

  • Edge Intelligence
    • Implementing smoothing for new and lost tag
    • EPC decoding
    • Groups tags read by antennas groups
    • Groups tags by EPC decoding.
  • Placeholders (See Placeholders)
    • #{antennaId} Llrp protocol antenna Id set at antennas supported property
    • #{smoothingResult} if smoothing has been set to true LLRP reader observations can be sent to a topic depending of the smoothing process result [new|lost]
    • #{llrpReaderProximity} Set the llrp reader proximity area supported property value to targetThing proximity value field
    • #{antennaProximity} Set the llrp antenna proximity area supported property value to targetThing proximity value field
    • #{tagEncoding} EPC encoding name
    • A component of decoded epc tag; helpful to organize epc observations; for example company-prefix to inform companies about products arrival or set access control.
   #{epcUri|companyPrefix|itemReference|serialNumber|
   serialReference|locationReference|extension|assetType|
   individualAssetReference|serviceReference|documentType|
   managerNumber|objectClass|cAGEOrDODAAC}
  • Produced observations (see /amtech/linkeddata/types/composite/observation)
    • /amtech/linkeddata/types/composite/observation/observationresourcecrud
    • /amtech/linkeddata/types/composite/observation/graiEPC
    • /amtech/linkeddata/types/composite/observation/graiEPC
    • /amtech/linkeddata/types/composite/observation/decode96EPC
    • /amtech/linkeddata/types/composite/observation/sgtinEPC
    • /amtech/linkeddata/types/composite/observation/dodEPC
    • /amtech/linkeddata/types/composite/observation/giaiEPC
    • /amtech/linkeddata/types/composite/observation/ssccEPC
    • /amtech/linkeddata/types/composite/observation/gdtiEPC
    • /amtech/linkeddata/types/composite/observation/llrpError
    • /amtech/linkeddata/types/composite/observation/dataEPC
    • /amtech/linkeddata/types/composite/observation/encoded96EPC
    • /amtech/linkeddata/types/composite/observation/gidEPC
  • Commands (see /amtech/linkeddata/types/composite/observation)
    • /amtech/linkeddata/types/composite/observation/gpoWriteDataEPC

BLEbeaconsScanner

Bridge bluetooth low energy apple's ibecon and google's eddystone protocols to IoT DAP (See BLEbeaconsScanner) and /amtech/linkeddata/types/composite/entity/BLEbeaconsScanner

  • Edge Intelligence
    • Implementing smoothing for new, broadcast and lost tag
  • Placeholders (See Placeholders)
    • #{smoothingResult} if smoothing has been set to true EddystoneScan observations can be sent to a topic depending of the smoothing process result [new|lost|broadcast]
    • #{eddystoneType} Eddystone frame types, permissible values are uid, url and tlm
      • uid broadcasts an opaque, unique 16-byte Beacon ID composed of a 10-byte namespace and a 6-byte instance.
      • url broadcasts a URL using a compressed encoding format in order to fit more within the limited advertisement packet.
      • tlm telemetrics
    • #{eddystoneNamespace} 10-byte ID Namespace
    • #{eddystoneInstance} 6-byte ID Instance
    • #{proximityarea} Set the EddystoneHub proximity area supported property value to targetThing proximity value field
    • #{bleProtocol} [eddystone|ibeacon]
    • #{ibeaconUuid'} iBeacon advertised uuid
    • #{'ibeaconMajor'} iBeacon advertised major
    • #{'ibeaconMinor'} iBeacon advertised minor
    • #{'ibeaconProximity} current proximity from sacanner [unknown|immediate|near|far]
  • Produced observations (see /amtech/linkeddata/types/composite/observation)
    • /amtech/linkeddata/types/composite/observation/observationresourcecrud
    • /amtech/linkeddata/types/composite/observation/ibeaconScan
    • /amtech/linkeddata/types/composite/observation/eddystoneBrodcast
    • /amtech/linkeddata/types/composite/observation/eddystoneScan
    • /amtech/linkeddata/types/composite/observation/eddystoneScan

SNMPDevice

Bridge simple network management protocol to IoT DAP (See SNMPDevice) and /amtech/linkeddata/types/composite/entity/SNMPDevice

  • Edge Intelligence
    • Groups multiple snmp reads and writes in a single call
    • Maps snmp oid into human readable names
  • Produced observations (see /amtech/linkeddata/types/composite/observation)
    • /amtech/linkeddata/types/composite/observation/observationresourcecrud
    • /amtech/linkeddata/types/composite/observation/snmpError
    • /amtech/linkeddata/types/composite/observation/snmpTrap
  • Commands (see /amtech/linkeddata/types/composite/observation)
    • /amtech/linkeddata/types/composite/observation/snmpSet