@@ -56,6 +56,9 @@ namespace BPASmartClient.Business | |||
new OrderStatusChangedEvent() { SortNum = mork.SortNum.ToString(), Status = ORDER_STATUS.COMPLETED_COOK, SubOrderId = mork.SuborderId, GoodName = mork.GoodsName }.Publish(); | |||
Thread.Sleep(5000); | |||
new OrderStatusChangedEvent() { SortNum = mork.SortNum.ToString(), Status = ORDER_STATUS.COMPLETED_TAKE, SubOrderId = mork.SuborderId, GoodName = mork.GoodsName }.Publish(); | |||
string num = mork.SortNum.ToString().Substring(0, mork.SortNum.ToString().Length - 1); | |||
if (int.TryParse(num, out int sort)) | |||
ActionManage.GetInstance.Send("COMPLETED_TAKE_Notify", sort.ToString("0000")); | |||
Thread.Sleep(2000); | |||
} | |||
} | |||
@@ -114,7 +117,8 @@ namespace BPASmartClient.Business | |||
else if (message is StirFryPushMessage frybom) | |||
{ | |||
IDevice device = deviceMgr.GetDevices().FirstOrDefault(x => x.DeviceId == 28); | |||
new StirFryGoodsEvent() { | |||
new StirFryGoodsEvent() | |||
{ | |||
DeviceId = device.DeviceId, | |||
stirFrymessage = frybom | |||
}.Publish(); | |||
@@ -266,8 +266,20 @@ | |||
<None Remove="Image\顶部线条.png" /> | |||
<None Remove="Image\顶部背景.png" /> | |||
<None Remove="Image\黑菠萝科技.png" /> | |||
<None Remove="Vioce\0.wav" /> | |||
<None Remove="Vioce\1.wav" /> | |||
<None Remove="Vioce\2.wav" /> | |||
<None Remove="Vioce\3.wav" /> | |||
<None Remove="Vioce\4.wav" /> | |||
<None Remove="Vioce\5.wav" /> | |||
<None Remove="Vioce\6.wav" /> | |||
<None Remove="Vioce\7.wav" /> | |||
<None Remove="Vioce\8.wav" /> | |||
<None Remove="Vioce\9.wav" /> | |||
<None Remove="Vioce\取餐通知.wav" /> | |||
<None Remove="Vioce\号用户取餐.wav" /> | |||
<None Remove="Vioce\电子提示音.wav" /> | |||
<None Remove="Vioce\请.wav" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
@@ -550,6 +562,42 @@ | |||
<Resource Include="Image\顶部线条.png" /> | |||
<Resource Include="Image\顶部背景.png" /> | |||
<Resource Include="Image\黑菠萝科技.png" /> | |||
<EmbeddedResource Include="Vioce\0.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\1.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\2.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\3.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\4.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\5.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\6.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\7.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\8.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\9.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\号用户取餐.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
<EmbeddedResource Include="Vioce\请.wav"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
@@ -0,0 +1,90 @@ | |||
using BPASmartClient.Message; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.CustomResource | |||
{ | |||
public class VoiceAPI | |||
{ | |||
public VoiceAPI() | |||
{ | |||
} | |||
static VoiceAPI() | |||
{ | |||
BPA.Helper.ThreadManage.GetInstance().StartLong(new Action(() => | |||
{ | |||
while (msg.Count > 0) | |||
{ | |||
if (msg.TryDequeue(out string str)) | |||
{ | |||
WaitMeaLSpeak(str); | |||
} | |||
} | |||
Thread.Sleep(1000); | |||
}), "语音播报", true); | |||
} | |||
[DllImport("winmm.dll")] | |||
public static extern bool PlaySound(string pszSound, int hmod, int fdwSound); | |||
private static ConcurrentQueue<string> msg { get; set; } = new ConcurrentQueue<string>(); | |||
public static void Speak(string s) | |||
{ | |||
if (int.TryParse(s.Substring(0, s.Length - 1), out int num)) | |||
msg.Enqueue(num.ToString("0000")); | |||
} | |||
// 系统播放wav格式的文件 | |||
private static void m_SystemPlayWav(string strPlayFile) | |||
{ | |||
try | |||
{ | |||
if (strPlayFile.Trim() == "") | |||
{ return; }//为空不放 | |||
string strPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; | |||
strPath = strPath + strPlayFile; | |||
int SND_FILENAME = 0x00020000; | |||
int SND_ASYNC = 0x0001; | |||
PlaySound(strPath, 0, SND_ASYNC | SND_FILENAME);//播放音乐 | |||
} | |||
catch (Exception ex) | |||
{ | |||
MessageLog.GetInstance.ShowEx(ex.Message); | |||
} | |||
} | |||
private static void WaitMeaLSpeak(string meal, int count = 1, int IntervalTime = 1000) | |||
{ | |||
m_SystemPlayWav(@"Vioce\电子提示音.wav"); | |||
Thread.Sleep(1000); | |||
for (int m = 0; m < count; m++) | |||
{ | |||
m_SystemPlayWav(@"Vioce\请.wav"); | |||
Thread.Sleep(500); | |||
for (int i = 0; i < meal.Length; i++) | |||
{ | |||
string name = meal.Substring(i, 1); | |||
m_SystemPlayWav($"Vioce\\{name}.wav"); | |||
Thread.Sleep(500); | |||
} | |||
m_SystemPlayWav(@"Vioce\号用户取餐.wav"); | |||
Thread.Sleep(1500 + IntervalTime); | |||
} | |||
} | |||
} | |||
} |
@@ -8,6 +8,7 @@ | |||
<ItemGroup> | |||
<PackageReference Include="BPA.Message" Version="1.0.86" /> | |||
<PackageReference Include="Microsoft.CognitiveServices.Speech" Version="1.27.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
@@ -0,0 +1,72 @@ | |||
using Microsoft.CognitiveServices.Speech; | |||
using Microsoft.CognitiveServices.Speech.Audio; | |||
using System; | |||
using System.Runtime.InteropServices; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.IO; | |||
using System.Diagnostics; | |||
namespace BPASmartClient.Device | |||
{ | |||
public class Speech | |||
{ | |||
public static uint SND_ASYNC = 0x0001; | |||
public static uint SND_FILENAME = 0x0002; | |||
[DllImport("winmm.dll", CharSet = CharSet.Auto)] | |||
public static extern int mciSendString(string m_strCmd, string m_strReceive, int m_v1, int m_v2); | |||
[DllImport("Kernel32", CharSet = CharSet.Auto)] | |||
public static extern Int32 GetShortPathName(string path, StringBuilder shortPath, Int32 shortPathLength); | |||
private volatile static Speech _Instance; | |||
public static Speech GetInstance => _Instance ?? (_Instance = new Speech()); | |||
private Speech() { } | |||
/// <summary> | |||
/// 播放语音 | |||
/// </summary> | |||
/// <param name="SpeakText"></param> | |||
public void Speak(string SpeakText) | |||
{ | |||
string path = $"{AppDomain.CurrentDomain.BaseDirectory}Sound";//设置音频文件保存路径 | |||
Directory.CreateDirectory(path); | |||
string SpeakPath = $"{path}\\{SpeakText}.wav"; | |||
SpeakPath = SpeakPath.Replace(' ', '_'); | |||
if (!File.Exists(SpeakPath)) | |||
{ | |||
var res = SynthesizeAudioAsync(SpeakText, SpeakPath); | |||
} | |||
StringBuilder shortPath = new StringBuilder(200); | |||
int result = GetShortPathName(SpeakPath, shortPath, shortPath.Capacity); | |||
string shortName = shortPath.ToString(); | |||
mciSendString(@"close all", null, 0, 0); | |||
mciSendString(@"open " + shortName + " alias song", null, 0, 0); | |||
mciSendString(@"play song", null, 0, 0); | |||
//return "22"; | |||
} | |||
/// <summary> | |||
/// 文字转音频 | |||
/// </summary> | |||
/// <param name="text"></param> | |||
/// <returns></returns> | |||
private string SynthesizeAudioAsync(string text, string path) | |||
{ | |||
var config = SpeechConfig.FromSubscription("b88f6907c8f64075a6169dc4d7dff65a", "chinanorth2"); | |||
config.SpeechSynthesisLanguage = "zh-CN"; //config.SpeechSynthesisVoiceName = ""; | |||
using var audioConfig = AudioConfig.FromWavFileOutput(path); | |||
using var synthesizer = new SpeechSynthesizer(config, audioConfig); | |||
synthesizer.SpeakTextAsync(text).Wait(); | |||
//await Task.Delay(TimeSpan.FromSeconds(2)); | |||
return "1"; | |||
} | |||
} | |||
} |
@@ -23,6 +23,7 @@ using BPA.Models; | |||
using System.Speech.Synthesis; | |||
using System.Windows.Forms; | |||
using System.Media; | |||
using BPASmartClient.CustomResource; | |||
namespace BPASmartClient.MorkS | |||
{ | |||
@@ -317,65 +318,73 @@ namespace BPASmartClient.MorkS | |||
{ | |||
EventBus.EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle) | |||
{ | |||
if (@event == null) return; | |||
if (@event is DoOrderEvent order) | |||
{ | |||
mORKS.doOrderEvents.Add(order); | |||
if (order.MorkOrder.GoodBatchings == null) return; | |||
if (mORKS.HistorySuborderId.Contains(order.MorkOrder.SuborderId)) return; | |||
OrderCount++; | |||
if (DateTime.Now.Subtract(Json<OrderStatistics>.Data.StatisticsTime).Days != 0) | |||
Json<OrderStatistics>.Data.Count = 0; | |||
Json<OrderStatistics>.Data.StatisticsTime = DateTime.Now; | |||
Json<OrderStatistics>.Data.Count++; | |||
Json<OrderStatistics>.Save(); | |||
OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT); | |||
if (order.MorkOrder.GoodBatchings.Count <= 1) | |||
{ | |||
DeviceProcessLogShow($"数据解析失败,商品物料信息为空,请检查后台配置!"); | |||
return; | |||
} | |||
DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}"); | |||
mORKS.HistorySuborderId.Add(order.MorkOrder.SuborderId); | |||
foreach (var item in order.MorkOrder.GoodBatchings) | |||
{ | |||
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); | |||
if (res != null) | |||
{ | |||
if (ushort.TryParse(res.BatchingLoc, out ushort loc)) | |||
{ | |||
if (loc >= 1 && loc <= 5) | |||
{ | |||
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { GoodName = order.MorkOrder.GoodsName, Loc = ushort.Parse(res.BatchingLoc), SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId }); | |||
} | |||
else if (loc >= 10 && loc <= 11) | |||
{ | |||
int index = 0; | |||
if (recipeBoms != null) | |||
{ | |||
index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId); | |||
index++; | |||
} | |||
if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) | |||
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() | |||
{ | |||
BatchingId = res.BatchingId, | |||
GoodName = order.MorkOrder.GoodsName, | |||
Loc = ushort.Parse(res.BatchingLoc), | |||
SuborderId = order.MorkOrder.SuborderId, | |||
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 | |||
}); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
DeviceProcessLogShow($"数据解析失败,未找到商品信息,请检查后台配置!"); | |||
} | |||
} | |||
} | |||
}); | |||
if (@event == null) return; | |||
if (@event is DoOrderEvent order) | |||
{ | |||
mORKS.doOrderEvents.Add(order); | |||
if (order.MorkOrder.GoodBatchings == null) return; | |||
if (mORKS.HistorySuborderId.Contains(order.MorkOrder.SuborderId)) return; | |||
OrderCount++; | |||
if (DateTime.Now.Subtract(Json<OrderStatistics>.Data.StatisticsTime).Days != 0) | |||
Json<OrderStatistics>.Data.Count = 0; | |||
Json<OrderStatistics>.Data.StatisticsTime = DateTime.Now; | |||
Json<OrderStatistics>.Data.Count++; | |||
Json<OrderStatistics>.Save(); | |||
OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT); | |||
if (order.MorkOrder.GoodBatchings.Count <= 1) | |||
{ | |||
DeviceProcessLogShow($"数据解析失败,商品物料信息为空,请检查后台配置!"); | |||
return; | |||
} | |||
DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}"); | |||
mORKS.HistorySuborderId.Add(order.MorkOrder.SuborderId); | |||
foreach (var item in order.MorkOrder.GoodBatchings) | |||
{ | |||
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); | |||
if (res != null) | |||
{ | |||
if (ushort.TryParse(res.BatchingLoc, out ushort loc)) | |||
{ | |||
if (loc >= 1 && loc <= 5) | |||
{ | |||
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() | |||
{ | |||
GoodName = order.MorkOrder.GoodsName, | |||
Loc = ushort.Parse(res.BatchingLoc), | |||
SuborderId = order.MorkOrder.SuborderId, | |||
SortNum = order.MorkOrder.SortNum, | |||
BatchingId = res.BatchingId | |||
}); | |||
} | |||
else if (loc >= 10 && loc <= 11) | |||
{ | |||
int index = 0; | |||
if (recipeBoms != null) | |||
{ | |||
index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId); | |||
index++; | |||
} | |||
if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) | |||
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() | |||
{ | |||
BatchingId = res.BatchingId, | |||
GoodName = order.MorkOrder.GoodsName, | |||
Loc = ushort.Parse(res.BatchingLoc), | |||
SuborderId = order.MorkOrder.SuborderId, | |||
SortNum = order.MorkOrder.SortNum, | |||
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 | |||
}); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
DeviceProcessLogShow($"数据解析失败,未找到商品信息,请检查后台配置!"); | |||
} | |||
} | |||
} | |||
}); | |||
} | |||
public override void MainTask() | |||
@@ -416,6 +425,7 @@ namespace BPASmartClient.MorkS | |||
{ | |||
mORKS.TakeBowlId = orderLocInfo.SuborderId; | |||
mORKS.TakeBowName = orderLocInfo.GoodName; | |||
mORKS.TakeBowSortNum = orderLocInfo.SortNum; | |||
TakeBowlControl(orderLocInfo.Loc); | |||
SetRecipeNumber(orderLocInfo.RecipeNumber); | |||
OrderChange(mORKS.TakeBowlId, ORDER_STATUS.COOKING); | |||
@@ -630,6 +640,7 @@ namespace BPASmartClient.MorkS | |||
if (!string.IsNullOrEmpty(mORKS.OutMealId)) OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE); | |||
mORKS.OutMealId = mORKS.IngredientsCompleteId; | |||
mORKS.OutMealName = mORKS.IngredientsCompleteName; | |||
mORKS.OutMealSortNum = mORKS.IngredientsCompleteSortNum; | |||
mORKS.IngredientsCompleteId = string.Empty; | |||
mORKS.CookNodelId[loc] = string.Empty; | |||
DeviceProcessLogShow($"{loc + 1} 号位置出餐控制,订单ID:{mORKS.OutMealId}"); | |||
@@ -650,8 +661,10 @@ namespace BPASmartClient.MorkS | |||
{ | |||
mORKS.IngredientsCompleteId = mORKS.TakeBowlId; | |||
mORKS.IngredientsCompleteName = mORKS.TakeBowName; | |||
mORKS.IngredientsCompleteSortNum = mORKS.TakeBowSortNum; | |||
mORKS.TakeBowlId = string.Empty; | |||
mORKS.TakeBowName = string.Empty; | |||
mORKS.TakeBowSortNum = 0; | |||
DeviceProcessLogShow($"碗到位,允许到面,{mORKS.IngredientsCompleteId}"); | |||
mORKS.TakeBowlInterlock = false; | |||
} | |||
@@ -663,7 +676,6 @@ namespace BPASmartClient.MorkS | |||
DeviceProcessLogShow($"订单【{mORKS.OutMealId}】制作完成"); | |||
mORKS.CookCompleteFlatBit = true; | |||
mORKS.OutNoodleing = false; | |||
WaitMeaLSpeak(mORKS.OutMealName); | |||
} | |||
//加汤 | |||
@@ -678,9 +690,12 @@ namespace BPASmartClient.MorkS | |||
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE); | |||
DeviceProcessLogShow($"订单【{mORKS.OutMealId}】取餐完成"); | |||
ResetCookComplete(); | |||
DeviceProcessLogShow($"出餐订单序号【{mORKS.OutMealSortNum}】"); | |||
VoiceAPI.Speak(mORKS.OutMealSortNum.ToString()); | |||
mORKS.CookCompleteFlatBit = false; | |||
mORKS.OutMealId = string.Empty; | |||
mORKS.OutMealName = string.Empty; | |||
mORKS.OutMealSortNum = 0; | |||
} | |||
//机器人取面完成信号检测 | |||
@@ -706,17 +721,19 @@ namespace BPASmartClient.MorkS | |||
} | |||
/// <summary> | |||
/// 语音提醒取餐 | |||
/// </summary> | |||
/// <param name="meal"></param> | |||
private void WaitMeaLSpeak(string meal) | |||
{ | |||
VoiceAPI.m_SystemPlayWav(@"Vioce\电子提示音.wav"); | |||
Thread.Sleep(1000); | |||
if (meal != null) mORKS.speech.Speak(meal); | |||
VoiceAPI.m_SystemPlayWav(@"Vioce\取餐通知.wav"); | |||
} | |||
///// <summary> | |||
///// 语音提醒取餐 | |||
///// </summary> | |||
///// <param name="meal"></param> | |||
//private void WaitMeaLSpeak(string meal) | |||
//{ | |||
// VoiceAPI.m_SystemPlayWav(@"Vioce\电子提示音.wav"); | |||
// Thread.Sleep(1000); | |||
// if (meal != null) mORKS.speech.Speak(meal); | |||
// VoiceAPI.m_SystemPlayWav(@"Vioce\取餐通知.wav"); | |||
//} | |||
#region PLC 控制函数 | |||
@@ -337,6 +337,11 @@ namespace BPASmartClient.MorkS | |||
/// 取碗订单名称 | |||
/// </summary> | |||
public string TakeBowName = string.Empty; | |||
/// <summary> | |||
/// 配料完成订单名称 | |||
/// </summary> | |||
public int TakeBowSortNum = 0; | |||
/// <summary> | |||
/// 配料完成订单ID | |||
@@ -346,12 +351,18 @@ namespace BPASmartClient.MorkS | |||
/// 配料完成订单名称 | |||
/// </summary> | |||
public string IngredientsCompleteName = string.Empty; | |||
/// <summary> | |||
/// 配料完成订单名称 | |||
/// </summary> | |||
public int IngredientsCompleteSortNum = 0; | |||
/// <summary> | |||
/// 煮面口对应的订单ID | |||
/// </summary> | |||
public string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; | |||
/// <summary> | |||
/// 出餐订单ID | |||
/// </summary> | |||
@@ -360,6 +371,11 @@ namespace BPASmartClient.MorkS | |||
/// 出餐订单名称 | |||
/// </summary> | |||
public string OutMealName = string.Empty; | |||
/// <summary> | |||
/// 出餐排序号 | |||
/// </summary> | |||
public int OutMealSortNum = 0; | |||
/// <summary> | |||
/// 转台位置轮询 | |||
@@ -16,6 +16,7 @@ namespace BPASmartClient.MorkS | |||
public string GoodName { get; set; } | |||
public int RecipeId { get; set; } | |||
public int SortNum { get; set; } | |||
public List<int> Recipes { get; set; } | |||
@@ -1,42 +1,81 @@ | |||
using BPASmartClient.Message; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.MorkS | |||
{ | |||
public class VoiceAPI | |||
{ | |||
public VoiceAPI() | |||
{ | |||
} | |||
[DllImport("winmm.dll")] | |||
public static extern bool PlaySound(string pszSound, int hmod, int fdwSound); | |||
// 系统播放wav格式的文件 | |||
public static void m_SystemPlayWav(string strPlayFile) | |||
{ | |||
try | |||
{ | |||
if (strPlayFile.Trim() == "") | |||
{ return; }//为空不放 | |||
string strPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; | |||
strPath = strPath + strPlayFile; | |||
int SND_FILENAME = 0x00020000; | |||
int SND_ASYNC = 0x0001; | |||
PlaySound(strPath, 0, SND_ASYNC | SND_FILENAME);//播放音乐 | |||
} | |||
catch (Exception ex) | |||
{ | |||
MessageLog.GetInstance.ShowEx(ex.Message); | |||
} | |||
} | |||
} | |||
} | |||
//using BPASmartClient.Message; | |||
//using System; | |||
//using System.Collections.Concurrent; | |||
//using System.Collections.Generic; | |||
//using System.Linq; | |||
//using System.Runtime.InteropServices; | |||
//using System.Text; | |||
//using System.Threading; | |||
//using System.Threading.Tasks; | |||
//namespace BPASmartClient.MorkS | |||
//{ | |||
// public class VoiceAPI | |||
// { | |||
// public VoiceAPI() | |||
// { | |||
// BPA.Helper.ThreadManage.GetInstance().StartLong(new Action(() => | |||
// { | |||
// while (msg.Count > 0) | |||
// { | |||
// if (msg.TryDequeue(out string str)) | |||
// { | |||
// WaitMeaLSpeak(str); | |||
// } | |||
// } | |||
// Thread.Sleep(1000); | |||
// }), "语音播报", true); | |||
// } | |||
// [DllImport("winmm.dll")] | |||
// public static extern bool PlaySound(string pszSound, int hmod, int fdwSound); | |||
// private static ConcurrentQueue<string> msg { get; set; } = new ConcurrentQueue<string>(); | |||
// public static void Speak(string s) => msg.Enqueue(s); | |||
// // 系统播放wav格式的文件 | |||
// private static void m_SystemPlayWav(string strPlayFile) | |||
// { | |||
// try | |||
// { | |||
// if (strPlayFile.Trim() == "") | |||
// { return; }//为空不放 | |||
// string strPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; | |||
// strPath = strPath + strPlayFile; | |||
// int SND_FILENAME = 0x00020000; | |||
// int SND_ASYNC = 0x0001; | |||
// PlaySound(strPath, 0, SND_ASYNC | SND_FILENAME);//播放音乐 | |||
// } | |||
// catch (Exception ex) | |||
// { | |||
// MessageLog.GetInstance.ShowEx(ex.Message); | |||
// } | |||
// } | |||
// private void WaitMeaLSpeak(string meal, int count = 1, int IntervalTime = 1000) | |||
// { | |||
// m_SystemPlayWav(@"Vioce\电子提示音.wav"); | |||
// Thread.Sleep(1000); | |||
// for (int m = 0; m < count; m++) | |||
// { | |||
// m_SystemPlayWav(@"Vioce\请.wav"); | |||
// Thread.Sleep(500); | |||
// for (int i = 0; i < meal.Length; i++) | |||
// { | |||
// string name = meal.Substring(i, 1); | |||
// m_SystemPlayWav($"Vioce\\{name}.wav"); | |||
// Thread.Sleep(500); | |||
// } | |||
// m_SystemPlayWav(@"Vioce\号用户取餐.wav"); | |||
// Thread.Sleep(1500 + IntervalTime); | |||
// } | |||
// } | |||
// } | |||
//} |
@@ -22,6 +22,7 @@ using BPASmartClient.Model.小炒机; | |||
using BPA.Models; | |||
using System.Windows.Forms; | |||
using System.Media; | |||
using BPASmartClient.CustomResource; | |||
//using BPA.Helper; | |||
namespace BPASmartClient.MorkSUpgradedVer | |||
@@ -363,7 +364,14 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
if (loc >= 1 && loc <= 5) | |||
{ | |||
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { GoodName = order.MorkOrder.GoodsName, Loc = ushort.Parse(res.BatchingLoc), SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId }); | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() | |||
{ | |||
GoodName = order.MorkOrder.GoodsName, | |||
Loc = ushort.Parse(res.BatchingLoc), | |||
SuborderId = order.MorkOrder.SuborderId, | |||
SortNum = order.MorkOrder.SortNum, | |||
BatchingId = res.BatchingId | |||
}); | |||
} | |||
else if (loc >= 10 && loc <= 11) | |||
{ | |||
@@ -380,6 +388,7 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
GoodName = order.MorkOrder.GoodsName, | |||
Loc = ushort.Parse(res.BatchingLoc), | |||
SuborderId = order.MorkOrder.SuborderId, | |||
SortNum = order.MorkOrder.SortNum, | |||
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 | |||
}); | |||
} | |||
@@ -415,6 +424,7 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
{ | |||
mORKS.TakeBowlId = orderLocInfo.SuborderId; | |||
mORKS.TakeBowName = orderLocInfo.GoodName; | |||
mORKS.TakeBowSortNum = orderLocInfo.SortNum; | |||
TakeBowlControl(orderLocInfo.Loc); | |||
OrderChange(mORKS.TakeBowlId, ORDER_STATUS.COOKING); | |||
DeviceProcessLogShow($"订单【{mORKS.TakeBowlId}】执行取碗控制,位置:[{orderLocInfo.Loc}]"); | |||
@@ -620,6 +630,7 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
mORKS.CookCompleteFlatBit = true; | |||
mORKS.OutMealId = mORKS.IngredientsCompleteId; | |||
mORKS.OutMealName = mORKS.IngredientsCompleteName; | |||
mORKS.OutMealSortNum = mORKS.IngredientsCompleteSortNum; | |||
mORKS.IngredientsCompleteId = string.Empty; | |||
mORKS.CookNodelId[loc] = string.Empty; | |||
DeviceProcessLogShow($"{loc + 1} 号位置出餐控制,订单ID:{mORKS.OutMealId}"); | |||
@@ -639,6 +650,8 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
{ | |||
mORKS.IngredientsCompleteId = mORKS.TakeBowlId; | |||
mORKS.IngredientsCompleteName = mORKS.TakeBowName; | |||
mORKS.IngredientsCompleteSortNum = mORKS.TakeBowSortNum; | |||
mORKS.TakeBowSortNum = 0; | |||
mORKS.TakeBowlId = string.Empty; | |||
mORKS.TakeBowName = string.Empty; | |||
DeviceProcessLogShow($"碗到位,允许到面,{mORKS.IngredientsCompleteId}"); | |||
@@ -651,9 +664,12 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE); | |||
DeviceProcessLogShow($"订单【{mORKS.OutMealId}】取餐完成"); | |||
WriteData("M10.1", false); | |||
DeviceProcessLogShow($"出餐订单序号【{mORKS.OutMealSortNum}】"); | |||
VoiceAPI.Speak(mORKS.OutMealSortNum.ToString()); | |||
mORKS.CookCompleteFlatBit = false; | |||
mORKS.OutMealId = string.Empty; | |||
mORKS.OutMealName = string.Empty; | |||
mORKS.OutMealSortNum = 0; | |||
} | |||
//机器人取面完成信号检测 | |||
@@ -120,6 +120,11 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
/// 取碗订单名称 | |||
/// </summary> | |||
public string TakeBowName { get; set; } = string.Empty; | |||
/// <summary> | |||
/// 配料完成订单名称 | |||
/// </summary> | |||
public int TakeBowSortNum { get; set; } = 0; | |||
/// <summary> | |||
/// 允许倒面位置ID | |||
@@ -129,6 +134,11 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
/// 配料完成订单名称 | |||
/// </summary> | |||
public string IngredientsCompleteName { get; set; } = string.Empty; | |||
/// <summary> | |||
/// 配料完成订单名称 | |||
/// </summary> | |||
public int IngredientsCompleteSortNum { get; set; } = 0; | |||
/// <summary> | |||
/// 煮面口对应的订单ID | |||
@@ -143,6 +153,11 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
/// 出餐订单名称 | |||
/// </summary> | |||
public string OutMealName { get; set; } = string.Empty; | |||
/// <summary> | |||
/// 出餐排序号 | |||
/// </summary> | |||
public int OutMealSortNum { get; set; } = 0; | |||
/// <summary> | |||
/// 转台位置轮询 | |||
@@ -14,6 +14,7 @@ namespace BPASmartClient.MorkSUpgradedVer | |||
public ushort RecipeNumber { get; set; } | |||
public int BatchingId { get; set; } | |||
public string GoodName { get; set; } | |||
public int SortNum { get; set; } | |||
public int RecipeId { get; set; } | |||
@@ -124,7 +124,6 @@ namespace BPASmartClient.ViewModel | |||
WaitTakeMeal.Insert(0, orderStatusLists.ElementAt(index)); | |||
orderStatusLists.RemoveAt(index); | |||
} | |||
}); | |||
} | |||
@@ -4,7 +4,7 @@ | |||
<!--通用配置--> | |||
<!--<add key="ClientId" value="43"/>--> | |||
<add key="IsEnableTest" value="false"/> | |||
<add key="IsEnableTest" value="true"/> | |||
<!--测试环境--> | |||
<!--<add key="apollouri" value="http://10.2.1.21:28080/"/> | |||
@@ -1,5 +1,7 @@ | |||
using BPA.Message; | |||
using BPA.Message.Enum; | |||
using BPASmartClient.CustomResource; | |||
using BPASmartClient.CustomResource.Pages.Model; | |||
using BPASmartClient.Helper; | |||
using BPASmartClient.Message; | |||
using BPASmartClient.Model; | |||
@@ -10,6 +12,8 @@ using System.Configuration; | |||
using System.Data; | |||
using System.Drawing; | |||
using System.Linq; | |||
using System.Speech.Synthesis; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using System.Windows.Forms; | |||
@@ -31,8 +35,14 @@ namespace BPASmartClient | |||
mainView.Show(); | |||
SplitScreenDisplay(); | |||
NoCompleteOrderInit(); | |||
ActionManage.GetInstance.Register(new Action<object>(par => | |||
{ | |||
if (par != null) | |||
VoiceAPI.Speak(par.ToString()); | |||
}), "COMPLETED_TAKE_Notify"); | |||
} | |||
/// <summary> | |||
/// 分屏显示 | |||
/// </summary> | |||
@@ -25,5 +25,6 @@ | |||
Height="30" | |||
Margin="300,24,400,381" | |||
Content="使能" Click="Button_Click_2" /> | |||
<TextBox Name="text" Height="30" Margin="36,80,400,325"/> | |||
</Grid> | |||
</Window> |
@@ -88,24 +88,31 @@ namespace WpfApp1 | |||
} | |||
JaKaHelper jaKaHelper = new JaKaHelper(); | |||
private void Button_Click(object sender, RoutedEventArgs e) | |||
{ | |||
jaKaHelper.Conn("192.168.0.12"); | |||
MessageBox.Show($"连接成功,{jaKaHelper.rshd}"); | |||
Speech.GetInstance.aa("请0001号客户到1号窗口取餐"); | |||
//Task.Run(() => | |||
//{ | |||
// Speech.GetInstance.Speak($"请0001号客户到1号窗口取餐"); | |||
//}); | |||
//Speech.GetInstance.SpeechSpeak(new SpeechInfo() | |||
//{ | |||
// Text = text.Text, | |||
// time = 10000 | |||
//}); | |||
} | |||
private void Button_Click_1(object sender, RoutedEventArgs e) | |||
{ | |||
jaKaHelper.Power_On(); | |||
MessageBox.Show($"上电成功,{jaKaHelper.rshd}"); | |||
} | |||
private void Button_Click_2(object sender, RoutedEventArgs e) | |||
{ | |||
jaKaHelper.Enable_robot(); | |||
MessageBox.Show($"使能成功,{jaKaHelper.rshd}"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,149 @@ | |||
using Microsoft.CognitiveServices.Speech; | |||
using Microsoft.CognitiveServices.Speech.Audio; | |||
using System; | |||
using System.Runtime.InteropServices; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.IO; | |||
using System.Diagnostics; | |||
using System.Collections.Concurrent; | |||
using System.Threading; | |||
using System.Windows.Documents; | |||
namespace WpfApp1 | |||
{ | |||
public class Speech | |||
{ | |||
public static uint SND_ASYNC = 0x0001; | |||
public static uint SND_FILENAME = 0x0002; | |||
[DllImport("winmm.dll", CharSet = CharSet.Auto)] | |||
public static extern int mciSendString(string m_strCmd, string m_strReceive, int m_v1, int m_v2); | |||
[DllImport("Kernel32", CharSet = CharSet.Auto)] | |||
public static extern Int32 GetShortPathName(string path, StringBuilder shortPath, Int32 shortPathLength); | |||
private volatile static Speech _Instance; | |||
public static Speech GetInstance => _Instance ?? (_Instance = new Speech()); | |||
private Speech() | |||
{ | |||
//Task.Factory.StartNew(() => | |||
//{ | |||
// while (true) | |||
// { | |||
// while (speechInfos.Count > 0) | |||
// { | |||
// if (speechInfos.TryDequeue(out SpeechInfo si)) | |||
// { | |||
// for (int i = 0; i < si.Count; i++) | |||
// { | |||
// Speak(si.Text); | |||
// Thread.Sleep(si.time); | |||
// } | |||
// } | |||
// } | |||
// Thread.Sleep(1000); | |||
// } | |||
//}); | |||
} | |||
private ConcurrentQueue<SpeechInfo> speechInfos = new ConcurrentQueue<SpeechInfo>(); | |||
public void SpeechSpeak(SpeechInfo si) | |||
{ | |||
speechInfos.Enqueue(si); | |||
} | |||
private void OutputSpeechSynthesisResult(SpeechSynthesisResult speechSynthesisResult, string text) | |||
{ | |||
switch (speechSynthesisResult.Reason) | |||
{ | |||
case ResultReason.SynthesizingAudioCompleted: | |||
Console.WriteLine($"Speech synthesized for text: [{text}]"); | |||
break; | |||
case ResultReason.Canceled: | |||
var cancellation = SpeechSynthesisCancellationDetails.FromResult(speechSynthesisResult); | |||
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}"); | |||
if (cancellation.Reason == CancellationReason.Error) | |||
{ | |||
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}"); | |||
Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]"); | |||
Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?"); | |||
} | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
public async void aa(string text) | |||
{ | |||
var speechConfig = SpeechConfig.FromSubscription("b88f6907c8f64075a6169dc4d7dff65a", "chinanorth2"); | |||
// The language of the voice that speaks. | |||
speechConfig.SpeechSynthesisVoiceName = "zh-CN"; | |||
using (var speechSynthesizer = new SpeechSynthesizer(speechConfig)) | |||
{ | |||
// Get text from the console and synthesize to the default speaker. | |||
Console.WriteLine("Enter some text that you want to speak >"); | |||
//string text = Console.ReadLine(); | |||
var speechSynthesisResult = await speechSynthesizer.SpeakTextAsync(text); | |||
OutputSpeechSynthesisResult(speechSynthesisResult, text); | |||
} | |||
Console.WriteLine("Press any key to exit..."); | |||
} | |||
/// <summary> | |||
/// 播放语音 | |||
/// </summary> | |||
/// <param name="SpeakText"></param> | |||
public void Speak(string SpeakText) | |||
{ | |||
string path = $"{AppDomain.CurrentDomain.BaseDirectory}Sound";//设置音频文件保存路径 | |||
Directory.CreateDirectory(path); | |||
string SpeakPath = $"{path}\\{SpeakText}.wav"; | |||
SpeakPath = SpeakPath.Replace(' ', '_'); | |||
if (!File.Exists(SpeakPath)) | |||
{ | |||
var res = SynthesizeAudioAsync(SpeakText, SpeakPath); | |||
} | |||
StringBuilder shortPath = new StringBuilder(200); | |||
int result = GetShortPathName(SpeakPath, shortPath, shortPath.Capacity); | |||
string shortName = shortPath.ToString(); | |||
mciSendString(@"close all", null, 0, 0); | |||
mciSendString(@"open " + shortName + " alias song", null, 0, 0); | |||
mciSendString(@"play song", null, 0, 0); | |||
//return "22"; | |||
} | |||
/// <summary> | |||
/// 文字转音频 | |||
/// </summary> | |||
/// <param name="text"></param> | |||
/// <returns></returns> | |||
private string SynthesizeAudioAsync(string text, string path) | |||
{ | |||
var config = SpeechConfig.FromSubscription("b88f6907c8f64075a6169dc4d7dff65a", "chinanorth2"); | |||
config.SpeechSynthesisLanguage = "zh-CN"; //config.SpeechSynthesisVoiceName = ""; | |||
using var audioConfig = AudioConfig.FromWavFileOutput(path); | |||
using var synthesizer = new SpeechSynthesizer(config, audioConfig); | |||
synthesizer.SpeakTextAsync(text).Wait(); | |||
//await Task.Delay(TimeSpan.FromSeconds(2)); | |||
return "1"; | |||
} | |||
} | |||
public class SpeechInfo | |||
{ | |||
public string Text { get; set; } | |||
public int Count { get; set; } = 1; | |||
public int time { get; set; } = 2000; | |||
} | |||
} |
@@ -7,6 +7,10 @@ | |||
<UseWPF>true</UseWPF> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.CognitiveServices.Speech" Version="1.19.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.JakaRobot\BPASmartClient.JakaRobot.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.S7Net\BPASmartClient.S7Net.csproj" /> | |||