技术论坛

WinCC解决方案-短信

作者 主题
游士

经验值: 216
发帖数: 14
精华帖: 0
主题:【分享】WinCC解决方案-短信
推荐帖


只看楼主 楼主 2017-11-22 13:55:40

在WINCC组态中,我们有时会遇到需要发送短信的场合

WinCC可以通过VBS脚本写串口通讯利用短信模块发送短信,单存在一些问题

  1. 中文短信乱码,需要重新编码。

  2. 短信频率高的时候会造成UI线程阻塞、卡顿

  3. 访问串口过快会使短信发送不成功。

针对如上问题,我开发了一个WinCC控件,组态时只需将控件放入画面中,在发送短信时调用控件的函数发送;在控件内部使用了多线程、队列,不管短信频率多高都不会影响画面运行,也不会造成串口繁忙而使短信发送失败,支持中文,现将核心代码分享给大家:




在WinCC中添加控件,并根据实际情况设置如下属性:



需要发送短信的时候使用如下脚本:



试用控件地址:

https://www.ad.siemens.com.cn/club/bbs/post.aspx?a_id=1441984&b_id=5&b_sid=&s_id=17&pno=0



承接WinCC脚本、控件、数据采集、存档、报表开发。微信见头像。
分享帖版主置评: 如果你能把你做的控件发上来就更好了。 (推荐人:zhangli0)
以下网友喜欢您的帖子:

  
重要声明:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

帖子链接:https://www.ad.siemens.com.cn/club/bbs/post.aspx?a_id=1438632&b_id=5&s_id=17&num=6

游士

经验值: 216
发帖数: 14
精华帖: 0
回复:WinCC解决方案-短信
推荐帖 推荐帖


只看楼主 楼主 1楼 2017-11-22 14:00:21

补下中文编码的代码:


    public class PDUEncoder

    {

        /// <summary>

        /// 服务中心地址编码(SCA = Service Center Adress)

        /// </summary>

        /// <param name="SCA">服务中心地址</param>

        /// <returns>编码后的字符串</returns>

        /// <remarks>

        /// SCA组成:1~12个八位位组

        /// A:服务中心地址长度,长度1,其值为B+C字节数

        /// B:服务中心地址类型,长度0~1

        /// C:服务中心地址,长度0~10。

        /// </remarks>

        private static string SCAEncoding(string SCA)

        {

            if (string.IsNullOrEmpty(SCA))

            {   // 表示使用SIM卡内部的设置值,该值通过AT+CSCA指令设置

                return "00";

            }


            StringBuilder sb = new StringBuilder(SCA.Length + 5);

            int Index = 0;

            if (SCA.StartsWith("+"))

            {   // 国际号码

                sb.Append((SCA.Length / 2 + 1).ToString("X2"));         // SCA长度编码

                sb.Append("91");    // SCA类型编码

                Index = 1;

            }

            else

            {   // 国内号码

                sb.Append(((SCA.Length + 1) / 2 + 1).ToString("X2"));   // SCA长度编码

                sb.Append("81");    // SCA类型编码

            }


            // SCA地址编码

            for (; Index < SCA.Length; Index += 2)

            {   // 号码部分奇偶位对调

                if (Index == SCA.Length - 1)

                {

                    sb.Append(SCA[Index]);

                }

                else

                {

                    sb.Append(SCA[Index + 1]);

                }

            }


            return sb.ToString();

        }

        /// <summary>

        /// 接收方地址编码

        /// </summary>

        /// <param name="DA">接收方地址</param>

        /// <returns>编码后的字符串</returns>

        /// <remarks>

        /// DA组成:2~12个八位位组

        /// F:地址长度,长度1。注意:其值是接收方地址长度,而非字节数

        /// G:地址类型,长度1,取值同B。

        /// H:地址,长度0~10。

        /// </remarks>

        private static string DAEncoding(string DA)

        {

            if (string.IsNullOrEmpty(DA))

            {   // 地址长度0,地址类型未知

                return "0080";

            }


            StringBuilder sb = new StringBuilder(DA.Length + 5);

            sb.Append("1100");

            int Index = 0;

            if (DA.StartsWith("+"))

            {   // 国际号码

                sb.Append((DA.Length - 1).ToString("X2"));  // 地址长度编码

                sb.Append("91");    // 地址类型

                Index = 1;

            }

            else

            {   // 国内号码

                sb.Append(DA.Length.ToString("X2"));        // 地址长度编码

                sb.Append("81");    // 地址类型

            }


            for (; Index < DA.Length; Index += 2)

            {   // 号码部分奇偶位对调

                if (Index == DA.Length - 1)

                {

                    sb.Append("F");     // 补“F”凑成偶数个

                }

                else

                {

                    sb.Append(DA[Index + 1]);

                    sb.Append(DA[Index]);

                }

            }

            return sb.ToString();

        }


        /// <summary>

        /// 用户数据内容编码

        /// </summary>

        /// <param name="UDC">用户数据内容</param>

        /// <param name="UDCL">输出:UCS2编码字节数或7-Bit编码字符数</param>

        /// <returns>编码字符串</returns>

        private static string UDCEncoding(string UDC, out int UDCL)

        {

            if (string.IsNullOrEmpty(UDC))

            {

                UDCL = 0;

                return string.Empty;

            }


            // UCS2编码

            UDCL = UDC.Length;     // 字节数

            StringBuilder sb = new StringBuilder(UDCL << 1);

            foreach (char Letter in UDC)

            {

                sb.Append(Convert.ToInt32(Letter).ToString("X4"));

            }


            return sb.ToString();

        }

        /// <summary>

        /// 获取PDU

        /// </summary>

        /// <param name="SCA">服务中心地址</param>

        /// <param name="DA">短信发送地址</param>

        /// <param name="msg">短信内容</param>

        /// <param name="DALen">数据长度</param>

        /// <returns></returns>

        public static string GetPDU(string SCA, string DA, string msg,out int DALen)

        {

            string SCAPdu = SCAEncoding(SCA);

            string DAPdu = DAEncoding(DA);

            int len = 0;

            string UDCPdu = UDCEncoding(msg, out len);


            StringBuilder sb = new StringBuilder();

            sb.Append(SCAPdu).Append(DAPdu).Append(len.ToString("X2")).Append(UDCPdu);

            DALen = (sb.Length - SCAPdu.Length) / 2;

            return sb.ToString();

        }

    }



承接WinCC脚本、控件、数据采集、存档、报表开发。微信见头像。
推荐帖推荐理由: 代码体现解决问题的思路 (推荐人:'Razor)
以下网友喜欢您的帖子:

  
侠圣

经验值: 3434
发帖数: 211
精华帖: 4
回复:WinCC解决方案-短信
推荐帖


只看楼主 2楼 2017-11-22 17:32:02

赞成版主的说法,能把控件上传上来就牛逼了!



哈哈哈哈,人生不如意事,十有七八,能与人诉之一二。
以下网友喜欢您的帖子:

  
版主

经验值: 43582
发帖数: 15779
精华帖: 61
回复:WinCC解决方案-短信
推荐帖


只看楼主 3楼 2017-11-22 21:40:08

楼主,你的这个代码是写在哪里才可以呢?c?vs?wincc的c脚本?还是其他的什么?


活到老,学到老!为了生活学习吧!
以下网友喜欢您的帖子:

  
至圣

经验值: 18061
发帖数: 1524
精华帖: 2
回复:WinCC解决方案-短信


只看楼主 4楼 2017-11-23 09:07:25

写的wincc的全局脚本吗?


我回来了!继续努力!
以下网友喜欢您的帖子:

  
游士

经验值: 216
发帖数: 14
精华帖: 0
回复:WinCC解决方案-短信


只看楼主 楼主 5楼 2017-11-23 10:32:44
以下是引用zhangli0在2017-11-22 21:40:08的发言 >3楼

楼主,你的这个代码是写在哪里才可以呢?c?vs?wincc的c脚本?还是其他的什么?

你好,代码用C#封装成控件就可以了。在WinCC里面只需要一条VBS脚本调用就可以。


承接WinCC脚本、控件、数据采集、存档、报表开发。微信见头像。
以下网友喜欢您的帖子:

  
游士

经验值: 216
发帖数: 14
精华帖: 0
回复:WinCC解决方案-短信


只看楼主 楼主 6楼 2017-11-23 10:33:17
以下是引用yecao2006在2017-11-23 09:07:25的发言 >4楼

写的wincc的全局脚本吗?

你好,代码用C#封装成控件就可以了。在WinCC里面只需要一条VBS脚本调用就可以。WinCC没法做这么复杂的程序的。


承接WinCC脚本、控件、数据采集、存档、报表开发。微信见头像。
以下网友喜欢您的帖子:

  
侠圣

经验值: 3893
发帖数: 236
精华帖: 1
回复:WinCC解决方案-短信


只看楼主 7楼 2017-11-23 14:48:42

有意思,我也试试!


Stay Hungry ,Stay Foolish .
以下网友喜欢您的帖子:

  
游士

经验值: 216
发帖数: 14
精华帖: 0
回复:WinCC解决方案-短信


只看楼主 楼主 8楼 2017-11-23 16:07:06
以下是引用West Door在2017-11-23 14:48:42的发言 >7楼

有意思,我也试试!

欢迎探讨~


承接WinCC脚本、控件、数据采集、存档、报表开发。微信见头像。
以下网友喜欢您的帖子:

  
侠圣

经验值: 3756
发帖数: 416
精华帖: 0
回复:WinCC解决方案-短信


只看楼主 9楼 2017-12-27 18:21:28


强帖必须得火啊!


继续努力!
以下网友喜欢您的帖子:

  
侠圣

经验值: 2461
发帖数: 227
精华帖: 0
回复:WinCC解决方案-短信


只看楼主 10楼 2017-12-29 14:55:12


厉害了伙计


 
以下网友喜欢您的帖子:

  
  • 上一页
  • 1
  • 下一页
收起
WinCC解决方案-短信
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。