MagicMirror integration into Home Assistant with MQTT

I’m building a MagicMirror2 for my bathroom.
Up until now I’ve had to have some REST commands defined in the configuration to have it turn the monitor on and off from within HA, but now @bugsounet and
@sergge1 has released a MQTT module for it, and after a lot of errors and misunderstandings on my side, it’s working perfectly.

So now I can send MQTT commands from HA to turn the screen on and off, and also receive MQTT status messages from the screen, so I can configure a switch in HA with the state from that.

I use two MagicMirror2 modules, MMM-Remote-Control and MMM-MQTTbridge.

First off, the config.js from magicmirror:
config.js

    {
      module: 'MMM-Remote-Control',
      config: {
      }
    },
    {
      module: 'MMM-MQTTbridge',
      disabled: false,
      config: {
        mqttServer: "mqtt://mqttuser:[email protected]:1883",
        mqttConfig:
        {
          listenMqtt: true,
          useMqttBridgeFromatOnly: false,
          interval: 300000,
          topicSubscr: ["cmnd/bathroom/mirror"],
        },
        notiConfig:
        {
          listenNoti: true,
          useMqttBridgeFromatOnly: false,
          ignoreNotiSender: ["system","clock","newsfeed","currentweather","calendar"],
        },
        // set "NOTIFICATIONS -> MQTT" dictionary at /dict/notiDictionary.js
        // set "MQTT -> NOTIFICATIONS" dictionary at /dict/mqttDictionary.js
      }
    }

(yes, the typos are on purpose, it will be fixed in a later version of the module).

Then there are the ‘dictionaries’ from the module.
First, the MQTT translation to Notifications:

mqttDictionary.js

var mqttHook = [
    {
      mqttPayload: "MONITOROFF",
      mqttNotiCmd: ["MONITOROFF"]
    },
    {
      mqttPayload: "MONITORON",
      mqttNotiCmd: ["MONITORON"]
    },
    {
      mqttPayload: "UNDIM",
      mqttNotiCmd: ["UNDIM"]
    },
    {
      mqttPayload: "DIM",
      mqttNotiCmd: ["DIM"]
    },
 ];
var mqttNotiCommands = [
    {
      commandId: "MONITOROFF",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "MONITOROFF"}
    },
    {
      commandId: "MONITORON",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "MONITORON"}
    },
    {
      commandId: "UNDIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "BRIGHTNESS", value: "100"}
    },
    {
      commandId: "DIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "BRIGHTNESS", value: "50"}
    }
  ];

  module.exports = { mqttHook,  mqttNotiCommands};

Then the other way around, from MagicMirror notifications to MQTT:

notiDictionary.js

var notiHook = [
  {
    notiId: "USER_PRESENCE",
    notiPayload: [
      {
        payloadValue: true,
        notiMqttCmd: ["SCREENON"]
      },
      {
        payloadValue: false,
        notiMqttCmd: ["SCREENOFF"]
      },
    ],
  },
];
var notiMqttCommands = [
  {
    commandId: "SCREENOFF",
    mqttTopic: "home/bathroom/mirror/screen",
    mqttMsgPayload: 'OFF'
  },
  {
    commandId: "SCREENON",
    mqttTopic: "home/bathroom/mirror/screen",
    mqttMsgPayload: 'ON'
  },
];

module.exports = { notiHook, notiMqttCommands };

Then in Home Assistant, I set up a binary sensor:

  - platform: mqtt
    name: "MagicMirror Bathroom"
    state_topic: 'home/bathroom/mirror/screen'
    device_class: window

And a switch:

  - platform: template
    switches:
      magicmirror_bathroom:
        friendly_name: "Magicmirror Badeværelse"
        value_template: "{{ is_state('binary_sensor.magicmirror_bathroom', 'on') }}"
        turn_on:
          service: mqtt.publish
          data:
            topic: "cmnd/bathroom/mirror"
            payload: "MONITORON"
        turn_off:
          service: mqtt.publish
          data:
            topic: "cmnd/bathroom/mirror"
            payload: "MONITOROFF"
        entity_picture_template: >-
          {% if is_state('binary_sensor.magicmirror_bathroom', 'on') %}
            /local/images/mirror_on.png
          {% else %}
            /local/images/mirror_off.png
          {% endif %}

The images I’ve created:
mirror mirror_on

Then I’ve placed the switch in a lovelacecard:

      - entities:
          - entity: switch.magicmirror_bathroom
            name: Mirror
        type: entities

So I can turn it on and off manually.

I also have some presence detection that turns on light, and I’ve chosen that the mirror is to follow the light on the toilet, so the automations I have created looks like this:

- id: '1583539250849'
  alias: Bath - Turn on MagicMirror when toilet light is on - daytime
  description: ''
  trigger:
  - entity_id: light.toilet
    from: 'off'
    platform: state
    to: 'on'
  condition:
  - after: '8:00'
    before: '22:59'
    condition: time
  action:
  - entity_id: switch.magicmirror_bathroom
    service: switch.turn_on
  - data:
      payload: UNDIM
      topic: cmnd/bathroom/mirror
    service: mqtt.publish
- id: '1583539089923'
  alias: Bath - Turn on magic mirror when light on bathroom turns on at night
  description: ''
  trigger:
  - entity_id: light.toilet
    from: 'off'
    platform: state
    to: 'on'
  condition:
  - after: '23:00'
    before: 07:59
    condition: time
  action:
  - entity_id: switch.magicmirror_bathroom
    service: switch.turn_on
  - data:
      payload: DIM
      topic: cmnd/bathroom/mirror
    service: mqtt.publish
- id: '1583515369036'
  alias: Bath - Turn off Magic Mirror when toilet light on bathroom turns off
  description: ''
  trigger:
  - entity_id: light.toilet
    from: 'on'
    platform: state
    to: 'off'
  condition: []
  action:
  - entity_id: switch.magicmirror_bathroom
    service: switch.turn_off

This works perfectly, and the switch is updated very fast (no lag)

1 Like

Great stuff and helped a lot because I got confused about the different use of ", ’ and without any quotes. Thanks!

But I have a question:
Did also you get sometimes the message

[MQTT bridge] MQTT -> NOTI issued: REMOTE_ACTION, payload: [object Object]

in the logs?

1 Like

Yes, and that is apparently the correct log message according to the developers, it just reports that it has an object.

1 Like

Hi, I am trying to get it to work,but something is wrong. Can you see if you can spot it?

Posting everything…

Mosquitto broker @ HASS addon config.

logins:
  - username: admin
    password: password
anonymous: false
customize:
  active: false
  folder: mosquitto
certfile: fullchain.pem
keyfile: privkey.pem
require_certificate: false

configuration.yaml @ HASS

mqtt:
  broker: 127.0.0.1
  port: 1883
  username: admin
  password: password
  keepalive: 15
binary_sensor:

  - platform: mqtt
    name: "MagicMirror korridor"
    state_topic: 'home/hallway/mirror/screen'
    device_class: window
switch:

  - platform: template
    switches:
      magicmirror_bathroom:
        friendly_name: "Magic Mirror Korridor"
        value_template: "{{ is_state('binary_sensor.magicmirror_hallway', 'on') }}"
        turn_on:
          service: mqtt.publish
          data:
            topic: "cmnd/hallway/mirror"
            payload: "MONITORON"
        turn_off:
          service: mqtt.publish
          data:
            topic: "cmnd/hallway/mirror"
            payload: "MONITOROFF"

config.js @ MagicMirror

		{
      		module: 'MMM-Remote-Control',
      		config: {
      		}
    		},
    		{
      		module: 'MMM-MQTTbridge',
      		disabled: false,
      		config: {
        		mqttServer: "mqtt://admin:[email protected]:1883", //IP to HASS
        		mqttConfig:
        		{
          		  listenMqtt: true,
          		  useMqttBridgeFromatOnly: false,
          		  interval: 300000,
          		  topicSubscr: ["cmnd/hallway/mirror"],
        		},
        		notiConfig:
        		{
          		  listenNoti: true,
          		  useMqttBridgeFromatOnly: false,
          		  ignoreNotiSender: ["system","clock","newsfeed","currentweather","calendar"],
        		},
        		// set "NOTIFICATIONS -> MQTT" dictionary at /dict/notiDictionary.js
        		// set "MQTT -> NOTIFICATIONS" dictionary at /dict/mqttDictionary.js
      			}
    		},

notiDictionary.js @MagicMirror

var notiHook = [
  {
    notiId: "USER_PRESENCE",
    notiPayload: [
      {
        payloadValue: true,
        notiMqttCmd: ["SCREENON"]
      },
      {
        payloadValue: false,
        notiMqttCmd: ["SCREENOFF"]
      },
    ],
  },
];
var notiMqttCommands = [
  {
    commandId: "SCREENOFF",
    mqttTopic: "home/hallway/mirror/screen",
    mqttMsgPayload: 'OFF'
  },
  {
    commandId: "SCREENON",
    mqttTopic: "home/hallway/mirror/screen",
    mqttMsgPayload: 'ON'
  },
];

module.exports = { notiHook, notiMqttCommands };

mqttDictionary.js @ MagicMirror

var mqttHook = [
    {
      mqttPayload: "MONITOROFF",
      mqttNotiCmd: ["MONITOROFF"]
    },
    {
      mqttPayload: "MONITORON",
      mqttNotiCmd: ["MONITORON"]
    },
    {
      mqttPayload: "UNDIM",
      mqttNotiCmd: ["UNDIM"]
    },
    {
      mqttPayload: "DIM",
      mqttNotiCmd: ["DIM"]
    },
 ];
var mqttNotiCommands = [
    {
      commandId: "MONITOROFF",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "MONITOROFF"}
    },
    {
      commandId: "MONITORON",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "MONITORON"}
    },
    {
      commandId: "UNDIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "BRIGHTNESS", value: "100"}
    },
    {
      commandId: "DIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "BRIGHTNESS", value: "50"}
    }
  ];

  module.exports = { mqttHook,  mqttNotiCommands};

Hi there

I’m not sure which part is not working, so first off, get the MQTTBox installed.
Then get that connected to your mqtt, and subscribe to cmnd/hallway/# to see if you can get messages through on the mqtt.
If not then it’s the mqtt setup, if there is, then it’s something in MM.
You can also send MQTT commands throgh the MQTT Box directly to see if the mirror reacts to it.

Did you handle the mirror integration? It doesn’t work for me either: /

Mine works, I’ll try and grab the parts from my config.

MagicMirror/config/config.js

    {
      module: 'MMM-MQTTbridge',
      disabled: false,
      config: {
        mqttServer: "mqtt://mqtt_user:[email protected]:1883",
        mqttConfig:
        {
          listenMqtt: true,
          useMqttBridgeFromatOnly: false,
          interval: 300000,
          topicSubscr: ["cmnd/bathroom/mirror"],
        },
        notiConfig:
        {
          listenNoti: true,
          useMqttBridgeFromatOnly: false,
          ignoreNotiSender: ["clock","newsfeed","currentweather","calendar"],
        }
        // set "NOTIFICATIONS -> MQTT" dictionary at /dict/notiDictionary.js
        // set "MQTT -> NOTIFICATIONS" dictionary at /dict/mqttDictionary.js
      }
    }

/MagicMirror/modules/MMM-MQTTbridge/dict/mqttDictionary.js

/**  mqtt-to-notification                     **/
/**  dictionaty                               **/
/**  for MMM-MQTTbridge module                **/
/**  modify comands                           **/
/**         @sergge1                          **/

var mqttHook = [
    {
      mqttPayload: "MONITOROFF",
      mqttNotiCmd: ["MONITOROFF"]
    },
    {
      mqttPayload: "MONITORON",
      mqttNotiCmd: ["MONITORON"]
    },
    {
      mqttPayload: "UNDIM",
      mqttNotiCmd: ["UNDIM"]
    },
    {
      mqttPayload: "DIM",
      mqttNotiCmd: ["DIM"]
    },
 ];
var mqttNotiCommands = [
    {
      commandId: "MONITOROFF",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "MONITOROFF"}
    },
    {
      commandId: "MONITORON",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "MONITORON"}
    },
    {
      commandId: "UNDIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "BRIGHTNESS", value: "100"}
    },
    {
      commandId: "DIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: "BRIGHTNESS", value: "50"}
    }
  ];

  module.exports = { mqttHook,  mqttNotiCommands};

/MagicMirror/modules/MMM-MQTTbridge/dict/notiDictionary.js

/**  mqtt-to-notification                     **/
/**  dictionaty                               **/
/**  for MMM-MQTTbridge module                **/
/**  modify comands                           **/
/**         @sergge1                          **/


var notiHook = [
  {
    notiId: "USER_PRESENCE",
    notiPayload: [
      {
        payloadValue: true,
        notiMqttCmd: ["SCREENON"]
      },
      {
        payloadValue: false,
        notiMqttCmd: ["SCREENOFF"]
      },
    ],
  },
];
var notiMqttCommands = [
  {
    commandId: "SCREENOFF",
    mqttTopic: "home/bathroom/mirror/screen",
    mqttMsgPayload: 'OFF'
  },
  {
    commandId: "SCREENON",
    mqttTopic: "home/bathroom/mirror/screen",
    mqttMsgPayload: 'ON'
  },
];

module.exports = { notiHook, notiMqttCommands };

I hope this helps!

i have issued an update today evening, some functionality has been added.

Key change - ability to use variable for mqttPayload or notiPayload. E.g. if you receiving and message on mqtt topics with specific payload, you can transmit this payload to noti. and, of course, vise versa.

Also, for conveniance, you do not need to specify the topics in config, add them to mqttDictionary. So the module will subscribe to those that are in mqttDictionary and will listen each of them.

Ok, mine stopped working with the latest updates.
How do I go about updating it, to see if that fixes it?

hello, sorry had no time to review the reasons of yours non working issues.
In order to revert, use the previous release 1.0


I will look soon the updates. For that, send me or there your logs from MM please.

have you read the documentation? config cnaged slightly as well as mqttDict and notiDict files, so should be updated

I’ll try and have a look at it again, I was finishing my magicmirror project, and then I cracked the monitor :sob:
So now I have to get a new one.

Ahhh… Thats crapy.
Interested in mm2 integration as wel.
I want to build this as well.
Could you maybe post a screenshot of what it looks like in the mm?
Good luck with the replacement.

What do you want to see? A picture of the magicmirror project or the config in mm,or the config in HA?
I have some pictures of the old build-up, and then I changed the monitor because it was getting too hot, and then I broke the new monitor :frowning:


I’m going to pick up yet another of the same monitor today, and hopefully I will not break it, at least I’m going to be much more gentle with it.

Just a small update, the mirror finally arrived a while ago, and I got it set up on the bathroom.
This is the result:


I’ve had to modify the configurations a bit, as there have been quite a few updates to the system.

The mirror itself needs to accept remote commands from whitelisted ips, so this added to the top of the config:

var config = {
  address: '0.0.0.0',
  port: 8080,
  ipWhitelist: ['127.0.0.1','localhost','192.168.0.0/24'],

Then there is the MMM-Remote-Control module, which has a very simple config, it accepts commands via the notification system in MagicMirror, and I also show a webmenu to controll it on http://magicmirror:8080/remote.html:

    {
      module: 'MMM-Remote-Control',
      config: {
        showModuleApiMenu: true,
      }
    },

Then there is the MMM-MQTT-module, it connects to the MQTT server on HomeAssistant, and also makes it listen to MQTT, and notifications, and then it silences some modules that sends out a lot of uninteresting notifications:

    {
      module: 'MMM-MQTTbridge',
      disabled: false,
      config: {
        mqttServer: 'mqtt://username:[email protected]:1883',
        mqttConfig:
        {
          listenMqtt: true,
          interval: 2000,
        },
        notiConfig:
        {
          listenNoti: true,
          ignoreNotiId: ['CLOCK_MINUTE', 'NEWS_FEED'],
          ignoreNotiSender: ['clock','newsfeed','currentweather','calendar']
        }
      }
    }

The real work is in the dictionaries for the MMM-MQTTbridge (which are located under the modules folder in the noti folder)
mqttDictionary.js this translates from MQTT to notifications, I’ve created 4 commands, monitor on/off and dim/undim:

var mqttHook = [
    {
      mqttTopic: "cmnd/bathroom/mirror",
      mqttPayload: [
        {
          payloadValue: "MONITOROFF",
          mqttNotiCmd: ["MONITOROFF"]
        },
        {
          payloadValue: "MONITORON",
          mqttNotiCmd: ["MONITORON"]
        },
        {
          payloadValue: "UNDIM",
          mqttNotiCmd: ["UNDIM"]
        },
        {
          payloadValue: "DIM",
         mqttNotiCmd: ["DIM"]
        },
      ],
    },
  ];

var mqttNotiCommands = [
    {
      commandId: "MONITOROFF",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: 'MONITOROFF'}
    },
    {
      commandId: "MONITORON",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: 'MONITORON'}
    },
    {
      commandId: "DIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: 'BRIGHTNESS', value: '50'}
    },
    {
      commandId: "UNDIM",
      notiID: 'REMOTE_ACTION',
      notiPayload: {action: 'BRIGHTNESS', value: '255'}
    },
  ];

module.exports = { mqttHook,  mqttNotiCommands};

Then I need to report status back to HomeAssistant so I can make a statefull switch. The USER_PRESENCE indicates if the HDMI is turned on or off.

var notiHook = [
  {
    notiId: "USER_PRESENCE",
    notiPayload: [
      {
        payloadValue: '1',
        notiMqttCmd: ["SCREENON"]
      },
      {
        payloadValue: '0',
        notiMqttCmd: ["SCREENOFF"]
      }
    ]
  }
];
var notiMqttCommands = [
  {
    commandId: "SCREENOFF",
    mqttTopic: "state/bathroom/mirror/monitor",
    mqttMsgPayload: "OFF"
  },
  {
    commandId: "SCREENON",
    mqttTopic: "state/bathroom/mirror/monitor",
    mqttMsgPayload: "ON"
  }
];

module.exports = { notiHook, notiMqttCommands };

In HomeAssistant I then have a binary sensor:

- platform: mqtt
    name: "MagicMirror Bathroom"
    state_topic: 'state/bathroom/mirror/monitor'
    device_class: window

Which indicates if the HDMI is on or off, as I send the ON/OFF directly from MagicMirror, the binary sensor is very simple.
Final step is a switch in HomeAssistant, the switch has two images representing the mirror being on or off, these are placed in the HomeAssistant config folder under /config/www/images.:

- platform: template
    switches:
      magicmirror_bathroom:
        friendly_name: "Magicmirror"
        value_template: "{{ is_state('binary_sensor.magicmirror_bathroom', 'on') }}"
        turn_on:
          service: mqtt.publish
          data:
            topic: "cmnd/bathroom/mirror"
            payload: "MONITORON"
        turn_off:
          service: mqtt.publish
          data:
            topic: "cmnd/bathroom/mirror"
            payload: "MONITOROFF"
        entity_picture_template: >-
          {% if is_state('binary_sensor.magicmirror_bathroom', 'on') %}
            /local/images/mirror_on.png
          {% else %}
            /local/images/mirror_off.png
          {% endif %}
2 Likes