-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(lights)!: remove individual fixture requirements and constraints (…
…#38) * chore(lights)!: refactor fixtures to strategy design pattern * chore(lights): refactor master dimmer to relative brightness * chore(lights)!: move master dim and shutter channels to color strategies * feat(lights): make master dimmer and shutter optional * feat(lights): add specific nr of channels required for each fixture BREAKING CHANGE: new database structure
- Loading branch information
Showing
19 changed files
with
738 additions
and
542 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import { Column } from 'typeorm'; | ||
import { RgbColor, rgbColorDefinitions } from '../color-definitions'; | ||
import LightsFixtureShutterOptions, { ShutterOption } from './lights-fixture-shutter-options'; | ||
import Colors from './colors'; | ||
import { IColorsWheel } from './colors-wheel'; | ||
|
||
export type ColorChannel = keyof ColorsRgb; | ||
|
||
export interface IColorsRgb { | ||
redChannel: number; | ||
greenChannel: number; | ||
blueChannel: number; | ||
coldWhiteChannel?: number | null; | ||
warmWhiteChannel?: number | null; | ||
amberChannel?: number | null; | ||
uvChannel?: number | null; | ||
} | ||
|
||
export default class ColorsRgb extends Colors implements IColorsRgb { | ||
@Column({ type: 'tinyint', unsigned: true, nullable: true }) | ||
public masterDimChannel?: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true, nullable: true }) | ||
public shutterChannel?: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true }) | ||
public redChannel: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true }) | ||
public greenChannel: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true }) | ||
public blueChannel: number; | ||
|
||
@Column({ type: 'tinyint', nullable: true, unsigned: true }) | ||
public coldWhiteChannel?: number | null; | ||
|
||
@Column({ type: 'tinyint', nullable: true, unsigned: true }) | ||
public warmWhiteChannel?: number | null; | ||
|
||
@Column({ type: 'tinyint', nullable: true, unsigned: true }) | ||
public amberChannel?: number | null; | ||
|
||
@Column({ type: 'tinyint', nullable: true, unsigned: true }) | ||
public uvChannel?: number | null; | ||
|
||
private strobePing = false; | ||
|
||
private currentValues: Required<IColorsRgb> = { | ||
redChannel: 0, | ||
greenChannel: 0, | ||
blueChannel: 0, | ||
coldWhiteChannel: 0, | ||
warmWhiteChannel: 0, | ||
amberChannel: 0, | ||
uvChannel: 0, | ||
}; | ||
|
||
public setColor(color: RgbColor): void { | ||
this.currentValues = rgbColorDefinitions[color].definition; | ||
} | ||
|
||
public setCustomColor(color: IColorsRgb): void { | ||
const givenColors = Object.keys(color) as (keyof IColorsRgb)[]; | ||
givenColors.forEach((key: keyof IColorsRgb) => { | ||
this.currentValues[key] = color[key]!; | ||
}); | ||
} | ||
|
||
public reset(): void { | ||
this.currentValues = { | ||
redChannel: 0, | ||
greenChannel: 0, | ||
blueChannel: 0, | ||
coldWhiteChannel: 0, | ||
warmWhiteChannel: 0, | ||
amberChannel: 0, | ||
uvChannel: 0, | ||
}; | ||
} | ||
|
||
private getColor(color: keyof Required<IColorsRgb>): number { | ||
let value = this.currentValues[color]!; | ||
if (this.masterDimChannel) return value; | ||
value = Math.round(value * this.currentBrightness); | ||
return value; | ||
} | ||
|
||
public setStrobeInDmx(values: number[], shutterOptions: LightsFixtureShutterOptions[]): number[] { | ||
if (this.masterDimChannel) values[this.masterDimChannel - 1] = 255; | ||
if (this.shutterChannel) | ||
values[this.shutterChannel - 1] = | ||
shutterOptions.find((o) => o.shutterOption === ShutterOption.STROBE)?.channelValue ?? 0; | ||
|
||
if (this.shutterChannel || this.strobePing) { | ||
// If we have a shutter channel or we should manually strobe | ||
values[this.redChannel - 1] = 255; | ||
values[this.blueChannel - 1] = 255; | ||
values[this.greenChannel - 1] = 255; | ||
if (this.warmWhiteChannel) values[this.warmWhiteChannel - 1] = 255; | ||
if (this.coldWhiteChannel) values[this.coldWhiteChannel - 1] = 255; | ||
if (this.amberChannel) values[this.amberChannel - 1] = 255; | ||
} else if (!this.shutterChannel) { | ||
// If we do not have a shutter channel and the ping is off, | ||
// turn off all colors | ||
values[this.redChannel - 1] = 0; | ||
values[this.blueChannel - 1] = 0; | ||
values[this.greenChannel - 1] = 0; | ||
if (this.warmWhiteChannel) values[this.warmWhiteChannel - 1] = 0; | ||
if (this.coldWhiteChannel) values[this.coldWhiteChannel - 1] = 0; | ||
if (this.amberChannel) values[this.amberChannel - 1] = 0; | ||
} | ||
|
||
// If we have no shutter channel, manually flip the strobe bit | ||
if (!this.shutterChannel) { | ||
this.strobePing = !this.strobePing; | ||
} | ||
|
||
return values; | ||
} | ||
|
||
public setColorsInDmx(values: number[], shutterOptions: LightsFixtureShutterOptions[]): number[] { | ||
if (this.masterDimChannel) | ||
values[this.masterDimChannel - 1] = Math.round(this.currentBrightness * 255); | ||
if (this.shutterChannel) | ||
values[this.shutterChannel - 1] = | ||
shutterOptions.find((o) => o.shutterOption === ShutterOption.OPEN)?.channelValue ?? 0; | ||
values[this.redChannel - 1] = this.getColor('redChannel'); | ||
values[this.greenChannel - 1] = this.getColor('greenChannel'); | ||
values[this.blueChannel - 1] = this.getColor('blueChannel'); | ||
if (this.coldWhiteChannel != null) { | ||
values[this.coldWhiteChannel - 1] = this.getColor('coldWhiteChannel'); | ||
} | ||
if (this.warmWhiteChannel != null) { | ||
values[this.warmWhiteChannel - 1] = this.getColor('warmWhiteChannel'); | ||
} | ||
if (this.amberChannel != null) { | ||
values[this.amberChannel - 1] = this.getColor('amberChannel'); | ||
} | ||
if (this.uvChannel != null) { | ||
values[this.uvChannel - 1] = this.getColor('uvChannel'); | ||
} | ||
|
||
return values; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { Column, OneToMany } from 'typeorm'; | ||
import LightsMovingHeadWheelShutterOptions from './lights-moving-head-wheel-shutter-options'; | ||
import LightsWheelColorChannelValue from './lights-wheel-color-channel-value'; | ||
import LightsWheelGoboChannelValue from './lights-wheel-gobo-channel-value'; | ||
import LightsWheelRotateChannelValue from './lights-wheel-rotate-channel-value'; | ||
import { RgbColor, rgbColorDefinitions, WheelColor } from '../color-definitions'; | ||
import Colors from './colors'; | ||
import LightsFixtureShutterOptions, { ShutterOption } from './lights-fixture-shutter-options'; | ||
|
||
export interface IColorsWheel { | ||
colorChannel: number; | ||
goboChannel: number; | ||
goboRotateChannel?: number | null; | ||
} | ||
|
||
export default class ColorsWheel extends Colors implements IColorsWheel { | ||
@Column({ type: 'tinyint', unsigned: true }) | ||
public masterDimChannel: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true, nullable: true }) | ||
public shutterChannel?: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true }) | ||
public colorChannel: number; | ||
|
||
@Column({ type: 'tinyint', unsigned: true }) | ||
public goboChannel: number; | ||
|
||
@Column({ type: 'tinyint', nullable: true, unsigned: true }) | ||
public goboRotateChannel: number | null; | ||
|
||
@OneToMany(() => LightsWheelColorChannelValue, (c) => c.movingHead, { eager: true }) | ||
public colorChannelValues: LightsWheelColorChannelValue[]; | ||
|
||
@OneToMany(() => LightsWheelGoboChannelValue, (c) => c.movingHead, { eager: true }) | ||
public goboChannelValues: LightsWheelGoboChannelValue[]; | ||
|
||
@OneToMany(() => LightsWheelRotateChannelValue, (c) => c.movingHead, { eager: true }) | ||
public goboRotateChannelValues: LightsWheelRotateChannelValue[]; | ||
|
||
private strobePing = false; | ||
|
||
private currentValues: IColorsWheel = { | ||
colorChannel: 0, | ||
goboChannel: 0, | ||
goboRotateChannel: 0, | ||
}; | ||
|
||
public setColor(color: RgbColor): void { | ||
const wheelColor = rgbColorDefinitions[color].alternative; | ||
const channelValueObj = this.colorChannelValues.find((v) => v.name === wheelColor); | ||
this.currentValues = { | ||
...this.currentValues, | ||
colorChannel: channelValueObj?.value ?? 0, | ||
}; | ||
} | ||
|
||
public setGobo(gobo?: string) { | ||
const channelValueObj = this.goboChannelValues.find((v) => v.name === gobo); | ||
this.currentValues = { | ||
...this.currentValues, | ||
goboChannel: channelValueObj?.value ?? 0, | ||
}; | ||
} | ||
|
||
public setGoboRotate(rotate?: string) { | ||
const channelValueObj = this.goboRotateChannelValues.find((v) => v.name === rotate); | ||
this.currentValues = { | ||
...this.currentValues, | ||
goboRotateChannel: channelValueObj?.value ?? 0, | ||
}; | ||
} | ||
|
||
public reset(): void { | ||
this.currentValues = { | ||
colorChannel: 0, | ||
goboChannel: 0, | ||
goboRotateChannel: 0, | ||
}; | ||
} | ||
|
||
private get channelValues() { | ||
return this.currentValues; | ||
} | ||
|
||
public setStrobeInDmx(values: number[], shutterOptions: LightsFixtureShutterOptions[]): number[] { | ||
if (this.shutterChannel) | ||
values[this.shutterChannel - 1] = | ||
shutterOptions.find((o) => o.shutterOption === ShutterOption.STROBE)?.channelValue ?? 0; | ||
values[this.colorChannel - 1] = | ||
this.colorChannelValues.find((o) => o.name === WheelColor.WHITE)?.value ?? 0; | ||
|
||
if (this.shutterChannel || this.strobePing) { | ||
// If we have a shutter channel or we should manually strobe, | ||
// turn on the light | ||
values[this.masterDimChannel - 1] = 255; | ||
} else if (!this.shutterChannel) { | ||
// If we do not have a shutter channel and the ping is off, | ||
// turn off the light | ||
values[this.masterDimChannel - 1] = 0; | ||
} | ||
|
||
// If we have no shutter channel, manually flip the strobe bit | ||
if (!this.shutterChannel) { | ||
this.strobePing = !this.strobePing; | ||
} | ||
return values; | ||
} | ||
|
||
public setColorsInDmx(values: number[], shutterOptions: LightsFixtureShutterOptions[]): number[] { | ||
values[this.masterDimChannel - 1] = Math.round(this.currentBrightness * 255); | ||
if (this.shutterChannel) | ||
values[this.shutterChannel - 1] = | ||
shutterOptions.find((o) => o.shutterOption === ShutterOption.OPEN)?.channelValue ?? 0; | ||
values[this.colorChannel - 1] = this.channelValues.colorChannel; | ||
values[this.goboChannel - 1] = this.channelValues.goboChannel; | ||
if (this.goboRotateChannel != null) { | ||
values[this.goboRotateChannel - 1] = this.channelValues.goboRotateChannel || 0; | ||
} | ||
|
||
return values; | ||
} | ||
} |
Oops, something went wrong.