import { clamp , roundTo } from "alcalzone-shared/math" ; import { padStart } from "alcalzone-shared/strings" ; import { PropertyTransformKernel } from "./ipsoObject" ; import { Light } from "./light" ; import { colorTemperatureRange , MAX_COLOR } from "./predefined-colors" ; const colorTemperature_out = ( value ) => { const [ min , max ] = colorTemperatureRange ; value = clamp ( value , 0 , 100 ) ; return roundTo ( min + ( value / 100 ) * ( max - min ) , 0 ) ; } ; const colorTemperature_in = ( value ) => { const [ min , max ] = colorTemperatureRange ; value = ( value - min ) / ( max - min ) ; value = clamp ( value , 0 , 1 ) ; return roundTo ( value * 100 , 1 ) ; } ; function rgbToHSV ( r , g , b ) { [ r , g , b ] = [ r , g , b ] . map ( ( c ) => c / 255 ) ; const max = Math . max ( r , g , b ) ; const min = Math . min ( r , g , b ) ; let h ; let s ; const v = roundTo ( max , 2 ) ; if ( r === g && g === b ) { h = 0 ; } else if ( max === r ) { h = 60 * ( 0 + ( g - b ) / ( max - min ) ) ; } else if ( max === g ) { h = 60 * ( 2 + ( b - r ) / ( max - min ) ) ; } else if ( max === b ) { h = 60 * ( 4 + ( r - g ) / ( max - min ) ) ; } h = Math . round ( h ! ) ; if ( h < 0 ) h += 360 ; if ( max === 0 ) { s = 0 ; } else { s = roundTo ( ( max - min ) / max , 3 ) ; } return { h , s , v } ; } function rgbFromHSV ( h , s , v ) { let r ; let g ; let b ; if ( s === 0 ) { r = g = b = v ; } else { const hi = Math . floor ( h / 60 ) ; const f = h / 60 - hi ; const p = v * ( 1 - s ) ; const q = v * ( 1 - s * f ) ; const t = v * ( 1 - s * ( 1 - f ) ) ; switch ( hi ) { case 0 : case 6 : [ r , g , b ] = [ v , t , p ] ; break ; case 1 : [ r , g , b ] = [ q , v , p ] ; break ; case 2 : [ r , g , b ] = [ p , v , t ] ; break ; case 3 : [ r , g , b ] = [ p , q , v ] ; break ; case 4 : [ r , g , b ] = [ t , p , v ] ; break ; case 5 : [ r , g , b ] = [ v , p , q ] ; break ; } } [ r , g , b ] = [ r ! , g ! , b ! ] . map ( ( c ) => Math . round ( clamp ( c , 0 , 1 ) * 255 ) ) ; return { r , g , b } ; } function rgbToString ( r , g , b ) { return [ r , g , b ] . map ( ( c ) => padStart ( c . toString ( 16 ) , 2 , "0" ) ) . join ( "" ) ; } function rgbFromString ( rgb ) { const r = parseInt ( rgb . substr ( 0 , 2 ) , 16 ) ; const g = parseInt ( rgb . substr ( 2 , 2 ) , 16 ) ; const b = parseInt ( rgb . substr ( 4 , 2 ) , 16 ) ; return { r , g , b } ; } const hue_out = ( value , light ? ) => { if ( light != null && light . spectrum !== "rgb" ) return null ; value = clamp ( value , 0 , 360 ) ; return roundTo ( ( value / 360 ) * MAX_COLOR , 0 ) ; } ; const hue_in = ( value ) => { value = clamp ( value / MAX_COLOR , 0 , 1 ) ; return roundTo ( value * 360 , 1 ) ; } ; const saturation_out = ( value , light ? ) => { if ( light != null && light . spectrum !== "rgb" ) return null ; value = clamp ( value , 0 , 100 ) ; return roundTo ( ( value / 100 ) * MAX_COLOR , 0 ) ; } ; const saturation_in = ( value ) => { value = clamp ( value / MAX_COLOR , 0 , 1 ) ; return roundTo ( value * 100 , 1 ) ; } ; const transitionTime_out = ( val ) => val && val * 10 ; const transitionTime_in = ( val ) => val / 10 ; const brightness_out = ( value ) => { value = clamp ( value , 0 , 100 ) ; return roundTo ( ( value / 100 ) * 254 , 0 ) ; } ; const brightness_in = ( value ) => { value = clamp ( value , 0 , 254 ) ; if ( value === 0 ) return 0 ; value = ( value / 254 ) * 100 ; return roundTo ( value , 1 ) ; } ; const position_out = ( val ) => 100 - val ; const position_in = position_out ; const fan_speed_out = ( val ) => { if ( val === 0 ) return 0 ; if ( val < 10 ) return 10 ; if ( val > 50 ) return 50 ; return Math . round ( val / 5 ) * 5 ; } ; const boolean_inverted_out = ( bool ) => bool ? 0 : 1 ; const boolean_inverted_in = ( raw ) => ! ( raw === 1 || raw === "true" || raw === "on" || raw === true ) ; export const serializers = { transitionTime : transitionTime_out , hue : hue_out , saturation : saturation_out , brightness : brightness_out , colorTemperature : colorTemperature_out , position : position_out , booleanInverted : boolean_inverted_out , fanSpeed : fan_speed_out , } ; export const deserializers = { transitionTime : transitionTime_in , hue : hue_in , saturation : saturation_in , brightness : brightness_in , colorTemperature : colorTemperature_in , position : position_in , booleanInverted : boolean_inverted_in , } ; export const conversions = { rgbFromHSV , rgbToHSV , rgbToString , rgbFromString , } ;