Showing posts with label email. Show all posts
Showing posts with label email. Show all posts

Monday, April 1, 2019

Something Didn't Work

I am writing about another input node. I have a water softener in my house, it goes with the well, since the water is hard, and there is a bit of iron. Every month or so I need to put about 200lbs of salt in the tank. The tank is large and opaque, so I don't actually end up opening the tank, to check on it as often as I should.

I read a story on hackaday about someone who built a water softener monitor. I thought I could do something similar. I thought I could use a simple HC-SR04 ultrasonic module to measure how far down the salt was from the sensor. Connecting one of these sonar modules is dirt simple, and then enclosing the sensor in a 3D printed box would allow measuring to the salt.




Everything seemed to work, the first month. The device is in the tank, I have a USB charger cable going out the the slot in the tank where the brine flushes, so no real modifications. The sensor box is zip tied to the larger tube in the tank. It measures a distance, that seems consistent even though the surface isn't uniform.

To get familiar with the setup, I had the node email me the measurement every night about 11PM. This seemed to go great. A couple measurements were way out of spec, but mostly it was going down a few centimeters every couple days. The email reminded me to check on the tank a couple times a week. After it got down to a level where I thought I should fill it, I changed the code to only email me when it got more than a few centimeters of that level.

Here is the code for the node:

/** 
 *  Sensor that measures salt level in water softener, and sends result over MQTT (node-red)
 *    Sonar distance measured at regular intervals sent over MQTT.
 *
 * The board selected in the IDE is WeMos D1 R2 & Mini. Standard everything 
 * 
 * 
 * TGB 2/20/19
 */

 
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <PubSubClientTools.h>

// Update these with values suitable for your network.

const char* ssid = "raspi-webgui";
const char* password = "XXXXXXXX";
const char* MQTT_SERVER = "10.3.141.1";

#define echoPin 12 // Echo Pin
#define trigPin 13 // Trigger Pin

WiFiClient espClient;
PubSubClient client(MQTT_SERVER, 1883, espClient);
PubSubClientTools mqtt(client);

long lastMsg = 0;
char msg[50];
int value = 0;
String s = "";

int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup() 
{
  // put your setup code here, to run once:
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();


  // Connect to MQTT
  Serial.print(s+"Connecting to MQTT: "+MQTT_SERVER+" ... ");
  if (client.connect("ESP8266Client")) {
    Serial.println("connected");
  } else {
    Serial.println(s+"failed, rc="+client.state());
  }
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  setup_wifi();
}

void setup_wifi() 
{
  // Connect to WiFi
  Serial.print(s+"Connecting to WiFi: "+ssid+" ");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(s+" connected with IP: "+WiFi.localIP());
   digitalWrite(BUILTIN_LED, HIGH); // turn LED off

  // Connect to MQTT
  Serial.print(s+"Connecting to MQTT: "+MQTT_SERVER+" ... ");
  if (client.connect("SaltReader")) {
    Serial.println("connected");
  } else {
    Serial.println(s+"failed, rc="+client.state());
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("SaltReader")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic","saltReader Restart");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      // Wait 5 seconds before retrying
    }
  }
}


//////////////////////////////////////////////////////////////////////////
////////// Sonar Sample //////////////////////////////////////////////////
long sample() 
{
/* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */ 
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 
 //Calculate the distance (in cm) based on the speed of sound.
 distance = duration/58.2;
 
 if (distance >= maximumRange || distance <= minimumRange)
 {
   /* Send a negative number to computer and Turn LED ON 
   to indicate "out of range" */
   Serial.println("-1");
 }
 else
 {
   /* Send the distance to the computer using Serial protocol, and
   turn LED OFF to indicate successful reading. */
   Serial.println(distance);
 }
 return distance;
}


void publisher() {
  long now = millis();
  if (now - lastMsg > 30000) {  // 30 seconds
    lastMsg = now;
    long distance=sample();
    ++value;
    
    snprintf (msg, 75, "%ld", distance);
    Serial.print("Publish message: ");
    Serial.println(msg);
    mqtt.publish("salt/level", msg);
  }
}

void loop() 
{
  if (!client.connected()) {
    reconnect();
  }
  
  client.loop();
  publisher();
}


This node sends a MQTT message on the "salt/level" topic with the measured distance as the payload. The time in the loop is 30 seconds, so twice a minute this will publish the message. That is all it needs to do.

The flow in Node Red is:



The receiver listens for messages on the "salt/level" topic. The output of that node goes to a debug node, an email formatter function and two dashboard items, slider and text. The email formatter also goes to an email node and another debug node.

The function that formats the email is:


context.saltLevel = 0;

if (msg.topic === 'salt/level') {
  context.saltLevel = msg.payload;
}


if ((context.global.minute == 32) && 
    (context.global.hour == 23) && 
    (context.saltLevel > 30))
{
    msg.payload = "Subject: Salt Level\n salt level "+context.saltLevel;
    return msg;  
}

msg.payload = context.global.hour+":"+context.global.minute 

The node context maintains the current salt level. I have another flow that outputs time, that I promise to show soon. The level is compared to a level of 30 centimeters, and if greater formats the email and sends the mail if the time is 23:32. Since the MQTT message is published every 30 seconds, I usually get 2 emails with the salt level. For me that is fine, it allows cross checking.

For the Dashboard, I have a "Salt Tank" group. This creates a tab just for the salt tank. The tab display is equally simple, and quick to determine the status:


Setting up email


If you want to use the email output node for alerts and such, and you use gmail, I suggest sending from some rarely used email address. Get a sub-gmail address to send from and use that as your send address. For the most part the node is easy to configure.


Gmail is very well protected. Google does a good job of filtering spam both from gmail senders and gmail receivers. To get around some of these protections, you need to turn down the safety of the gmail account that node-red will send from. In advanced settings set the sender to enable less secure access:



What is wrong


The dashboard is showing 38cm of salt. It should be sending email, and it does, every night. The trouble is, the salt tank is still about 1/3 full. Actually, the measurement is no longer consistent. A few times, this sent me email about the level being 109cm, and other times it sends email that the tank is at 77cm.

The basic fault might be that the box is in a high concentration of potentially moist salt dust. I am suspecting some form of corrosion, or possibly something conducting across something it shouldn't be.

Going back to the hackaday example, that person used a LIDAR instead of sonar. Lidar, being optical should allow the sensor box to be sealed, hopefully preventing humid salt from damaging the system.

For now the system mostly works. It is reminding me to look in the tub every few days, and we haven't run out of salt two months in a row.



Friday, October 18, 2013

Some Vendors

A while ago, it was my son's birthday, and I thought I'd get him one of the JXD 7300's. I thought it would be better than the JXD 5110, it is bigger and I thought it would be more useful. I waited too long to order it from China, so I looked for a US vendor. I had no luck finding a US vendor. I thought I might be OK getting it express shipped. 

I ordered it on a Thursday, and paid the extra $30 for 3-5 day shipping. The device arrived 15 days later. The correspondence with the company was challenging. On Sunday they sent me a note:

Since the value for your order is a little expensive, to protect the safe of your paypal account,

we want to confirm some info from you, hope your kindly understanding.
1st,  Could you pls confirm your shipping address whether correct or not

Well I appreciate that they are worried for my safety, but $144 isn't that much, I have spent way more than that on Paypal before. I also realize it is already tomorrow in China, so my Thursday order was really Friday early morning, and the Sunday correspondence was really Monday, but follow along. I did tell them that it was me, and that I thought my Paypal account was verified. I responded on Sunday, which I am sure they got on Tuesday. Their response Monday at 2AM my time was:

May I know when do you expect to receive the parcel? then I will arrange a shipment, since normally we will ship the order within 3-7 working days.

Ok, shouldn't they expect that if I paid for 3 day shipping I might want it really soon? What is there about 3-7 working days before they ship it? Holy cow, it seems really obvious now I am not going to get the thing in time. So I decide to look for a new vendor, maybe someone in the US. I look, and there is a vendor in New Jersey who has 10 of them listed on Ebay. I decide to order the one from ebay, and try to work something out with this Chinese vendor.  

I sent the following message:

I expect to receive the device by Thursday 10/10/2013.

The response I got was:

Hi friend,
Thanks for your email.
I will ask the warehouse to ship it by Thursday, pls wait patiently.
Hope your understanding in advance.

Best regards,

This is almost comical. I want it by Thursday, so they will ship it by Thursday? Maybe they know it is yesterday here in the US, so they can ship it and it will arrive Tomorrow? By now, I've had enough, since this won't make it even the week of my son's birthday, so I am ok with cancelling the order. Remember the first message, they weren't even sure it was me, they ought to be cool with me cancelling the order. I send a note back:

I wanted it at my house on Thursday!

Can we just Cancel this order?

Wow, that seems pretty clear. I am asking, not telling, but I have things arranged, and I no longer want the unit from them. Their response is:

Hi friend,
Even though we ship it yesterday, it is impossible to arrive you in one day. It will usually will take 3-7 working days via DHL.
We will urge the warehouse to ship it in 1 day, is it OK?
Looking forward to your reply.
Best regards,

Did they ship it yesterday? Am I in a time warp? I realize they are adjusting days, and this message I got on Wednesday, I know I don't want it. I did send them a note, that I thought was pretty clear:

If you are going to ship it anyway, then it doesn't matter.

It will be late, and I will just give your company a bad review.
I'd rather you not ship it, refund my money and we both
go away disappointed.

Is this clearer? "I would rather they not ship it and refund my money". I felt that was pretty clear. They did send one more note:

Hi friend,
Thanks for your email.
We will ship it today, pls wait for a while patiently.

It arrived 9 days later. Unbelievable, did they expect me to say good things about them? What do you think, did I miss something? I've bought most of my Arduino stuff from China, and I expect those things to arrive at my house 2-3weeks after I pay for the item. This took 2 weeks using express mail! I don't get it. 

I'll share the vendors name, if you ask.