1. Overview
WinCC Flexible (2008 SP5 and earlier runtime suites, superseded by TIA Portal WinCC) exposes a single "Send Email" scripting function that accepts exactly one recipient string per call. Engineers who need notification distribution to operators, supervisors, and on-call rotation lists must therefore wrap the function in a loop, while engineers who need to change the recipient at runtime (e.g., shift handover) must bind an internal string tag to an I/O field. This reference covers both patterns, the alarm-event trigger that is the most common use case, and the tag-change trigger that supports polling or condition-based dispatch.
The technique below works for:
- WinCC Flexible 2008 SP2 / SP3 / SP4 / SP5
- Panels: OP 177B, TP 177B, MP 177, MP 277, MP 377, Comfort Panels (legacy project ported forward)
- PC Runtime: WinCC Flexible RT 2008
- Connection to an SMTP relay (no direct authenticated SMTP in legacy WinCC Flexible)
2. Prerequisites
| Item | Specification | Notes |
|---|---|---|
| WinCC Flexible ES | 2008 SP2 or newer | SP5 recommended for ES, SP3+ for RT stability |
| Panel firmware | Match the ES project version | Mismatched versions cause "Send Email" runtime errors |
| SMTP relay | Internal relay, no auth, port 25 | Examples: IIS SMTP, Postfix with mynetworks, hMailServer |
| Network reachability | Panel IP must reach relay on TCP/25 | Verify with ping and telnet from a service laptop |
| Licensing | WinCC Flexible RT license on PC runtime | Panel firmware has the function natively |
| Free string tag | WString 255 char minimum | Used to hold the runtime-editable address |
3. SMTP Relay Configuration
Before any "Send Email" call will succeed, the panel must be able to reach an SMTP server that accepts unauthenticated messages from its IP address. Confirm three things in this order:
- DNS resolution if you use a hostname. Panels without proper DNS configuration often fail silently. Configure the SMTP server's IP address directly in the script to eliminate this variable.
- Firewall open TCP/25 from panel IP to relay IP in both directions (some relays respond on high ports for DSN).
-
Relay trust list includes the panel IP. On Postfix:
mynetworks = 127.0.0.0/8 192.168.10.0/24and on IIS SMTP add the panel IP to the relay restrictions whitelist.
4. The Send Email Function
The legacy scripting signature is exposed in VBScript under HMIRuntime:
HMIRuntime.SmartMail "smtp.server.local", 25, "[email protected]", "[email protected]", "Subject", "Body text", False, 0
| Parameter | Type | Description |
|---|---|---|
| SmtpServer | String | Hostname or IP of the relay |
| Port | Long | Typically 25 (no auth) or 587 with relay that accepts no auth on submission |
| Sender | String | From address; many relays rewrite this |
| Recipient | String | One address only per call |
| Subject | String | Plain text, no MIME encoding support |
| Body | String | Plain text; newline = Chr(13) & Chr(10) |
| Attachment | Boolean | False on most panels; True only on PC Runtime with file path |
| Encoding | Long | 0 = 7-bit ASCII, 1 = 8-bit; avoid non-ASCII in subjects |
5. Triggering Email on Alarm Events
WinCC Flexible exposes three event hooks on the Alarm View control. The most useful for notification dispatch is Activate (triggered when the operator opens the alarm screen) or, more reliably, a custom button placed on the alarm screen that calls the script. For purely automatic dispatch, use the Tag Change approach in section 6.
To bind the script to alarm view activation:
- Open the project in WinCC Flexible ES.
- Navigate to the screen containing the Alarm View.
- Right-click the Alarm View, select Properties > Events.
- Under Activate, click the right column to open the function list.
- Select Call Script and pick the VBScript you created in section 9.
This fires the script every time the operator brings the alarm screen to the front, which is useful for "email me the current active alarms" workflows.
6. Triggering Email on Tag Value Change
For event-driven dispatch (the most common requirement: "send mail when alarm tag rises"), use the Change Value event on an internal Boolean tag that you set from the alarm bit:
- Create a new internal tag
EmailTriggerof type Bool. - In the HMI tag connection, drive it from the PLC's alarm bit using a tag-side script or a direct pointer where the panel is the polling master.
- Open Tag Properties > Events > Change Value on
EmailTrigger. - Add a VBScript call that inspects the tag's new value and only sends on the rising edge.
The rising-edge guard prevents flood when the PLC keeps the alarm bit high:
If SmartTags("EmailTrigger") = True Then
' rising edge: send
HMIRuntime.SmartMail "192.168.10.5", 25, "[email protected]", _
SmartTags("MailTo"), _
"Alarm: " & SmartTags("AlarmText"), _
"Tag: " & SmartTags("AlarmTagName") & vbCrLf & _
"Time: " & Time & " Date: " & Date, _
False, 0
SmartTags("EmailTrigger") = False ' clear for next edge
End If
7. Sending to Multiple Recipients
The single-recipient signature cannot accept a comma-separated list. Wrap calls in a loop, with the recipient list declared as a VBScript array or parsed from an internal string tag using a delimiter such as ; (semicolons avoid the comma ambiguity in CSV exports).
Dim recipients, i
recipients = Split(SmartTags("MailTo"), ";")
For i = LBound(recipients) To UBound(recipients)
Dim addr
addr = Trim(recipients(i))
If Len(addr) > 0 Then
HMIRuntime.SmartMail "192.168.10.5", 25, "[email protected]", _
addr, _
"Alarm: " & SmartTags("AlarmText"), _
"Body line 1" & vbCrLf & "Body line 2", _
False, 0
End If
Next
Keep the array length bounded; many panels queue SMTP work synchronously and a 20-recipient flood on a busy MP 277 will block the alarm screen for 4-6 seconds. Use 5-8 recipients maximum, or stagger the loop with a counter tag and a cyclical trigger.
8. Dynamic Recipients with an Internal Tag
Bind a WString tag (255 char) to an I/O field on the settings screen. Operators edit the list at runtime; the script reads the tag at trigger time, so the list changes without an ES recompile.
- Create tag
MailToas WString, length 255. - On the Settings screen, drop an I/O field, set Process to
MailTo, set Field type to String, untick Hidden input. - Document the format in a label:
[email protected]; [email protected]. - Validate the tag on change (optional) to reject addresses without
@.
Validation example attached to the Change Value event of MailTo:
Dim s, p
s = SmartTags("MailTo")
p = InStr(s, "@")
If p = 0 Then
SmartTags("MailToStatus") = "Invalid: missing @"
SmartTags("MailToValid") = False
Else
SmartTags("MailToStatus") = "OK"
SmartTags("MailToValid") = True
End If
9. Complete Script: Alarm-Triggered Multi-Recipient Dispatch
Combine all three patterns. Save as SendAlarmMail.vbs in the project's Scripts folder.
' --- SendAlarmMail.vbs ---
' Trigger: Tag "EmailTrigger" Change Value
' Reads: MailTo (WString 255), AlarmText (WString 64), AlarmTagName (String 32)
Const SMTP_HOST = "192.168.10.5"
Const SMTP_PORT = 25
Const MAIL_FROM = "[email protected]"
If Not SmartTags("EmailTrigger") Then Exit Sub
If Not SmartTags("MailToValid") Then
HMIRuntime.Trace "Mail dispatch aborted: recipient list invalid"
Exit Sub
End If
Dim list, i, addr, subject, body
list = Split(SmartTags("MailTo"), ";")
subject = "PLANT ALARM: " & SmartTags("AlarmText")
body = "Tag: " & SmartTags("AlarmTagName") & vbCrLf & _
"Time: " & FormatDateTime(Now, vbShortTime) & vbCrLf & _
"Date: " & FormatDateTime(Now, vbShortDate) & vbCrLf & _
"PLC: " & SmartTags("PlcName")
For i = LBound(list) To UBound(list)
addr = Trim(list(i))
If Len(addr) > 0 And InStr(addr, "@") > 0 Then
On Error Resume Next
HMIRuntime.SmartMail SMTP_HOST, SMTP_PORT, MAIL_FROM, _
addr, subject, body, False, 0
If Err.Number <> 0 Then
HMIRuntime.Trace "SMTP error to " & addr & ": " & Err.Description
Err.Clear
End If
On Error Goto 0
End If
Next
SmartTags("EmailTrigger") = False
SmartTags("LastDispatchCount") = SmartTags("LastDispatchCount") + 1
10. Verification Procedure
- Compile and transfer the project to the panel. WinCC Flexible ES > Project > Compiler > All (no errors).
- Start Runtime on the panel.
- Force the alarm tag from the PLC or simulator. The EmailTrigger must transition False → True.
-
Check the relay log: Postfix logs at
/var/log/maillog; IIS SMTP drops messages intoC:\inetpub\mailroot\Queueif delivery fails. - Check the inbox of the test recipient. Subject line and body should match the script's concatenation.
-
Check the panel trace: WinCC Flexible ES > Tools > Trace > Live view, or via ProSave > Diagnostics.
HMIRuntime.Tracelines appear with timestamp.
11. Troubleshooting Matrix
| Symptom | Likely Root Cause | Diagnostic | Fix |
|---|---|---|---|
| Mail silently never arrives | Panel cannot reach SMTP relay | telnet 192.168.10.5 25 from service laptop on same subnet | Open firewall TCP/25; add IP to relay trust list |
| Relay logs "Relay access denied" | Panel IP not in mynetworks / not whitelisted | Inspect relay log source IP | Add panel IP to Postfix mynetworks or IIS relay restrictions |
| Trace shows "SMTP error -1" | DNS resolution failure on hostname | Set SMTP host to IP, not hostname, retest | Replace hostname with literal IP in script constant |
| Body text contains ???? in place of accented characters | Encoding flag set to 0 (7-bit) and non-ASCII subject | Check subject for ö, á, etc. | Set encoding to 1 or strip non-ASCII from subject |
| Script runs but only first recipient gets mail | Error 0x80004005 mid-loop stops iteration | Trace each iteration | Wrap each call in On Error Resume Next as shown in section 9 |
| Alarm floods mail server | No rising-edge guard; trigger is level-based | Count messages in relay log vs alarm count | Reset trigger to False in the same script that sends |
| "Object doesn't support this property" on HMIRuntime.SmartMail | Wrong function name (was SmartMail in legacy, renamed in TIA) | Confirm ES version | Use HMIRuntime.SmartMail for WinCC Flexible; HMIRuntime.UI.RTMessage patterns differ in TIA WinCC Unified |
| Mail works on PC Runtime, fails on panel | Panel firmware older than ES project | ProSave > Device information > Firmware | Update panel firmware to match ES version (SP3 ↔ SP3, etc.) |
| Subject truncated at ~32 chars | MP 277 firmware bug pre-SP3 | Test with short subject | Upgrade panel firmware to SP3 or later |
12. Migration to TIA Portal / WinCC Unified
WinCC Flexible reached end of life with the 2008 SP5 update. New projects should target TIA Portal V17+ with WinCC Unified or Comfort Panels (which use the modern TIA runtime). The newer runtime offers authenticated SMTP, TLS, and HTML bodies. The pattern maps as follows:
| WinCC Flexible | TIA Portal WinCC Unified / Comfort |
|---|---|
| HMIRuntime.SmartMail | Mail.Send via mail provider configuration |
| Unauthenticated port 25 | TLS on 587 with credentials |
| Plain text body | HTML or plain text |
| VBScript only | VB and C# scripting |
| Single tag, no central config | Mail provider object in project tree |
Engineers maintaining legacy fleets can keep the patterns above indefinitely; the SMTP relay + VBScript combination remains the lowest-friction way to add multi-recipient email to a WinCC Flexible system without ES-side upgrades.
13. Field-Commissioning Checklist
- Confirm panel IP is static and documented.
- Confirm SMTP relay is on a UPS-protected power feed.
- Confirm relay has 7-30 days of disk space for the queue.
- Bind the trigger tag to a PLC tag that does not chatter (debounce 500 ms minimum).
- Add a "Test Mail" button on the settings screen that calls the script with a fixed subject and a known good recipient.
- Log every dispatch with
HMIRuntime.Traceand mirror to an audit tag readable via ProSave. - Schedule a quarterly test that forces a known alarm and verifies mail arrival within 60 seconds.
How do I send an email to more than one recipient from WinCC Flexible?
Call HMIRuntime.SmartMail once per recipient inside a VBScript For loop. Parse a ;-delimited string from an internal WString tag named MailTo using Split(), then dispatch a separate message to each parsed address. Loop size should stay under 8 recipients to avoid blocking the alarm screen.
Can the operator change the email recipient at runtime?
Yes. Create an internal WString tag (length 255) and bind it to an I/O field on a settings screen with field type "String". Operators enter the recipient list at runtime; the script reads the tag value at trigger time, so no ES recompile is required.
How do I trigger the email script when an alarm occurs?
Use the "Change Value" event of an internal Bool tag (e.g., EmailTrigger) that mirrors the alarm bit. In the script, check that the new value is True (rising edge), send the mail, and reset the trigger to False to prevent flooding. This is more reliable than binding directly to the Alarm View Activate event.
Does WinCC Flexible support authenticated SMTP or TLS?
No. The legacy HMIRuntime.SmartMail function only supports unauthenticated SMTP on port 25. Deploy an internal SMTP relay (Postfix, IIS SMTP, hMailServer) that accepts mail from the panel's IP without credentials. For authenticated/TLS email, migrate the panel firmware and project to TIA Portal V17+ Comfort Panels or WinCC Unified.
Why does the script run on PC Runtime but not on the panel?
Most often a firmware version mismatch between the project (compiled in ES) and the panel's runtime. Match them exactly (e.g., ES SP3 ↔ Panel SP3). Use ProSave to read the panel's firmware version under Device Information. The second most common cause is the SMTP relay firewall blocking the panel's IP specifically while allowing the service laptop.