Read the statement by Michael Teeuw here.
Getting update from python code interval-ly
-
Here are the code I used in my module just in case
MMM-Attend.js
Module.register("MMM-Attend",{ // Default module config. defaults: { updateInterval: 30000, fadespeed: 4000 }, getDom: function() { var e = document.createElement("div") e.id = "DISPLAY" //console.log (test) return e }, start: function() { Log.info('Starting module: ' + this.name); }, notificationReceived: function(notification, payload, sender) { switch(notification) { case "DOM_OBJECTS_CREATED": var timer = setInterval(()=>{ this.sendSocketNotification("GIVE_ME_DATA") //var test = "kel" }, 1000) break } }, socketNotificationReceived: function(notification, payload) { switch(notification) { case "HERE_IS_DATA": var e = document.getElementById("DISPLAY") e.innerHTML = payload // display nama var timer = setInterval(() =>{ console.log ("e", e.innerHTML) }, 1000) } }, getStyles: function() { return ['MMM-Attend.css'] }, })
node_helper.js
/// node_helper.js const spawn = require("child_process").spawn var NodeHelper = require("node_helper") var process = spawn("python", ["/home/pi/MagicMirror/modules/MMM-Attend/attendance.py"]) var interval = 1000 module.exports = NodeHelper.create({ socketNotificationReceived: function(notification, payload) { switch(notification) { case "GIVE_ME_DATA": this.job() break } }, job: function() { process.stdout.on("data", (data)=>{ //var timer = setInterval(() =>{ console.log ("node_helper", data) //}, 1000) var result = String.fromCharCode.apply(null, new Uint16Array((data))) this.sendSocketNotification("HERE_IS_DATA", result) }) } })
-
@ntahlah so, you start the python code once.
and the process.on.stdout() is setup and when it gets data from the python code it will send and update (HERE_IS_DATA)
but what causes the python code to either run again, or send any update?
the job function just sets up the stdout handler… but it was setup already
it doesn’t tell the python code to do anything
and the node_helper is loaded only once, so the python code is started only once -
Hello @sdetweil , thank you for the reply.
I tried your advice where I use setInterval() in MMM-Attend.js which you could see it here:
Module.register("MMM-Attend", { start: function() { setInterval(notificationReceived, 1000); //perform every 1000 milliseconds. }, getDom: function() { var e = document.createElement("div") e.id = "DISPLAY" ///console.log("getDom" + ) return e }, notificationReceived: function(notification, payload, sender) { this.sendSocketNotification("GIVE_ME_DATA") console.log("notificationRecieved") }, socketNotificationReceived: function(notification, payload) { switch(notification) { case "HERE_IS_DATA": var e = document.getElementById("DISPLAY") e.innerHTML = payload break } }, getStyles: function() { return ['MMM-Attend.css'] }, })
however it gave me error. Is this the way to call it interval-ly? Pardon my Javascript as I really not good at it
-
@ntahlah said in Getting update from python code interval-ly:
setInterval(notificationReceived, 1000); //perform every 1000 milliseconds.
but… that is not the problem
when the python script does this
sendJson = json.dumps(conJson)
then how does that data get OUT to the thing that started the script? u need to use print to send the stdout,
so that the process.stdout.on handler will be triggeredI think you want to uncomment the
#print(sendJson)
then the script will send the json or the "No new staff " on every cycle and the
process.stdout.on("data", (data)=>{
function will be triggered
I also think you want to change the "No new staff message to []
and also wrap the sendJson in []
then the modulename.js will get an array of attendents, and if the array is 0 length, there is nothing to do.
u could check that in the process.stdout.on handler and NOT send an empty message to the modulename.js
(minimize the work when nothing to do)
even better, do NOT send any output from python when no new user
(comment out the # print (“No new staff”) ) -
@sdetweil ahhh so that seems to be the problem… I thought using
print("Welcome! \n" + staff_name(int(staff_id)))
is enough to get the output (since I could get the output from print(“No new staff”)).
Oh in addition, I also got this
MaxListenersExceededWarning
so I put this
require('events').EventEmitter.defaultMaxListeners = 0;
inside nodehelper.js (based on my google search) and it seems to run albeitly very slow, well that is something I guess.
Thanks for the help and advice though.
-
@ntahlah u don’t need this but once…
socketNotificationReceived: function(notification, payload) { switch(notification) { case "GIVE_ME_DATA": this.job() break } },
once u setup the handler in this.job one time. you are done…
the handler is set forever (until u unset it, or the process ends)
this is why u got the too many handlers problems…
so you keep adding a new handler to the list and it gets longer and longer and lonnnnnnger
and slower and slower and … -
@sdetweil oh I see, I made some modification based on your suggestion
const spawn = require("child_process").spawn var NodeHelper = require("node_helper") var process = spawn("python", ["/home/pi/MagicMirror/modules/MMM-Attend/attendance.py"]) require('events').EventEmitter.defaultMaxListeners = 0; module.exports = NodeHelper.create({ socketNotificationReceived: function(notification, payload){ switch(notification) { case "GIVE_ME_DATA": process.stderr.on("data", (data)=>{ console.log("attend process errorr= "+data) }) process.stdout.on("data", (data)=>{ console.log("attend data = "+data) var result = String.fromCharCode.apply(null, new Uint16Array((data))) this.sendSocketNotification("HERE_IS_DATA", result) }) break } }, })
is this what you mean based on your previous comment. Because I don’t really get it