Explore the apps

In this section, you will explore the implementation of the apps. The first part will briefly explain the overall project structure, and the second and third section will focus on the fishes used by the apps as well as the apps themselves.

Need help?

If you run into problems or want to give feedback you are welcome to join our Discord chat, raise an issue in the GitHub repo or write us an e-mail to [email protected].

Project structure

The project consists of a few configuration files, as well as 3 apps in the src folder: dashboard, erp-simulator, wago-connector. The fish folder contains all relevant fishes used in the apps.

DemoMachineKit/
├── src/
│   ├── dashboard
│   ├── erp-simulator
│   ├── wago-connector
│   └── fish/
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .prettierrc.js
├── package.json
├── package-lock.json
├── README.md
└── tsconfig.json

Business logic

Before diving into the code, have a look at the below illustration. It shows the events and states that will be modelled in the fishes and apps.

You will find the implementation of the event and state types, as well as the actual state machine, in the fishes. Event emission is triggered in the apps.

Fishes

As discussed in more detail in the Actyx Pond documentation, a fish is the main programming unit in the Actyx Pond framework. It always represents one entity of your business logic and should always have only a single responsibility – which means in this case, you need fishes to keep track of your machines, as well as your orders.

DemoMachineKit/src/fish/
├── index.ts
├── machineFish.ts
└── orderFish.ts

The machineFish.ts and orderFish.ts code is structured into the same sections:

1. Definition of state types

2. Definition of event types

3. Definition of tag types

4. Definition of fishes

For this use case, two kinds of fishes are defined for machines as well as orders. Each of the fishes serves a different purpose:

  • implement state and logic of a single entity: A fish responsible for a single machine or order
  • track and access many instances of an entity: A fish responsible for tracking all machines or all orders

In the following sections, we will take a closer look on how the fishes that track a single machine or order work.

Machine fish

Open machineFish.ts. The following illustration should make it easier to understand machineFish.ts. It represents the state- and event types of the machine fish responsible for the state of a single machine:

Order fish

Open orderFish.ts. The following illustration should make it easier to understand orderFish.ts. It represents the state- and event types of the order fish responsible for the state of a single order:

As you can see in orderfish.ts , DefinedState can be – depending on the event – either idle, active, or done.

Apps

Now that you have seen the business logic shared by all apps in the fishes, this section gives a short overview of the three apps. Depending on whether the app will be packaged for the Webview Runtime (Dashboard and ERP-Simulator) or for the Docker Runtime (Wago-connector), the content of the app folder is slightly different. Each app directory is at least composed of:

  • ax-manifest.yml describing the ActyxOS app
  • settings-schema.json describing the settings schema of the app

In addition to the above, you will find files describing the logic itself.

If you want to know more about the ActyxOS-specific parts, please visit our guide on building apps.

ERP Simulator App

The ERP Simulator is a React app. Open App.tsx to inspect the business logic.

The order in this example is created through the UI and only contains information about the duration, machine, and name. In reality, this event would be generated by your ERP system (e.g. through an API) and have much more associated information – the underlying logic would be similar though.

Dashboard App

Just as the ERP Simulator, the Dashboard is a React app. Open Orders.tsx and have a look at the logic of the ERP simulator app.

Machine App

info

The PLC used for this example is a Wago PLC.

While this app is integrating with the above Wago PLC, the underlying logic is model-independent and would be similar for any other machine integration.