Newer
Older
Correlator / Correlator / Util / MethodExtensions.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using Correlator.Model;
using Correlator.SensorHubTag;
using HandyControl.Controls;
using MathWorks.MATLAB.NET.Arrays;
using NAudio.Wave;
using Tag = Correlator.SensorHubTag.Tag;

namespace Correlator.Util
{
    public static class MethodExtensions
    {
        /// <summary>
        /// Log本地化,并输出在Console,便于Debug
        /// </summary>
        /// <param name="className"></param>
        /// <param name="log"></param>
        public static void WriteLog(this string className, string log)
        {
            Console.WriteLine($@"{className} => {log}");
            LogHelper.Info(log);
        }

        /// <summary>
        /// 计算文件占用空间大小
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string FormatFileSize(this long length)
        {
            var size = (double)length / (1024 * 1024);
            return $"{size:F2}MB";
        }

        /// <summary>
        /// 字节数组转Int
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static int ConvertToInt(this byte[] bytes)
        {
            return bytes.Aggregate(0, (current, b) => 16 * 16 * current + b);
        }

        /// <summary>
        /// 字节数组转String
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        private static string ConvertToString(this byte[] bytes)
        {
            return bytes.Aggregate("", (current, t) => current + t.ToString("X2"));
        }

        /// <summary>
        /// 字符串转byte
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte ConvertToByte(this string str)
        {
            return byte.Parse(str, NumberStyles.HexNumber);
        }

        /// <summary>
        /// 字符串转byte[]
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static byte[] ConvertToByteArray(string str)
        {
            var ret = new byte[str.Length / 2];
            for (var i = 0; i < str.Length / 2; i++)
            {
                ret[i] = byte.Parse(str.Substring(i * 2, 2), NumberStyles.HexNumber);
            }

            return ret;
        }

        public static string AppendLeftZero(this int i)
        {
            //数据固定长度2
            return i.ToString("G").PadLeft(2, '0');
        }

        /// <summary>
        /// 转16进制字符串
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static string ConvertToHexString(this string src)
        {
            if (src.Length == 4)
            {
                return src;
            }

            var temp = "";
            for (var i = 0; i < 4 - src.Length; i++)
            {
                temp += "0";
            }

            return temp + src;
        }

        /// <summary>
        /// 截屏
        /// </summary>
        /// <param name="filePath"></param>
        public static void SnapShot(this string filePath)
        {
            var width = Screen.PrimaryScreen.Bounds.Width;
            var height = Screen.PrimaryScreen.Bounds.Height;
            var memoryImage = new Bitmap(width, height);
            var memoryGraphics = Graphics.FromImage(memoryImage);
            memoryGraphics.CopyFromScreen(0, 0, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy);
            var data = new MemoryStream();
            memoryImage.Save(data, ImageFormat.Png);

            var fs = new FileStream(filePath, FileMode.OpenOrCreate);
            var w = new BinaryWriter(fs);
            w.Write(data.ToArray());
            fs.Close();
            data.Close();

            Growl.Success("快照已保存");
        }

        /// <summary>
        /// 字节数组转数据Tag集合
        /// </summary>
        /// <param name="tagBytes"></param>
        /// <returns></returns>
        public static List<Tag> GetTags(this byte[] tagBytes)
        {
            var tags = new List<Tag>();
            try
            {
                var i = 0;
                // var n = 0;
                while (i < tagBytes.Length)
                {
                    // n++;
                    var oidBytes = new byte[4];
                    Array.Copy(tagBytes, i, oidBytes, 0, 4);
                    var oid = oidBytes.ConvertToString();

                    //value域的长度
                    var tagValueBytes = new byte[2];
                    Array.Copy(tagBytes, i + 4, tagValueBytes, 0, 2);
                    Array.Reverse(tagValueBytes);
                    int tagValueLength = BitConverter.ToInt16(tagValueBytes, 0);
                    // Console.WriteLine($@"value域的长度 => {tagValueLength}");

                    var valueBytes = new byte[tagValueLength];
                    Array.Copy(tagBytes, i + 6, valueBytes, 0, tagValueLength);

                    i = i + 6 + tagValueLength;
                    var tag = TagFactory.Create(oid, tagValueLength, valueBytes);
                    tags.Add(tag);
                }
            }
            catch (Exception e)
            {
                "MethodExtensions".WriteLog($"设备上传协议出错:{e.Message}");
            }

            return tags;
        }

        /// <summary>
        /// 通过Linq查找电量Tag
        /// </summary>
        /// <param name="tags"></param>
        /// <returns></returns>
        public static CellTag GetCellTag(this List<Tag> tags)
        {
            return tags.Where(tag => tag is CellTag).Cast<CellTag>().FirstOrDefault();
        }

        /// <summary>
        /// 通过Linq查找状态Tag
        /// </summary>
        /// <param name="tags"></param>
        /// <returns></returns>
        public static SensorExceptionTag GetSensorExceptionTag(this IEnumerable<Tag> tags)
        {
            return tags.Where(tag => tag is SensorExceptionTag).Cast<SensorExceptionTag>().FirstOrDefault();
        }

        /// <summary>
        /// 十六进制转double
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static double HexToDouble(this IReadOnlyList<byte> src)
        {
            if (src.Count != 3)
                return 0;

            short result1 = src[0];
            short result2 = src[1];
            short result3 = src[2];

            if ((result1 & 0x80) == 0x80)
            {
                result1 = Convert.ToInt16(result1 - 255);
                result2 = Convert.ToInt16(result2 - 255);
                result3 = Convert.ToInt16(result3 - 255);
            }

            var data = (result1 * 65536 + result2 * 256 + result3) * 5 / 83.88607 / 100000;
            return data;
        }

        /// <summary>
        /// 通过Linq查找噪声Tag
        /// </summary>
        /// <param name="tags"></param>
        /// <returns></returns>
        public static UploadTag GetUploadNoiseTag(this IEnumerable<Tag> tags)
        {
            return tags.Where(tag => tag is UploadTag).Cast<UploadTag>().FirstOrDefault();
        }

        /// <summary>
        /// MWNumericArray转double[]
        /// </summary>
        /// <param name="inputMw"></param>
        /// <returns></returns>
        public static double[] GetArray(this MWNumericArray inputMw)
        {
            var num = inputMw.NumberOfElements;
            var outArray = new double[num];
            for (var i = 0; i < num; i++)
            {
                outArray[i] = Convert.ToDouble(inputMw[i + 1].ToString());
            }

            return outArray;
        }

        /// <summary>
        /// 二进制转byte[]
        /// </summary>
        /// <param name="ints"></param>
        /// <returns></returns>
        public static byte[] ToByteArray(this List<int> ints)
        {
            var bitIndex = new List<byte>();
            for (var i = 1; i <= 64; i++)
            {
                bitIndex.Add(ints.Contains(i) ? (byte)0 : (byte)1);
            }

            //每八位为一个字节
            var tempBytes = new List<byte>();
            for (var i = 0; i < bitIndex.Count; i += 8)
            {
                var bytes = new List<byte>
                {
                    bitIndex[i],
                    bitIndex[i + 1],
                    bitIndex[i + 2],
                    bitIndex[i + 3],
                    bitIndex[i + 4],
                    bitIndex[i + 5],
                    bitIndex[i + 6],
                    bitIndex[i + 7]
                };
                var builder = new StringBuilder();
                foreach (var b in bytes)
                {
                    builder.Append(b);
                }

                var binary = builder.ToString();
                //二进制转十进制
                var decimalValue = Convert.ToInt32(binary, 2);
                //十进制转byte,0~255之间的int值才可以,否则需要先转为Hex,再由Hex转为byte[]
                tempBytes.Add(Convert.ToByte(decimalValue));
            }

            return tempBytes.ToArray();
        }

        /// <summary>
        /// 数据类型
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public static string ToChineseType(this int i)
        {
            //1,2,3,4分别代表流量、压力、液位、噪声
            switch (i)
            {
                case 1:
                    return "流量数据";
                case 2:
                    return "压力数据";
                case 3:
                    return "液位数据";
                case 4:
                    return "噪声数据";
                default:
                    return "未知类型数据";
            }
        }

        /// <summary>
        /// 二维集合转为一维数组
        /// </summary>
        /// <param name="doubleArrays">二维集合</param>
        /// <returns></returns>
        public static double[] ToOneDimensionalArray(this List<List<double>> doubleArrays)
        {
            var totalData = new List<double>();
            foreach (var item in doubleArrays)
            {
                totalData.AddRange(item);
            }

            return totalData.ToArray();
        }

        /// <summary>
        /// 保存传感器上传的原始数据
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="response"></param>
        public static void SaveSensorResponse(this string fileName, List<string> response)
        {
            var builder = new StringBuilder();
            for (var i = 0; i < response.Count; i++)
            {
                var str = response[i];
                if (i == response.Count - 1)
                {
                    builder.Append(str);
                }
                else
                {
                    builder.Append(str).Append("\r\n");
                }
            }

            File.AppendAllText(fileName, builder.ToString());
        }

        /// <summary>
        /// 每个音频数据
        /// </summary>
        private static string _perData;

        /// <summary>
        /// 保存听音上传的原始数据
        /// </summary>
        /// <param name="dataArray"></param>
        public static void SaveSoundData(this List<byte[]> dataArray)
        {
            using (var manager = new DataBaseManager())
            {
                var today = DateTime.Now.ToString("yyyyMMdd");
                var configModel = manager
                    .Table<CorrelatorConfigModel>()
                    .Where(x => x.Date == today)
                    .OrderBy(x => x.Date)
                    .LastOrDefault() ?? new CorrelatorConfigModel
                {
                    Date = today,
                    Pipe = 1,
                    LocateTimes = 1,
                    ListenTimes = 1
                };

                //如果配置里面的日期相同,则取配置里面的Pipe作为index,如果配置里面的日期不相同,则默认index=1
                var pipeIndex = configModel.Date.Equals(today) ? configModel.Pipe : 1;
                var listenDataDir = DirectoryManager.GetListenDir();

                var listenTimes = configModel.LocateTimes;
                var fileName = $"{listenDataDir}\\听音数据{today}.{pipeIndex}.{listenTimes}.txt";

                var builder = new StringBuilder();
                for (var i = 0; i < dataArray.Count; i++)
                {
                    _perData = BitConverter.ToString(dataArray[i]);
                    if (i == dataArray.Count - 1)
                    {
                        builder.Append(_perData);
                    }
                    else
                    {
                        builder.Append(_perData).Append("\r\n");
                    }
                }

                File.AppendAllText(fileName, builder.Replace("-", "").ToString());

                //插入新纪录
                configModel.Pipe++;
                configModel.LocateTimes++;
                manager.Insert(configModel);

                //清空缓存
                RuntimeCache.SoundCaches.Clear();
            }
        }

        /// <summary>
        /// 保存定位数据
        /// </summary>
        /// <param name="fileName">完整路径</param>
        /// <param name="it">CorrelatorDataModel</param>
        public static void SaveLocateData(this string fileName, CorrelatorDataModel it)
        {
            var builder = new StringBuilder();
            builder.Append(DateTime.Now.ToString(CultureInfo.InvariantCulture)).Append("\r\n");
            foreach (var d in it.LeftDeviceDataArray)
            {
                builder.Append(d).Append("\r\n");
            }

            builder.Append("===============").Append("\r\n");
            for (var i = 0; i < it.RightDeviceDataArray.Length; i++)
            {
                var d = it.RightDeviceDataArray[i];
                if (i == it.RightDeviceDataArray.Length - 1)
                {
                    builder.Append(d);
                }
                else
                {
                    builder.Append(d).Append("\r\n");
                }
            }

            File.AppendAllText(fileName, builder.ToString());
        }

        /// <summary>
        /// 原始数据转UploadTag
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static UploadTag HandleLocalData(this string data)
        {
            var tempArray = new List<string>();
            for (var i = 0; i < data.Length; i += 2)
            {
                tempArray.Add(data.Substring(i, 2));
            }

            var bytes = new byte[tempArray.Count];
            for (var i = 0; i < tempArray.Count; i++)
            {
                bytes[i] = Convert.ToByte(tempArray[i], 16);
            }

            //测试是否转化成功
            if (!data.Equals(BitConverter.ToString(bytes).Replace("-", "")))
            {
                return null;
            }

            var tagBytes = new byte[bytes.Length - 18];
            Array.Copy(bytes, 16, tagBytes, 0, bytes.Length - 18);
            var tags = tagBytes.GetTags();
            //其实就3个Tag,[CellTag,TimeTag,UploadTag]
            return tags.Where(tag => tag is UploadTag).Cast<UploadTag>().First();
        }

        /// <summary>
        /// 本地数据读取
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static List<string> ReadFromFile(this string filePath)
        {
            var list = new List<string>();
            var streamReader = new StreamReader(filePath);
            string line;
            while ((line = streamReader.ReadLine()) != null)
            {
                list.Add(line);
            }

            streamReader.Close();
            return list;
        }

        /// <summary>
        /// 判断是否是数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsNumber(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }

            var regex = new Regex("^[0-9]*[1-9][0-9]*$");
            return regex.IsMatch(value.Trim());
        }

        /// <summary>
        /// 采用流的方式加载图片资源,防止资源被一直占用
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        public static BitmapImage GetBitmapImage(this string imagePath)
        {
            var bitmap = new BitmapImage();
            if (File.Exists(imagePath))
            {
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                using (Stream ms = new MemoryStream(File.ReadAllBytes(imagePath)))
                {
                    bitmap.StreamSource = ms;
                    bitmap.EndInit();
                    bitmap.Freeze();
                }
            }

            return bitmap;
        }

        /// <summary>
        /// 采用流的方式加载图片资源,防止资源被一直占用
        /// </summary>
        /// <param name="audioPath"></param>
        /// <returns></returns>
        public static string GetAudioDuration(this string audioPath)
        {
            var duration = "--:--";
            if (File.Exists(audioPath))
            {
                using (var reader = new AudioFileReader(audioPath))
                {
                    var timeSpan = reader.TotalTime;
                    duration = timeSpan.ToString(@"mm\:ss");
                }
            }

            return duration;
        }

        /// <summary>
        /// List 转 ObservableCollection
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static ObservableCollection<T> ToObservableCollection<T>(this List<T> list)
        {
            var collection = new ObservableCollection<T>();
            foreach (var t in list)
            {
                collection.Add(t);
            }

            return collection;
        }
    }
}