In this section, I am going to attempt to show and describe the Javascript, CSS, and HTML used to interact with the MQTT server. I don't know if I will be successful. The entire control.html file is also added to the files section of this website.
The Paho MQTT client requires a couple Javascript libraries. Link directly to them or load them on your server. You'll need jquery and mqttws31. Google finds them pretty easily.
<script type='text/javascript' src='/source/jquery-1.8.3.js'></script>
<script type='text/javascript' src="/source/mqttws31.js"></script>
All the important stuff is set up and handled in the Javascript load function:
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
var client = new Paho.MQTT.Client("myserver.somewhere.com", Number(8080), "clientId" + Date.now().toString());
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
//Options object for connection
var connect_options = {
timeout: 3,
onSuccess: function () {
// Connection succeeded; subscribe to our topic
client.subscribe('feeds/Garage/Door/Status', {qos: 0});
client.subscribe('feeds/Garage/Sensor/Status', {qos: 0});
client.subscribe('feeds/Driveway/Gate/Status', {qos: 0});
client.subscribe('feeds/Driveway/Sensor/Status', {qos: 0});
},
onFailure: function (message) {
window.location.reload(false);
}
};
// connect the client
client.connect(connect_options);
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
window.location.reload(false);
}
}
// called when a message arrives
function onMessageArrived(message) {
if (message.destinationName == "feeds/Garage/Door/Status") {
if (message.payloadString == "Moving...") { // neither sensor set (opening?)
$("#gdstatus").html("Moving...");
$("#gdaction").html("Moving...");
} else if (message.payloadString == "Closed") { // open sensor set
$("#gdstatus").html("Closed");
$("#gdaction").html("Open Garage Door");
} else if (message.payloadString == "Open") { // close sensor set
$("#gdstatus").html("Open");
$("#gdaction").html("Close Garage Door");
} else {
$("#gdstatus").html(message.payloadString);
$("#gdaction").html("Unknown Status");
}
} else if (message.destinationName == "feeds/Driveway/Gate/Status") {
if (message.payloadString == "Moving...") { // neither sensor set (opening?)
$("#gatestatus").html("Moving...");
$("#gateaction").html("Moving...");
} else if (message.payloadString == "Closed") { // open sensor set
$("#gatestatus").html("Closed");
$("#gateaction").html("Open Gate");
} else if (message.payloadString == "Open") { // close sensor set
$("#gatestatus").html("Open");
$("#gateaction").html("Close Gate");
} else {
$("#gatestatus").html(message.payloadString);
$("#gateaction").html("Unknown Status");
}
} else if (message.destinationName == "feeds/Garage/Sensor/Status") {
$("#sensor").html(message.payloadString);
} else if (message.destinationName == "feeds/Driveway/Sensor/Status") {
$("#gatesensor").html(message.payloadString);
}
}
//Do this when button is clicked.
$( "#gdbutton" ).click(function() {
message = new Paho.MQTT.Message("1");
message.destinationName = "feeds/Garage/Door/Activate";
client.send(message);
});
$( "#gatebutton" ).click(function() {
message = new Paho.MQTT.Message("1");
message.destinationName = "feeds/Driveway/Gate/Activate";
client.send(message);
});
});//]]>
</script>
Much of this is self explanatory to those familiar with Javascript. Some of the more odd things in this code are around making sure that when a smartphone brings up the web page after being screen locked or the app has been in the background for a while the proper status is shown. I found that many smartphones, most importantly my wife's smartphone, would disconnect from the wifi and/or the cellular data connection to save battery which disconnected the MQTT Websockets connection. So, I had to come up with a way for the page to reload when the page was displayed after being in the background or behind a locked screen.I created an inline style sheet mainly because I just wanted to deal with a single file. Again, simplicity. I may move it out into it's own file eventually. Easy enough.
Oh, and yeah, I cheated and used a CSS button tool to make buttons that didn't look like crap.
<style media="screen" type="text/css">
.gdbuttonclass {
-moz-box-shadow: 0px 10px 14px -7px #3e7327;
-webkit-box-shadow: 0px 10px 14px -7px #3e7327;
box-shadow: 0px 10px 14px -7px #3e7327;
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #77b55a), color-stop(1, #72b352));
background:-moz-linear-gradient(top, #77b55a 5%, #72b352 100%);
background:-webkit-linear-gradient(top, #77b55a 5%, #72b352 100%);
background:-o-linear-gradient(top, #77b55a 5%, #72b352 100%);
background:-ms-linear-gradient(top, #77b55a 5%, #72b352 100%);
background:linear-gradient(to bottom, #77b55a 5%, #72b352 100%);
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#77b55a', endColorstr='#72b352',GradientType=0);
background-color:#77b55a;
-moz-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
border:1px solid #4b8f29;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Trebuchet MS;
font-size:28px;
font-weight:bold;
padding:6px 12px;
text-decoration:none;
text-shadow:0px 1px 0px #5b8a3c;
text-align: center;
}
.gdbuttonclass:hover {
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #72b352), color-stop(1, #77b55a));
background:-moz-linear-gradient(top, #72b352 5%, #77b55a 100%);
background:-webkit-linear-gradient(top, #72b352 5%, #77b55a 100%);
background:-o-linear-gradient(top, #72b352 5%, #77b55a 100%);
background:-ms-linear-gradient(top, #72b352 5%, #77b55a 100%);
background:linear-gradient(to bottom, #72b352 5%, #77b55a 100%);
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#72b352', endColorstr='#77b55a',GradientType=0);
background-color:#72b352;
}
.gdbuttonclass:active {
position:relative;
top:1px;
}
.gdtextclass {
color:#000000;
font-family:Trebuchet MS;
font-size:28px;
padding:6px 12px;
text-shadow:0px 1px 0px #5b8a3c;
text-align: center;
}
.gdtextclassbold {
color:#000000;
background-color: #dddddd;
border:3px solid #4b8f29;
font-family:Trebuchet MS;
font-size:28px;
font-weight:bold;
padding:6px 12px;
text-shadow:0px 1px 0px #5b8a3c;
text-align: center;
}
</style>
And finally the body of the web page. Very simple compared to the above.
<body>
<div style="text-align: center; background-color: #ccccff; width: 300px; border: 2px solid #ffffff">
<br>
<span class="gdtextclass">Garage Door Status</span>
<br> <br>
<span id="gdstatus" class="gdtextclassbold"></span>
<br> <br> <br>
<a href="#" id="gdbutton" class="gdbuttonclass"><span id="gdaction"></span></a>
<br> <br>
</div>
<div style="text-align: center; background-color: #99cc99; width: 300px; border: 2px solid #ffffff">
<br>
<span class="gdtextclass">Driveway Gate Status</span>
<br> <br>
<span id="gatestatus" class="gdtextclassbold"></span>
<br> <br> <br>
<a href="#" id="gatebutton" class="gdbuttonclass"><span id="gateaction"></span></a>
<br> <br>
</div>
<div style="font-family:Trebuchet MS; font-size:8px">
Garage: <span id="sensor">Unknown</span> / Gate: <span id="gatesensor">Unknown</span>
</div>
<br><br>
</body>
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.