Stack Configuration Tool
Stack Configuration Tool – Use Chrome browser and connect stack via USB cable
Stack Configuration Tool – Use Chrome browser and connect stack via USB cable
Wifi module AP Server Functionality
This block provides web server functionality on a stack to serve simple web apps using Wifi hardware. Using any web browser, from the desktop or mobile, authenticated end users can connect to the stack over wi-fi to view, edit, update data and control other aspects of the stack. This block is available in Library under Network & Communications section.
The Webserver is accessible from the IP address of the Wifi module [at the time it got assigned by DHCP of the router its connected to] AND via the Access Point IP Address if the WIFI block is setup to act as an Access Point. See WIFI module for details on AP functionality.
By default, the root of the webserver is /. There are a few paths from the root that are predefined such as
/webapp/ –> Path under which all web applications [single page webapps(html+css+js)] are hosted. For example, a web application ‘sensordashboard’ that displays sensor data as a form layout could be specified at /webapp/sensordashboard [Note: we didn’t specify the port in the host address if we are using the standard HTTP server port of 80 which is the default setup]
/data/ –> Path under which data for each of the web applications are accessed. Using the above example, the data for the ‘sensordashboard’ web app could be retrieved and updated independently at the URL /data/sensordashboard
/stack/ –> Path for stack related web services
PROPERTIES:
‘webapp’ : This is a dictionary that specifies the parameters of your default web application. Each web app can have the following specs: ‘path’ –> which will point to /webapp/, ‘label’ –> human readable name which could also be used as a title on the web app if used by the template, ‘template’ –> single page webapp(html+css+js) that is either a blob of text or a UUID of some yet to be defined file type (maybe .html), ‘data’ –> which has any dynamic data to show that will be referenced by GET and PUT/POST at /data/ i.e, the data and webapp paths are parallel structures. The stack web server has a built-in template to display forms and charts which will be used as default it a value is not specified (See Template info for details)
‘credentials’: a list of dictionaries of the form {‘username’:xxx,’password’:yyy,’path’:[‘/zzz’,’/www’]}, where the path, if specified, limits access to THAT user for the specific list of paths (and sub trees below those paths). If path is not specified, the default behavior is that the entire webroot (/) is accessible by that user. This model provides a flexible, fine grained multi-user access control for individual web applications and other web services. Since this property stores sensitive access information, use caution to make sure this is not set on Blueprints directly but is instead allocated via the more secure Stack Environment setup.
‘port’: port number of the HTTP server to which clients connect to access the web server. Default is the standard HTTP port 80
INPUT TERMINALS:
1:init – Any message received by this terminal will initialize the server to start listening on the specified port. Typically this is triggered only once to kickstart the process.
3: in – This is a generic terminal that can handle multiple messages types. The common message is a dictionary of the form similar to the ‘webapp’ property. This can be used to create new web apps or update the data displayed by an existing web application. From our earlier sensordashboard example, when our sensor values changes, we can update them on the webserver by sending a message {‘path’:’sensordashboard’, data:}
In the case of a default web app hosted at /webapp/ as specified in the ‘path’ attribute of the ‘webapp’ property, a convenience feature is to send the data directly without having a need to specify the web app’s path [since it is the only one]. In this case, the data message must always be sent as a list even for a singleton data value.
More than one web app can be created, updated anytime by sending a dictionary that contains at least the ‘path’ attribute along with other attributes optionally.
OUTPUT TERMINALS:
2: out – This is a generic terminal that outputs multiple message types. Typically the output is a dictionary of the form specified in the ‘webapp’ property and is emitted whenever data is modified via a POST or PUT method. For example, in the ‘sensordashboard’ web app, when the user updates a value using the web form template, a dictionary message of the form similar to the ‘webapp’ property is sent out to be handled by the stack application logic which can then proceed to update the sensor configuration and values. In the sensordashboard example, the message will be of the form {‘path’:’sensordashboard’, data:[]}
In the case of a default web app hosted at /webapp/ as specified in the ‘path’ attribute of the ‘webapp’ property, a convenience feature is to send the data directly without having a need to specify the web app’s path [since it is the only one]. In this case, the data message will always be sent as a list even for a singleton data value.
Default Template:
Any web app that doesn’t have a ‘template’ attribute will make use of the default template(s). There are two templates that are available for use based on the user needs.
Form Template:
This is a simple template that provides a form based interface to view and edit properties and their values, say sensor data, in a simple clean layout based on a stripped down version of a light weight css (just 4KB) called Pure – https://purecss.io/
The form template will render the web app based on the data associated with that web app. For instance, in our sensordashboard example, if we want to display three sensor values for Co2 levels, Humidity and Temperature, we would then need to have the data associated with the web app (say via the ‘data’ attribute of the ‘webapp’ property or via any dictionary that has a key value pair of ‘data’:[datavalues]) sent to the 3: in terminal along with the ‘path’ key to associate the data with the corresponding webapp) as follows
[{
"name": 'co2',
"label": 'Co2',
"type": 'number',
"value": 300
}, {
"name": 'humidity',
"label": 'Humidity',
"type": 'number',
"value": 34.3,
}, {
"name": 'temp',
"label": 'Temperature',
"type": 'number',
"value": 79.2,
"editable": True,
}]
From the structure above, each data item has a “name” which serves to identify the data item, a “label” which will be used as a label on the form layout, a “type” that describes the value type associated with this data item [numbers, strings etc], a “value” attribute that has the value for the data item and an “editable” attribute that determines if the value can be changed using the web app.
Note: The template will auto-update the data associated with the web app every 4 seconds.
Displaying Graphs:
Any web app using the default template can also display the data as a graph or chart by simply adding a parameter, ?display=graph, to the URL of the web app. For example, if we want to visualize the sensordashboard app as a series of graphs, one for each data sensor type, we can do so by
<ipaddr>/webapp/sensordashboard?display=graph
Note: The graph template will auto-refresh the data associated with the web app every 2 seconds and will render the graph as a time series graph with a sliding window of 100 values that translates to 200 seconds of time series data.
Example Project – Simple Webservice
In the above project, the ‘dashboard data handler’ block provides the data on startup to intiliaze the ‘stackdashboard’ webapp and every few seconds, based on the refresh property, randomizes the values(hence the channels to the Base block’s Random number generation terminals). The following image shows the block details
With the blueprint loaded and having known the IP address of the Wifi block, opening a web browser and pointing it to the ipaddr (in this example it is 192.168.1.105) will bring up a login prompt for the first time (in each browser until the browser is closed). Providing the valid credentials as specified in the credentials property will allow access to the web apps.
Refer to documentation on many other topics at interstacks.com/knowledge-base.
Please email info@interstacks.com with any questions.
MTConnect is one of many messaging protocols used to communicate between machines. This document describes, using an example, setting up a MTConnect Adapter for an Interstack Device that communicates temperature and humidity sample values to an MTConnect Agent on a LAN via Ethernet.
The screenshot above shows the MTConnect Demo( ~015516494ace3a11e7b226c27461e15f81) project which can be imported to your Stackbuilder [ click on the Project tab on the set of Palettes to the right. Then from the OS Menu, go to Block–>Import. Copy and Paste the UUID string to import the project into your Projects collection. Once available, double click on it to open]
The 4 blocks that make up the project are as follows
Base – High Speed Every Stack needs a Base module. In our project, the Base provides a kickstart message via the “22:Stack Ready” terminal to initialize the other blocks and provides time functions
Unix Time – from Base This block provides an convenient way to extract Unix Time from the Base. The “5:startup_unixtime” terminal is wired in to the MTConnect Ethernet Block to provide timestamps for messages sent by the adapter to the agent.
humidity, temp data This is a test data generator that outputs temperature and humidity data at set intervals with a default of 2 seconds. The interval can be set by the user via the ‘sampleinterval’ property of this block.
MTConnect Ethernet Block
This block provides the communication between the adapter and the agent via the Ethernet Module on the stack. This block automatically deals with the MTConnect PING PONG protocol for keep alives and the AVAIL dataitem.
This Block is available in the Library Tabs–>Network & Communications to be drag and dropped in to your projects.
Details of this block are as follows:
PROPERTIES:
‘mtc.port’ – The port number in which the Adapter will listen for incoming connections from the agent. Default is 7878.
‘mtc.delimiter’ – The delimiter character used in the messages sent by the adapter. Default is ‘|’ character as per MTConnect standard.
‘mtc.heartbeat’ – The heartbeat interval for the PING PONG messages. Default is 10000. Units are milliseconds.
‘mtc.include_ts’ – Boolean that determines whether a timestamp will be sent with each message. Default is True.
‘mtc.newlinechar’ – The newline character to be used to indicate the end of a message. Default is ‘\r\n’. On some agents, they may requires just the ‘\n’ or ‘\r’.
‘mtc.staticip’ – The static IP Address to be set for the Ethernet. Should be a valid IP Address string of the format ‘xxx.xxx.xxx.xxx’. Default is EMPTY indicating the IP Address for the Ethernet module is DYNAMICALLY set via DHCP. Check with your network administrator if you need to provide a static ip.
INPUT TERMINALS:
1:init – Initializes the adapter, sets up the ethernet connection with the LAN and starts the server to listen for incoming connections from the agent.
2:starttime – Receives the unix time from the Unix Time block for including timestamps in the MTConnect message protocol
3:msg_in – Receives data from the stack which will be sent out as MTConnect message. This terminal can receive three kinds of message.
Delimited string of key values – e.g. “temperature|34.34|humidity|56.45” where | is the delimiter character between the consecutive keys and values
Python List of keys and values – e.g, [“temperature”,34.34,”humidity”,56.45]
Pythton dictionary of keys and values – {‘temperature’:34.34,”humidity”:56.45} This is the format sent by the “humidity, temp data” block in the demo as it the most convenient to use.
Each time a message is received in msg_in, it will be sent out on the LAN as long as there’s an agent listening.
Example Output of running the demo.
You can directly run the imported Demo or make a copy of it and run your version.
Once you load the project to the Stack via the “Send to Stack” button, the Console tab from the bottom will show up as shown below.
After the STARTUP message, if the Ethernet cable is plugged into the Ethernet module (and in the case of DHCP) the next message will indicate the IP Address of the this Ethernet Adapter. Make note of the IP Address to configure your agent to connect at this IP address.
Example agent config and example data specification for the stack adapter device are provided for reference.
agent.cfg
Isxmtcdev.xml
For MTConnect agent configuration please refer to MTConnect Agent (github)
Once the agent is started and begins communication with the Stack Adapter, the console log on Stackbuilder will indicate the messages being sent to the agent
To confirm the receipt of these messages by the agent, you can verify by requesting the current state of the agent for the specified adapter. Here’s an example of the kind of information available from the adapter.
Refer to documentation on many other topics at interstacks.com/knowledge-base.
Please email info@interstacks.com with any questions.
The Stackbuilder Library Tab (in the right rail), in the “Network & Communication” collection, has a number of software blocks that facilitate sending data to IoT cloud platforms. What follows is information on some of them. New ones are being added on a regular basis. A separate downloadable document on this support web site covers using Interstacks with PTC’s Thingworx IoT cloud platform.
Exosite Cloud HTTP API Interface
(~01dbd2dfd2468a11e59a6bcd55860b4b3e)
This block pre configures relevant properties of the base HTTP API block interstacks.com/knowledge-base/internet-communication-with-http-block/ with default values pertaining to Exosite’s One Platform docs.exosite.com/portals/http such that the Block can work with minimal configuration by the user.
The only parameter required to be set by the user is their Exosite’s Authentication Token called Client Identification Key (CIK) which can be set by the user for the exposed property named ‘cik’
The default properties, which can be overridden, for this block are as follows:
‘requesttype’: ‘POST’ –> Preconfigure to allow sending device data to Exosite
‘authtokenheader’: ‘X-Exosite-CIK’ –> Specifies to use Exosite’s CIK as the authentication header
‘content-type’: ‘application/x-www-form-urlencoded’ –> Format of the content type, may be changed to json for ease of use
‘url’: ‘http://m2.exosite.com/api:v1/stack/alias‘}) –> Default URL for device data to Exosite using version 1
IBM Watson (Bluemix) IoT HTTP API
(~01adedbe025a8311e79d79f63ed4d343a0)
This block configures the HTTP API block with IBM specific parameters obtained from the user’s account with IBM Watson to post data as a device. The parameters exposed by this block (in addition to those of the HTTP API block) are:
baseurl – string – Base URL to build the specific device URL. Defaults to “messaging.internetofthings.ibmcloud.com:1883/api/v0002/device/types”
orgid – string – Organization ID as specified in your IBM Watson IoT account settings
devicetype – string – Device Type as specified in your IBM Watson IoT account settings
deviceid – string – Device ID as specified in your IBM Watson IoT account settings
eventid – string – Event ID describing the event type. Typical event id may be “status” to indicate the status or value of a device’s sensor data.
authtoken – string – Authentication Token password/token associated with the device for authentication with IBM IoT
The first five properties will build the specific URL for the event associated with the device and the authtoken property is the token associated with the device.
The “init” input terminal will accept Python dictionaries/E-forms with all the keys specified above and their values along with all the keys associated with the HTTP API block.
The “http request” input terminal and the two output terminals are the same as that of the HTTP API Block.
Azure IoT Hub Device API
(~01fdc8daae569611e7a984ecc6e2eb86b7)
This block provides an interface to the Device API of Micrsoft Azure’s IoT Hub. The connection parameters of the IoT Hub are specified via the following properties:
connection_string – string – Connection string of a device obtained from the IoT Hub for a specific device
device_id – string – Device ID of this device
token_validity – integer – Validity of an obtained token in seconds. Default is 86400 which equals 24 hours. The tokens get auto-renewed automatically without requiring user action
api_version – string – API version string of Azure IoT Hub to be used with the request. Default is “2016-02-03”
Input Terminals:
“1:init” – This terminal will accept dictionaries/E-forms with keys and values corresponding to the properties specified above.
“3:data” – Once connection to IoT Hub is established, any message received by this terminal will be sent to the Azure IoT Hub as JSON.
“5:current_time” – Since Azure connections rely upon computing Unix Time, this terminal accepts unix time to aid in making the connection. Typically this terminal is connected with the output terminal of the “sync time and date from server” block found in the “Network & Communication” section of the Library in Stackbuilder.
Output Terminals:
“2:status” and “4:http_response” are the same as that of the HTTP API Block
“6:sastoken_info” – Provides token information at the time of establishing a connection with Azure. May be used for verification by the end user.
Refer to documentation on many other topics at interstacks.com/knowledge-base.
Please email info@interstacks.com with any questions.
You can send and get information from a stack to web sites, or other internet hosts, that support REST API calls over a HTTP (or HTTPS) internet connection. First, use the Wifi hardware block to connect your stack to your local LAN and hence the internet. In your Stackbuilder blueprint, drag and drop the Wifi block from the Hardware tab into your blueprint. Then click once on the Wifi block to select it. Use the Property Editor in the bottom right to set the ’N’ property for LAN network name (SSID), and the ‘P’ property for the password.
Set Properties for Wifi block
Click on the first empty row’s first column under “PROPERTY” and type N (for Network name), hit Tab to go to the next column (“Default Value”) and type in the SSID of the wifi network you want to connect to, say for example “mynetwork” (type the quotes as well). Hit tab twice to move on to the next row. Now type P (for password), hit Tab to go to the next column and type in the password for the wifi network, say for example “mynetpass” (type the quotes as well) and hit tab twice to move on to the next row.
Put HTTP API block in your blueprint
To set up a HTTP API to the server of your choice, on the Right Rail of tabs, click on Library and then click on “Network & Communication” to reveal the “HTTP API Interface” block. Drag and drop the block onto the project. When you click once on the HTTP API block, notice the properties on the bottom right corner as shown in the screenshot below.
Set Properties for HTTP API block
You can configure the properties of the HTTP API Interface to point to your server and compose the message format to send. Click on the DEFAULT VALUE column of each property to set its value. Set all string values within “” marks and make sure you hit the Tab key to tab out of the column. The property definitions are as follows.
Url – The REST URL of the server. For Exosite, it is “http://m2.exosite.com/api:v1/stack/alias“. Fill in your server address (it could be IP address as well, but prefix it with http:// for example “http://123.123.123.123/Mydata/dataid/“).
Httptimeout – This represents the timeout in seconds, after which a HTTP connection will be reset if not completed. The default is 30 seconds. This should be entered as a number without quotes.
Requesttype – The type of the HTTP request. For Exosite it is “POST”. Other possible values are “GET”, and “PUT”.
The rest of the properties define some of the common message headers to be used in a HTTP request/response. For in-depth details, refer to the Headers section of the HTTP/1.1 protocol RFC at https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. Some common headers exposed as part of the API are as follows:
connection – Specifies the option for that particular HTTP connection. The default is set to ‘Close’ indicating the connection will be closed after completion of the response.
content-type – This refers to the encoding type of the data being sent to the server. For Exosite, the value is “application/x-www-form-urlencoded”. Other values are “application/json” for example, to send JSON data.
accept – Refers to the acceptable media types in the response for the request. This is by default set to / which indicates all media types.
accept-encoding – Similar to Accept, but restricts the content-codings that are acceptable in the response. By default, it is not set (or set to None) implying there is no restriction on the encoding types that will be accepted in the response.
Authtokenheader – If your REST API server requires a security header to verify the authenticity, specify the name of the header. For example ( We will be using Exosite – a cloud based IOT data aggregator to illustrate the setup), “X-Exosite-CIK” as the default value.
Authtokenvalue – This is the security token that identifies the user with the server. In the Exosite example, this is provided by them per user, which should be kept secret. Fill in your own secret, if your server requires it.
user-agent – Specifies information about the client agent originating the request. The default value is ‘python-requests/2.8.0’ indicating the underlying python based HTTP request block.
extraheaders – Optional header/value pairs that could be added in addition to the already provided header options.
After configuring this block, any correctly formatted data sent into the “http request” terminal of this block will be sent out to the server via REST calls. The entire HTTP response to the REST call is available from the “http response” terminal of this block, which can be wired to any of your logic. The “status” terminal is a short-hand in case all you want to know is success or failure. A value of 0 from this terminal means success and -1 means failure.
Your blueprint should wait to send/receive (“POST” / “GET”) from the HTTP block until the Wifi block has established a connection to your LAN. Its “Connected?” output terminal will send an integer value of 2, once it is connected and has an IP address assigned.
If you want to GET information from a web site, for example the weather, you will often just send an empty string “” to the “Http Request” input terminal, after setting all of the appropriate properties for the block. The Request type would be set to “GET” and the url might be of the form: “http://forecast.weather.gov/MapClick.php?lat=38.4247341&lon=-86.9624086&FcstType=json“.
As an example, here’s a code snippet (from Exosite example) for formatting a list of sensor data as a form-urlencoded string. You can create a new Software Block and copy paste the snippet below in the code area of the handler.
#sensor values set to some test values. In this example, we have 5 sensor readings.
temp,humid,co2,part1,part2 = [10,20,30,40,50]
#convert to form-urlencoded string
form-urlmessage = "temperature=%f&humidity=%f&co2=%d&smparticle=%d&lgparticle=%d" %(temp,humid,co2,part1,part2)
#send out the message, the channel from this output is wired into the "http request" terminal of the HTTP API block
I.sendmessage(2,form-urlmessage)
If you would like to send JSON data instead:
import json
temp,humid,co2,part1,part2 = [10,20,30,40,50] #sensor values set to some test values
#convert to json data
jsonmessage = json.dumps({"temperature":temp,"humidity":humid,"co2":co2,"smparticle":part1,"lgparticle":part2})
I.sendmessage(2,jsonmessage)
Refer to documentation on many other topics at interstacks.com/knowledge-base.
Please email info@interstacks.com with any questions.
The Interstacks Base hardware block contains an 8GB repository for data storage in non-volatile Flash memory. Interstacks repositories have a built-in database to make saving and reading data easy to use. You use the built-in software blocks in the Data Storage category (of the Library palette in the right rail of Stackbuilder) to read and write data to/from the flash memory repository. Drag and drop the data storage block(s) you want to use from the blocks palette into your blueprint. There are blocks that provide basic functionality and ones that provide advanced database access.
We will now describe these blocks, from basic to advanced.
Data – One Value
A value to write is sent to Terminal 1. When you want to read that value, send any message to terminal 2. The value is sent out of the output terminal.
Data – One Value List
A value to write is sent to Terminal 1. It is appended to a list of all previous values sent to it. The values must be of the same type. When you want to read that value, send any message to terminal 2. The value is sent out of the output terminal as a Python list e.g. [1, 2, 3, 4]
Data – [Name, Value]
Input terminal 1 accepts a message that is a list of a Name and its value e.g. [‘Temperature’, 72]. The value will be written to the repository and will stay associated with the Name. When you want to read the value, send a list with just the Name e.g. [‘Temperature’]. The value will be sent out of the output terminal. You can send as many different [‘name’, value] pairs as you want. The values can be any valid Python value. This is sometimes referred to as a No-SQL, attribute-value store.
Its important to recognize that the Names used to store and retrieve data via this block will only work with this specific block, unless you use more advanced data storage blocks.
Data – [Name, Value] List
This block functions just like the “Data – [Name, Value] block, but values sent with the same name are appended to a list. All reads will be sent out as a Python list.
Its important to recognize that the Names used to store and retrieve data via this block will only work with this specific block, unless you use more advanced data storage blocks.
Advanced Data Storage
These next two data storage blocks are for advanced use and require understanding the underlying structure of the built-in database. Values are stored in the Interstacks built-in database using u-forms. A u-form is a UUID (large, unique number), followed by a list of name-value pairs. To read a value, you need its UUID and Name.
Data – [UUID, Name, Value, List]
Input terminal 1 accepts a list that is [UUID, Name,, <optionally 1 if want append to list> ]. If you send [ UUID, Name] the value is read and sent out the output terminal. If you send [ UUID, Name, Value] the value is written using the UUID and Name. If you send [ UUID, Name, Value, 1] the value is written and appended to the list of all previous values sent to that UUID-Name. When using the append to list option, the values must be of the same type and all the writes must have the list option set to 1.
Example to write a value: [UUID(‘~00443322667700’), ‘myfirstval’, 345] Example to read a value: [UUID(‘~00443322667700’), ‘myfirstval’] To generate a unique UUID, use: myUUID = UUID().
Data – UForms
The Data-UForms block supports movement through the entire built-in Interstacks data repository in the hardware stack. The repository stores data in non-volatile memory in the stack using the model of a UUID with a list of <Attribute Name – Value> pairs.
A UUID is a large, unique number. Each UUID can have an arbitrary number of <Attribute name – Value> pairs. This UUID, Name-Value list is called a Form. You can retrieve any value by using its UUID and Attribute name (use the “Data – [UUID, Name, Value, List]” software block). The value can be any valid Python type, from integers and character strings to lists and dictionaries. This type of model is sometimes referred to as a No-SQL database. There are other advanced database concepts that this model supports that we will leave to other documents.
Terminal 1 accepts a UUID.
If it receives a valid UUID, it outputs the entire list of Name-Value pairs for that UUID.
Output example: [ [‘value1’, 7], [‘value2’, 8] ]
so firstName = value read[0][0] firstValue = valueread[0][1]
Terminal 3 – Get next u-form
If any message is sent to the second input terminal, the block moves to the next u-form stored in the repository and sends out the output terminal a list with the UUID and all of its Name-Value pairs.
Output example. [ UUID(‘~110044559988334422’), [‘value1’, 7], [‘value2’, 8] ]
theUUID = valueread[0]
firstName = valueread[1][0]
firstValue = valueread[1][1]
If send it None, it starts at the first UUID in repository. It outputs None when it reaches the last u-form.
To start moving through a repository, send None to the second input terminal, then any message. The None will set up the next read to be from the first u-form in the repository. After the last u-form is read, the next GetNextUForm request will return None.
Refer to documentation on many other topics at interstacks.com/knowledge-base.
An academic paper on distributed databases and U-forms is here: “Toward the Universal Database: U-forms and the VIA Repository”
Please email info@interstacks.com with any questions.