Read the statement by Michael Teeuw here.
Trying to fix my module
-
Hello, I come to you because I started trying to create my own module. Because I didn’t know anything about javascript, html and css 2 weeks ago and not much in programmation either, I pretty much learned everything in 2 weeks so please, be indulgent :p
The module I’m creating is supposed to display the data from a french public transport API. I worked on the display using a local server, just to test things out, I made it work, then I tried to implement it to my magic mirror, but here started the problems, I used the default modules as a guide and tried to move the diffrents pieces where they should be and now, I have this, but when I start my mirror, the screen stays black and it doesn’t start:
Module.register(“schedules”, {
defaults: { updateInterval: 20000 fadeSpeed: 4000 }, getScripts: function() { return ["moment.js"] }, getStyles: function() { return ["font-awesome.css", "schedules.css"] }, start: function() { Log.info("Starting module: " + this.name); var self = this; setInterval(function() { self.updateDom(self.config.fadeSpeed); }, this.config.updateInterval); }, getDom: function() { dataDirSM = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=robinson+saint+remy+les+chevreuse&endingstation=les+baconnets") data = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=charles+de+gaulle+mitry+claye&endingstation=les+baconnets"); setTimeout(function() { var wrapper = document.createElement("div") var realtable = document.createElement('table'); realtable.appendChild(this.createUpperRow()); var row1 = document.createElement('tr') row1.appendChild(this.boxHeader(data.response.schedules[0].message)) row1.appendChild(this.boxHeader(data.response.schedules[0].id)) row1.appendChild(this.boxHeader(dataDirSM.response.schedules[0].id)) row1.appendChild(this.boxHeader(dataDirSM.response.schedules[0].message)) realtable.appendChild(row1) var row2 = document.createElement('tr') row2.appendChild(this.boxHeader(data.response.schedules[1].message)) row2.appendChild(this.boxHeader(data.response.schedules[1].id)) row2.appendChild(this.boxHeader(dataDirSM.response.schedules[1].id)) row2.appendChild(this.boxHeader(dataDirSM.response.schedules[1].message)) realtable.appendChild(row2) var row3 = document.createElement('tr') row3.appendChild(this.boxHeader(data.response.schedules[2].message)) row3.appendChild(this.boxHeader(data.response.schedules[2].id)) row3.appendChild(this.boxHeader(dataDirSM.response.schedules[2].id)) row3.appendChild(this.boxHeader(dataDirSM.response.schedules[2].message)) realtable.appendChild(row3) wrapper.appendChild(realtable) return wrapper }, (5 * 1000)); }, createUpperRow: function() { function createUpperRow() { var firstTableRow = document.createElement('tr'); var tableh1 = document.createElement('th'); tableh1.classList.add('align-left'); var tx1 = document.createTextNode('Time'); tableh1.appendChild(tx1); firstTableRow.appendChild(tableh1); var tableh2 = document.createElement('th'); tableh2.classList.add('align-left'); var tx2 = document.createTextNode('Paris'); tableh2.appendChild(tx2); firstTableRow.appendChild(tableh2); // deuxième moitier var tableh3 = document.createElement('th'); tableh3.classList.add('align-right'); var tx3 = document.createTextNode('Sud'); tableh3.appendChild(tx3); firstTableRow.appendChild(tableh3); var tableh4 = document.createElement('th'); tableh4.classList.add('align-right'); var tx4 = document.createTextNode('Time'); tableh4.appendChild(tx4); firstTableRow.appendChild(tableh4); return firstTableRow; }, boxHeader: function(inside) { if (inside == 'Train à l\'approche' || inside == 'Train à quai') { inside = 'no way' } else if (inside == 'Train retardé') { inside = 'retard' } var fillNode = document.createTextNode(inside); var realBox = document.createElement('td') realBox.appendChild(fillNode); return realBox; } })and my css file :
.schedules .logo {
margin-right: 5px;
}.schedules .centered {
text-align: center;
}.schedules .table {
border-spacing: 10px 0px;
border-collapse: separate;
}(I don’t know why it doesn’t auto format)
if you guys had little hints for me to fix my mistakes, I’ll be highly thankful.
-
what jumped on my eyes on the first look,
the getDom function requires a synchronous answer, but with the timeout it’s asynchronous, you should load your data outside of this function and in getdom check if the data is there otherwise display a placeholder, then when you received data in the other function you call updateDom to refresh your display
and there is a ratp module out there, maybe you will extend this one instead of creating a new one https://github.com/lgmorand/MMM-Ratp
-
Thank you for your reply, I didn’t know about this synchronous problem. But I think I saw that the start function is only called once, not each reload, so in which function should I get the data ?
I couldn’t find the ratp module you told me about, if you could send me a link, that would be cool :)
-
@skoz the link is above
to give you an idea i wrote something little quick to give you an idea how it can be
set an interval in start()
setInterval(() => { this.getData(); this.updateDom(); }, 30*60*1000); //calls getData every 30 minsgetData()
this.dataDirSM = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=robinson+saint+remy+les+chevreuse&endingstation=les+baconnets"); this.data = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=charles+de+gaulle+mitry+claye&endingstation=les+baconnets");getDom()
var wrapper = document.createElement("div") if(this.dataDirSM && this.data){ var realtable = document.createElement('table'); realtable.appendChild(this.createUpperRow()); for(var i = 0; i < Math.min(this.data.response.schedules.length, this.dataDirSM.response.schedules.length); i++){ var row = document.createElement('tr') row.appendChild(this.boxHeader(this.data.response.schedules[i].message)) row.appendChild(this.boxHeader(this.data.response.schedules[i].id)) row.appendChild(this.boxHeader(this.dataDirSM.response.schedules[i].id)) row.appendChild(this.boxHeader(this.dataDirSM.response.schedules[i].message)) realtable.appendChild(row) } wrapper.appendChild(realtable) } else { wrapper.innerHTML = "NO DATA"; } return wrapper -
oh, i’m blind xD I had never seen this module, thanks for pointing it out !
You fixed the for loop, i had trouble with this one, I refused to work and i still don’t know why so i decided to bypass it. Thanks alot for fixing my code, if I understand right, the getDom function will check if data has arrived and if True, it will display the table, if False, it will display the"NO DATA" ? and each reload, the program will reload the data and display it ?
I’ll just have to shorten the time between each refresh because train pass by a bit more regularly so it wont be up to date if i wait 30 minutes each time.Thank you alot, I will try this new code now :)
-
@skoz yes, but it’s not tested i just wrote it down to give you an idea. if you get in trouble feel free to wite me a pn or check out the other module
-
Well at least, this time, something happened, the mirror boot up but where the table should be, its written :
schedules
module_5_schedulesModule.register(“schedules”, {
defaults: { updateInterval: 20000 fadeSpeed: 4000 }, getScripts: function() { return ["moment.js"] }, getStyles: function() { return ["font-awesome.css", "schedules.css"] }, start: function() { Log.info("Starting module: " + this.name); setInterval(() => { this.getData(); this.updateDom(); }, 20 * 1000); //calls getData every 20 second }, getDom: function() { var wrapper = document.createElement("div") if (this.dataDirSM && this.data) { var realtable = document.createElement('table'); realtable.appendChild(this.createUpperRow()); for (var i = 0; i < Math.min(this.data.response.schedules.length, this.dataDirSM.response.schedules.length); i++) { var row = document.createElement('tr') row.appendChild(this.boxHeader(this.data.response.schedules[i].message)) row.appendChild(this.boxHeader(this.data.response.schedules[i].id)) row.appendChild(this.boxHeader(this.dataDirSM.response.schedules[i].id)) row.appendChild(this.boxHeader(this.dataDirSM.response.schedules[i].message)) realtable.appendChild(row) } wrapper.appendChild(realtable) } else { wrapper.innerHTML = "NO DATA"; }, getData: function() { this.dataDirSM = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=robinson+saint+remy+les+chevreuse&endingstation=les+baconnets"); this.data = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=charles+de+gaulle+mitry+claye&endingstation=les+baconnets"); }, createUpperRow: function() { function createUpperRow() { var firstTableRow = document.createElement('tr'); var tableh1 = document.createElement('th'); tableh1.classList.add('align-left'); var tx1 = document.createTextNode('Time'); tableh1.appendChild(tx1); firstTableRow.appendChild(tableh1); var tableh2 = document.createElement('th'); tableh2.classList.add('align-left'); var tx2 = document.createTextNode('Paris'); tableh2.appendChild(tx2); firstTableRow.appendChild(tableh2); // deuxième moitier var tableh3 = document.createElement('th'); tableh3.classList.add('align-right'); var tx3 = document.createTextNode('Sud'); tableh3.appendChild(tx3); firstTableRow.appendChild(tableh3); var tableh4 = document.createElement('th'); tableh4.classList.add('align-right'); var tx4 = document.createTextNode('Time'); tableh4.appendChild(tx4); firstTableRow.appendChild(tableh4); return firstTableRow; }, boxHeader: function(inside) { if (inside == 'Train à l\'approche' || inside == 'Train à quai') { inside = 'no way' } else if (inside == 'Train retardé') { inside = 'retard' } var fillNode = document.createTextNode(inside); var realBox = document.createElement('td') realBox.appendChild(fillNode); return realBox; } })and here is what I got from your advices
-
@skoz you forgot to return wrapper at the end of getDom and remove
function createUpperRow() {in vreateUpperRow -
Oh you are right, I also forget a curly brace after the ‘else’, I changed all that but it still doesn’t work
I paste the code again if you want to see it clearModule.register(“schedules”, {
defaults: { updateInterval: 20000 fadeSpeed: 4000 }, getScripts: function() { return ["moment.js"] }, getStyles: function() { return ["font-awesome.css", "schedules.css"] }, start: function() { Log.info("Starting module: " + this.name); setInterval(() => { this.getData(); this.updateDom(); }, 20 * 1000); //calls getData every 20 seconds }, getDom: function() { var wrapper = document.createElement("div") if (this.dataDirSM && this.data) { var realtable = document.createElement('table'); realtable.appendChild(this.createUpperRow()); for (var i = 0; i < Math.min(this.data.response.schedules.length, this.dataDirSM.response.schedules.length); i++) { var row = document.createElement('tr') row.appendChild(this.boxHeader(this.data.response.schedules[i].message)) row.appendChild(this.boxHeader(this.data.response.schedules[i].id)) row.appendChild(this.boxHeader(this.dataDirSM.response.schedules[i].id)) row.appendChild(this.boxHeader(this.dataDirSM.response.schedules[i].message)) realtable.appendChild(row) } wrapper.appendChild(realtable) } else { wrapper.innerHTML = "NO DATA"; }; return wrapper }, getData: function() { this.dataDirSM = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=robinson+saint+remy+les+chevreuse&endingstation=les+baconnets"); this.data = loadJSON("https://api-ratp.pierre-grimaud.fr/v2/rers/B/stations/les+baconnets?destination=charles+de+gaulle+mitry+claye&endingstation=les+baconnets"); }, createUpperRow: function() { var firstTableRow = document.createElement('tr'); var tableh1 = document.createElement('th'); tableh1.classList.add('align-left'); var tx1 = document.createTextNode('Time'); tableh1.appendChild(tx1); firstTableRow.appendChild(tableh1); var tableh2 = document.createElement('th'); tableh2.classList.add('align-left'); var tx2 = document.createTextNode('Paris'); tableh2.appendChild(tx2); firstTableRow.appendChild(tableh2); // deuxième moitier var tableh3 = document.createElement('th'); tableh3.classList.add('align-right'); var tx3 = document.createTextNode('Sud'); tableh3.appendChild(tx3); firstTableRow.appendChild(tableh3); var tableh4 = document.createElement('th'); tableh4.classList.add('align-right'); var tx4 = document.createTextNode('Time'); tableh4.appendChild(tx4); firstTableRow.appendChild(tableh4); return firstTableRow; }, boxHeader: function(inside) { if (inside == 'Train à l\'approche' || inside == 'Train à quai') { inside = 'no way' } else if (inside == 'Train retardé') { inside = 'retard' } var fillNode = document.createTextNode(inside); var realBox = document.createElement('td') realBox.appendChild(fillNode); return realBox; }})
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login