nothing changed. but now i see the HAVEDATA notification again. could it be, that the Dom-update (from notification) not really goes ?
i mean i saw in the dev, that the birthday-data are right. it was the first entry of this data-string (or jsonObj) …
only the header i can see …
Read the statement by Michael Teeuw here.
![](/assets/uploads/profile/uid-17827/17827-profileavatar.png)
Posts
-
RE: read csv-data and put it in an array
-
RE: read csv-data and put it in an array
error => now.getYear() is not a function
-
RE: read csv-data and put it in an array
before looking in dev: i saw the following:
var birth_date_moment = moment(birth_date + now.getYear(),"DD.MMYYYY");
change to DD.MM.YYYY (point between MM and YYYY) ?
-
RE: read csv-data and put it in an array
only the header i see, BUT now i see the terminal-message “HAVEDATA” but an error, too:
-
RE: read csv-data and put it in an array
ok, nothing changed and i don’t see any messages of “HAVEDATA” (changed it in both files to big letter without space). i only see the header “Geburtstage” … :-(
node_helper.js:var NodeHelper = require("node_helper"); var moment = require("moment"); // add require of other javascripot components here // var xxx = require('yyy'); here const csv = require("csvtojson"); var birthdaysArray = []; module.exports = NodeHelper.create({ /* init(){ console.log("init module helper perlchamp"); }, */ start() { }, /* stop(){ console.log("Stopping module helper: " + this.name); }, */ // handle messages from our module// each notification indicates a different messages // payload is a data structure that is different per message.. up to you to design this socketNotificationReceived(notification, payload) { var self = this; console.log("Starting module helper: " + this.name); // convert the csv-file into a JSON-String const csvFilePath = this.path + '/data/birthdays.csv'; csv() .fromFile(csvFilePath) .then((jsonObj)=>{ birthdaysArray = JSON.stringify(jsonObj); // send data to [modulname].js self.sendSocketNotification("HAVEDATA", jsonObj); }) // if config message from module if (notification === "CONFIG") { // save payload config info this.config = payload; // wait 15 seconds, send a message back to module setTimeout(()=> {this.sendSocketNotification("message_from_helper"," this is a test_message")}, 15000); } else if(notification === "????2") { } }, });
maye change this part, cause i never need this variable birthdaysArray:
.then((jsonObj)=>{ birthdaysArray = JSON.stringify(jsonObj);
perlchamp.js:
Module.register("perlchamp", { defaults: { language: "de", dimmEntries: true // true: dims entries and the associated // symbol when the date has expired. // false: delete entries and the associated // symbol when the date has expired. }, active_birthdays: { }, init: function(){ Log.log(this.name + " is in init!"); }, start: function(){ Log.log("Starting module: " + this.name); // Set locale moment.locale(config.language); }, loaded: function(callback) { Log.log(this.name + " is loaded!"); callback(); }, // return list of other functional scripts to use, if any (like require in node_helper) getScripts: function() { return ["moment.js"]; }, // return list of stylesheet files to use if any getStyles: function() { return [this.data.path + "/css/perlchamp.css"]; }, // only called if the module header was configured in module config in config.js getHeader: function() { return this.data.header; }, // messages received from other modules and the system (NOT from your node helper) // payload is a notification dependent data structure notificationReceived: function(notification, payload, sender) { // once everybody is loaded up if(notification==="ALL_MODULES_STARTED"){ // send our config to our node_helper this.sendSocketNotification("CONFIG",this.config); } if (sender) { Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); } else { Log.log(this.name + " received a system notification: " + notification); } }, // messages received from from your node helper (NOT other modules or the system) // payload is a notification dependent data structure, up to you to design between module and node_helper socketNotificationReceived: function(notification, payload) { if(notification === "HAVEDATE"){ Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); var now = moment(); for(var birthday of payload) { // get 1st 5 chars of birthdate, thru month // we will use this as the key in the hash var birth_date = birthday.birth.substring(0,4); // get the birthday as a moment in this year, for comparing var birth_date_moment = moment(birth_date + now.getYear(),"DD.MMYYYY"); // u can add days to a moment object and then compare // if the birthdate is before that date (and after now) // so within the next xx days // if the date is the same or later, don't use time of day if(birth_date.startOf('day').isSame(now.startOf('day'))) { // birthday is in this month // check the hash if we've seen anything for today yet // if we haven't see this date yet if(this.active_birthdays[birth_date] == undefined){ // create the holder for its info (array of // names) in the hash this.active_birthdays[birth_date] = []; } // save the persons name on the list this.active_birthdays[birth_date].push(birthday.name); } } // tell MM to call and get our content self.updateDom(); } }, // system notification your module is being hidden // typically you would stop doing UI updates (getDom/updateDom) if the module is hidden suspend: function(){ }, // system notification your module is being unhidden/shown // typically you would resume doing UI updates (getDom/updateDom) if the module is shown resume: function(){ }, // this is the major worker of the module, it provides the displayable content for this module getDom: function() { var wrapper = document.createElement("div"); for(var birthday of Object.keys(this.active_birthdays)){ for(var name of this.active_birthdays[birthday]){ var m = document.createElement('div'); m.innerText = birthday + ' '+ name; wrapper.appendChild(m); } } // pass the created content back to MM to add to DOM. return wrapper; } })
please have an eye on the getDom-sektion.
-
RE: read csv-data and put it in an array
ok, be carefully. keep corona away. use mouth and nose protection and wear disposable gloves !
thanks, but doesn’t work. it seems, that i’m too stupid for this ?
modified perlchamp.js:Module.register("perlchamp", { defaults: { language: "de", dimmEntries: true // true: dims entries and the associated // symbol when the date has expired. // false: delete entries and the associated // symbol when the date has expired. }, active_birthdays: { }, init: function(){ Log.log(this.name + " is in init!"); }, start: function(){ Log.log("Starting module: " + this.name); // Set locale moment.locale(config.language); }, loaded: function(callback) { Log.log(this.name + " is loaded!"); callback(); }, // return list of other functional scripts to use, if any (like require in node_helper) getScripts: function() { return ["moment.js"]; }, // return list of stylesheet files to use if any getStyles: function() { return [this.data.path + "/css/perlchamp.css"]; }, // only called if the module header was configured in module config in config.js getHeader: function() { return this.data.header; }, // messages received from other modules and the system (NOT from your node helper) // payload is a notification dependent data structure notificationReceived: function(notification, payload, sender) { // once everybody is loaded up if(notification==="ALL_MODULES_STARTED"){ // send our config to our node_helper this.sendSocketNotification("CONFIG",this.config); } if (sender) { Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); } else { Log.log(this.name + " received a system notification: " + notification); } }, // messages received from from your node helper (NOT other modules or the system) // payload is a notification dependent data structure, up to you to design between module and node_helper socketNotificationReceived: function(notification, payload) { if(notification === "have data"){ Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); var now = moment(); for(var birthday of payload) { // get 1st 5 chars of birthdate, thru month // we will use this as the key in the hash var birth_date = birthday.birth.substring(0,4); // get the birthday as a moment in this year, for comparing var birth_date_moment = moment(birth_date + now.getYear(),"DD.MMYYYY"); // u can add days to a moment object and then compare // if the birthdate is before that date (and after now) // so within the next xx days // if the date is the same or later, don't use time of day if(birth_date.startOf('day').isSame(now.startOf('day'))) { // birthday is in this month // check the hash if we've seen anything for today yet // if we haven't see this date yet if(this.active_birthdays[birth_date] == undefined){ // create the holder for its info (array of // names) in the hash this.active_birthdays[birth_date] = []; } // save the persons name on the list this.active_birthdays[birth_date].push(birthday.name); } } // tell MM to call and get our content self.updateDom(); } }, // system notification your module is being hidden // typically you would stop doing UI updates (getDom/updateDom) if the module is hidden suspend: function(){ }, // system notification your module is being unhidden/shown // typically you would resume doing UI updates (getDom/updateDom) if the module is shown resume: function(){ }, // this is the major worker of the module, it provides the displayable content for this module getDom: function() { var wrapper = document.createElement("div"); for(var birthday of Object.keys(this.active_birthdays)){ for(var name of this.active_birthdays[birthday]){ var m = document.createElement('div'); m.innerText = birthday + ' '+ name; wrapper.appendChild(m); } } // pass the created content back to MM to add to DOM. return wrapper; } })
in node_helper.js was nothing to be changed. maybe I put a few semicolons where none have to go?
-
RE: read csv-data and put it in an array
this is the getDom-section where the data finally should be placed (perlchamp is for testing) :
getDom: function() { if ((moment() > this.midnight) || (!this.loaded)) { var month = moment().month(); var year = moment().year(); var monthName = moment().format("MMMM"); var monthLength = moment().daysInMonth(); // tabelle erstellen var wrapper = document.createElement("table"); wrapper.className = 'table'; wrapper.id = 'birthday-table'; // tabellenkopf erstellen var tHeader = document.createElement("thead"); tHeader.className = "thead"; tHeader.id = "birthday-thead"; var headerTR = document.createElement("tr"); headerTR.className = "tr-head"; headerTR.id = "birthday-tr-head"; var headerTH = document.createElement("th"); headerTH.colSpan = "2"; headerTH.scope = "col"; headerTH.className = "th-head"; headerTH.id = "birthday-th-head"; headerTH.innerHTML = this.translate(this.config.title); headerTR.appendChild(headerTH); tHeader.appendChild(headerTR); wrapper.appendChild(tHeader); // Create TFOOT section -- currently used for debugging only var tFooter = document.createElement('tfoot'); tFooter.className = "tfoot"; tFooter.id = "birthday-tfoot"; var footerTR = document.createElement("tr"); footerTR.className = "tr-foot"; footerTR.id = "birthday-tr-foot"; var footerTD = document.createElement("td"); footerTD.colSpan ="2"; footerTD.className = "td-foot"; footerTD.id = "birthday-td-foot"; if (this.config.debugging) { footerTD.innerHTML = "Birthdaylist is currently in DEBUG mode!<br />Please see console log."; } else { footerTD.innerHTML = ""; } footerTR.appendChild(footerTD); tFooter.appendChild(footerTR); wrapper.appendChild(tFooter); // Create TBODY section with day names var eintraege = 3; for (var i=1; i<=eintraege; i++) { var tBody = document.createElement("tBody"); tBody.className = "tbody"; tBody.id = "birthday-tbody"; var bodyTR = document.createElement("tr"); bodyTR.className = "tr-body"; bodyTR.id = "birthday-tr-body"; var bodyTDimage = document.createElement("td"); bodyTDimage.className = "td-image"; bodyTDimage.id = "birthday-td-image"; bodyTDimage.innerHTML = "23"; var bodyTD = document.createElement("td"); bodyTD.className = "td-body"; bodyTD.id = "birthday-td-body"; bodyTD.innerHTML = "Bettina Zimmermann <span class=\"age-span\">46</span></br>Frank Dubiel <span class=\"age-span\">54</span></br>Jürgen Gruse <span class=\"age-span\">52</span>"; /* var bodyAgeSpan = document.createElement("span"); bodyAgeSpan.className = "age-span"; bodyAgeSpan.id = "birthday-age-span"; bodyAgeSpan.innerHTML = " 46"; bodyTD.appendChild(bodyAgeSpan); */ bodyTR.appendChild(bodyTDimage); bodyTR.appendChild(bodyTD); tBody.appendChild(bodyTR); wrapper.appendChild(tBody); } this.loaded = true; return wrapper; }
the data here are text, ifilles in, no variables …
-
RE: read csv-data and put it in an array
black screen, again. this is my perlchamp.js:
Module.register("perlchamp", { defaults: { language: "de", dimmEntries: true // true: dims entries and the associated // symbol when the date has expired. // false: delete entries and the associated // symbol when the date has expired. }, init: function(){ Log.log(this.name + " is in init!"); }, start: function(){ Log.log("Starting module: " + this.name); // Set locale moment.locale(config.language); }, loaded: function(callback) { Log.log(this.name + " is loaded!"); callback(); }, // return list of other functional scripts to use, if any (like require in node_helper) getScripts: function() { return ["moment.js"]; }, // return list of stylesheet files to use if any getStyles: function() { return [this.data.path + "/css/perlchamp.css"]; }, /* // return list of translation files to use, if any getTranslations: function() { return { // sample of list of files to specify here, if no files, do not use this routine, , or return empty list // en: "translations/en.json", (folders and filenames in your module folder) // de: "translations/de.json" } }, */ // only called if the module header was configured in module config in config.js getHeader: function() { return this.data.header; }, // messages received from other modules and the system (NOT from your node helper) // payload is a notification dependent data structure notificationReceived: function(notification, payload, sender) { // once everybody is loaded up if(notification==="ALL_MODULES_STARTED"){ // send our config to our node_helper this.sendSocketNotification("CONFIG",this.config); } if (sender) { Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); } else { Log.log(this.name + " received a system notification: " + notification); } }, // messages received from from your node helper (NOT other modules or the system) // payload is a notification dependent data structure, up to you to design between module and node_helper socketNotificationReceived: function(notification, payload) { /* Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); if(notification === "message_from_helper"){ this.config.message = payload; // tell mirror runtime that our data has changed, // we will be called back at GetDom() to provide the updated content this.updateDom(1000); } */ if(notification === "have data"){ Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); var now = moment(); var active_birthdays = {}; for(var birthday of payload) { // get 1st 5 chars of birthdate, thru month // we will use this as the key in the hash var birth_date = birthday.birth.subString(0,4); // get the birthday as a moment in this year, for comparing var birth_date_moment = moment(birth_date + now.getYear(),"DD.MMYYYY"); // u can add days to a moment object and then compare // if the birthdate is before that date (and after now) // so within the next xx days // if the date is the same or later, don't use time of day if(birth_date.startOf('day').isSame(now.startOf('day'))) { // birthday is in this month // check the hash if we've seen anything for today yet // if we haven't see this date yet if(active_birthdays[birth_date] == undefined){ // create the holder for its info (array of // names) in the hash active_birthdays[birth_date] = []; } // save the persons name on the list active_birthdays[birth_date].push(birthday.name); } } // tell MM to call and get our content self.updateDom(); } /* this.config.message = payload; // tell mirror runtime that our data has changed, // we will be called back at GetDom() to provide the updated content this.updateDom(1000) // filters the birthdaylist and output only the birthdays // of the current month, sorted (ascending) by days in // the following format: // [{ day: "10", name: ["firstname lastname",...] }] // set variables var today_month = moment().format("MM"); var today_day_month = moment().format("DD.MM"); var result = Object.entries(jsonObj .filter(({birth}) => birth.split('.')[1] === today_month) .reduce((a, {birth, name}) => { const day = +birth.split('.')[0]; a[day] = [...(a[day] || []), name]; return a }, {}) ).map(([day, name]) => ({day, name})).sort((a, b) => +a.day - b.day); birthdaysArray = result; // for debugging only //console.log("filtered and sorted: ", birthdaysArray); */ }, // system notification your module is being hidden // typically you would stop doing UI updates (getDom/updateDom) if the module is hidden suspend: function(){ }, // system notification your module is being unhidden/shown // typically you would resume doing UI updates (getDom/updateDom) if the module is shown resume: function(){ }, // this is the major worker of the module, it provides the displayable content for this module getDom: function() { var wrapper = document.createElement("div"); for(var birthday of Object.keys(this.active_birthdays)){ for(var name of this.active_birthdays[birthday]){ var m = document.createElement('div'); m.innerText = birthday + ' '+ name; wrapper.appendChild(m); } } // pass the created content back to MM to add to DOM. return wrapper; } })
this the node_helper.js:
var NodeHelper = require("node_helper"); var moment = require("moment"); // add require of other javascripot components here // var xxx = require('yyy'); here const csv = require("csvtojson"); var birthdaysArray = []; module.exports = NodeHelper.create({ init(){ console.log("init module helper perlchamp"); }, start() { var self = this; console.log("Starting module helper: " + this.name); // convert the csv-file into a JSON-String const csvFilePath = this.path + '/data/birthdays.csv'; csv() .fromFile(csvFilePath) .then((jsonObj)=>{ birthdaysArray = JSON.stringify(jsonObj); // for debugging only //console.log("birthdaysArray: ", birthdaysArray); // send data to [modulname].js self.sendSocketNotification("have data", jsonObj); }) }, stop(){ console.log("Stopping module helper: " + this.name); }, // handle messages from our module// each notification indicates a different messages // payload is a data structure that is different per message.. up to you to design this socketNotificationReceived(notification, payload) { // if config message from module if (notification === "CONFIG") { // save payload config info this.config = payload; // wait 15 seconds, send a message back to module setTimeout(()=> { this.sendSocketNotification("message_from_helper"," this is a test_message")}, 15000); } else if(notification === "????2") { } }, });
these are the terminal outputs:
dirk@raspberrypi:~/MagicMirror/modules/perlchamp $ npm start > magicmirror@2.11.0 start /home/dirk/MagicMirror > DISPLAY="${DISPLAY:=:0}" ./node_modules/.bin/electron js/electron.js [2020-05-02 02:52:02.407] [LOG] Starting MagicMirror: v2.11.0 [2020-05-02 02:52:02.414] [LOG] Loading config ... [2020-05-02 02:52:02.418] [LOG] Loading module helpers ... [2020-05-02 02:52:02.424] [LOG] Initializing new module helper ... [2020-05-02 02:52:02.425] [LOG] Module helper loaded: MMM-Logging [2020-05-02 02:52:02.579] [LOG] init module helper perlchamp [2020-05-02 02:52:02.580] [LOG] Module helper loaded: perlchamp [2020-05-02 02:52:02.580] [LOG] All module helpers loaded. [2020-05-02 02:52:02.711] [LOG] Starting server on port 8080 ... [2020-05-02 02:52:02.718] [INFO] You're using a full whitelist configuration to allow for all IPs [2020-05-02 02:52:02.726] [LOG] Server started ... [2020-05-02 02:52:02.727] [LOG] Connecting socket for: MMM-Logging [2020-05-02 02:52:02.727] [LOG] Module helper started for MMM-Logging [2020-05-02 02:52:02.728] [LOG] Connecting socket for: perlchamp [2020-05-02 02:52:02.728] [LOG] Starting module helper: perlchamp [2020-05-02 02:52:02.732] [LOG] Sockets connected & modules started ... [2020-05-02 02:52:02.829] [LOG] Launching application. [2020-05-02 02:52:04.803] [LOG] Starting module: perlchamp (/home/dirk/MagicMirror/modules/MMM-Logging/node_helper.js:34 Class.socketNotificationReceived) [2020-05-02 02:52:04.805] [LOG] All modules started! (/home/dirk/MagicMirror/modules/MMM-Logging/node_helper.js:37 Class.socketNotificationReceived) [2020-05-02 02:52:04.806] [LOG] payload: undefined (/home/dirk/MagicMirror/modules/MMM-Logging/node_helper.js:31 Class.socketNotificationReceived) [2020-05-02 02:52:04.807] [LOG] perlchamp received a system notification: ALL_MODULES_STARTED (/home/dirk/MagicMirror/modules/MMM-Logging/node_helper.js:34 Class.socketNotificationReceived) [2020-05-02 02:52:04.810] [ERROR] {} (/home/dirk/MagicMirror/modules/MMM-Logging/node_helper.js:43 Class.socketNotificationReceived) [2020-05-02 02:52:04.811] [LOG] Browser Error: {} (/home/dirk/MagicMirror/modules/MMM-Logging/node_helper.js:46 Class.socketNotificationReceived) [2020-05-02 02:52:07.185] [LOG] Shutting down server... (/home/dirk/MagicMirror/js/electron.js:105 App.<anonymous>) [2020-05-02 02:52:07.188] [LOG] Stopping module helper: MMM-Logging (/home/dirk/MagicMirror/js/node_helper.js:33 Class.stop) [2020-05-02 02:52:07.190] [LOG] Stopping module helper: perlchamp (/home/dirk/MagicMirror/modules/perlchamp/node_helper.js:39 Class.stop) dirk@raspberrypi:~/MagicMirror/modules/perlchamp $
i didn’t never seen the notification “have data” …
-
RE: read csv-data and put it in an array
so, sam, everything is fixed :-)
but now i don’t know how to handle the receiving data. i only need a little entry … don’t know how to handle this object-element. actually nothing is displayed except the header i configured …