This got covered over in a post in the ‘Applications’ forum, but I felt it worth putting in here as well.
While the scratchpad is the main way to send an email from a PAC Controller, its not the only way…
There is another;
Use a chart to talk to your email server.
This is pretty powerful as we are all very used to working in charts and they are nice and easy to debug.
Here is some code that we have been working with on and off for a little while.
It works well, we have had a few users get it up and running, but I, nor PSG, cant support it, that said, if you need to send an email from a controller, and you have a little time, its probably worth you trying it.
Here is what the basic chart structure looks like;
As you can see, we simply check for an alarm (or an analog condition, or a variable going true or false or a…).
If its true, we check to see if we have sent an email once already. If not (as is the case the first time around), then send an email and set a variable true so that next time around, when the point is still on, the variable says, ‘hey, we have already sent one email, don’t send another’. (This is really really really important, you don’t want to send 1000’s of emails just because the point is still on… (Ask me how I know this…)
To send the email, we first load up a few addresses, here is whats in that block (#209 in the screen shot);
email servers IP address. Change to match yours.
Move String
From: 192.168.1.1
To: email_server_ip_address_string
Who the message is from:
Move String
From: someone@domain.com
To: email_from_address_string
who you are sending the email to:
Move String
From: mrsmith@domain.com.au
To: email_to_address_string
subject:
Move String
From: email subject for alarm 1
To: email_subject_string
body:
Move String
From: Email from a chart… How cool is that??
To: email_body_string
This is a very important step, it prevents you from sending 1000+ emails while the alarm point is in alarm. The email chart will set the flag true once the email has been sent, the user sets it false when the alarm is not longer active.
Move to Pointer
Object: email_alarm_1_sent_flag
Pointer: email_complete_ptr
Thats a cut and past from block ‘load message’. You can see the comments from each instruction. Yes, you could change it to an OptoScript block.
Now, the good stuff…
Here is the code that is in the OptoScript block (#198), the stuff that does all the talking to your email server…
email_status_string = "";
email_status_ok_continue_flag = 1; // set email_status_ok_continue_flag to true
email_temp_string = "tcp:" + email_server_ip_address_string + ":25";
SetCommunicationHandleValue(email_temp_string, email_server_com_handle);
email_status_flag = OpenOutgoingCommunication(email_server_com_handle);
email_server_delay = 0; // initialize the counter
repeat
DelayMSec(100); // do a little loop waiting for the email server to answer our request.
email_server_delay = email_server_delay + 1; // increment the counter
until (email_server_delay >= 100) or (GetNumCharsWaiting(email_server_com_handle) > 0); // Either time out or the email server will answer.
// Check the connection and receive the greeting
if (0 == email_status_flag) then
email_status_ok_continue_flag = 0; // assume an error
if (GetNumCharsWaiting(email_server_com_handle) > 0) then
DelayMSec(delay_short);
email_status_flag = ReceiveString(email_temp_string, email_server_com_handle);
if (0 == email_status_flag) then
if (FindSubstringInString("220", 0, email_temp_string) >= 0) then
email_status_ok_continue_flag = 1;
else
email_status_string = email_temp_string;
endif
endif
else
email_status_string = "Unable to connect to email server";
endif
else
email_status_string = "Unable to connect to email server";
endif
// Send Greeting
if (email_status_ok_continue_flag) then
GetControlEngineAddress(email_temp_string);
email_send_string = "HELO " + email_temp_string + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 == email_status_flag) then
if (GetNumCharsWaiting(email_server_com_handle) > 0) then
email_status_flag = ReceiveString(email_temp_string, email_server_com_handle);
if (0 == email_status_flag) then
if (FindSubstringInString("250", 0, email_temp_string) >= 0) then
email_status_ok_continue_flag = 1;
else
email_status_string = email_temp_string;
endif
endif
endif
endif
endif
// Send MAIL FROM
if (email_status_ok_continue_flag) then
email_status_ok_continue_flag = 0; // assume an error
email_send_string = "MAIL FROM:" + email_from_address_string + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 == email_status_flag) then
if (GetNumCharsWaiting(email_server_com_handle) > 0) then
email_status_flag = ReceiveString(email_temp_string, email_server_com_handle);
if (0 == email_status_flag) then
if (FindSubstringInString("250", 0, email_temp_string) >= 0) then
email_status_ok_continue_flag = 1;
else
email_status_string = email_temp_string;
endif
endif
endif
endif
endif
// Send RCPT TO:
if (email_status_ok_continue_flag) then
email_status_ok_continue_flag = 0; // assume an error
email_send_string = "RCPT TO:" + email_to_address_string + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 == email_status_flag) then
if (GetNumCharsWaiting(email_server_com_handle) > 0) then
email_status_flag = ReceiveString(email_temp_string, email_server_com_handle);
if (0 == email_status_flag) then
if (FindSubstringInString("250", 0, email_temp_string) >= 0) then
email_status_ok_continue_flag = 1;
else
email_status_string = email_temp_string;
endif
endif
endif
endif
endif
// Send DATA
if (email_status_ok_continue_flag) then
email_status_ok_continue_flag = 0; // assume an error
email_send_string = "DATA" + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 == email_status_flag) then
if (GetNumCharsWaiting(email_server_com_handle) > 0) then
email_status_flag = ReceiveString(email_temp_string, email_server_com_handle);
if (0 == email_status_flag) then
if (FindSubstringInString("354", 0, email_temp_string) >= 0) then
email_status_ok_continue_flag = 1;
else
email_status_string = email_temp_string;
endif
endif
endif
endif
endif
// Send Subject, To, From, etc.
if (email_status_ok_continue_flag) then
email_send_string = "Subject:" + email_subject_string + Chr(13) + Chr(10) +
"To:" + email_to_address_string + Chr(13) + Chr(10) +
"From:" + email_from_address_string + Chr(13) + Chr(10) + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 <> email_status_flag) then
email_status_ok_continue_flag = 0;
endif
endif
// Send Subject, To, From, etc.
if (email_status_ok_continue_flag) then
email_send_string = email_body_string + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 <> email_status_flag) then
email_status_ok_continue_flag = 0;
endif
endif
// Send end of data
if (email_status_ok_continue_flag) then
email_status_ok_continue_flag = 0; // assume an error
email_send_string = Chr(13) + Chr(10) + Chr(46) + Chr(13) + Chr(10);
email_status_flag = TransmitString(email_send_string, email_server_com_handle);
if (0 == email_status_flag) then
if (GetNumCharsWaiting(email_server_com_handle) > 0) then
email_status_flag = ReceiveString(email_temp_string, email_server_com_handle);
if (0 == email_status_flag) then
if (FindSubstringInString("250", 0, email_temp_string) >= 0) then
email_status_ok_continue_flag = 1;
else
email_status_string = email_temp_string;
endif
endif
endif
endif
endif
if (email_status_ok_continue_flag) then
email_status_string = "Message Sent";
SetVariableTrue(*email_complete_ptr);
endif
CloseCommunication(email_server_com_handle);
That should get you up and running.
The nice thing about sending email from a chart using this code is that it can be sent from FactoryFloor controllers or newer.
There is one major ‘got-ya’ for any method (mem map or chart) that you might chose to use when sending emails from the controller with firmware versions less than v9.1…
There is no way to enter a user name or password to authenticate with the email server.
If you are on a company network with its own email server, you might need to talk with the IT guys and get them to whitelist the IP address of the controller sending the email. This means that they allow that IP address to relay emails from the controller without authentication.
If your controller is not on the same domain as the email server, and you want to use one out on the web, like yahoo or gmail, then there is only one thing I can suggest…
Subscribe to ‘OptoNews’ and wait… We might, just maybe, perhaps, have a solution to this authentication issue (and more) in the works…
In the mean time… Code on!