/* Copyright (C) Arnaud Houdelette 2012-2014 Copyright (C) Emmanuel Langlois 2012-2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Threading; using System.IO.Ports; using System.Xml; namespace DMX2 { public class DriverBoitierV1 : DriverDMX, IEventProvider { struct buttonState { public buttonState(byte _button, bool _pressed){ button=_button; pressed=_pressed; } public byte button; public bool pressed; } enum etatAutomate { Deconnecte, Transmission, Erreur, Reset, Parametrage, Fin } bool[] buttons = new bool[8]; bool[] watchButtons = new bool[8]; // tampons Entrée/Sortie byte[] inputbuffer = new byte[1]; byte[] outputbuffer = new byte[260]; //Thread de boucle Thread loopthread=null; public UniversDMX patch=null; string portname = ""; SerialPort serial = null; public DriverBoitierV1 (string serialport, string id): base(id) { portname = serialport; Start(); //serial = serialport; outputbuffer[0]=27; outputbuffer[1]=68; outputbuffer[4]=255; } void Start () { if (loopthread == null) { loopthread = new Thread(new ThreadStart(MainLoop)); loopthread.Start(); } } void Connection () { Console.WriteLine ("DriverV1.Connection()"); if (serial != null) { serial.Close(); serial.Dispose(); serial = null; } if (!System.IO.File.Exists (portname)) { Thread.Sleep (200); return; } serial = new SerialPort(portname, 460800,Parity.None,8,StopBits.One); serial.DtrEnable = false; serial.ReadTimeout = 15; serial.WriteTimeout = 200; serial.Open(); etat = etatAutomate.Transmission; } volatile etatAutomate etat = etatAutomate.Deconnecte; DateTime finAttente = DateTime.Now; void MainLoop() { while(etat != etatAutomate.Fin) { switch (etat) { case etatAutomate.Deconnecte: Connection(); Attente(DateTime.Now.AddMilliseconds(200)); break; case etatAutomate.Transmission: finAttente = DateTime.Now.AddMilliseconds (22); EnvoiTrame(); Reception(); Attente(finAttente); break; case etatAutomate.Erreur: Deconnecte(); Attente(DateTime.Now.AddSeconds(2)); break; // case etatAutomate.Parametrage: // EnvoiParam(); // break; // case etatAutomate.Reset: // EnvoiReset(); // break; } } Deconnecte(); } void Attente (DateTime date) { int sleeptime = (int) (date - DateTime.Now).TotalMilliseconds; if(sleeptime>2) Thread.Sleep(sleeptime); while (DateTime.Now\d+)?", System.Text.RegularExpressions.RegexOptions.Compiled); System.Collections.Concurrent.ConcurrentQueue eventsPending = new System.Collections.Concurrent.ConcurrentQueue(); bool IEventProvider.Bind (string eventId) { var res = regexEventID.Match (eventId); if (res.Success) { int bt = int.Parse (res.Groups ["button"].Value); if(bt<0||bt>7) return false; watchButtons[bt] = true; return true; } return false; } void IEventProvider.Unbind (string eventId) { var res = regexEventID.Match (eventId); if (res.Success) { int bt = int.Parse (res.Groups ["button"].Value); if(bt<0||bt>7) return ; watchButtons[bt] = false; } return; } Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler) { Gtk.Menu retmenu = new Gtk.Menu (); Gtk.MenuItem evmenuitem = new Gtk.MenuItem ("Boutons"); retmenu.Add (evmenuitem); Gtk.Menu evmenu = new Gtk.Menu (); evmenuitem.Submenu = evmenu; for (int i= 0; i<8;i++ ) { Gtk.MenuItem item = new Gtk.MenuItem(string.Format("Bouton {0}",i+1)); item.Data[EventManager.EventIdKey] = string.Format("BV1-B{0}",i); item.Data[EventManager.StateKey] = state; item.ButtonPressEvent += handler; evmenu.Add (item); } return retmenu; } void IEventProvider.ProcessEvents (EventManagerCallback callback) { buttonState bt; EventData evd; while (eventsPending.TryDequeue(out bt)) { evd.id= string.Format("BV1-B{0}",bt.button ); evd.value = bt.pressed?(byte)0xFF:(byte)0x00; callback(evd); } } string IEventProvider.MenuName { get { return "Boitier V1"; } } #endregion #region implemented abstract members of DMX2.DriverDMX public override void Save (System.Xml.XmlElement parent) { System.Xml.XmlElement el = parent.OwnerDocument.CreateElement ("DriverBoitierV1"); parent.AppendChild (el); el.SetAttribute ("portname", portname.ToString ()); el.SetAttribute ("id", ID); if(patch!=null) el.SetAttribute ("univers", patch.Nom); } #endregion public static new DriverDMX Load(Conduite conduite, XmlElement el) { //System.Xml.XmlElement xmlE; string port = el.GetAttribute("portname"); if(! System.IO.File.Exists(port)) return null; string id = el.GetAttribute("id"); DriverBoitierV1 drv = new DriverBoitierV1(port,id); if(el.HasAttribute("univers")) { string univ = el.GetAttribute("univers"); foreach (UniversDMX u in conduite.Patches){ if(u.Nom== univ){ drv.patch = u; break; } } } return drv; } } }