void AnalogIODevice::applyChannelValues(SimpleCB aDoneCB, bool aForDimming) { MLMicroSeconds transitionTime = 0; // abort previous transition MainLoop::currentMainLoop().cancelExecutionTicket(timerTicket); // generic device, show changed channels if (analogIOType==analogio_dimmer) { // single channel PWM dimmer LightBehaviourPtr l = boost::dynamic_pointer_cast<LightBehaviour>(output); if (l && l->brightnessNeedsApplying()) { transitionTime = l->transitionTimeToNewBrightness(); l->brightnessTransitionStep(); // init applyChannelValueSteps(aForDimming, transitionTime==0 ? 1 : (double)TRANSITION_STEP_TIME/transitionTime); } // consider applied l->brightnessApplied(); } else if (analogIOType==analogio_rgbdimmer) { // three channel RGB PWM dimmer RGBColorLightBehaviourPtr cl = boost::dynamic_pointer_cast<RGBColorLightBehaviour>(output); if (cl) { if (needsToApplyChannels()) { // needs update // - derive (possibly new) color mode from changed channels cl->deriveColorMode(); // - calculate and start transition // TODO: depending to what channel has changed, take transition time from that channel. For now always using brightness transition time transitionTime = cl->transitionTimeToNewBrightness(); cl->brightnessTransitionStep(); // init cl->colorTransitionStep(); // init applyChannelValueSteps(aForDimming, transitionTime==0 ? 1 : (double)TRANSITION_STEP_TIME/transitionTime); } // if needs update // consider applied cl->appliedColorValues(); } } else { // direct single channel PWM output, no smooth transitions ChannelBehaviourPtr ch = getChannelByIndex(0); if (ch && ch->needsApplying()) { double chVal = ch->getTransitionalValue()-ch->getMin(); double chSpan = ch->getMax()-ch->getMin(); analogIO->setValue(chVal/chSpan*100); // 0..100% ch->channelValueApplied(); // confirm having applied the value } } // always consider apply done, even if transition is still running inherited::applyChannelValues(aDoneCB, aForDimming); }
void OlaDevice::applyChannelValues(SimpleCB aDoneCB, bool aForDimming) { MLMicroSeconds transitionTime = 0; // abort previous transition MainLoop::currentMainLoop().cancelExecutionTicket(transitionTicket); // generic device, show changed channels if (olaType==ola_dimmer) { // single channel dimmer LightBehaviourPtr l = boost::dynamic_pointer_cast<LightBehaviour>(output); if (l && l->brightnessNeedsApplying()) { transitionTime = l->transitionTimeToNewBrightness(); l->brightnessTransitionStep(); // init applyChannelValueSteps(aForDimming, transitionTime==0 ? 1 : (double)TRANSITION_STEP_TIME/transitionTime); } // consider applied l->brightnessApplied(); } else if (olaType==ola_fullcolordimmer) { // RGB, RGBW or RGBWA dimmer RGBColorLightBehaviourPtr cl = boost::dynamic_pointer_cast<RGBColorLightBehaviour>(output); if (cl) { MovingLightBehaviourPtr ml = boost::dynamic_pointer_cast<MovingLightBehaviour>(output); if (needsToApplyChannels()) { // needs update // - derive (possibly new) color mode from changed channels cl->deriveColorMode(); // - calculate and start transition // TODO: depending to what channel has changed, take transition time from that channel. For now always using brightness transition time transitionTime = cl->transitionTimeToNewBrightness(); cl->brightnessTransitionStep(); // init cl->colorTransitionStep(); // init if (ml) ml->positionTransitionStep(); // init applyChannelValueSteps(aForDimming, transitionTime==0 ? 1 : (double)TRANSITION_STEP_TIME/transitionTime); } // consider applied if (ml) ml->appliedPosition(); cl->appliedColorValues(); } } inherited::applyChannelValues(aDoneCB, aForDimming); }
void OlaDevice::applyChannelValueSteps(bool aForDimming, double aStepSize) { // generic device, show changed channels if (olaType==ola_dimmer) { // single channel dimmer LightBehaviourPtr l = boost::dynamic_pointer_cast<LightBehaviour>(output); double w = l->brightnessForHardware()*255/100; setDMXChannel(whiteChannel,(DmxValue)w); // next step if (l->brightnessTransitionStep(aStepSize)) { ALOG(LOG_DEBUG, "transitional DMX512 value %d=%d", whiteChannel, (int)w); // not yet complete, schedule next step transitionTicket = MainLoop::currentMainLoop().executeOnce( boost::bind(&OlaDevice::applyChannelValueSteps, this, aForDimming, aStepSize), TRANSITION_STEP_TIME ); return; // will be called later again } if (!aForDimming) { ALOG(LOG_INFO, "final DMX512 channel %d=%d", whiteChannel, (int)w); } l->brightnessApplied(); // confirm having applied the new brightness } else if (olaType==ola_fullcolordimmer) { // RGB, RGBW or RGBWA dimmer RGBColorLightBehaviourPtr cl = boost::dynamic_pointer_cast<RGBColorLightBehaviour>(output); MovingLightBehaviourPtr ml = boost::dynamic_pointer_cast<MovingLightBehaviour>(output); // RGB lamp, get components double r,g,b; double w = 0; double a = 0; if (whiteChannel!=dmxNone) { if (amberChannel!=dmxNone) { // RGBW cl->getRGBWA(r, g, b, w, a, 255); setDMXChannel(amberChannel,(DmxValue)a); } else { // RGBW cl->getRGBW(r, g, b, w, 255); } setDMXChannel(whiteChannel,(DmxValue)w); } else { // RGB cl->getRGB(r, g, b, 255); // get brightness per R,G,B channel } // There's always RGB setDMXChannel(redChannel,(DmxValue)r); setDMXChannel(greenChannel,(DmxValue)g); setDMXChannel(blueChannel,(DmxValue)b); // there might be position as well double h = 0; double v = 0; if (ml) { h = ml->horizontalPosition->getTransitionalValue()/100*255; setDMXChannel(hPosChannel,(DmxValue)h); v = ml->verticalPosition->getTransitionalValue()/100*255; setDMXChannel(vPosChannel,(DmxValue)v); // step position ml->positionTransitionStep(aStepSize); } // next step if (cl->colorTransitionStep(aStepSize)) { ALOG(LOG_DEBUG, "transitional DMX512 values R(%hd)=%d, G(%hd)=%d, B(%hd)=%d, W(%hd)=%d, A(%hd)=%d, H(%hd)=%d, V(%hd)=%d", redChannel, (int)r, greenChannel, (int)g, blueChannel, (int)b, whiteChannel, (int)w, amberChannel, (int)a, hPosChannel, (int)h, vPosChannel, (int)v ); // not yet complete, schedule next step transitionTicket = MainLoop::currentMainLoop().executeOnce( boost::bind(&OlaDevice::applyChannelValueSteps, this, aForDimming, aStepSize), TRANSITION_STEP_TIME ); return; // will be called later again } if (!aForDimming) { ALOG(LOG_INFO, "final DMX512 values R(%hd)=%d, G(%hd)=%d, B(%hd)=%d, W(%hd)=%d, A(%hd)=%d, H(%hd)=%d, V(%hd)=%d", redChannel, (int)r, greenChannel, (int)g, blueChannel, (int)b, whiteChannel, (int)w, amberChannel, (int)a, hPosChannel, (int)h, vPosChannel, (int)v ); } } }
void AnalogIODevice::applyChannelValueSteps(bool aForDimming, double aStepSize) { // generic device, show changed channels if (analogIOType==analogio_dimmer) { // single channel PWM dimmer LightBehaviourPtr l = boost::dynamic_pointer_cast<LightBehaviour>(output); bool moreSteps = l->brightnessTransitionStep(aStepSize); double w = l->brightnessForHardware(); double pwm = l->brightnessToPWM(w, 100); analogIO->setValue(pwm); // next step if (moreSteps) { ALOG(LOG_DEBUG, "AnalogIO transitional brightness value: %.2f", w); // not yet complete, schedule next step timerTicket = MainLoop::currentMainLoop().executeOnce( boost::bind(&AnalogIODevice::applyChannelValueSteps, this, aForDimming, aStepSize), TRANSITION_STEP_TIME ); return; // will be called later again } if (!aForDimming) ALOG(LOG_INFO, "AnalogIO final PWM value: %.2f", w); } else if (analogIOType==analogio_rgbdimmer) { // three channel RGB PWM dimmer RGBColorLightBehaviourPtr cl = boost::dynamic_pointer_cast<RGBColorLightBehaviour>(output); bool moreSteps = cl->brightnessTransitionStep(aStepSize); if (cl->colorTransitionStep(aStepSize)) moreSteps = true; // RGB lamp, get components double r, g, b, pwm; double w = 0; if (analogIO4) { // RGBW lamp cl->getRGBW(r, g, b, w, 100); // get brightness for R,G,B,W channels pwm = cl->brightnessToPWM(w, 100); analogIO4->setValue(pwm); } else { // RGB only cl->getRGB(r, g, b, 100); // get brightness for R,G,B channels } // - red pwm = cl->brightnessToPWM(r, 100); analogIO->setValue(pwm); // - green pwm = cl->brightnessToPWM(g, 100); analogIO2->setValue(pwm); // - blue pwm = cl->brightnessToPWM(b, 100); analogIO3->setValue(pwm); // next step if (moreSteps) { ALOG(LOG_DEBUG, "AnalogIO transitional RGBW values: R=%.2f G=%.2f, B=%.2f, W=%.2f", r, g, b, w); // not yet complete, schedule next step timerTicket = MainLoop::currentMainLoop().executeOnce( boost::bind(&AnalogIODevice::applyChannelValueSteps, this, aForDimming, aStepSize), TRANSITION_STEP_TIME ); return; // will be called later again } if (!aForDimming) ALOG(LOG_INFO, "AnalogIO final RGBW values: R=%.2f G=%.2f, B=%.2f, W=%.2f", r, g, b, w); } }