This example demonstrates how a state machine can be generated as typescript artifact and how to integrate this into an angular 4 application.
This example needs the YAKINDU Labs Typescript generator. You can install it by adding the following update site to your YAKINDU Statechart Tools: https://updates.yakindu.com/statecharts/labs/ With the update site you can install the typescript generator.
In this example, we have a simple HMI that represents an infotainment system for cars. For a more general description on how to develop human machine interfaces with state machines, see also our blog post.
This application consists of two screens:
The infotainment component represents a container for further components like infotainment menu, weather, music player and phone.
You need to set up your development environment before you can run the angular application.
Install Node.js and npm if they are not already on your machine.
Verify that you are running at least node 6.9.x and npm 3.x.x by running node -v and npm -v in a terminal/console window.
Then install the Angular CLI globally with
npm install -g @angular/cli.
Open the ycar_app root folder in a terminal/console window and run
npm install. By this command all project dependencies are installed.
In the terminal/console window run
npm start .
With this command the application is bundled by webpack and a dev server is started. If the bundling process was successful you will see this messages in your terminal/console window:
Open the url http://localhost:4200 in a web browser.
You should see the main screen of the YCar App as follows:
If you click the turn on button on the welcome screen, the welcome screen will disappear and the main screen will be displayed.
This behavior was modeled as follows (ycar_app/control/screenService.sct):
In the definition section two in events and two operation callbacks were defined. When the YCar application starts, the application enters the off-state and call the navigateToWelcomeScreen callback function. Thereby the welcome screen is shown.
If the turn_on button is clicked, the in-event onTurnOn will be raised and a state transition to state on occurs. By entering the on state, the operation callback navigateToMainScreen is called and the main screen appears.
On the right side you see the menu with three items. If you click on an item, the correspond feature will be displayed.
The behavior was modeled as follows (ycar_app/control/menuService.sct)
In the definition section we defined a menuState variable of type string. The menuState is used to decide which state is to be entered.
Then we have defined an in-event onMenuChanged to respond to user interactions.
Finally, we have defined four operation callbacks which display the correspond feature.
Our goal is that the statechart is generated into the YCar project.
For configuring the code generation process, YAKINDU Statechart Tools uses a textual generator model called SGen. It can be created either by using the provided wizard YAKINDU Statechart Generator Model or by creating a new text file with the extension .sgen.
The Outlet feature specifies target project and target folder for the generated artifacts. It is a required feature and has the following parameters:
With the Outlet feature we specify that our target project is ycar_app. Our generated artifact should be generated into src/app/gen/statemachine.The generated state machines have some dependencies which are generated into the library target folder src/app/gen/stateutils.
With the GeneratorFeatures we specify that our statechart should be generated as angular service (useAngular = true) with an event driven (useEventQueue = true) behavior.
In context of angular, the generated ScreenService state machine was generated as Service. We need to add this service as provider into the ycar_app/src/app/app.module.ts:
The service instance is injected into the AppComponent (ycar_app/src/app/ app.component.ts) by constructor injection (line 17).
We need to write some glue code for setting the in-events and operation callbacks. We do that in the component lifecycle hook ngAfterViewInit (line 30 - 46).
In line 31 - 32 the screenService subscribes to the Observables tunOff$ and turnOn$.
In line 34 - 41 we define an object from type IOperationCallback. The members of this Object are callback functions which are called from the screenService.
In line 43 the operationCallback object is passed as argument to setdefaultScopeOperationCallback function.
In line 44 - 45 we initialize and enter the screenService state machine.
The menuService need to be added as provider to src/app/y-main-screen/y_main_screen.module.ts .
The instance of menuService is also injected like the screenService (line 24).
We need to customize YMainScreenComponent (src/app/y-main-screen/y_main_screen.component.ts )
From line 34 to 47 we define the operation callback object from type IOperationCallback. The members of this object are callback functions which are called from the menuService.
In line 48 the operationCallback object is passes as argument to setdefautScopeOperationCallback function.
The mainScreenService.menuChanged observable is subscribed. Depending on the menuState value, the menuState from the menuService is set.