Closed chaos39 closed 8 years ago
@chaos39
Generally speaking, yes you can declare variables outside of your ready
handler and give them a wider scope but you cannot instantiate a new LCD object and assign it to your LCD variable until the board is ready. So declare outside board.on("ready"...) but assign inside.
Can your work()
function be called before the board is ready? If so, you'll need to make sure that lcd is an instance of LCD before you call on
or off
.
Honestly I'd consider refactoring to avoid this chicken/egg pickle, but if this is a one-off fun project it might not be worth the effort.
Also, the code was really hard to read. You can add four tick marks before and after your code to make it a code block. Also indentation helps. Your more likely to get a response if the helpers can easily digest your question.
p.s. "Chicken/Egg pickle" is a new technical term I just invented. I hope it catches on.
var amqp = require('amqplib/callback_api');
var five = require("johnny-five");
var Edison = require("edison-io");
var board = new five.Board({
port: "/dev/ttyMFD1"
});
var CLOUDAMQP_URL = 'amqp://james:1234@192.168.0.99:5672/%2F';
var amqpConn = null;
var lcd;
function start() {
amqp.connect(CLOUDAMQP_URL + "?heartbeat=60", function(err, conn) {
if (err) {
console.error("[AMQP]", err.message);
return setTimeout(start, 1000);
}
conn.on("error", function(err) {
if (err.message !== "Connection closing") {
console.error("[AMQP] conn error", err.message);
}
});
conn.on("close", function() {
console.error("[AMQP] reconnecting");
return setTimeout(start, 1000);
});
console.log("[AMQP] connected");
amqpConn = conn;
whenConnected();
});
}
function whenConnected() {
startPublisher();
startWorker();
}
var pubChannel = null;
var offlinePubQueue = [];
function startPublisher() {
amqpConn.createConfirmChannel(function(err, ch) {
if (closeOnErr(err)) return;
ch.on("error", function(err) {
console.error("[AMQP] channel error", err.message);
});
ch.on("close", function() {
console.log("[AMQP] channel closed");
});
pubChannel = ch;
while (true) {
var m = offlinePubQueue.shift();
if (!m) break;
publish(m[0], m[1], m[2]);
}
});
}
function publish(exchange, routingKey, content) {
try {
pubChannel.publish(exchange, routingKey, content, { persistent: true },
function(err, ok) {
if (err) {
console.error("[AMQP] publish", err);
offlinePubQueue.push([exchange, routingKey, content]);
pubChannel.connection.close();
}
});
} catch (e) {
console.error("[AMQP] publish", e.message);
offlinePubQueue.push([exchange, routingKey, content]);
}
}
// A worker that acks messages only if processed succesfully
function startWorker() {
amqpConn.createChannel(function(err, ch) {
if (closeOnErr(err)) return;
ch.on("error", function(err) {
console.error("[AMQP] channel error", err.message);
});
ch.on("close", function() {
console.log("[AMQP] channel closed");
});
ch.prefetch(10);
ch.assertQueue("TPQueue", { durable: true }, function(err, _ok) {
if (closeOnErr(err)) return;
ch.consume("TPQueue", processMsg, { noAck: false });
console.log("Worker is started");
});
function processMsg(msg) {
work(msg, function(ok) {
try {
if (ok)
ch.ack(msg);
else
ch.reject(msg, true);
} catch (e) {
closeOnErr(e);
}
});
}
});
}
function work(msg, cb) {
console.log("Received:", msg.content.toString());
var msgIn = msg.content.toString();
colonIndex = msgIn.indexOf(":");
if (colonIndex>0){
cmdString = msgIn.substr(colonIndex+2, 3);
switch(cmdString){
case"OFF":
console.log("Command:",cmdString);
// Make sure lcd is an instance of LCD here
lcd.off();
break;
case"ON":
console.log("Command :",cmdString);
// Make sure lcd is an instance of LCD here
lcd.on();
break;
default:
console.log("Received:",cmdString);
}
}
cb(true);
}
function closeOnErr(err) {
if (!err) return false;
console.error("[AMQP] error", err);
amqpConn.close();
return true;
}
board.on("ready", function() {
lcd = new five.LCD({
controller: "JHD1313M1"
});
var led0 = new five.Led(10); // yellow led
var led = new five.Led(11);
var led1 = new five.Led(12);
var gas = new five.Sensor({
controller: "GROVE",
pin: "A3",
freq: 1000
});
var temperature = new five.Thermometer({
controller: "GROVE",
pin: "A2",
freq: 1000
});
var c = 0;
temperature.on("data", function() {
c = Math.round(this.celsius);
if ( c >=24 ){
led.on();
led1.off();
lcd.cursor(0,5).print("HOT ");
lcd.bgColor("red");
publish("Bridge","cupOUT",new Buffer(c+"c"+" HOT"))
} else if ( c <=20){
led.off();
led1.on();
lcd.cursor(0,5).print("Cold");
lcd.bgColor("blue");
publish("Bridge","cupOUT",new Buffer(c+"c"+"COLD"))
} else {
led.off();
led1.off();
lcd.cursor(0,5).print("Warm");
lcd.bgColor("green");
}
lcd.cursor(0,0).print(c+"*c");
});
gas.on("change", function() {
if (this.scaleTo(100,2000) > 300) {
led0.on();
lcd.cursor(1,0).print('AL: Beer');
lcd.bgColor("yellow");
} else if (this.scaleTo(100,2000) > 450) {
led.blink(500)
lcd.cursor(1,0).print('AL: Wine');
lcd.bgColor("purple");
} else {
led0.off()
lcd.cursor(1,0).print('Normal ');
}
});
});
start();
@dtex thanks for taking a look at this.
Since this isn't a bug in Johnny-Five, and the issue can be resolved by refactoring the program towards correctness, I'm going to close this issue. Thanks everyone!
Hello, guys, I would like to check whether is it possible to var Something before Board.on ready function. I trying to connect to a server called rabbitmq, from the command given by the server, I should be able to switch on or switch off my LCD display the error that I got was : [AMQP] channel error lcd is not defined [AMQP] channel closed
Thanks
this is the current code that I have been doing
var amqp = require('amqplib/callback_api'); var five = require("johnny-five"); var Edison = require("edison-io"); var board = new five.Board({ port: "/dev/ttyMFD1" });
var CLOUDAMQP_URL = 'amqp://james:1234@192.168.0.99:5672/%2F';
var amqpConn = null;
function start() { amqp.connect(CLOUDAMQP_URL + "?heartbeat=60", function(err, conn) { if (err) { console.error("[AMQP]", err.message); return setTimeout(start, 1000); } conn.on("error", function(err) { if (err.message !== "Connection closing") { console.error("[AMQP] conn error", err.message); } }); conn.on("close", function() { console.error("[AMQP] reconnecting"); return setTimeout(start, 1000); }); console.log("[AMQP] connected"); amqpConn = conn; whenConnected(); }); }
function whenConnected() { startPublisher(); startWorker(); }
var pubChannel = null; var offlinePubQueue = []; function startPublisher() { amqpConn.createConfirmChannel(function(err, ch) { if (closeOnErr(err)) return; ch.on("error", function(err) { console.error("[AMQP] channel error", err.message); }); ch.on("close", function() { console.log("[AMQP] channel closed"); });
}); }
function publish(exchange, routingKey, content) { try {
pubChannel.publish(exchange, routingKey, content, { persistent: true }, function(err, ok) { if (err) { console.error("[AMQP] publish", err); offlinePubQueue.push([exchange, routingKey, content]); pubChannel.connection.close(); } }); } catch (e) {
console.error("[AMQP] publish", e.message); offlinePubQueue.push([exchange, routingKey, content]); } } // A worker that acks messages only if processed succesfully function startWorker() { amqpConn.createChannel(function(err, ch) { if (closeOnErr(err)) return; ch.on("error", function(err) { console.error("[AMQP] channel error", err.message); });
}); } function work(msg, cb) { console.log("Received:", msg.content.toString()); var msgIn = msg.content.toString(); colonIndex = msgIn.indexOf(":"); if (colonIndex>0){ cmdString = msgIn.substr(colonIndex+2, 3); switch(cmdString){ case"OFF": console.log("Command:",cmdString); lcd.off(); break; case"ON": console.log("Command :",cmdString); lcd.on(); break; default: console.log("Received:",cmdString); }
cb(true); }
function closeOnErr(err) { if (!err) return false; console.error("[AMQP] error", err); amqpConn.close(); return true; }
board.on("ready", function() {
var lcd = new five.LCD({ controller: "JHD1313M1" }); var led0 = new five.Led(10); // yellow led var led = new five.Led(11); var led1 = new five.Led(12); var gas = new five.Sensor({ controller: "GROVE", pin: "A3", freq: 1000 }); var temperature = new five.Thermometer({ controller: "GROVE", pin: "A2", freq: 1000 });
var c = 0;
temperature.on("data", function() { c = Math.round(this.celsius); if ( c >=24 ){ led.on(); led1.off(); lcd.cursor(0,5).print("HOT "); lcd.bgColor("red"); publish("Bridge","cupOUT",new Buffer(c+"_c"+" HOT")) } else if ( c <=20){ led.off(); led1.on(); lcd.cursor(0,5).print("Cold"); lcd.bgColor("blue"); publish("Bridge","cupOUT",new Buffer(c+"_c"+"COLD")) } else { led.off(); led1.off(); lcd.cursor(0,5).print("Warm"); lcd.bgColor("green"); } lcd.cursor(0,0).print(c+"*c"); });
gas.on("change", function() { if (this.scaleTo(100,2000) > 300) { led0.on(); lcd.cursor(1,0).print('AL: Beer'); lcd.bgColor("yellow"); } else if (this.scaleTo(100,2000) > 450) { led.blink(500) lcd.cursor(1,0).print('AL: Wine'); lcd.bgColor("purple"); } else { led0.off() lcd.cursor(1,0).print('Normal '); } }); function work(msg, cb) { console.log("Received:", msg.content.toString()); var msgIn = msg.content.toString(); colonIndex = msgIn.indexOf(":"); if (colonIndex>0){ cmdString = msgIn.substr(colonIndex+2, 3); switch(cmdString){ case"OFF": console.log("Command:",cmdString); lcd.off(); break; case"ON": console.log("Command :",cmdString); lcd.on(); break; default: console.log("Received:",cmdString); }
cb(true); } });
start();