Skip to content

Commit e5a3d82

Browse files
Initial Release
0 parents  commit e5a3d82

16 files changed

+4642
-0
lines changed

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Ignore everything
2+
**
3+
4+
# Allow files and directories
5+
!/package.json
6+
!/Dockerfile
7+
!/LICENSE
8+
!/MAINTAINERS
9+
!/README.md
10+
!/src/**
11+
!/docs/**

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
node_modules
3+
.scannerwork/

Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM node:12-alpine
2+
3+
WORKDIR /machine
4+
5+
COPY package.json /machine
6+
7+
RUN npm install
8+
9+
COPY ./src/ /machine
10+
11+
USER node
12+
13+
CMD node index.js

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Spruik Technologies
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Tom Hollingworth <[email protected]>

README.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Manufacturing Line PackML MQTT Simulator
2+
3+
| Manufacturing line simulator interfaced using PackML over MQTT.
4+
5+
PackML MQTT Simulator is a virtual line that interfaces using PackML implemented over MQTT. For use with the development of Industry 4.0 software solutions. The simulator implements the following PackML State model:
6+
7+
![PackML State Model](./docs/PackML-StateModel.png)
8+
9+
and communicates over MQTT using `<SITE>/<AREA>/<LINE>/*` topics as defined by environmental variables.
10+
11+
## Getting Started
12+
13+
To start and run the PackML simulation, you'll need an MQTT server running and accessible to the image. Once available, the easiest approach is using docker to run the simulation using environmental variables to control the MQTT host, Site, Area, and line. Once up and running, use an MQTT client to publish to .../Command/Reset and .../Command/Start to get the simulated machine into the execute state.
14+
15+
### Docker
16+
17+
Start your container with environmental variables
18+
19+
```shell
20+
$ docker run -it -e SITE=Site -e AREA=Area -e LINE=Line -e MQTT_HOST=mqtt://broker.hivemq.com spruiktec/packml-simulator
21+
2020-06-22T03:13:49.301Z | info: Initializing
22+
2020-06-22T03:13:49.817Z | info: Connected to mqtt://broker.hivemq.com
23+
2020-06-22T03:13:49.819Z | info: Site/Area/Line/Status/UnitModeCurrent : Production
24+
```
25+
26+
### Node
27+
28+
```shell
29+
$ npm i
30+
...
31+
added 421 packages from 213 contributors and audited 421 packages in 12.337s
32+
found 0 vulnerabilities
33+
$ node ./src/index.js
34+
2020-06-22T03:13:49.301Z | info: Initializing
35+
2020-06-22T03:13:49.817Z | info: Connected to mqtt://broker.hivemq.com
36+
2020-06-22T03:13:49.819Z | info: Site/Area/Line/Status/UnitModeCurrent : Production
37+
```
38+
39+
## Simulation
40+
41+
The simulation consists of
42+
43+
- On Startup, the machine will automatically enter the *Clearing* and then *Stopped* state
44+
- PackML UnitMode command and status
45+
- PackML State Model with commands and status
46+
- Machine Speed (ramping up/down and flicker)
47+
- Setpoint Observed
48+
- Status of current speed
49+
- Machine Design Speed Respected
50+
- Counters
51+
- 1x Consumed
52+
- 1x Produced
53+
- 1x Defective
54+
- Automatic machine suspension/unsuspension from Execute state
55+
- Echo's command of Parameters, RemoteInterface, and Products back onto the status tags
56+
57+
The simulation uses probability dice rolls to determine actions.
58+
59+
## Interfacing
60+
61+
Interface with the virtual line via MQTT. The virtual line subscribes to `<SITE>/<AREA>/<LINE>/Command/*` (see below) and publishes information to `<SITE>/<AREA>/<LINE>/Status` and `<SITE>/<AREA>/<LINE>/Admin`. `<SITE>`, `<AREA>` and `<LINE>` are set using environmental variables.
62+
63+
### Commands
64+
65+
Available Commands
66+
67+
| Topic | Values | Function |
68+
|-------------------------------------------------------------------------------|---------|-----------------------------------------------------------|
69+
| `<SITE>/<AREA>/<LINE>/Command/Clear` | 1, 0 | Clear Command |
70+
| `<SITE>/<AREA>/<LINE>/Command/Reset` | 1, 0 | Reset Command |
71+
| `<SITE>/<AREA>/<LINE>/Command/Start` | 1, 0 | Start Command |
72+
| `<SITE>/<AREA>/<LINE>/Command/Hold` | 1, 0 | Hold Command |
73+
| `<SITE>/<AREA>/<LINE>/Command/Unhold` | 1, 0 | Unhold Command |
74+
| `<SITE>/<AREA>/<LINE>/Command/Complete` | 1, 0 | Complete Command |
75+
| `<SITE>/<AREA>/<LINE>/Command/Stop` | 1, 0 | Stop Command |
76+
| `<SITE>/<AREA>/<LINE>/Command/Abort` | 1, 0 | Abort Command |
77+
| `<SITE>/<AREA>/<LINE>/Command/UnitMode` | String | Unit Mode Command (`Production`, `Manual`, `Maintenance`) |
78+
| `<SITE>/<AREA>/<LINE>/Command/MachSpeed` | Decimal | Machine Speed Command |
79+
| `<SITE>/<AREA>/<LINE>/Command/Parameter/*n*/ID` | Integer | Parameter *n* ID |
80+
| `<SITE>/<AREA>/<LINE>/Command/Parameter/*n*/Name` | String | Parameter *n* Name |
81+
| `<SITE>/<AREA>/<LINE>/Command/Parameter/*n*/Unit` | String | Parameter *n* Unit |
82+
| `<SITE>/<AREA>/<LINE>/Command/Parameter/*n*/Value` | Decimal | Parameter *n* Value |
83+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/ID` | Integer | Product *n* ID |
84+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/ProcessParameter/*j*/ID` | Integer | Product *i* Process Parameter *j* ID |
85+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/ProcessParameter/*j*/Name` | Integer | Product *i* Process Parameter *j* Name |
86+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/ProcessParameter/*j*/Unit` | Integer | Product *i* Process Parameter *j* Unit |
87+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/ProcessParameter/*j*/Value` | Integer | Product *i* Process Parameter *j* Value |
88+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/Ingredient/*j*/ID` | Integer | Product *i* Ingredient *n* ID |
89+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/Ingredient/*j*/Parameter/*k*/ID` | Integer | Product *i* Ingredient *j* Paramter *k* ID |
90+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/Ingredient/*j*/Parameter/*k*/Name` | Integer | Product *i* Ingredient *j* Paramter *k* Name |
91+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/Ingredient/*j*/Parameter/*k*/Unit` | Integer | Product *i* Ingredient *j* Paramter *k* Unit |
92+
| `<SITE>/<AREA>/<LINE>/Command/Product/*i*/Ingredient/*j*/Parameter/*k*/Value` | Integer | Product *i* Ingredient *j* Paramter *k* Value |
93+
94+
### Status
95+
96+
Available Status'
97+
98+
| Topic | Values | Function |
99+
|------------------------------------------------------------------------------|---------|-----------------------------------------------------------|
100+
| `<SITE>/<AREA>/<LINE>/Status/StateCurrent` | String | Current PackML State |
101+
| `<SITE>/<AREA>/<LINE>/Status/UnitMode` | String | Current PackML Model |
102+
| `<SITE>/<AREA>/<LINE>/Status/CurMachSpeed` | Decimal | Current Machine Speed |
103+
| `<SITE>/<AREA>/<LINE>/Status/MachSpeed` | Decimal | Current Machine Speed Setpoint |
104+
| `<SITE>/<AREA>/<LINE>/Status/Parameter/*n*/ID` | Integer | Parameter *n* ID |
105+
| `<SITE>/<AREA>/<LINE>/Status/Parameter/*n*/Name` | String | Parameter *n* Name |
106+
| `<SITE>/<AREA>/<LINE>/Status/Parameter/*n*/Unit` | String | Parameter *n* Unit |
107+
| `<SITE>/<AREA>/<LINE>/Status/Parameter/*n*/Value` | Decimal | Parameter *n* Value |
108+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/ID` | Integer | Product *n* ID |
109+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/ProcessParameter/*j*/ID` | Integer | Product *i* Process Parameter *j* ID |
110+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/ProcessParameter/*j*/Name` | Integer | Product *i* Process Parameter *j* Name |
111+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/ProcessParameter/*j*/Unit` | Integer | Product *i* Process Parameter *j* Unit |
112+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/ProcessParameter/*j*/Value` | Integer | Product *i* Process Parameter *j* Value |
113+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/Ingredient/*j*/ID` | Integer | Product *i* Ingredient *n* ID |
114+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/Ingredient/*j*/Parameter/*k*/ID` | Integer | Product *i* Ingredient *j* Paramter *k* ID |
115+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/Ingredient/*j*/Parameter/*k*/Name` | Integer | Product *i* Ingredient *j* Paramter *k* Name |
116+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/Ingredient/*j*/Parameter/*k*/Unit` | Integer | Product *i* Ingredient *j* Paramter *k* Unit |
117+
| `<SITE>/<AREA>/<LINE>/Status/Product/*i*/Ingredient/*j*/Parameter/*k*/Value` | Integer | Product *i* Ingredient *j* Paramter *k* Value |
118+
119+
### Admin
120+
121+
Available Admin Status
122+
123+
| Topic | Values | Function |
124+
|--------------------------------------------------------------|---------|-----------------------------------------------------------|
125+
| `<SITE>/<AREA>/<LINE>/Admin/MachDesignSpeed` | String | Current PackML State |
126+
| `<SITE>/<AREA>/<LINE>/Admin/ProdConsumedCount/*i*/ID` | String | Consumed Counter ID |
127+
| `<SITE>/<AREA>/<LINE>/Admin/ProdConsumedCount/*i*/Name` | String | Consumed Counter Name |
128+
| `<SITE>/<AREA>/<LINE>/Admin/ProdConsumedCount/*i*/Unit` | String | Consumed Counter Units |
129+
| `<SITE>/<AREA>/<LINE>/Admin/ProdConsumedCount/*i*/Count` | String | Consumed Counter Count since reset |
130+
| `<SITE>/<AREA>/<LINE>/Admin/ProdConsumedCount/*i*/AccCount` | String | Consumed Counter Total Count |
131+
| `<SITE>/<AREA>/<LINE>/Admin/ProdProcessedCount/*i*/ID` | String | Processed Counter ID |
132+
| `<SITE>/<AREA>/<LINE>/Admin/ProdProcessedCount/*i*/Name` | String | Processed Counter Name |
133+
| `<SITE>/<AREA>/<LINE>/Admin/ProdProcessedCount/*i*/Unit` | String | Processed Counter Units |
134+
| `<SITE>/<AREA>/<LINE>/Admin/ProdProcessedCount/*i*/Count` | String | Processed Counter Count since reset |
135+
| `<SITE>/<AREA>/<LINE>/Admin/ProdProcessedCount/*i*/AccCount` | String | Processed Counter Total Count |
136+
| `<SITE>/<AREA>/<LINE>/Admin/ProdDefectiveCount/*i*/ID` | String | Defective Counter ID |
137+
| `<SITE>/<AREA>/<LINE>/Admin/ProdDefectiveCount/*i*/Name` | String | Defective Counter Name |
138+
| `<SITE>/<AREA>/<LINE>/Admin/ProdDefectiveCount/*i*/Unit` | String | Defective Counter Units |
139+
| `<SITE>/<AREA>/<LINE>/Admin/ProdDefectiveCount/*i*/Count` | String | Defective Counter Count since reset |
140+
| `<SITE>/<AREA>/<LINE>/Admin/ProdDefectiveCount/*i*/AccCount` | String | Defective Counter Total Count |
141+
142+
## Environmental Variables
143+
144+
The application is configured using the following environmental variables:
145+
146+
### SITE
147+
148+
The ISA-95 Model site name of this line. SITE used as the parent topic in the MQTT structure. If this is unset, _Site_ will be used.
149+
150+
### AREA
151+
152+
The ISA-95 Model area name of this line. AREA used as the second topic in the MQTT structure. If this is unset, _Area_ will be used.
153+
154+
### LINE
155+
156+
The ISA-95 model line name of this line. LINE used as the third topic in the MQTT structure. If this is unset, _Line_ will be used.
157+
158+
### MQTT_URL
159+
160+
The address of the MQTT server. If this is unset, _mqtt://broker.hivemq.com_ will be used.
161+
162+
### MQTT_USERNAME
163+
164+
The name of the MQTT user with subscribe and publish permissions.
165+
166+
### MQTT_PASSWORD
167+
168+
The password for the MQTT user with subscribe and publish permissions.
169+
170+
## Enterprise Simulation
171+
172+
Use docker-compose to simulate multiple independent lines at once. E.g.
173+
174+
```yml
175+
version: "3.7"
176+
177+
services:
178+
greenville-packaging-line1:
179+
image: spruiktec/packml-simulator
180+
environment:
181+
SITE: Greenville
182+
AREA: Packaging
183+
LINE: 'Line 1'
184+
greenville-packaging-line1:
185+
image: spruiktec/packml-simulator
186+
environment:
187+
SITE: Greenville
188+
AREA: Packaging
189+
LINE: 'Line 2'
190+
...
191+
```
192+
193+
## Contributing
194+
195+
For any issue, there are fundamentally three ways an individual can contribute:
196+
197+
- By opening the issue for discussion: For instance, if you believe that you have uncovered a bug in, creating a new issue in the ![GitHub issue tracker](./issues) is the way to report it.
198+
- By helping to triage the issue: This can be done either by providing supporting details (a test case that demonstrates a bug), or providing suggestions on how to address the issue.
199+
- By helping to resolve the issue: Typically, this is done either in the form of demonstrating that the issue reported is not a problem after all, or more often, by opening a Pull Request that changes some bit of something in the simulator in a concrete and reviewable manner.
200+
201+
## Changelog
202+
203+
- 1.0.0. Initial Release

docs/PackML-StateModel.png

47.4 KB
Loading

0 commit comments

Comments
 (0)