Skip to content
Patrick Pogscheba edited this page Mar 1, 2024 · 3 revisions

Tutorial-App: HelloCubes

A simple tutorial app named HelloCubes is available with some examples of event handling:

Unity-App

This app handles the orientation Event from CubeControl events sent by the backend. Additionally it receives MQTT-messages on puzzlecubes/app/helloCubes and responds to it on an own topic puzzlecubes/<CUBE_ID>/app/helloCubes.

Move the cube (or press the right keys) to deactivate the spashscreen.

HelloCubesEventDispatcher: This script is derived from the base EventDispatcher class and subscribes to the mqtt event sent by the gamemaster app which is internally dispatched to a HelloCubes-Unity-Event. A convenience function DispatchHelloCubes is added to be used by components to send out the individual HelloCubes-Message to MQTT.

HelloCubesAppState: Inherits from AppState and adds orientation field.

HelloCubesAppController: This script inherits from base AppController handles the HelloCubes-Message (this method is connected through the editor to the EventDispatcher) by responding with its own Message calling DispatchHelloCubes.

It also listens to CubeControl-Events with its HandleCubeControl-method (also comnnected to EventDispatcher in Unity Editor). The orientation from CubeControl is extracted and sent to an orientationEvent. This can be used by other scripts (e.g. WorldOrientationHandler). When the isMoving-flag is set in CubeControl the spashscreen is removed.

When the orientation differs more than 10 degrees from orientation stored in appState the state is set dirty so it gets sent out by MQTT. The appState is initialized in the initialize-function.

HelloCubesKeyboardController: The keyboard control script inherits from base KeyboardController and just introduces sending HelloCubes messages by Space-Bar.

Gamemaster Web Frontend

Author:Anna Holthausen, date 02/2024

The Gamemaster frontend is based on the React base package and just has a button to sent out HelloCube-Messages by MQTT and listens to responses from each cube which are displayed in a textbox.

This tutorial app introduces all necessary funcionality to build a Cube App with client-server mechanics. Events from sensor backend can be handled and communication over MQTT is described. Extending to intercube-communication is straight forward using the MQTT interface.

AppState store: The store maintains an array of AppState objects, where each object represents the state of a cube within the application.

The AppState type defines the structure of each cube's state, including properties such as $type, locked, appName, cubeId, isRunning, volume, and mqttConnected.

The UseStore type defines the methods available for interacting with the store. These methods include addAppState, updateAppState, findAppState, and existsAppState, allowing adding, updating, finding, and checking for the existence of cube states, respectively.

The useStore function creates the Zustand store using the create function. It initializes the store with an empty array of appState and defines the methods for manipulating this state. The store is then exported as both a named export and the default export.

Overall, this Zustand store provides a convenient way to manage and manipulate cube states within the application.

HelloCubeMessage Store: The store maintains an array of HelloCubeMessage objects, each representing a message with properties for the message content and timestamp.

The HelloCubeMessage type defines the structure of each message, including properties such as message and timestamp.

The HelloCubeStore type defines the methods available for interacting with the store. In this case, it only includes the addHelloCube method, allowing the addition of new hello cube messages to the store.

The useHelloCubeStore function creates the Zustand store using the create function. It initializes the store with an empty array for helloCubes and defines the addHelloCube method for adding new messages to the store.

Overall, this Zustand store provides a simple yet effective way to manage and manipulate hello cube messages within an application.

Connector Component: For easy access to the cube state, we provide a component called Connector.

The Connector component is the entry point for the puzzlecube-core library. It connects to the MQTT broker and handles the communication for the cube state. It also provides default functions to send and receive messages. The Connector connects to the default broker at 192.168.111.1 on the production server in the puzzlecube network. It can be configured to connect to a different broker by passing the brokerUrl as a prop.

Example:

<Connector brokerUrl='localhost:9001' />

Header Component: The Header Component imports the useMqttStore hook from the package@mirevi/puzzlecube-core, which provides access to the MQTT store holding client and connection status information.

Inside the Header component, it utilizes the useMqttStore hook to retrieve the connectionStatus. This status is displayed within the header component, represented by a black-bordered box.

The header also contains the project's logo "CUBES PROJECT" and possibly additional functionalities represented by icons like mute and settings, although these are not implemented in the provided code.

TestButtons Component: This code defines a React component named TestButton. It imports MqttCommunication from a local file named MqttCommunication.js and a custom hook useHelloCubeStore from '../stores/useHelloCubeStore'.

The component renders a button labeled "HELLO CUBES" and a message display area. When the button is clicked, it triggers the handleStart function, which uses the MqttCommunication instance to send a message.

The component also retrieves data from the helloCubes state using the useHelloCubeStore hook and displays it in the message display area. If there are no messages, it displays "No messages yet."

MqttCommunication hook: The code defines a custom hook named MqttCommunication which facilitates communication with the MQTT broker. It imports various hooks, including useMqttStore from '@mirevi/puzzlecube-core', useStore, and useHelloCubeStore from local files.

The hook provides two main functions:

  1. subscribeAndListenToAppState: This function subscribes to specific topics on the MQTT broker and listens for incoming messages. It handles messages related to the application state and helloCubes topic. When receiving a helloCubes message, it adds the message to the helloCube store. When receiving an app state message, it either adds a new app state or updates an existing one in the store.
  2. sendHelloCubes: This function sends a helloCubes message to the MQTT broker. It constructs a payload containing a message and a timestamp, then publishes this payload to the 'puzzleCubes/app/helloCubes' topic.

The hook returns these two functions, allowing other components to utilize MQTT communication functionalities.

CubeMode Component: This component imports several hooks, including useCubeStateStore, usePerformanceBotStore, and useMqttStore from different locations.

Within the component, it renders a list of cubes, each represented by a block element with a fixed width and height. The appearance of each block depends on the cube's state, which is retrieved from the cubeState array obtained through the useCubeStateStore hook. The component also uses the findAppState function from the usePerformanceBotStore hook to determine if each cube is active or inactive.

If a cube is active (isRunning is true), it displays "ACTIVE" inside the block along with the cube's ID. If inactive, it displays "INACTIVE" along with the cube's ID.

Overall, the CubeMode component provides a visual representation of the state of each cube based on the data obtained from the provided hooks.

CubeWindow Component: This component manages the state of a cube window, allowing it to open and close. It imports the useState hook from React and the CubeMode component.

The component maintains a boolean state variable open using the useState hook, initially set to false. The window's appearance changes based on this state: when open, it displays a black background, and when closed, it becomes transparent.

There's a button within the window that toggles the open state when clicked. Depending on whether the window is open or closed, it displays different SVG icons: an arrow pointing left when closed, and an arrow pointing right when open.

If the window is open (open === true), the CubeMode component is rendered inside the window, displaying cube-related content.

Overall, CubeWindow manages the visibility and content of a cube window within a React application.

Neighbourhood handling: In App.tsx the connectionPairSubject is used to handle incoming connection pairs and posting them in the message Box via the store method addHelloCube.


Look into the main documentation (https://github.com/dasdigitalefoyer/cubes-documentation) for more information about app development and deployment on the cubes.

Clone this wiki locally