diff --git a/.eslintcache b/.eslintcache index 73d3cb2..cce26c1 100644 --- a/.eslintcache +++ b/.eslintcache @@ -1 +1 @@ -[{"/home/nathan/source/inovelli-led-strip-toolbox/src/index.js":"1","/home/nathan/source/inovelli-led-strip-toolbox/src/swconfig.js":"2","/home/nathan/source/inovelli-led-strip-toolbox/src/AppWrapper.js":"3","/home/nathan/source/inovelli-led-strip-toolbox/src/App.js":"4","/home/nathan/source/inovelli-led-strip-toolbox/src/ThemeProvider.js":"5","/home/nathan/source/inovelli-led-strip-toolbox/src/Strip.js":"6","/home/nathan/source/inovelli-led-strip-toolbox/src/AppBar.js":"7","/home/nathan/source/inovelli-led-strip-toolbox/src/Options.js":"8","/home/nathan/source/inovelli-led-strip-toolbox/src/CustomStripEffects.js":"9","/home/nathan/source/inovelli-led-strip-toolbox/src/LED.js":"10","/home/nathan/source/inovelli-led-strip-toolbox/src/CustomEffectEditor.js":"11","/home/nathan/source/inovelli-led-strip-toolbox/src/HomeAssistantIcon.js":"12","/home/nathan/source/inovelli-led-strip-toolbox/src/ParameterModal.js":"13","/home/nathan/source/inovelli-led-strip-toolbox/src/SaveAsIcon.js":"14","/home/nathan/source/inovelli-led-strip-toolbox/src/SaveIcon.js":"15","/home/nathan/source/inovelli-led-strip-toolbox/src/SaveDialog.js":"16","/home/nathan/source/inovelli-led-strip-toolbox/src/ImportProgram.js":"17","/home/nathan/source/inovelli-led-strip-toolbox/src/OpenDialog.js":"18","/home/nathan/source/inovelli-led-strip-toolbox/src/Utils.js":"19","/home/nathan/source/inovelli-led-strip-toolbox/src/ClipboardAccess.js":"20","/home/nathan/source/inovelli-led-strip-toolbox/src/AboutDialog.js":"21","/home/nathan/source/inovelli-led-strip-toolbox/src/ShareDialog.js":"22","/home/nathan/source/inovelli-led-strip-toolbox/src/service-worker.js":"23","/home/nathan/source/inovelli-led-strip-toolbox/src/serviceWorkerRegistration.js":"24","/home/nathan/source/inovelli-led-strip-toolbox/src/reportWebVitals.js":"25"},{"size":673,"mtime":1609907230223,"results":"26","hashOfConfig":"27"},{"size":268,"mtime":1609804151378,"results":"28","hashOfConfig":"27"},{"size":519,"mtime":1609804875869,"results":"29","hashOfConfig":"27"},{"size":8125,"mtime":1609889361748,"results":"30","hashOfConfig":"27"},{"size":1539,"mtime":1609804151370,"results":"31","hashOfConfig":"27"},{"size":2337,"mtime":1609804151369,"results":"32","hashOfConfig":"27"},{"size":1013,"mtime":1609889386785,"results":"33","hashOfConfig":"27"},{"size":3874,"mtime":1609804252874,"results":"34","hashOfConfig":"27"},{"size":20884,"mtime":1609899698961,"results":"35","hashOfConfig":"27"},{"size":2516,"mtime":1609804151363,"results":"36","hashOfConfig":"27"},{"size":4325,"mtime":1609804151358,"results":"37","hashOfConfig":"27"},{"size":1181,"mtime":1609804151361,"results":"38","hashOfConfig":"27"},{"size":9236,"mtime":1609804151366,"results":"39","hashOfConfig":"27"},{"size":645,"mtime":1609804151367,"results":"40","hashOfConfig":"27"},{"size":422,"mtime":1609804151368,"results":"41","hashOfConfig":"27"},{"size":1013,"mtime":1609804151368,"results":"42","hashOfConfig":"27"},{"size":1514,"mtime":1609804151362,"results":"43","hashOfConfig":"27"},{"size":4402,"mtime":1609804151363,"results":"44","hashOfConfig":"27"},{"size":1598,"mtime":1609804151371,"results":"45","hashOfConfig":"27"},{"size":1095,"mtime":1609804151357,"results":"46","hashOfConfig":"27"},{"size":2175,"mtime":1609889188886,"results":"47","hashOfConfig":"27"},{"size":2872,"mtime":1609899465406,"results":"48","hashOfConfig":"27"},{"size":2837,"mtime":1609907109824,"results":"49","hashOfConfig":"50"},{"size":5064,"mtime":1609907080375,"results":"51","hashOfConfig":"27"},{"size":364,"mtime":1609907068474,"results":"52","hashOfConfig":"50"},{"filePath":"53","messages":"54","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},"jq0hv9",{"filePath":"56","messages":"57","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"58","usedDeprecatedRules":"55"},{"filePath":"59","messages":"60","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"61","messages":"62","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"63","usedDeprecatedRules":"55"},{"filePath":"64","messages":"65","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"66","messages":"67","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"68","messages":"69","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"70","messages":"71","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"72","messages":"73","errorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"74","usedDeprecatedRules":"55"},{"filePath":"75","messages":"76","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"77","messages":"78","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"79","messages":"80","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"81","messages":"82","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"83","messages":"84","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"85","messages":"86","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"87","messages":"88","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"89","messages":"90","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"91","messages":"92","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"93","messages":"94","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"95","messages":"96","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"97","messages":"98","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"99","messages":"100","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"101","messages":"102","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"8stn2s",{"filePath":"103","messages":"104","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"55"},{"filePath":"105","messages":"106","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/nathan/source/inovelli-led-strip-toolbox/src/index.js",[],["107","108"],"/home/nathan/source/inovelli-led-strip-toolbox/src/swconfig.js",["109"],"export default {\r\n onUpdate: registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n },\r\n onSuccess: registration => {\r\n console.info(\"service worker on success state\");\r\n console.log(registration);\r\n }\r\n};\r\n","/home/nathan/source/inovelli-led-strip-toolbox/src/AppWrapper.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/App.js",["110","111","112"],"import React from \"react\";\nimport { CssBaseline, withStyles, Tabs, Tab } from \"@material-ui/core\";\nimport Strip from \"./Strip\";\n\nimport AppBar from \"./AppBar\";\nimport Options from \"./Options\";\nimport CustomStripEffects from \"./CustomStripEffects\";\n\nimport {\n createConnection,\n callService,\n createLongLivedTokenAuth,\n} from \"home-assistant-js-websocket\";\nimport AboutDialog from \"./AboutDialog\";\n\nconst styles = (theme) => ({\n root: {\n //height: \"98vh\",\n display: \"flex\",\n alignItems: \"center\",\n flexDirection: \"column\",\n \"&>:first-child\": {\n //flex: \"0 0 auto\",\n width: \"100%\",\n },\n \"&>:last-child\": {\n flex: \"1 1 100%\",\n display: \"flex\",\n width: \"100%\",\n alignItems: \"stretch\",\n justifyContent: \"center\",\n },\n },\n tabWrapper: {\n width: \"100%\",\n },\n areaWrapper: {\n display: \"flex\",\n alignItems: \"stretch\",\n \"&>:first-child\": {\n flex: \"1 1 100%\",\n //alignItems: \"center\",\n display: \"flex\",\n justifyContent: \"center\",\n maxWidth: \"800px\",\n },\n \"&>:last-child\": {\n //justifyItem: \"start\",\n //minWidth: \"400px\",\n //backgroundColor: theme.palette.background.paper,\n },\n },\n});\n\nclass App extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n customStripEffects: [],\n finishBehavior: 0,\n HA_URL: window.localStorage.getItem(\"HA_URL\"),\n HA_TOKEN: window.localStorage.getItem(\"HA_TOKEN\"),\n HA_NODE: window.localStorage.getItem(\"HA_NODE\"),\n HA_SERVICE: window.localStorage.getItem(\"HA_SERVICE\"),\n valueFormat: window.localStorage.getItem(\"valueFormat\") || 10,\n aboutDialogOpen: false\n };\n\n if (this.state.HA_URL && this.state.HA_TOKEN) {\n (async () => {\n const auth = createLongLivedTokenAuth(\n this.state.HA_URL,\n this.state.HA_TOKEN\n );\n\n const connection = await createConnection({ auth });\n this.setState({ homeAssistant: connection }, () => {\n console.info(\"Home Assistant Connection Saved to State....\");\n });\n })();\n }\n }\n\n handleChangeTab = (e, value) => {\n this.setState({ tab: value });\n };\n\n handleParameter10Changes = (field, value) => {\n this.setState({\n parameter10: { ...this.state.parameter10, [field]: value },\n });\n };\n\n handleCustomStripEffectChange = (effectArray) => {\n this.setState({\n customStripEffects: effectArray,\n });\n };\n\n handleTimeUnitChange = (unit) => {\n this.setState({ timeUnit: unit });\n };\n\n handleFinishBehaviorChange = (behavior) => {\n this.setState({ finishBehavior: behavior });\n };\n\n handleOnPlay = (lightShow) => {\n this.setState({ lightShow });\n };\n\n handleOpenOptions = () => {\n this.setState({ optionsOpen: true });\n };\n\n handleOptionsClosed = () => {\n this.setState({ optionsOpen: false });\n if (this.state.homeAssistant) {\n this.state.homeAssistant.close();\n }\n if (this.state.HA_URL && this.state.HA_TOKEN) {\n (async () => {\n const auth = createLongLivedTokenAuth(\n this.state.HA_URL,\n this.state.HA_TOKEN\n );\n\n const connection = await createConnection({ auth });\n this.setState({ homeAssistant: connection }, () => {\n console.info(\"Home Assistant Connection Saved to State....\");\n });\n })();\n }\n };\n\n handleHomeAssistantURLChange = (value) => {\n this.setState({ HA_URL: value });\n window.localStorage.setItem(\"HA_URL\", value);\n };\n\n handleHomeAssistantTokenChange = (value) => {\n this.setState({ HA_TOKEN: value });\n window.localStorage.setItem(\"HA_TOKEN\", value);\n };\n\n handleHomeAssistantNodeChange = (value) => {\n this.setState({ HA_NODE: value });\n window.localStorage.setItem(\"HA_NODE\", value);\n };\n\n handleHomeAssistantServiceChange = (value) => {\n this.setState({ HA_SERVICE: value });\n window.localStorage.setItem(\"HA_SERVICE\", value);\n };\n\n handleChangeValueFormat = (value) => {\n this.setState({ valueFormat: value });\n window.localStorage.setItem(\"valueFormat\", value);\n };\n\n handleChangeThemeValue = (value) => {\n this.setState({theme:value});\n window.localStorage.setItem(\"theme\",value);\n }\n\n sendProgamThroughHomeAssistant = (program) => {\n const SERVICE_PARTS = this.state.HA_SERVICE.split(\".\");\n console.log(SERVICE_PARTS);\n const HA_SERVICE_DOMAIN = SERVICE_PARTS[0];\n const HA_SERVICE = SERVICE_PARTS[1];\n console.log(SERVICE_PARTS[0], SERVICE_PARTS[1]);\n Promise.all([\n callService(this.state.homeAssistant, HA_SERVICE_DOMAIN, HA_SERVICE, {\n node_id: parseInt(this.state.HA_NODE),\n parameter: 30,\n value: 0,\n }),\n ...program.map(async (parameter) => {\n return callService(\n this.state.homeAssistant,\n HA_SERVICE_DOMAIN,\n HA_SERVICE,\n {\n node_id: parseInt(this.state.HA_NODE),\n parameter: parseInt(parameter.number),\n value: parseInt(parameter.value),\n }\n );\n }),\n ])\n .then(() => {\n console.info(\"Successfully sent to Home Assistant\");\n })\n .catch((ex) => {\n console.error(ex);\n });\n };\n\n handleCloseAboutDialog = () => {\n this.setState({aboutDialogOpen:false})\n }\n\n handleOpenAboutDialog = () => {\n this.setState({aboutDialogOpen: true});\n }\n\n render() {\n return (\n \n \n \n \n
\n
\n {/* \n \n \n \n \n */}\n {/*
\n {this.state.tab === 0 && (\n \n )}\n {this.state.tab === 2 && (\n \n )} \n
*/}\n
\n
\n {/*
\n \n
*/}\n {/*
*/}\n \n \n {/*
*/}\n
\n
\n
\n );\n }\n}\n\nexport default withStyles(styles)(App);\n","/home/nathan/source/inovelli-led-strip-toolbox/src/ThemeProvider.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/Strip.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/AppBar.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/Options.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/CustomStripEffects.js",["113","114","115","116","117","118"],"import React from \"react\";\nimport {\n FormControl,\n IconButton,\n InputLabel,\n Menu,\n MenuItem,\n List,\n ListItem,\n ListItemIcon,\n ListItemText,\n ListItemSecondaryAction,\n Select,\n TextField,\n withStyles,\n Divider,\n InputAdornment,\n Tooltip,\n SvgIcon,\n Button,\n Typography,\n Grid,\n Slider,\n FormHelperText,\n} from \"@material-ui/core\";\nimport Add from \"@material-ui/icons/Add\";\nimport Light from \"@material-ui/icons/EmojiObjects\";\nimport MoreVert from \"@material-ui/icons/MoreVert\";\nimport CustomEffectEditor from \"./CustomEffectEditor\";\nimport Open from \"@material-ui/icons/FolderOpen\";\nimport Import from \"@material-ui/icons/SaveAlt\";\nimport PlayIcon from \"@material-ui/icons/PlayArrow\";\nimport FormatListNumberedIcon from \"@material-ui/icons/FormatListNumbered\";\nimport {\n byteArrayToLong,\n longToByteArray,\n shortToByteArray,\n UNITS,\n COLORS,\n EFFECTS,\n FINISHES,\n} from \"./Utils\";\nimport ParameterModal from \"./ParameterModal\";\nimport InfiniteIcon from \"@material-ui/icons/AllInclusive\";\nimport TimelapseIcon from \"@material-ui/icons/Timelapse\";\nimport SaveDialog from \"./SaveDialog\";\nimport OpenDialog from \"./OpenDialog\";\nimport HomeAssistantIcon from \"./HomeAssistantIcon\";\nimport SaveIcon from \"./SaveIcon\";\nimport SaveAsIcon from \"./SaveAsIcon\";\nimport NewIcon from \"@material-ui/icons/AddBox\";\nimport ShareIcon from '@material-ui/icons/Share';\nimport ImportProgram from \"./ImportProgram\";\nimport qs from 'qs';\nimport ShareDialog from './ShareDialog';\n\nconst styles = (theme) => ({\n root: {\n display: \"flex\",\n flexDirection: \"row-reverse\",\n },\n});\n\nclass CustomStripEffects extends React.Component {\n static defaultProps = {\n timeUnit: 1,\n finishBehavior: 0,\n };\n constructor(props) {\n super(props);\n this.state = {\n editorOpen: false,\n effects: [],\n selectedEffect: undefined,\n effect: {},\n anchorEl: null,\n iterations: 255,\n timeUnit: 1,\n finishBehavior: 0,\n saveDialogOpen: false,\n openDialogOpen: false,\n savedAnimation: { animation: {} },\n indexOfSavedAnimation: null,\n importProgramDialogOpen: false,\n shareDialogOpen: false,\n };\n }\n\n componentDidMount(){\n //Import Program from Share Link\n if(window.location.search){\n let query = qs.parse(window.location.search.replace(/\\?/,\"\"));\n console.log(query);\n let COLORS = longToByteArray(query.p22).map(\n (colorEffect) => shortToByteArray(colorEffect)[1]\n );\n let EFFECTS = longToByteArray(query.p22).map(\n (colorEffect) => shortToByteArray(colorEffect)[0]\n );\n let BRIGHTNESS = longToByteArray(query.p23);\n let DURATIONS = longToByteArray(query.p24);\n let SETTINGS = longToByteArray(query.p30);\n //console.log(COLORS, EFFECTS, BRIGHTNESS, DURATIONS);\n //Drop Empty Effects\n for (let i = COLORS.length - 1; i >= 0; i--) {\n if (DURATIONS[i] !== 0) {\n break;\n }\n COLORS.pop();\n EFFECTS.pop();\n BRIGHTNESS.pop();\n DURATIONS.pop();\n }\n COLORS.reverse();\n EFFECTS.reverse();\n BRIGHTNESS.reverse();\n DURATIONS.reverse();\n //console.log(COLORS, EFFECTS, BRIGHTNESS, DURATIONS);\n const IMPORTED_EFFECTS = COLORS.map((color, index) => ({\n color: color,\n effect: EFFECTS[index],\n brightness: BRIGHTNESS[index],\n duration: DURATIONS[index],\n }));\n \n this.setState({\n effects: IMPORTED_EFFECTS,\n iterations: SETTINGS[0],\n finishBehavior: SETTINGS[1],\n timeUnit: SETTINGS[2],\n });\n }\n \n }\n\n openContextMenu = (selectedEffect) => (e) => {\n this.setState({ selectedEffect, anchorEl: e.currentTarget });\n };\n\n handleCloseContextMenu = () => {\n this.setState({ selectedEffect: undefined, anchorEl: null });\n };\n\n handleEditEffect = (i) => () => {\n this.setState({\n editorOpen: true,\n effect: Object.assign({}, this.state.effects[i]),\n selectedEffect: i,\n });\n };\n\n handleAddEffect = () => {\n this.setState({\n editorOpen: true,\n selectedEffect: undefined,\n effect: {\n color: 0,\n effect: 0,\n brightness: 99,\n duration: 1,\n },\n });\n };\n\n handleFinishBehaviorChange = (e) => {\n const { value } = e.target;\n this.setState({ finishBehavior: value });\n };\n\n onCloseEditor = () => {\n this.setState({ editorOpen: false });\n };\n\n onSave = (effect) => {\n this.setState((lastState) => {\n let effects = JSON.parse(JSON.stringify(lastState.effects));\n if (lastState.selectedEffect !== undefined) {\n effects[lastState.selectedEffect] = effect;\n } else {\n effects.push(effect);\n }\n return { effects, editorOpen: false, selectedEffect: undefined };\n });\n };\n\n handleTimeUnitChange = (e) => {\n const { value } = e.target;\n this.setState({ timeUnit: value });\n };\n\n handleDeleteEffect = () => {\n this.setState((lastState) => {\n let effects = JSON.parse(JSON.stringify(lastState.effects));\n effects.splice(this.state.selectedEffect, 1);\n return {\n anchorEl: null,\n effects,\n selectedEffect: undefined,\n };\n });\n };\n\n get parameter22() {\n return byteArrayToLong(\n Array.from(this.state.effects)\n .reverse()\n .map((effect) => effect.effect + effect.color * 8)\n ).toString(Number(this.props.format || 10));\n }\n\n get parameter23() {\n return byteArrayToLong(\n Array.from(this.state.effects)\n .reverse()\n .map((effect) => effect.brightness)\n ).toString(Number(this.props.format || 10));\n }\n\n get parameter24() {\n return byteArrayToLong(\n Array.from(this.state.effects)\n .reverse()\n .map((effect) => effect.duration)\n ).toString(Number(this.props.format || 10));\n }\n\n get parameter30() {\n return byteArrayToLong([\n this.state.iterations,\n this.state.finishBehavior,\n this.state.timeUnit,\n ]).toString(Number(this.props.format || 10));\n }\n\n toggleParameterModal = () => {\n this.setState((lastState) => ({\n parameterModalOpen: !lastState.parameterModalOpen,\n }));\n };\n\n setIterations = (e, value) => {\n this.setState({ iterations: value });\n };\n\n handleSaveDialog = () => {\n this.setState({ saveDialogOpen: true });\n };\n\n handleCloseSaveDialog = () => {\n this.setState({ saveDialogOpen: false });\n };\n\n handleSaveAnimation = (name) => {\n let animations = JSON.parse(window.localStorage.getItem(\"animations\"));\n if (!animations) {\n animations = [];\n }\n\n const date = new Date();\n\n animations.push({\n date: date.getTime(),\n animation: {\n iterations: this.state.iterations,\n finishBehavior: this.state.finishBehavior || 0,\n timeUnit: this.state.timeUnit,\n effects: this.state.effects,\n },\n name,\n });\n\n window.localStorage.setItem(\"animations\", JSON.stringify(animations));\n\n this.setState({\n saveDialogOpen: false,\n savedAnimation: {\n date: date.getTime(),\n animation: {\n iterations: this.state.iterations,\n finishBehavior: this.state.finishBehavior || 0,\n timeUnit: this.state.timeUnit,\n effects: this.state.effects,\n },\n name,\n },\n indexOfSavedAnimation: animations.length - 1,\n });\n };\n\n handleSaveToCurrentProgram = () => {\n let animations = JSON.parse(window.localStorage.getItem(\"animations\"));\n if (!animations) {\n animations = [];\n }\n\n const date = new Date();\n\n animations[this.state.indexOfSavedAnimation] = {\n date: date.getTime(),\n animation: {\n iterations: this.state.iterations,\n finishBehavior: this.state.finishBehavior || 0,\n timeUnit: this.state.timeUnit,\n effects: this.state.effects,\n },\n name: this.state.savedAnimation.name,\n };\n\n this.setState({\n savedAnimation: {\n date: date.getTime(),\n animation: {\n iterations: this.state.iterations,\n finishBehavior: this.state.finishBehavior || 0,\n timeUnit: this.state.timeUnit,\n effects: this.state.effects,\n },\n name: this.state.savedAnimation.name,\n },\n });\n\n window.localStorage.setItem(\"animations\", JSON.stringify(animations));\n };\n\n handleOpenDialog = () => {\n this.setState({ openDialogOpen: true });\n };\n\n handleCloseOpenDialog = () => {\n this.setState({ openDialogOpen: false });\n };\n\n handleOpenSavedAnimation = (index, entry) => {\n this.setState({\n openDialogOpen: false,\n indexOfSavedAnimation: index,\n savedAnimation: entry,\n iterations: entry.animation.iterations,\n timeUnit: entry.animation.timeUnit,\n effects: entry.animation.effects,\n finishBehavior: entry.animation.finishBehavior,\n });\n };\n\n handlePlayAnimationClick = () => {\n this.props.onPlay(\n JSON.parse(\n JSON.stringify({\n effects: this.state.effects,\n iterations: this.state.iterations,\n timeUnit: this.state.timeUnit,\n })\n )\n );\n };\n\n sendProgramToHomeAssistant = () => {\n this.props.onSendToHomeAssistant([\n { number: 22, value: this.parameter22 },\n { number: 23, value: this.parameter23 },\n { number: 24, value: this.parameter24 },\n { number: 30, value: this.parameter30 },\n ]);\n };\n\n handleStartNew = () => {\n this.setState({\n effects: [],\n selectedEffect: undefined,\n effect: {},\n anchorEl: null,\n iterations: 255,\n timeUnit: 1,\n finishBehavior: 0,\n savedAnimation: { animation: {} },\n indexOfSavedAnimation: null,\n });\n };\n\n handleOpenImportProgramDialog = () => {\n this.setState({\n importProgramDialogOpen: true,\n });\n };\n\n handleCloseImportProgramDialog = () => {\n this.setState({ importProgramDialogOpen: false });\n };\n\n handleImportProgram = (program) => {\n const PARAMETERS = program.split(\",\");\n console.log(longToByteArray(PARAMETERS[0]));\n let COLORS = longToByteArray(PARAMETERS[0]).map(\n (colorEffect) => shortToByteArray(colorEffect)[1]\n );\n let EFFECTS = longToByteArray(PARAMETERS[0]).map(\n (colorEffect) => shortToByteArray(colorEffect)[0]\n );\n let BRIGHTNESS = longToByteArray(PARAMETERS[1]);\n let DURATIONS = longToByteArray(PARAMETERS[2]);\n let SETTINGS = longToByteArray(PARAMETERS[3]);\n //console.log(COLORS, EFFECTS, BRIGHTNESS, DURATIONS);\n //Drop Empty Effects\n for (let i = COLORS.length - 1; i >= 0; i--) {\n if (DURATIONS[i] !== 0) {\n break;\n }\n COLORS.pop();\n EFFECTS.pop();\n BRIGHTNESS.pop();\n DURATIONS.pop();\n }\n COLORS.reverse();\n EFFECTS.reverse();\n BRIGHTNESS.reverse();\n DURATIONS.reverse();\n //console.log(COLORS, EFFECTS, BRIGHTNESS, DURATIONS);\n const IMPORTED_EFFECTS = COLORS.map((color, index) => ({\n color: color,\n effect: EFFECTS[index],\n brightness: BRIGHTNESS[index],\n duration: DURATIONS[index],\n }));\n\n this.setState({\n importProgramDialogOpen: false,\n effects: IMPORTED_EFFECTS,\n iterations: SETTINGS[0],\n finishBehavior: SETTINGS[1],\n timeUnit: SETTINGS[2],\n });\n };\n\n handleOpenShareDialog = () => {\n this.setState({shareDialogOpen: true});\n }\n\n handleCloseShareDialog = () => {\n this.setState({shareDialogOpen: false});\n }\n\n render() {\n const IS_SAVED_PROGRAM_CHANGED =\n JSON.stringify(this.state.savedAnimation.animation.effects) !==\n JSON.stringify(this.state.effects) ||\n this.state.timeUnit !== this.state.savedAnimation.animation.timeUnit ||\n this.state.iterations !==\n this.state.savedAnimation.animation.iterations ||\n this.state.finishBehavior !==\n this.state.savedAnimation.animation.finishBehavior;\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {this.state.savedAnimation.name && (\n \n \n {this.state.savedAnimation.name}{\" \"}\n {IS_SAVED_PROGRAM_CHANGED && (\n \n (Modified)\n \n )}\n \n \n )}\n \n \n \n Time Unit\n \n {UNITS.map((unit, index) => (\n {unit}\n ))}\n \n \n \n \n {this.state.effects.map((effect, i) => (\n \n \n \n \n \n \n \n \n \n \n Delete\n \n \n \n ))}\n {this.state.effects.length < 4 && (\n \n \n \n \n \n \n )}\n {this.state.effects.length > 0 && (\n \n \n \n
\n \n Iterations\n \n
\n \n \n \n \n \n \n \n \n \n \n \n
\n
\n
\n \n \n Finish Behavior\n \n Off\n Previous Color\n Last Color In Sequence\n \n {this.state.iterations === 255 && (\n \n No Finish Behavior for Infinite Iterations\n \n )}\n \n \n \n {/* \n \n \n \n \n */}\n \n \n \n \n \n \n {this.props.isHomeAssistantConfigured && \n \n \n \n \n } \n
\n )}\n
\n \n \n \n \n \n \n
\n );\n }\n}\n\nexport default withStyles(styles)(CustomStripEffects);\n","/home/nathan/source/inovelli-led-strip-toolbox/src/LED.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/CustomEffectEditor.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/HomeAssistantIcon.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ParameterModal.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/SaveAsIcon.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/SaveIcon.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/SaveDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ImportProgram.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/OpenDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/Utils.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ClipboardAccess.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/AboutDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ShareDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/service-worker.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/serviceWorkerRegistration.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/reportWebVitals.js",[],{"ruleId":"119","replacedBy":"120"},{"ruleId":"121","replacedBy":"122"},{"ruleId":"123","severity":1,"message":"124","line":1,"column":1,"nodeType":"125","endLine":11,"endColumn":3},{"ruleId":"126","severity":1,"message":"127","line":2,"column":35,"nodeType":"128","messageId":"129","endLine":2,"endColumn":39},{"ruleId":"126","severity":1,"message":"130","line":2,"column":41,"nodeType":"128","messageId":"129","endLine":2,"endColumn":44},{"ruleId":"126","severity":1,"message":"131","line":3,"column":8,"nodeType":"128","messageId":"129","endLine":3,"endColumn":13},{"ruleId":"126","severity":1,"message":"132","line":14,"column":3,"nodeType":"128","messageId":"129","endLine":14,"endColumn":12},{"ruleId":"126","severity":1,"message":"133","line":17,"column":3,"nodeType":"128","messageId":"129","endLine":17,"endColumn":17},{"ruleId":"126","severity":1,"message":"134","line":19,"column":3,"nodeType":"128","messageId":"129","endLine":19,"endColumn":10},{"ruleId":"126","severity":1,"message":"135","line":20,"column":3,"nodeType":"128","messageId":"129","endLine":20,"endColumn":9},{"ruleId":"126","severity":1,"message":"136","line":32,"column":8,"nodeType":"128","messageId":"129","endLine":32,"endColumn":16},{"ruleId":"126","severity":1,"message":"137","line":41,"column":3,"nodeType":"128","messageId":"129","endLine":41,"endColumn":11},"no-native-reassign",["138"],"no-negated-in-lhs",["139"],"import/no-anonymous-default-export","Assign object to a variable before exporting as module default","ExportDefaultDeclaration","no-unused-vars","'Tabs' is defined but never used.","Identifier","unusedVar","'Tab' is defined but never used.","'Strip' is defined but never used.","'TextField' is defined but never used.","'InputAdornment' is defined but never used.","'SvgIcon' is defined but never used.","'Button' is defined but never used.","'PlayIcon' is defined but never used.","'FINISHES' is defined but never used.","no-global-assign","no-unsafe-negation"] \ No newline at end of file +[{"/home/nathan/source/inovelli-led-strip-toolbox/src/index.js":"1","/home/nathan/source/inovelli-led-strip-toolbox/src/swconfig.js":"2","/home/nathan/source/inovelli-led-strip-toolbox/src/AppWrapper.js":"3","/home/nathan/source/inovelli-led-strip-toolbox/src/App.js":"4","/home/nathan/source/inovelli-led-strip-toolbox/src/ThemeProvider.js":"5","/home/nathan/source/inovelli-led-strip-toolbox/src/Strip.js":"6","/home/nathan/source/inovelli-led-strip-toolbox/src/AppBar.js":"7","/home/nathan/source/inovelli-led-strip-toolbox/src/Options.js":"8","/home/nathan/source/inovelli-led-strip-toolbox/src/CustomStripEffects.js":"9","/home/nathan/source/inovelli-led-strip-toolbox/src/LED.js":"10","/home/nathan/source/inovelli-led-strip-toolbox/src/CustomEffectEditor.js":"11","/home/nathan/source/inovelli-led-strip-toolbox/src/HomeAssistantIcon.js":"12","/home/nathan/source/inovelli-led-strip-toolbox/src/ParameterModal.js":"13","/home/nathan/source/inovelli-led-strip-toolbox/src/SaveAsIcon.js":"14","/home/nathan/source/inovelli-led-strip-toolbox/src/SaveIcon.js":"15","/home/nathan/source/inovelli-led-strip-toolbox/src/SaveDialog.js":"16","/home/nathan/source/inovelli-led-strip-toolbox/src/ImportProgram.js":"17","/home/nathan/source/inovelli-led-strip-toolbox/src/OpenDialog.js":"18","/home/nathan/source/inovelli-led-strip-toolbox/src/Utils.js":"19","/home/nathan/source/inovelli-led-strip-toolbox/src/ClipboardAccess.js":"20","/home/nathan/source/inovelli-led-strip-toolbox/src/AboutDialog.js":"21","/home/nathan/source/inovelli-led-strip-toolbox/src/ShareDialog.js":"22","/home/nathan/source/inovelli-led-strip-toolbox/src/service-worker.js":"23","/home/nathan/source/inovelli-led-strip-toolbox/src/serviceWorkerRegistration.js":"24","/home/nathan/source/inovelli-led-strip-toolbox/src/reportWebVitals.js":"25"},{"size":673,"mtime":1609907230223,"results":"26","hashOfConfig":"27"},{"size":268,"mtime":1609804151378,"results":"28","hashOfConfig":"27"},{"size":519,"mtime":1609804875869,"results":"29","hashOfConfig":"27"},{"size":8125,"mtime":1609889361748,"results":"30","hashOfConfig":"27"},{"size":1539,"mtime":1609804151370,"results":"31","hashOfConfig":"27"},{"size":2337,"mtime":1609804151369,"results":"32","hashOfConfig":"27"},{"size":1013,"mtime":1609889386785,"results":"33","hashOfConfig":"27"},{"size":3874,"mtime":1609804252874,"results":"34","hashOfConfig":"27"},{"size":20919,"mtime":1609912542030,"results":"35","hashOfConfig":"27"},{"size":2516,"mtime":1609804151363,"results":"36","hashOfConfig":"27"},{"size":4325,"mtime":1609804151358,"results":"37","hashOfConfig":"27"},{"size":1181,"mtime":1609804151361,"results":"38","hashOfConfig":"27"},{"size":9236,"mtime":1609804151366,"results":"39","hashOfConfig":"27"},{"size":645,"mtime":1609804151367,"results":"40","hashOfConfig":"27"},{"size":422,"mtime":1609804151368,"results":"41","hashOfConfig":"27"},{"size":1013,"mtime":1609804151368,"results":"42","hashOfConfig":"27"},{"size":1514,"mtime":1609804151362,"results":"43","hashOfConfig":"27"},{"size":4402,"mtime":1609804151363,"results":"44","hashOfConfig":"27"},{"size":1429,"mtime":1609912894738,"results":"45","hashOfConfig":"27"},{"size":1095,"mtime":1609804151357,"results":"46","hashOfConfig":"27"},{"size":2175,"mtime":1609889188886,"results":"47","hashOfConfig":"27"},{"size":2872,"mtime":1609899465406,"results":"48","hashOfConfig":"27"},{"size":2837,"mtime":1609907109824,"results":"49","hashOfConfig":"50"},{"size":5064,"mtime":1609907080375,"results":"51","hashOfConfig":"27"},{"size":364,"mtime":1609907068474,"results":"52","hashOfConfig":"50"},{"filePath":"53","messages":"54","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"jq0hv9",{"filePath":"55","messages":"56","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"57","messages":"58","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"59","messages":"60","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"61","messages":"62","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"63","messages":"64","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"65","messages":"66","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"67","messages":"68","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"69","messages":"70","errorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"71","messages":"72","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"73","messages":"74","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"75","messages":"76","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"77","messages":"78","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"79","messages":"80","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"81","messages":"82","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"83","messages":"84","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"85","messages":"86","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"87","messages":"88","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"89","messages":"90","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"91","messages":"92","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"93","messages":"94","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"95","messages":"96","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"97","messages":"98","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"8stn2s",{"filePath":"99","messages":"100","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"101","messages":"102","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/nathan/source/inovelli-led-strip-toolbox/src/index.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/swconfig.js",["103"],"/home/nathan/source/inovelli-led-strip-toolbox/src/AppWrapper.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/App.js",["104","105","106"],"/home/nathan/source/inovelli-led-strip-toolbox/src/ThemeProvider.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/Strip.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/AppBar.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/Options.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/CustomStripEffects.js",["107","108","109","110","111","112"],"/home/nathan/source/inovelli-led-strip-toolbox/src/LED.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/CustomEffectEditor.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/HomeAssistantIcon.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ParameterModal.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/SaveAsIcon.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/SaveIcon.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/SaveDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ImportProgram.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/OpenDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/Utils.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ClipboardAccess.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/AboutDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/ShareDialog.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/service-worker.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/serviceWorkerRegistration.js",[],"/home/nathan/source/inovelli-led-strip-toolbox/src/reportWebVitals.js",[],{"ruleId":"113","severity":1,"message":"114","line":1,"column":1,"nodeType":"115","endLine":11,"endColumn":3},{"ruleId":"116","severity":1,"message":"117","line":2,"column":35,"nodeType":"118","messageId":"119","endLine":2,"endColumn":39},{"ruleId":"116","severity":1,"message":"120","line":2,"column":41,"nodeType":"118","messageId":"119","endLine":2,"endColumn":44},{"ruleId":"116","severity":1,"message":"121","line":3,"column":8,"nodeType":"118","messageId":"119","endLine":3,"endColumn":13},{"ruleId":"116","severity":1,"message":"122","line":14,"column":3,"nodeType":"118","messageId":"119","endLine":14,"endColumn":12},{"ruleId":"116","severity":1,"message":"123","line":17,"column":3,"nodeType":"118","messageId":"119","endLine":17,"endColumn":17},{"ruleId":"116","severity":1,"message":"124","line":19,"column":3,"nodeType":"118","messageId":"119","endLine":19,"endColumn":10},{"ruleId":"116","severity":1,"message":"125","line":20,"column":3,"nodeType":"118","messageId":"119","endLine":20,"endColumn":9},{"ruleId":"116","severity":1,"message":"126","line":32,"column":8,"nodeType":"118","messageId":"119","endLine":32,"endColumn":16},{"ruleId":"116","severity":1,"message":"127","line":41,"column":3,"nodeType":"118","messageId":"119","endLine":41,"endColumn":11},"import/no-anonymous-default-export","Assign object to a variable before exporting as module default","ExportDefaultDeclaration","no-unused-vars","'Tabs' is defined but never used.","Identifier","unusedVar","'Tab' is defined but never used.","'Strip' is defined but never used.","'TextField' is defined but never used.","'InputAdornment' is defined but never used.","'SvgIcon' is defined but never used.","'Button' is defined but never used.","'PlayIcon' is defined but never used.","'FINISHES' is defined but never used."] \ No newline at end of file diff --git a/src/CustomStripEffects.js b/src/CustomStripEffects.js index 43bad23..7ddb3c0 100644 --- a/src/CustomStripEffects.js +++ b/src/CustomStripEffects.js @@ -97,6 +97,7 @@ class CustomStripEffects extends React.Component { let EFFECTS = longToByteArray(query.p22).map( (colorEffect) => shortToByteArray(colorEffect)[0] ); + console.log(COLORS,EFFECTS); let BRIGHTNESS = longToByteArray(query.p23); let DURATIONS = longToByteArray(query.p24); let SETTINGS = longToByteArray(query.p30); diff --git a/src/Utils.js b/src/Utils.js index 602ae1b..12421fe 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -13,8 +13,8 @@ export const longToByteArray = function (/*long*/ long) { export const shortToByteArray = function (/*short*/ short) { var byteArray = [0, 0]; - byteArray[0] = short & 0x6; - byteArray[1] = (short - (short & 0x6)) / 8; + byteArray[0] = short & 0x4; + byteArray[1] = (short - (short & 0x7)) / 8; return byteArray; }; @@ -58,11 +58,4 @@ export const COLORS = [ ]; export const EFFECTS = ["Fade", "Fade Blend", "Flash", "Chase", "Chase Blend"]; -window.shortToByteArray = shortToByteArray; - -console.log(shortToByteArray(24)); -console.log([0, 1]); -console.log(shortToByteArray(16)); -console.log([0, 2]); -console.log(shortToByteArray(8)); -console.log([0, 3]); +window.shortToByteArray = shortToByteArray; \ No newline at end of file