# uCOMmandIt (UCI) - An Extendable Inter Process Communication Base Class ## Supports multi type and transport communication via a JSON packet. *used as the basis of many of the UCI library classes* [![Build Status](https://img.shields.io/travis/uCOMmandIt/uci-base.svg?branch=master)](https://travis-ci.org/uCOMmandIt/uci-base) [![Inline docs](http://inch-ci.org/github/uCOMmandIt/uci-base.svg?branch=master)](http://inch-ci.org/github/uCOMmandIt/uci-base) [![Dependencies](https://img.shields.io/david/uCOMmandIt/uci-base.svg)](https://david-dm.org/uCOMmandIt/uci-base) [![devDependencies](https://img.shields.io/david/dev/uCOMmandIt/uci-base.svg)](https://david-dm.org/uCOMmandIt/uci-base?type=dev) [![codecov](https://img.shields.io/codecov/c/github/uCOMmandIt/uci-base/master.svg)](https://codecov.io/gh/uCOMmandIt/uci-base) ## What is it This module contains an JSON packet socket communication ES6 class. By extending this class you can bake in pretty much any conceivable inter process communication from named pipe to mqtt into your own class and instances. Your extended class can be both a socket(server) and a consumer(client) at the same time which allows you to listen for incoming packets, process them and then send or push them on to other processes running either locally or remotely. Further you can, at runtime, create additional sockets and consumers. ## What's it good for By extending this class you can create all manner of "smart" processes that an take action or request action from/to another process (either local or remote) via a simple JSON packet. So it's good for....most ANYTHING. Need to talk to an I2C device on some SBC then create an instance of an I2C-device class that talks to an instance of an I2C bus class both of which are extended from this UCI base class. Now create a "master controller" from the base class that takes in command packets from say a [websocket browser]() or an mqtt interface like [Home Assitant](https://www.home-assistant.io/) and boom you are controlling some I2C device from your browser or home assistant with a click. But that's already been done for you as both as UCI has both an i2c-device class and a UCI i2c-bus class available [UCI @github](https://github.com/uCOMmandIt) or [UCI @npm](https://www.npmjs.com/search?q=scope%3Auci) or [UCI @npms.io](https://npms.io/search?q=scope%3Auci) ## Prerequisites You'll of course need nodejs running and either npm or yarn. UCI tries to keep node as current as possible during development so use the latest version 10.x for best results or at a minimum the last version of 9.x. Getting these prerequistes set up is beyond the scope of this readme. One pretty easy way is using [node version manager](https://github.com/creationix/nvm) which makes it easy to swap between versions of node if need be (not supported in Windows but see their suggested alternative) ## OS Support UCI was developed primarly for IOT (internet of things) and SBCs (single board computers) like the Raspberry Pi that run linux and nodejs. As such there was NO effort made to confirm that this base class or any of its extensions will work on a machine running Windows or OSX. You are welcome to try. I predict no issues on OSX but definitely using 'named pipes' on Windows will likely not work without some changes to the @uci/socket module. ## Terminology While developing the UCI library the following terminolgy was adopted to describe a communication connection through which the JSON packets can potentially travel. Each connection is specified with a `type` and a `transport` **type**: can be either `s` or `c`. `s` refers to either **s**ocket or **s**erver and `c` refers to either **c**onsumer or **c**lient. **transport**: refers to how the packet is *transported* from a socket to consumer and vice versa. There are several transport Methods * `n` is for `named pipe` transport better known as a *unix socket* in unix. This is the prefered transport for communication within a single computing device. * `t` is for `TCP` transport which stands for *transmission control protocol* and is THE transport for IP(Internet Proctocol) networks which means it's great for both LAN and WAN communiction * `m` is for `MQTT` which is another protocol specifically adopted by the IOT community for easy inter-device communication. It requires one to run a **broker** in order to broker the packets from on device to another and vice versa. Home Assistant is one home control frontend that supports MQTT. This means home assistant can control any device which extends this base. * `w` is for `web socket`. A *web* socket is a special version of a `TCP` socket that allows easy communication from a browser to a web socket server. This means any classes derviced from this base class will be able to communicate directly with a broswer! ## The UCI JSON Packet 'Protocol' If you are a javascript programmer then you already know about object hashes. JSON is a `stringified` representation of such object hashes. Being a string JSON can be easily encoded and sent via a socket. It can then be parsed at the other end back into an object hash. There in lies the power of sending a JSON packet rather than some generic string. A UCI JSON packet starts and ends its life as an object hash. When creating this hash you need make sure to include at a minimum at command property (*key:value* pair e.g. `cmd:'switch/on'`). It is this `cmd` property that will result in a function being executed at the other end of the socket using the parsed value of `cmd:` as the function name and any other properties of the packet/hash you include as arguments or data to the called function. The function(s) that can be invoked at the *target* live in a name spaced hash. The base class manages invoking the appropriate function for you. You only need to create the function(s) hash for your instance/class that corresponds to the packet `cmd` values you want to recognize/support. That's the gist of how the UCI socket communication system works. Another cool thing about the UCI protocol is that it attaches automatically a unique header ID to each packet and then *listens* for when a packet comes back with that ID. In this way you can `await` for a response from your socket sever and then take an action like turning a button green after getting confirmation a 'switch/on' command did indeed turn on the corresponding circuit(s). The socket/server modules also support push notifications! As to MQTT the UCI mqtt module takes the `cmd` property and converts it into the equivlent mqtt topic and vice versa sending the remaing hash as the MQTT payload. This makes MQTT interoperabilty with the UCI JSON Packet *Protocol* seamless. ## Getting Started The best way to get started is to clone this repo and then take a look at and run the four-in-one example found in the /examples. You can run it with `npm run fio` script. This example creates an instance of this base class that fires up four socket/servers of each transport and two consumers of transport tcp and named pipe. With this running in a terminal you can now "mess around" sending packets to this instance with a mqtt or websocket client. Here are two clients I like [mqttbox](http://workswithweb.com/mqttbox.html) and [simple websocket client](https://chrome.google.com/webstore/detail/simple-websocket-client/pfdhoblngboilpfeibdedpjgfnlcodoo?hl=en) which runs only within google chrome . Another options is to use the UCI websocket development client found [here]() TODO describe how to connect and what packet command/topic to send/use. ## Creating an Instance ## Extending This Base Class ## Options ## API