西门子(中国)有限公司(SLC)

注册 登录

  签到   每日登录:+1西币 +1经验值我的支持中心

信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。

技术论坛


 WinCC解决方案-短信

返回主题列表
作者 主题
工控界的程序员
游士

经验值: 215
发帖数: 14
精华帖: 0
楼主    2017-11-22 13:55:40
主题:WinCC解决方案-短信 推荐帖

在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脚本、控件、数据采集、存档、报表开发。微信见头像。
工控界的程序员
游士

经验值: 215
发帖数:14
精华帖:0
1楼    2017-11-22 14:00:21
推荐帖  主题:回复:WinCC解决方案-短信

补下中文编码的代码:


    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脚本、控件、数据采集、存档、报表开发。微信见头像。
您收到0封站内信:
×
×