diff --git a/meshuser.js b/meshuser.js
index 49997e8e..03e6b787 100644
--- a/meshuser.js
+++ b/meshuser.js
@@ -2456,6 +2456,31 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 
                     // Send a response if needed
                     if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'inviteAgent', responseid: command.responseid, result: 'ok' })); } catch (ex) { } }
+                    break;
+                }
+            case 'setDeviceEvent':
+                {
+                    // Argument validation
+                    if (common.validateString(command.msg, 1, 4096) == false) break; // Check event
+                    if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid
+                    var splitid = command.nodeid.split('/');
+                    if ((splitid.length != 3) || (splitid[1] != domain.id)) return; // Invalid domain, operation only valid for current domain
+                    var idtype = splitid[0];
+                    if ((idtype != 'node')) return;
+
+                    // Check if this user has rights on this id to set notes
+                    db.Get(command.nodeid, function (err, nodes) {
+                        if ((nodes == null) || (nodes.length == 1)) {
+                            meshlinks = user.links[nodes[0].meshid];
+                            if ((meshlinks) && (meshlinks.rights) && (meshlinks.rights != 0)) {
+                                // Add an event for this device
+                                var targets = ['*', 'server-users', user._id, nodes[0].meshid];
+                                var event = { etype: 'node', userid: user._id, username: user.name, nodeid: nodes[0]._id, action: 'manual', msg: decodeURIComponent(command.msg), domain: domain.id };
+                                parent.parent.DispatchEvent(targets, obj, event);
+                            }
+                        }
+                    });
+
                     break;
                 }
             case 'setNotes':
diff --git a/mqttbroker.js b/mqttbroker.js
index bd626036..c9cc002d 100644
--- a/mqttbroker.js
+++ b/mqttbroker.js
@@ -126,8 +126,8 @@ module.exports.CreateMQTTBroker = function (parent, db, args) {
         if (clients == null) return;
         if (typeof message == 'string') { message = new Buffer(message); }
         for (var i in clients) {
-            // if (clients[i].subscriptions[topic] != null) { } // Add this if we only want to send subscribed topics.
-            clients[i].publish({ cmd: 'publish', qos: 0, topic: topic, payload: message, retain: false });
+            // Only publish to client that subscribe to the topic
+            if (clients[i].subscriptions[topic] != null) { clients[i].publish({ cmd: 'publish', qos: 0, topic: topic, payload: message, retain: false }); }
         }
     }
 
diff --git a/package.json b/package.json
index 9fb3e9d1..7876ea40 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "meshcentral",
-  "version": "0.4.2-r",
+  "version": "0.4.2-t",
   "keywords": [
     "Remote Management",
     "Intel AMT",
diff --git a/views/default-min.handlebars b/views/default-min.handlebars
index 92ded4a7..7e151545 100644
--- a/views/default-min.handlebars
+++ b/views/default-min.handlebars
@@ -10356,6 +10356,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this
                 // Show action button, only show if we have permissions 4, 8, 64
                 if ((meshrights & 76) != 0) { x += ''; }
                 x += '';
+                x += '';
                 //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '';  }
                 QH('p10html', x);
 
@@ -10479,6 +10480,13 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this
             go(panel);
         }
 
+        function writeDeviceEvent(nodeid) {
+            if (xxdialogMode) return;
+            setDialogMode(2, "Add Device Event", 3, writeDeviceEventEx, 'This will add an entry to this device\'s event log.', nodeid);
+        }
+
+        function writeDeviceEventEx(buttons, tag) { meshserver.send({ action: 'setDeviceEvent', nodeid: decodeURIComponent(tag), msg: encodeURIComponent(Q('d2devEvent').value) }); }
+
         function showNotes(readonly, noteid) {
             if (xxdialogMode) return;
             setDialogMode(2, "Notes", 2, showNotesEx, 'Device group notes can be viewed and changed by other device group administrators.', noteid);
diff --git a/views/default.handlebars b/views/default.handlebars
index a24219b0..34bb3736 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -4327,6 +4327,7 @@
                 // Show action button, only show if we have permissions 4, 8, 64
                 if ((meshrights & 76) != 0) { x += ''; }
                 x += '';
+                x += '';
                 //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '';  }
                 QH('p10html', x);
 
@@ -4450,6 +4451,13 @@
             go(panel);
         }
 
+        function writeDeviceEvent(nodeid) {
+            if (xxdialogMode) return;
+            setDialogMode(2, "Add Device Event", 3, writeDeviceEventEx, 'This will add an entry to this device\'s event log.', nodeid);
+        }
+
+        function writeDeviceEventEx(buttons, tag) { meshserver.send({ action: 'setDeviceEvent', nodeid: decodeURIComponent(tag), msg: encodeURIComponent(Q('d2devEvent').value) }); }
+
         function showNotes(readonly, noteid) {
             if (xxdialogMode) return;
             setDialogMode(2, "Notes", 2, showNotesEx, 'Device group notes can be viewed and changed by other device group administrators.', noteid);