|
| 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 | + |
| 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  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 |
0 commit comments