Ejemplo n.º 1
0
        void NotificationPattern(object sender, PatternSendEventArgs e)
        {
            Boolean found = false;

            TriggeredEvent ev = new TriggeredEvent(sender as CustomNotification, e.Channel, e.FirstLed, e.LastLed, e.Device, e.Pattern, e.Repeat, e.Duration);

            lock (e.Device.EventQueue)
            {
                foreach (TriggeredEvent pendingEvent in e.Device.EventQueue.ToArray())
                {
                    if (pendingEvent.Notification == sender)
                    {
                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    log.InfoFormat("Notification {0} already pending to play. Skipping.", (sender as CustomNotification).Name);
                }
                else
                {
                    e.Device.EventQueue.Enqueue(ev);
                }
            }

            if (!found)
            {
                e.Device.Start();
            }
        }
        Boolean CanPlayEvent(TriggeredEvent ev)
        {
            if (ev.NotificationSnapshot is PatternNotification)
            {
                PatternNotification notification = (PatternNotification)ev.NotificationSnapshot;
                int channel = notification.GetValidChannel();
                for (int i = notification.LedFirstIndex; i <= notification.LedLastIndex; i++)
                {
                    //If there is at least one LED currently in use, event needs to wait
                    if (LedBusy[channel][i])
                    {
                        return(false);
                    }
                }
            }
            else
            {
                for (int i = ev.FirstLed; i <= ev.LastLed; i++)
                {
                    if (LedBusy[ev.Channel][i])
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        public void SetColor(TriggeredEvent evnt, byte r, byte g, byte b)
        {
            if (BrightnessLimit < 100 && BrightnessLimit >= 0)
            {
                r = (byte)(BrightnessLimit / 100.0 * r);
                g = (byte)(BrightnessLimit / 100.0 * g);
                b = (byte)(BrightnessLimit / 100.0 * b);
            }

            lock (this)
            {
                for (int i = evnt.FirstLed; i <= evnt.LastLed; i++)
                {
                    LedFrame[evnt.Channel][i * 3]     = g;
                    LedFrame[evnt.Channel][i * 3 + 1] = r;
                    LedFrame[evnt.Channel][i * 3 + 2] = b;
                    OnSendColor((byte)evnt.Channel, (byte)i, r, g, b);
                }

                NeedsLedUpdate = true;
            }


            if (!Running)
            {
                this.Start();
            }
        }
 void AssignBusyLeds(TriggeredEvent ev, Boolean busy)
 {
     if (ev.NotificationSnapshot is PatternNotification)
     {
         PatternNotification notification = (PatternNotification)ev.NotificationSnapshot;
         int channel = notification.GetValidChannel();
         for (int i = notification.LedFirstIndex; i <= notification.LedLastIndex; i++)
         {
             LedBusy[channel][i] = busy;
         }
     }
     else
     {
         for (int i = ev.FirstLed; i <= ev.LastLed; i++)
         {
             LedBusy[ev.Channel][i] = busy;
         }
     }
 }
Ejemplo n.º 5
0
        private void NotificationTriggered(object sender, TriggeredEventArgs e)
        {
            log.InfoFormat("Notification [{0}] \"{1}\" triggered. Message: {2}",
                           (sender as CustomNotification).GetTypeName(),
                           (sender as CustomNotification).Name,
                           e.Message);

            PatternNotification notification = sender as PatternNotification;

            TriggeredEvent ev = new TriggeredEvent(notification, e.Message);

            if (e.Message != "")
            {
                DataModel.TriggeredEvents.Add(ev);
            }

            if (notification.Pattern == null)
            {
                log.WarnFormat("({0}) Pattern is not assigned", notification.Name);
                return;
            }

            BlinkStickDeviceSettings settings = DataModel.FindBySerial(notification.BlinkStickSerial);

            if (settings == null)
            {
                log.WarnFormat("({0}) BlinkStick with serial {1} not known", notification.Name, notification.BlinkStickSerial);
                return;
            }

            if (settings.Led == null)
            {
                log.WarnFormat("({0}) BlinkStick with serial {1} is not connected", notification.Name, notification.BlinkStickSerial);
                return;
            }

            Boolean found = false;

            lock (settings.EventQueue)
            {
                foreach (TriggeredEvent pendingEvent in settings.EventQueue.ToArray())
                {
                    if (pendingEvent.Notification == notification)
                    {
                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    log.InfoFormat("Notification {0} already pending to play. Skipping.", notification.Name);
                }
                else
                {
                    settings.EventQueue.Enqueue(ev);
                }
            }

            if (!found)
            {
                settings.Start();
            }
        }
        void patternAnimator_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;

            try
            {
                log.InfoFormat("[{0}] Starting pattern playback", this.Serial);

                List <TriggeredEvent> eventsPlaying = new List <TriggeredEvent>();

                while (!worker.CancellationPending)
                {
                    TriggeredEvent ev = null;

                    lock (EventQueue)
                    {
                        for (int i = 0; i < EventQueue.Count; i++)
                        {
                            ev = EventQueue.Dequeue();

                            for (int j = eventsPlaying.Count - 1; j >= 0; j--)
                            {
                                if (ev.Notification == eventsPlaying[j].Notification && (eventsPlaying[j].Repeat < 0 || eventsPlaying[j].Duration > 0))
                                {
                                    log.DebugFormat("Removing infinite playback notifications as there is another pending");
                                    TriggeredEvent evPlaying = eventsPlaying[j];
                                    eventsPlaying.RemoveAt(j);
                                    AssignBusyLeds(evPlaying, false);
                                }
                            }

                            if (CanPlayEvent(ev))
                            {
                                break;
                            }
                            else
                            {
                                EventQueue.Enqueue(ev);
                                ev = null;
                            }
                        }
                    }

                    if (ev != null)
                    {
                        if (ev.NotificationSnapshot is PatternNotification)
                        {
                            ev.EventStarted     = DateTime.Now;
                            ev.AnimationStarted = DateTime.Now;

                            PatternNotification notification = ev.NotificationSnapshot as PatternNotification;
                            foreach (Animation animation in notification.Pattern.Animations)
                            {
                                Animation copyAnimation = new Animation();
                                copyAnimation.Assign(animation);
                                ev.Animations.Add(copyAnimation);
                            }

                            ev.Animations[0].ReferenceColor = GetColor(ev.NotificationSnapshot);

                            AssignBusyLeds(ev, true);
                            eventsPlaying.Add(ev);
                        }
                        else
                        {
                            ev.AnimationStarted = DateTime.Now;
                            ev.EventStarted     = DateTime.Now;

                            foreach (Animation animation in ev.Pattern.Animations)
                            {
                                Animation copyAnimation = new Animation();
                                copyAnimation.Assign(animation);
                                ev.Animations.Add(copyAnimation);
                            }

                            ev.Animations[0].ReferenceColor = GetColor(ev.NotificationSnapshot);

                            AssignBusyLeds(ev, true);
                            eventsPlaying.Add(ev);
                        }
                    }

                    //Prepare next frame of data to send to LEDs
                    for (int ii = eventsPlaying.Count - 1; ii >= 0; ii--)
                    {
                        TriggeredEvent evnt = eventsPlaying[ii];

                        RgbColor color = evnt.Animations[evnt.AnimationIndex].GetColor(evnt.AnimationStarted.Value, DateTime.Now, evnt.Animations[evnt.AnimationIndex].ReferenceColor);

                        PatternNotification notification = evnt.NotificationSnapshot as PatternNotification;

                        lock (this)
                        {
                            SetColor(evnt, color.R, color.G, color.B);
                        }

                        if (evnt.Animations[evnt.AnimationIndex].AnimationFinished)
                        {
                            evnt.AnimationIndex += 1;

                            if (evnt.Duration > 0 && evnt.EventStarted.Value.AddMilliseconds(evnt.Duration) <= DateTime.Now)
                            {
                                eventsPlaying.RemoveAt(ii);
                                AssignBusyLeds(evnt, false);
                            }
                            else if (evnt.AnimationIndex == evnt.Animations.Count)
                            {
                                evnt.RepeatCount += 1;

                                if (evnt.Duration > 0 || evnt.Repeat < 0 || evnt.RepeatCount < evnt.Repeat)
                                {
                                    evnt.AnimationStarted = DateTime.Now;
                                    evnt.AnimationIndex   = 0;

                                    evnt.Animations.ForEach(delegate(Animation a) { a.Reset(); });
                                }
                                else
                                {
                                    eventsPlaying.RemoveAt(ii);
                                    AssignBusyLeds(evnt, false);
                                }
                            }
                            else
                            {
                                evnt.Animations[evnt.AnimationIndex].ReferenceColor = GetColor(evnt.NotificationSnapshot);
                                evnt.AnimationStarted = DateTime.Now;
                            }
                        }
                    }

                    if (Led != null && NeedsLedUpdate)
                    {
                        lock (this)
                        {
                            NeedsLedUpdate = false;
                        }

                        int retryCount = 5;

                        if (Led.BlinkStickDevice == BlinkStickDeviceEnum.BlinkStick ||
                            Led.BlinkStickDevice == BlinkStickDeviceEnum.BlinkStickPro && Led.Mode < 2)
                        {
                            while (retryCount > 0)                              //Retry loop
                            {
                                try
                                {
                                    Led.SetColor(LedFrame[0][1], LedFrame[0][0], LedFrame[0][2]);
                                    retryCount = 0;
                                }
                                catch (Exception ex)
                                {
                                    retryCount--;
                                    log.ErrorFormat("Failed to set color: {0}", ex);
                                    if (retryCount > 0)
                                    {
                                        Thread.Sleep(20);
                                        log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                    }
                                    else
                                    {
                                        log.Warn("Failed to set color 5 times, giving up...");
                                    }
                                }
                            }
                        }
                        else
                        {
                            byte[] frame = new byte[this.LedsR * 3];
                            Array.Copy(LedFrame[0], 0, frame, 0, frame.Length);

                            while (retryCount > 0)                             //Retry loop
                            {
                                try
                                {
                                    Led.SetColors(0, frame);
                                    retryCount = 0;
                                }
                                catch (Exception ex)
                                {
                                    retryCount--;
                                    log.ErrorFormat("Failed to set color: {0}", ex);
                                    if (retryCount > 0)
                                    {
                                        Thread.Sleep(20);
                                        log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                    }
                                    else
                                    {
                                        log.Warn("Failed to set color 5 times, giving up...");
                                    }
                                }
                            }

                            int sleep = Math.Max(2, (int)(this.LedsR * 3 * 8f / 400f * 1.2)); //number of LEDs times 3 color elements times 8 bytes divided by speed
                            Thread.Sleep(sleep);

                            if (Led != null && Led.BlinkStickDevice == BlinkStickDeviceEnum.BlinkStickPro)
                            {
                                frame = new byte[this.LedsG * 3];
                                Array.Copy(LedFrame[1], 0, frame, 0, frame.Length);

                                while (retryCount > 0)                                 //Retry loop
                                {
                                    try
                                    {
                                        Led.SetColors(1, frame);
                                        retryCount = 0;
                                    }
                                    catch (Exception ex)
                                    {
                                        retryCount--;
                                        log.ErrorFormat("Failed to set color: {0}", ex);
                                        if (retryCount > 0)
                                        {
                                            Thread.Sleep(20);
                                            log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                        }
                                        else
                                        {
                                            log.Warn("Failed to set color 5 times, giving up...");
                                        }
                                    }
                                }

                                sleep = Math.Max(2, (int)(this.LedsG * 3 * 8f / 400f * 1.2));
                                Thread.Sleep(sleep);

                                frame = new byte[this.LedsB * 3];
                                Array.Copy(LedFrame[2], 0, frame, 0, frame.Length);

                                while (retryCount > 0)                                 //Retry loop
                                {
                                    try
                                    {
                                        Led.SetColors(2, frame);
                                        retryCount = 0;
                                    }
                                    catch (Exception ex)
                                    {
                                        retryCount--;
                                        log.ErrorFormat("Failed to set color: {0}", ex);
                                        if (retryCount > 0)
                                        {
                                            Thread.Sleep(20);
                                            log.InfoFormat("Retry set color #{0}", 5 - retryCount);
                                        }
                                        else
                                        {
                                            log.Warn("Failed to set color 5 times, giving up...");
                                        }
                                    }
                                }

                                sleep = Math.Max(2, (int)(this.LedsB * 3 * 8f / 400f * 1.2));
                                Thread.Sleep(sleep);
                            }
                        }
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("Pattern playback crash {0}", ex);
            }

            log.InfoFormat("[{0}] Pattern playback stopped", this.Serial);

            Running = false;
        }