Home

Awesome

MMM-Scenes2

“Life is a theatre set in which there are but few practicable entrances.”

― Victor Hugo, Les Misérables

MagicMirror module to change screen scenes by time and order with ANIMATION EFFECT.

Demo

MMM-Scenes2 Demo & Screenshot Click To Play

Click it to see the DEMO. Its configuration file is in /examples/config.js.example

Successor of MMM-Scenes

Since MM 2.25, a new feature, animateCSS is introduced into the MagicMirror.

With this update, my previous MMM-Scenes would be obsoleted. So I remade a new module for MM 2.25

Concept

The scenario of the MM screen is made up of a series of scenes. Each module has its role in its appearance scenes to enter and exit by design.

When a scene begins, all modules whose roles end will be expelled, and all modules with the parts in that scene will be admitted.

As described in the scenario, your MM screen will play a drama with modules.

Features

Install

cd ~/MagicMirror/modules
git clone https://github.com/MMRIZE/MMM-Scenes2
cd MMM-Scenes2
npm install

Configuration

Don't worry, it's not as difficult as it looks. You can find a real-world example in the examples directory.

The simplest example;

{
  module: "clock",
  position: "top_left",
  hiddenOnStart: true,
  classes: "role1 role_final" // <-- assign role(s) to the module to control.
},
// ... other modules ...

{
  module: "MMM-Scenes2",
  position: 'bottom_bar', // Position of indicator
  config: {
    scenario: [ // `scenario` is REQUIRED
      { // First scene definition
        exit: ["role1", "role2"],
        enter: ["role3", "role4"],
      },
      { // Second scene definition
        exit: ["role3"],
        enter: ["role_final"],
      },
    ]
  }
}

This scenario has 2 scenes. At the first scene, "role1" and "role2" module(s) will exit from the scene with default animation. Then "role3" and "role4" module(s) will enter into the scene. After some lifetime, the second scene will start. "role3" module(s) will be disappeared and "role_final" scene will be revealed. ("role4" will remain at the second scene.) And the whole scenario will repeat.

In other words, the clock module will exit from the first scene as "role1" and will enter into the second scene as "role_final".

Options

config: {
  scenario: [ ... ], // Array of scene objects. This is the only option MUST-REQUIRED. You should fulfil this option in your configuration.

  //Below are omittable. You don't have to describe all these options in your config.
  life: 1000 * 60, // default life of each scene
  activeIndicator: '■', // default indicator of current scene
  inactiveIndicator: '□', // default indicator of other scenes inactive
  // You can ignore the belows if you are not an expert.
  lockString: 'mmm-scenes2', // lockString for hide mechanism
  defaultEnter: { animation, duration, gap }, // convenient definition of default options for `enter`
  defaultExit: { animation, duration, gap }, // convenient definition of default options for `exit`
}
propertydefaultdescription
scenario[]REQUIRED The order-set of scenes. You SHOULD set the scene definition (object) as the items of this property.
life1000 * 60(ms) The life of each scene after all roles are appeared. After this time, the next scene would start. <br> If set as 0, the scene would be paused unless external control(notification, telegram, ...) happens.
activeIndicator'■'Default indicator of current active scene. You can reassign it in each scene object.
inactiveIndicator'□'Default indicator of other inactive scenes. This could also be reassigned in each scene object.
lockString'mmm-scenes2'Just leave it if you don't know what this is for.
defaultEnter{ animation, duration, gap }Convenient definition of default options for enter. I'll explain later.
defaultExit{ animation, duration, gap }Convenient definition of default options for exit. I'll explain later.

There is no defaultNext or defaultPrevious because next and previous should differ according to the scene.

scene Object in scenario

scenario would have some series of scene objects. Each object would have these structures.

scenario: [
  {
    enter: [ ... ],
    exit: [ ... ],
    name: 'first_scene',
    life: 1000 * 30,
    activeIndicator: '■',
    inactiveIndicator: '□',
    next: null, // Since 1.1.0
    previous: null, // Since 1.1.0
  },
  // next scenes.
]

enter/exit Objects in scene

scenario: [
  {
    enter: [ "role1", "role2", ... ],
    // OR
    enter: [
      {
        role: "role1",
        animation: "bounceIn",
        duration: 1500,
        gap: 100,
      },
      {
        role: "role2",
        animation: "rotateIn",
      }
    ],
    // OR
    enter: [ 
      "role1",
      {
        role: "role2",
        animation: "flipInY",
        duration: 3000,
      }
    ]
    // ... other fields
  }
  // ... more
],

Each enter and exit could have a list of roles. role could be the name which you assigned in classes of modules, or the object which has a definition of the role, or a mix of names and objects.

When you don't need to order different behaviours to the specific roles in the scene, the names are enough to direct which module will enter/exit.

For your convenience, You can define defaultEnter and defaultExit for the common setting of all roles unless each value is reassigned in the specific scene.

config: {
  defaultEnter: {
    animation: 'fadeIn',
    duration: 1000,
    gap: 0,
  },
  defaultExit: {
    animation: 'fadeOut',
    duration: 1000,
    gap: 0,
  },
  scenario: [ ... ],
  ...
}

previous/next in scene (since 1.1.0)

By default, the order of the scenes is linearly executed in the order listed in scenario:[...]. For example, The third scene is executed after the second scene, and so on.

However, there are cases where you may want to arbitrarily adjust the order of the scenes.

scenario: [ 
...
  { 
    name: "scene_003",
    exit: ["role1", "role2"],
    enter: ["role3", "role4"],
    next: "scene_005", // sceneName
    previous: 2, // Or sceneIndex
  },
...

This example means; the next scene of the this scene would be "scene_005". And when SCENE_PREV is called, the previous of this scene would be the 3rd scene of the scenranio. (2 means 3rd because index would be zero-based.)

next: false,
previous: false,

This example means; SCENE_PREV or SCENE_NEXT will not work once you enter this scene. (but you can escape with SCENE_PLAY by force)

next: ({ scene, scenario }) => {
  // A Parameter `scene` would have the info of current scene.
  // A parameter `scenario` would have the whole scenario information.
  // console.log(scene, scenario)
  return (Math.random() > 0.5) ? "scene_001" : "scene_002"
}

This example shows, the next scene would be randomly selected between "scene_001" and "scene_002". Of course, you can program it for your purpose. (For example; Normal scenario / Party scenario by time, ...)

More detailed examples are in the wiki.

External Controls

Some syntax was changed from MMM-Scenes. Check it carefully if you are a user of the previous module.

Incoming notifications

this.sendNotification('SCENE_NEXT', {
  callback: (result) => { console.log(result.status) }
})

// Callback result example
 {
  status: true,
  currentScene: { name, enter, exit, ... },
  index: 0,
  message: "Example..."
}

SCENES_NEXT, payload: { callback }

Play the next scene.

SCENES_PREV, payload: { callback, }

Play the previous scene.

SCENES_PAUSE, payload: { callback }

Pause at current scene until another command comming.

SCENES_RESUME, payload: { callback }

Resume the scene. The remaining life at pause would be applied with this command. You can also resume with other commands(e.g. SCENES_NEXT). In that case, the remaining life would be ignored, and the scene would play instantly.

SCENES_CURRENT, payload: { callback }

Get information on the current scene.

SCENES_PLAY, payload: { callback, scene }

Play a specific scene. scene could be a name or an index of a scene in the scenario. If omitted, the current scene would be applied.

Outgoing Notification

SCENES_CHANGED, payload: { info }

When scenes are changed, this notification will be emitted.

WebAPI Endpoint

You can access MM URL to control this module from outside of MM. e.g.) IFTTT.

http://magicmirror.domain/scenes/pause
http://magicmirror.domain/scenes/resume
http://magicmirror.domain/scenes/next
http://magicmirror.domain/scenes/prev
http://magicmirror.domain/scenes/0
http://magicmirror.domain/scenes/scene_2

MMM-TelegramBot Integration

You can control MMM-Scenes2 using the Telegram app by installing the MMM-TelegramBot module.

Indicators

You can assign indicators globally or scene-specifically.

config: {
  activeIndicator: '■',
  inactiveIndicator: '□',
  scenario: [ ... ],
  ...
}

If you have 4 scenes in the scenario, the indicator will be shown as □ ■ □ □(the second scene is active).

config: {
  ...
  scenario: [
    { // First scene
      activeIndicator: '❶',
      inactiveIndicator: '①',
      ...
    },
    ...
  ]
}

Like this, you can reassign indicators for specific scenes. In this case, you can see ❶ □ □ □ or ① ■ □ □.

You can decorate the indicators with CSS in your custom.css; The structure of HTML created will be like this

<div class="scenes_indicator">
  <span class="scenes_indicator_scene index_0 inactive first">□</span>
  <span class="scenes_indicator_scene index_1 active">■</span> <!-- current scene -->
  <span class="scenes_indicator_scene index_2 inactive last">□</span>
</div>

You can decorate its look like this;

/* custom.css */
.scenes_indicator_scene.inactive {
  color: gray;
}

.scenes_indicator_scene.active {
  color: red;
  font-weight: bold;
  font-size: 200%;
}

One more thing: You can change the scene by clicking/touching the indicator if your MM supports click/touch.

Tips & ETC

History

1.1.0 (2024-08-09)

1.0.0 (2023-10-05)

Author

ko-fi