Compare commits
	
		
			1 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 1e95d57139 | 
							
								
								
									
										6
									
								
								.env
									
									
									
									
									
								
							
							
						
						| @ -1,8 +1,2 @@ | ||||
| REACT_APP_COMPILER_URL=https://compiler.sensebox.de | ||||
| REACT_APP_BOARD=sensebox-mcu | ||||
| REACT_APP_BLOCKLY_API=https://api.blockly.sensebox.de | ||||
| 
 | ||||
| GENERATE_SOURCEMAP=false | ||||
| 
 | ||||
| # in days | ||||
| REACT_APP_SHARE_LINK_EXPIRES=30 | ||||
|  | ||||
| @ -1,41 +0,0 @@ | ||||
| name: Build and push image | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     container: | ||||
|       image: catthehacker/ubuntu:act-latest | ||||
|     #defaults: | ||||
|     #  run: | ||||
|     #    working-directory: /repo | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           fetch-depth: 0 # all history for all branches and tags | ||||
| 
 | ||||
|       - name: Login to  gitea.simonzeyer.de Repo | ||||
|         uses: docker/login-action@v2 | ||||
|         with: | ||||
|           registry: gitea.simonzeyer.de | ||||
|           username: ${{ secrets.DOCKER_REPO_USER }} | ||||
|           password: ${{ secrets.DOCKER_REPO_PASSWD }} | ||||
| 
 | ||||
|       - name: Get Meta | ||||
|         id: meta | ||||
|         run: | | ||||
|           echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT | ||||
|           echo REPO_VERSION=$(git describe --always | sed 's/^v//') >> $GITHUB_OUTPUT           | ||||
|       - name: Build and push | ||||
|         uses: docker/build-push-action@v4 | ||||
|         env: | ||||
|           ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119 | ||||
|         with: | ||||
|           context: . | ||||
|           file: ./Dockerfile      | ||||
|           push: true | ||||
|           tags: | | ||||
|             gitea.simonzeyer.de/schuelerlabor-cleverlab/smarti:${{ steps.meta.outputs.REPO_VERSION }} | ||||
							
								
								
									
										38
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -1,38 +0,0 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Create a report to help us improve | ||||
| title: '' | ||||
| labels: '' | ||||
| assignees: '' | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| **Describe the bug** | ||||
| A clear and concise description of what the bug is. | ||||
| 
 | ||||
| **To Reproduce** | ||||
| Steps to reproduce the behavior: | ||||
| 1. Go to '...' | ||||
| 2. Click on '....' | ||||
| 3. Scroll down to '....' | ||||
| 4. See error | ||||
| 
 | ||||
| **Expected behavior** | ||||
| A clear and concise description of what you expected to happen. | ||||
| 
 | ||||
| **Screenshots** | ||||
| If applicable, add screenshots to help explain your problem. | ||||
| 
 | ||||
| **Desktop (please complete the following information):** | ||||
|  - OS: [e.g. iOS] | ||||
|  - Browser [e.g. chrome, safari] | ||||
|  - Version [e.g. 22] | ||||
| 
 | ||||
| **Smartphone (please complete the following information):** | ||||
|  - Device: [e.g. iPhone6] | ||||
|  - OS: [e.g. iOS8.1] | ||||
|  - Browser [e.g. stock browser, safari] | ||||
|  - Version [e.g. 22] | ||||
| 
 | ||||
| **Additional context** | ||||
| Add any other context about the problem here. | ||||
							
								
								
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -1,20 +0,0 @@ | ||||
| --- | ||||
| name: Feature request | ||||
| about: Suggest an idea for this project | ||||
| title: '' | ||||
| labels: '' | ||||
| assignees: '' | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| **Is your feature request related to a problem? Please describe.** | ||||
| A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] | ||||
| 
 | ||||
| **Describe the solution you'd like** | ||||
| A clear and concise description of what you want to happen. | ||||
| 
 | ||||
| **Describe alternatives you've considered** | ||||
| A clear and concise description of any alternative solutions or features you've considered. | ||||
| 
 | ||||
| **Additional context** | ||||
| Add any other context or screenshots about the feature request here. | ||||
							
								
								
									
										14
									
								
								.github/ISSUE_TEMPLATE/short-issue.md
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -1,14 +0,0 @@ | ||||
| --- | ||||
| name: Short Issue | ||||
| about: Template for Short Issues | ||||
| title: '' | ||||
| labels: '' | ||||
| assignees: '' | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ### Current behaviour | ||||
| Describe the current behaviour | ||||
| 
 | ||||
| ### Expected behaviour | ||||
| Describe how it is supposed to work | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -22,4 +22,4 @@ npm-debug.log* | ||||
| yarn-debug.log* | ||||
| yarn-error.log* | ||||
| package-lock.json | ||||
| 
 | ||||
| package-lock.json | ||||
|  | ||||
							
								
								
									
										26
									
								
								CITATION.cff
									
									
									
									
									
								
							
							
						
						| @ -1,26 +0,0 @@ | ||||
| # This CITATION.cff file was generated with cffinit. | ||||
| # Visit https://bit.ly/cffinit to generate yours today! | ||||
| 
 | ||||
| cff-version: 1.2.0 | ||||
| title: senseBox Learn- and Programming Environment | ||||
| message: Please cite this software using these metadata. | ||||
| type: software | ||||
| version: 1.0.0 | ||||
| date-released: 2021-09-30 | ||||
| url: "https://github.com/sensebox/React-Ardublockly" | ||||
| authors: | ||||
|   - given-names: Mario | ||||
|     family-names: Pesch | ||||
|     email: mario.pesch@uni-muenster.de | ||||
|     affiliation: >- | ||||
|       Institute for geoinformatics University of | ||||
|       Muenster | ||||
|   - given-names: Luc | ||||
|     family-names: Niski | ||||
|     affiliation: >- | ||||
|       Institute for geoinformatics University of | ||||
|       Muenster | ||||
|   - given-names: Felix | ||||
|     family-names: Erdmann | ||||
|     email: f.erdmann@reedu.de | ||||
|     affiliation: Reedu GmbH & Co. KG | ||||
							
								
								
									
										12
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						| @ -1,12 +0,0 @@ | ||||
| # specify the node base image with your desired version node:<version> | ||||
| FROM node:16 as build | ||||
| WORKDIR /app | ||||
| copy ./ /app | ||||
| RUN npm install  --verbose | ||||
| RUN npm run build  --verbose | ||||
| 
 | ||||
| FROM nginx:alpine | ||||
| COPY --from=build /app/build/ /usr/share/nginx/html | ||||
| RUN chmod 755 /usr/share/nginx/html/ -R | ||||
| EXPOSE 80 | ||||
| ENTRYPOINT ["sh", "-c", "cd /usr/share/nginx/html/ && nginx -g 'daemon off;'"] | ||||
							
								
								
									
										93
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						| @ -1,93 +0,0 @@ | ||||
| # Blockly 2020 | ||||
| 
 | ||||
| (aktuelles Preview unter: https://deploy-preview-37--blockly-react.netlify.app/) | ||||
| 
 | ||||
| In den letzten Wochen haben wir eine komplett neue Lern- und Programmierumgebung für die senseBox geschaffen. Die Basis bildet hierbei weiterhin Google Blockly und das Frontend wird über React realisiert. Fast alle Blöcke wurden bereits aus der alten Version in die neue Version migriert.  | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ## Blockly Core | ||||
| Nachdem die bisherige Version, die unter [blockly.sensebox.de](https://blockly.sensebox.de) verfügbar ist, auf einen Google Blockly Core von 2016 aufbaut, wurde es Zeit ein großes Update durchzuführen. Durch den neuen Blockly Core lassen sich auch andere Renderer der Blöcke verwenden. In den Einstellungen kannst du zwischen den zwei Renderern Geras und Zelos auswählen. Geras ist der klassische Blockly Renderer während Zelos vor allem für Touchoberfläche optimiert worden ist. | ||||
| 
 | ||||
| ### Typed Variablen | ||||
| 
 | ||||
| Neue Variablen werden nun direkt mit einem bestimmten Datentyp angelegt. Ein einfacher Check überprüft ob der zurückgegeben Typ eines Blockes mit dem der Variablen kompatibel ist.  | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ### Funktionen (funktioniert aktuell nicht!) | ||||
| 
 | ||||
| Funktionen mit Rückgabe Wert und Eingabeparametern können angelegt werden. Durch die Verwendung von Funktionen lassen sich auch komplexere Programme übersichtlicher darstellen und bearbeiten. Beim Anlegen einer Funktion kann über das Zahnrad weitere Eingabeparameter hinzuefügt werden.  | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ### GPS | ||||
| 
 | ||||
| Der Code für das GPS Modul wurde neu aufgebaut und ermöglicht es deutlich schneller einen GPS Fix zu bekommen. Zusätzlich lassen sich bald! die Koordinaten in zwei verschiedenen Formaten zurückgebenlassen. Zum einen als Kommazahl zum anderen als Zahl ohne nachkommastellen  | ||||
| 
 | ||||
| ### MQTT | ||||
| Zwei einfache Blöcke ermöglichen es nun die Daten über MQTT an einen Broker zu versenden. Zwei Broker sind bereits "vorprogrammiert" (Adafruit IO und DIOTY). Natürlich können auch eigene Broker verwendet werden. Falls ihr gute freie Broker kennt, die wir hinzufügen sollten meldet euch einfach bei uns. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ### TTN Mapper | ||||
| Bisher war es möglich einen "kleinen" TTN Mapper zu bauen, der die Daten als Cayenne Payload versendet hat. Es gibt nun einen Block der es direkt ermöglicht einen vollständigen TTN Mapper zu Programmieren, der die Daten auch auf [TTNMapper](https://ttnmapper.org/) veröffentlichen kann. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ## Fronted | ||||
| 
 | ||||
| In der Oberfläche gibt es einige Neuigkeiten. Ziel ist es Blockly für die senseBox zu einer vollständigen Lern- und Programmierumgebung weiterzuentwickeln.   | ||||
| 
 | ||||
| Die Codeanzeige ist standardmäßig ausgeblendet kann aber einfach durch eine Klick auf das `</>` Icon hinzugefügt werden. | ||||
| 
 | ||||
| ### Login mit openSenseMap/senseBox Account | ||||
| 
 | ||||
| Im Menü unter Login könnt ihr euch mit eurem openSenseMap Account anmelden. Sobald ihr angemeldet seid habt ihr die Möglichkeit Projekte online zu speichern.  | ||||
| Sobald der Login mit dem openSenseMap Account erfolgreich war lassen sich die bereits registrierten senseBox unter Account einsehen.  | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| Im Block zum senden an die openSenseMap müssen dann auch keine IDs mehr ausgewählt werden sondern die registrierten senseBox können einfach aus dem Dropdown Menü ausgewählt werden. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| ### Speichern von Projekten | ||||
| 
 | ||||
| Nach dem Login über den openSenseMap Account lassen sich Projekte online speichern und wieder abrufen | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ### Tutorials | ||||
| 
 | ||||
| Es gibt jetzt Tutorials! Eine reihe von verschiedenen Tutorials zeigt dir die ersten Schritte in der Programmierung mit Blockly. (Inhalte werden noch ausgebaut) | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| ### Gallery | ||||
| 
 | ||||
| In der Gallery finden sich Beispiele mit verschiedenen Programmen. Die Beispiele können direkt in Blockly geöffnet werden, um Änderungen vorzunehmen oder das Programm direkt auf deine senseBox zu übertragen.  | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ### Teilen von Programmen | ||||
| 
 | ||||
| Über den Share Button kann ein Link zum Teilen der aktuellen Blöcke erstellt werden. Wann immer du dein Projekt mit anderen Teilen willst musst du nicht mehr eine XML Datei erstellen und verschicken sondern kannst einen Link erstellen, der direkt zu deinem Programm führt. Beachte, dass vor dem Teilen von Blöcken sämtliche sensiblen Daten, wie zum Beispiel Passwörter, Netzwerknamen, Lora oder openSenseMap Keys entfernt werden sollten. Die Links zum teilen von Programmen laufen nach 30 Tagen ab. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| ## Fehler | ||||
| 
 | ||||
| Falls ihr Fehler findet legt bitte ein Issue in folgendem Repository an: https://github.com/sensebox/React-Ardublockly/issues | ||||
| 
 | ||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @ -2,18 +2,18 @@ | ||||
| 
 | ||||
| # React Ardublockly | ||||
| 
 | ||||
| This repository contains the source code and documentation of [sensebox-ardublockly](https://sensebox-ardublockly.netlify.app/). | ||||
| This repository contains the source code and documentation of [sensebox-ardublockly](https://sensebox-ardublockly.netlify.app/) :rocket:. | ||||
| 
 | ||||
| This project was created with [Create React App](https://github.com/facebook/create-react-app) and represents the continuation or improvement of [blockly.sensebox.de](https://blockly.sensebox.de/ardublockly/?lang=de&board=sensebox-mcu). | ||||
| 
 | ||||
| 
 | ||||
| ## Getting Started | ||||
| 
 | ||||
| 1. [Download](https://github.com/sensebox/React-Ardublockly/archive/master.zip) or clone the GitHub Repository ``git clone https://github.com/sensebox/React-Ardublockly`` and checkout to branch ``master``. | ||||
| 1. [Download](https://github.com/sensebox/React-Ardublockly/archive/bachelor.zip) or clone the GitHub Repository ``git clone https://github.com/sensebox/React-Ardublockly`` and checkout to branch ``bachelor``. | ||||
| 
 | ||||
| 2. install [Node.js v10.xx](https://nodejs.org/en/) on your local machine | ||||
| 
 | ||||
| 3. open shell and navigate inside folder ``React-Ardublockly`` | ||||
| 3. open shell and navigate inside folder ``React-Ardublockly`` or rather ``Quellcode`` | ||||
|     * run ``npm install`` | ||||
|     * run ``npm start`` | ||||
| 4. open  [localhost:3000](http://localhost:3000) | ||||
| @ -22,4 +22,7 @@ This project was created with [Create React App](https://github.com/facebook/cre | ||||
| Ensure that line 14 in [store.js](https://github.com/sensebox/React-Ardublockly/blob/master/src/store.js#L14) is commented out or otherwise you have installed [Redux DevTools Extension](http://extension.remotedev.io/). | ||||
| 
 | ||||
| ## Demo | ||||
| A demo of the current status of the master branch can be accessed via [https://blockly-react.netlify.app/](https://blockly-react.netlify.app/) :rocket:. | ||||
| A demo of the current status of the bachelor branch can be accessed via [sensebox-ardublockly.netlify.app](https://sensebox-ardublockly.netlify.app/) :rocket:. | ||||
| * [Home](https://sensebox-ardublockly.netlify.app/) | ||||
| * [Tutorial Overview](https://sensebox-ardublockly.netlify.app/tutorial) | ||||
| * [Tutorial-Builder](https://sensebox-ardublockly.netlify.app/tutorial/builder) | ||||
|  | ||||
| @ -1,11 +0,0 @@ | ||||
| # docker-compose.yml | ||||
| services: | ||||
|   smarti:  | ||||
|     mem_limit: 2048m | ||||
|     mem_reservation: 128M | ||||
|     cpus: 2 | ||||
|     build: | ||||
|       dockerfile: Dockerfile | ||||
|     ports: | ||||
|     - "80" | ||||
|        | ||||
							
								
								
									
										14361
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										94
									
								
								package.json
									
									
									
									
									
								
							
							
						
						| @ -1,64 +1,32 @@ | ||||
| { | ||||
|   "name": "blockly-react", | ||||
|   "version": "1.0.0", | ||||
|   "version": "0.1.0", | ||||
|   "private": true, | ||||
|   "dependencies": { | ||||
|     "@blockly/block-plus-minus": "^4.0.4", | ||||
|     "@blockly/field-grid-dropdown": "^2.0.4", | ||||
|     "@blockly/field-slider": "4.0.4", | ||||
|     "@blockly/plugin-scroll-options": "^3.0.5", | ||||
|     "@blockly/plugin-typed-variable-modal": "^5.0.6", | ||||
|     "@blockly/workspace-backpack": "^3.0.4", | ||||
|     "@blockly/zoom-to-fit": "^3.0.4", | ||||
|     "@emotion/react": "^11.10.5", | ||||
|     "@emotion/styled": "^11.10.5", | ||||
|     "@fortawesome/fontawesome-svg-core": "^6.2.1", | ||||
|     "@fortawesome/free-solid-svg-icons": "^6.2.1", | ||||
|     "@fortawesome/react-fontawesome": "^0.2.0", | ||||
|     "@monaco-editor/react": "^4.3.1", | ||||
|     "@mui/lab": "^5.0.0-alpha.110", | ||||
|     "@mui/material": "^5.10.16", | ||||
|     "@mui/styles": "^5.10.16", | ||||
|     "@testing-library/jest-dom": "^5.16.1", | ||||
|     "@testing-library/react": "^12.1.2", | ||||
|     "@blockly/block-plus-minus": "^2.0.10", | ||||
|     "@blockly/field-slider": "^2.1.1", | ||||
|     "@blockly/plugin-typed-variable-modal": "^3.1.1", | ||||
|     "@fortawesome/fontawesome-svg-core": "^1.2.30", | ||||
|     "@fortawesome/free-solid-svg-icons": "^5.14.0", | ||||
|     "@fortawesome/react-fontawesome": "^0.1.11", | ||||
|     "@material-ui/core": "^4.11.0", | ||||
|     "@testing-library/jest-dom": "^4.2.4", | ||||
|     "@testing-library/react": "^9.5.0", | ||||
|     "@testing-library/user-event": "^7.2.1", | ||||
|     "axios": "^0.22.0", | ||||
|     "blockly": "^9.2.0", | ||||
|     "file-saver": "^2.0.5", | ||||
|     "markdown-it": "^12.3.2", | ||||
|     "mnemonic-id": "^3.2.7", | ||||
|     "moment": "^2.29.4", | ||||
|     "prismjs": "^1.27.0", | ||||
|     "qrcode.react": "^3.1.0", | ||||
|     "react": "^17.0.2", | ||||
|     "react-cookie-consent": "^7.2.1", | ||||
|     "react-dom": "^17.0.2", | ||||
|     "react-markdown": "^8.0.0", | ||||
|     "react-markdown-editor-lite": "^1.3.3", | ||||
|     "react-mde": "^11.5.0", | ||||
|     "react-rating-stars-component": "^2.2.0", | ||||
|     "react-redux": "^7.2.9", | ||||
|     "react-router-dom": "^5.3.3", | ||||
|     "react-scripts": "^5.0.1", | ||||
|     "react-share": "^4.4.0", | ||||
|     "react-spinners": "^0.13.3", | ||||
|     "reactour": "^1.18.7", | ||||
|     "redux": "^4.2.0", | ||||
|     "redux-thunk": "^2.4.1", | ||||
|     "rehype-raw": "^6.1.1", | ||||
|     "remark-gemoji": "^7.0.1", | ||||
|     "remark-gfm": "^3.0.1", | ||||
|     "styled-components": "^4.4.1", | ||||
|     "uuid": "^8.3.1", | ||||
|     "watchpack": "^2.3.1" | ||||
|   }, | ||||
|   "resolutions": { | ||||
|     "//": "See https://github.com/facebook/create-react-app/issues/11773", | ||||
|     "react-error-overlay": "6.0.9" | ||||
|     "blockly": "^3.20200924.0", | ||||
|     "file-saver": "^2.0.2", | ||||
|     "moment": "^2.28.0", | ||||
|     "prismjs": "^1.20.0", | ||||
|     "react": "^16.13.1", | ||||
|     "react-dom": "^16.13.1", | ||||
|     "react-redux": "^7.2.0", | ||||
|     "react-router-dom": "^5.2.0", | ||||
|     "react-scripts": "3.4.1", | ||||
|     "redux": "^4.0.5", | ||||
|     "redux-thunk": "^2.3.0" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "start": "node_modules/react-scripts/bin/react-scripts.js start", | ||||
|     "dev": "set \"REACT_APP_BLOCKLY_API=http://localhost:8080\" && npm start", | ||||
|     "start": "react-scripts start", | ||||
|     "build": "react-scripts build", | ||||
|     "test": "react-scripts test", | ||||
|     "eject": "react-scripts eject" | ||||
| @ -66,12 +34,16 @@ | ||||
|   "eslintConfig": { | ||||
|     "extends": "react-app" | ||||
|   }, | ||||
|   "browserslist": [ | ||||
|     ">0.2%", | ||||
|     "not dead", | ||||
|     "not op_mini all" | ||||
|   ], | ||||
|   "devDependencies": { | ||||
|     "@babel/plugin-proposal-private-property-in-object": "7.21.11" | ||||
|   "browserslist": { | ||||
|     "production": [ | ||||
|       ">0.2%", | ||||
|       "not dead", | ||||
|       "not op_mini all" | ||||
|     ], | ||||
|     "development": [ | ||||
|       "last 1 chrome version", | ||||
|       "last 1 firefox version", | ||||
|       "last 1 safari version" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -24,13 +24,6 @@ | ||||
|   </head> | ||||
|   <body> | ||||
|     <noscript>You need to enable JavaScript to run this app.</noscript> | ||||
|     <!-- Matomo Image Tracker--> | ||||
|     <img | ||||
|       src="https://piwik.sensebox.kaufen/matomo.php?idsite=9&rec=1" | ||||
|       style="border: 0; display: none" | ||||
|       alt="" | ||||
|     /> | ||||
|     <!-- End Matomo --> | ||||
|     <div id="root"></div> | ||||
|     <!-- | ||||
|       This HTML file is a template. | ||||
|  | ||||
| Before Width: | Height: | Size: 194 KiB | 
| Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 199 KiB | 
| Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 381 KiB | 
| Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 57 KiB | 
| Before Width: | Height: | Size: 122 KiB | 
| Before Width: | Height: | Size: 106 KiB | 
| Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 197 KiB | 
| Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 185 KiB | 
| Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 239 KiB | 
| Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 319 KiB | 
| Before Width: | Height: | Size: 777 KiB | 
| Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 274 KiB | 
| Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 85 KiB | 
| Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 96 KiB | 
| Before Width: | Height: | Size: 84 KiB | 
| Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 112 KiB | 
| Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 196 KiB | 
| Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 54 KiB | 
| Before Width: | Height: | Size: 728 KiB | 
| Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 69 KiB | 
| Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 72 KiB | 
| Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 197 KiB | 
| Before Width: | Height: | Size: 286 KiB | 
| Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 218 KiB | 
| Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 641 KiB | 
| Before Width: | Height: | Size: 343 KiB | 
| Before Width: | Height: | Size: 54 KiB | 
| Before Width: | Height: | Size: 69 KiB | 
| Before Width: | Height: | Size: 77 KiB | 
| Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 171 KiB | 
| Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 189 KiB | 
| Before Width: | Height: | Size: 79 KiB | 
| Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 253 KiB | 
| Before Width: | Height: | Size: 472 KiB | 
| Before Width: | Height: | Size: 117 KiB | 
| Before Width: | Height: | Size: 47 KiB | 
							
								
								
									
										69
									
								
								src/App.css
									
									
									
									
									
								
							
							
						
						| @ -1,74 +1,7 @@ | ||||
| .wrapper { | ||||
|   min-height: calc( | ||||
|     100vh - 60px | ||||
|   ); /* will cover the 100% of viewport - height of footer (padding-bottom) */ | ||||
|   min-height: calc(100vh - 60px); /* will cover the 100% of viewport - height of footer (padding-bottom) */ | ||||
|   overflow: hidden; | ||||
|   display: block; | ||||
|   position: relative; | ||||
|   padding-bottom: 60px; /* height of your footer + 30px*/ | ||||
| } | ||||
| 
 | ||||
| .tutorial img { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   max-height: 40vh; | ||||
|   max-width: 100%; | ||||
|   margin: auto; | ||||
| } | ||||
| 
 | ||||
| .news img { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   max-height: 40vh; | ||||
|   max-width: 100%; | ||||
|   margin: auto; | ||||
| } | ||||
| 
 | ||||
| .tutorial blockquote { | ||||
|   background: #f9f9f9; | ||||
|   border-left: 10px solid#4EAF47; | ||||
|   margin: 1.5em 10px; | ||||
|   padding: 0.5em 10px; | ||||
|   quotes: "\201C""\201D""\2018""\2019"; | ||||
| } | ||||
| blockquote:before { | ||||
|   color: #4eaf47; | ||||
|   content: open-quote; | ||||
|   font-size: 4em; | ||||
|   line-height: 0.1em; | ||||
|   margin-right: 0.25em; | ||||
|   vertical-align: -0.4em; | ||||
| } | ||||
| blockquote p { | ||||
|   display: inline; | ||||
| } | ||||
| 
 | ||||
| .tutorial table, | ||||
| th, | ||||
| td { | ||||
|   border: 1px solid #ddd; | ||||
| } | ||||
| 
 | ||||
| .tutorial th { | ||||
|   padding-top: 12px; | ||||
|   padding-bottom: 12px; | ||||
|   text-align: left; | ||||
|   border-color: #4eaf47; | ||||
|   color: white; | ||||
| } | ||||
| 
 | ||||
| .overlay { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
| } | ||||
| 
 | ||||
| :root { | ||||
|   --url: url('./data/mcu_opacity.png'); | ||||
| } | ||||
| 
 | ||||
| .blocklySvg { | ||||
|   background-image: var(--url); | ||||
|   background-position: center; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
							
								
								
									
										66
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						| @ -1,52 +1,48 @@ | ||||
| import React, { Component } from "react"; | ||||
| import React from 'react'; | ||||
| 
 | ||||
| import { Router } from "react-router-dom"; | ||||
| import { BrowserRouter as Router } from 'react-router-dom'; | ||||
| import { createBrowserHistory } from "history"; | ||||
| 
 | ||||
| import { Provider } from "react-redux"; | ||||
| import store from "./store"; | ||||
| import { loadUser } from "./actions/authActions"; | ||||
| import { Provider } from 'react-redux'; | ||||
| import store from './store'; | ||||
| 
 | ||||
| import "./App.css"; | ||||
| import './App.css'; | ||||
| 
 | ||||
| import { ThemeProvider, StyledEngineProvider, createTheme } from "@mui/material/styles"; | ||||
| import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles'; | ||||
| 
 | ||||
| import Content from "./components/Content"; | ||||
| import Navbar from './components/Navbar'; | ||||
| import Footer from './components/Footer'; | ||||
| import Routes from './components/Routes'; | ||||
| 
 | ||||
| const theme = createTheme({ | ||||
| const theme = createMuiTheme({ | ||||
|   palette: { | ||||
|     primary: { | ||||
|       main: "#4EAF47", | ||||
|       contrastText: "#ffffff", | ||||
|       main: '#4EAF47', | ||||
|       contrastText: '#ffffff' | ||||
|     }, | ||||
|     secondary: { | ||||
|       main: "#DDDDDD", | ||||
|     }, | ||||
|     button: { | ||||
|       compile: "#e27136", | ||||
|     }, | ||||
|   }, | ||||
|       main: '#DDDDDD' | ||||
|     } | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| class App extends Component { | ||||
|   componentDidMount() { | ||||
|     store.dispatch(loadUser()); | ||||
|   } | ||||
| const customHistory = createBrowserHistory(); | ||||
| 
 | ||||
|   render() { | ||||
|     const customHistory = createBrowserHistory(); | ||||
|     return ( | ||||
|       <StyledEngineProvider injectFirst> | ||||
|         <ThemeProvider theme={theme}> | ||||
|           <Provider store={store}> | ||||
|             <Router history={customHistory}> | ||||
|               <Content /> | ||||
|             </Router> | ||||
|           </Provider> | ||||
|         </ThemeProvider> | ||||
|       </StyledEngineProvider> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| function App() { | ||||
|   return ( | ||||
|     <ThemeProvider theme={theme}> | ||||
|       <Provider store={store}> | ||||
|         <Router history={customHistory}> | ||||
|           <div className="wrapper"> | ||||
|             <Navbar /> | ||||
|             <Routes /> | ||||
|             <Footer /> | ||||
|           </div> | ||||
|         </Router> | ||||
|       </Provider> | ||||
|     </ThemeProvider> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default App; | ||||
|  | ||||
| @ -1,251 +0,0 @@ | ||||
| import { | ||||
|   GET_STATUS, | ||||
|   USER_LOADED, | ||||
|   USER_LOADING, | ||||
|   AUTH_ERROR, | ||||
|   LOGIN_SUCCESS, | ||||
|   LOGIN_FAIL, | ||||
|   LOGOUT_SUCCESS, | ||||
|   LOGOUT_FAIL, | ||||
|   REFRESH_TOKEN_SUCCESS, | ||||
| } from "../actions/types"; | ||||
| 
 | ||||
| import axios from "axios"; | ||||
| import { returnErrors, returnSuccess } from "./messageActions"; | ||||
| import { setLanguage } from "./generalActions"; | ||||
| 
 | ||||
| // Check token & load user
 | ||||
| export const loadUser = () => (dispatch) => { | ||||
|   // user loading
 | ||||
|   dispatch({ | ||||
|     type: USER_LOADING, | ||||
|   }); | ||||
|   const config = { | ||||
|     success: (res) => { | ||||
|       dispatch({ | ||||
|         type: GET_STATUS, | ||||
|         payload: res.data.user.status, | ||||
|       }); | ||||
|       dispatch(setLanguage(res.data.user.language)); | ||||
|       dispatch({ | ||||
|         type: USER_LOADED, | ||||
|         payload: res.data.user, | ||||
|       }); | ||||
|     }, | ||||
|     error: (err) => { | ||||
|       if (err.response) { | ||||
|         dispatch(returnErrors(err.response.data.message, err.response.status)); | ||||
|       } | ||||
|       var status = []; | ||||
|       if (window.localStorage.getItem("status")) { | ||||
|         status = JSON.parse(window.localStorage.getItem("status")); | ||||
|       } | ||||
|       dispatch({ | ||||
|         type: GET_STATUS, | ||||
|         payload: status, | ||||
|       }); | ||||
|       dispatch({ | ||||
|         type: AUTH_ERROR, | ||||
|       }); | ||||
|     }, | ||||
|   }; | ||||
|   axios | ||||
|     .get( | ||||
|       `${process.env.REACT_APP_BLOCKLY_API}/user`, | ||||
|       config, | ||||
|       dispatch(authInterceptor()) | ||||
|     ) | ||||
|     .then((res) => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       err.config.error(err); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| // Login user
 | ||||
| export const login = | ||||
|   ({ email, password }) => | ||||
|     (dispatch) => { | ||||
|       dispatch({ | ||||
|         type: USER_LOADING, | ||||
|       }); | ||||
|       // Headers
 | ||||
|       const config = { | ||||
|         headers: { | ||||
|           "Content-Type": "application/json", | ||||
|         }, | ||||
|       }; | ||||
|       // Request Body
 | ||||
|       const body = JSON.stringify({ email, password }); | ||||
|       axios | ||||
|         .post(`${process.env.REACT_APP_BLOCKLY_API}/user`, body, config) | ||||
|         .then((res) => { | ||||
|           dispatch(setLanguage(res.data.user.language)); | ||||
|           dispatch({ | ||||
|             type: LOGIN_SUCCESS, | ||||
|             payload: res.data, | ||||
|           }); | ||||
|           dispatch({ | ||||
|             type: GET_STATUS, | ||||
|             payload: res.data.user.status, | ||||
|           }); | ||||
|           dispatch(returnSuccess(res.data.message, res.status, "LOGIN_SUCCESS")); | ||||
|         }) | ||||
|         .catch((err) => { | ||||
|           dispatch( | ||||
|             returnErrors( | ||||
|               err.response.data.message, | ||||
|               err.response.status, | ||||
|               "LOGIN_FAIL" | ||||
|             ) | ||||
|           ); | ||||
|           dispatch({ | ||||
|             type: LOGIN_FAIL, | ||||
|           }); | ||||
|           var status = []; | ||||
|           if (window.localStorage.getItem("status")) { | ||||
|             status = JSON.parse(window.localStorage.getItem("status")); | ||||
|           } | ||||
|           dispatch({ | ||||
|             type: GET_STATUS, | ||||
|             payload: status, | ||||
|           }); | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
| // Logout User
 | ||||
| export const logout = () => (dispatch) => { | ||||
|   const config = { | ||||
|     success: (res) => { | ||||
|       dispatch({ | ||||
|         type: LOGOUT_SUCCESS, | ||||
|       }); | ||||
|       var status = []; | ||||
|       if (window.localStorage.getItem("status")) { | ||||
|         status = JSON.parse(window.localStorage.getItem("status")); | ||||
|       } | ||||
|       dispatch({ | ||||
|         type: GET_STATUS, | ||||
|         payload: status, | ||||
|       }); | ||||
|       var locale = "en_US"; | ||||
|       if (window.localStorage.getItem("locale")) { | ||||
|         locale = window.localStorage.getItem("locale"); | ||||
|       } else if (navigator.language === "de-DE") { | ||||
|         locale = "de_DE"; | ||||
|       } | ||||
|       dispatch(setLanguage(locale)); | ||||
|       dispatch(returnSuccess(res.data.message, res.status, "LOGOUT_SUCCESS")); | ||||
|     }, | ||||
|     error: (err) => { | ||||
|       dispatch( | ||||
|         returnErrors( | ||||
|           err.response.data.message, | ||||
|           err.response.status, | ||||
|           "LOGOUT_FAIL" | ||||
|         ) | ||||
|       ); | ||||
|       dispatch({ | ||||
|         type: LOGOUT_FAIL, | ||||
|       }); | ||||
|       var status = []; | ||||
|       if (window.localStorage.getItem("status")) { | ||||
|         status = JSON.parse(window.localStorage.getItem("status")); | ||||
|       } | ||||
|       dispatch({ | ||||
|         type: GET_STATUS, | ||||
|         payload: status, | ||||
|       }); | ||||
|     }, | ||||
|   }; | ||||
|   axios | ||||
|     .post("https://api.opensensemap.org/users/sign-out", {}, config) | ||||
|     .then((res) => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       if (err.response && err.response.status !== 401) { | ||||
|         err.config.error(err); | ||||
|       } | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const authInterceptor = () => (dispatch, getState) => { | ||||
|   // Add a request interceptor
 | ||||
|   axios.interceptors.request.use( | ||||
|     (config) => { | ||||
|       config.headers["Content-Type"] = "application/json"; | ||||
|       const token = getState().auth.token; | ||||
|       if (token) { | ||||
|         config.headers["Authorization"] = `Bearer ${token}`; | ||||
|       } | ||||
|       return config; | ||||
|     }, | ||||
|     (error) => { | ||||
|       Promise.reject(error); | ||||
|     } | ||||
|   ); | ||||
| 
 | ||||
|   // Add a response interceptor
 | ||||
|   axios.interceptors.response.use( | ||||
|     (response) => { | ||||
|       // request was successfull
 | ||||
|       return response; | ||||
|     }, | ||||
|     (error) => { | ||||
|       const originalRequest = error.config; | ||||
|       const refreshToken = getState().auth.refreshToken; | ||||
|       if (refreshToken) { | ||||
|         // try to refresh the token failed
 | ||||
|         if (error.response.status === 401 && originalRequest._retry) { | ||||
|           // router.push('/login');
 | ||||
|           return Promise.reject(error); | ||||
|         } | ||||
|         // token was not valid and 1st try to refresh the token
 | ||||
|         if (error.response.status === 401 && !originalRequest._retry) { | ||||
|           originalRequest._retry = true; | ||||
|           const refreshToken = getState().auth.refreshToken; | ||||
|           // request to refresh the token, in request-body is the refreshToken
 | ||||
|           axios | ||||
|             .post("https://api.opensensemap.org/users/refresh-auth", { | ||||
|               token: refreshToken, | ||||
|             }) | ||||
|             .then((res) => { | ||||
|               if (res.status === 200) { | ||||
|                 dispatch({ | ||||
|                   type: REFRESH_TOKEN_SUCCESS, | ||||
|                   payload: res.data, | ||||
|                 }); | ||||
|                 axios.defaults.headers.common["Authorization"] = | ||||
|                   "Bearer " + getState().auth.token; | ||||
|                 // request was successfull, new request with the old parameters and the refreshed token
 | ||||
|                 return axios(originalRequest) | ||||
|                   .then((res) => { | ||||
|                     originalRequest.success(res); | ||||
|                   }) | ||||
|                   .catch((err) => { | ||||
|                     originalRequest.error(err); | ||||
|                   }); | ||||
|               } | ||||
|               return Promise.reject(error); | ||||
|             }) | ||||
|             .catch((err) => { | ||||
|               // request failed, token could not be refreshed
 | ||||
|               if (err.response) { | ||||
|                 dispatch( | ||||
|                   returnErrors(err.response.data.message, err.response.status) | ||||
|                 ); | ||||
|               } | ||||
|               dispatch({ | ||||
|                 type: AUTH_ERROR, | ||||
|               }); | ||||
|               return Promise.reject(error); | ||||
|             }); | ||||
|         } | ||||
|       } | ||||
|       // request status was unequal to 401, no possibility to refresh the token
 | ||||
|       return Promise.reject(error); | ||||
|     } | ||||
|   ); | ||||
| }; | ||||
| @ -1,15 +0,0 @@ | ||||
| import { | ||||
|   BOARD, | ||||
| } from "./types"; | ||||
| import mini_opacity from "../data/mini_opacity.png" | ||||
| import mcu_opacity from "../data/mcu_opacity.png" | ||||
| 
 | ||||
| export const setBoard = (board) => (dispatch) => { | ||||
|   window.sessionStorage.setItem("board", board); | ||||
|   const root = document.querySelector(':root'); | ||||
|   root.style.setProperty('--url', `url(${board === "mcu" ? mcu_opacity : mini_opacity})`); | ||||
|   dispatch({ | ||||
|     type: BOARD, | ||||
|     payload: board, | ||||
|   }); | ||||
| }; | ||||
| @ -1,52 +1,8 @@ | ||||
| import { | ||||
|   VISIT, | ||||
|   LANGUAGE, | ||||
|   RENDERER, | ||||
|   SOUNDS, | ||||
|   STATISTICS, | ||||
|   PLATFORM, | ||||
| } from "./types"; | ||||
| import { VISIT } from './types'; | ||||
| 
 | ||||
| 
 | ||||
| export const visitPage = () => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: VISIT, | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setPlatform = (platform) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: PLATFORM, | ||||
|     payload: platform, | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setLanguage = (language) => (dispatch, getState) => { | ||||
|   if (!getState().auth.progress && !getState().auth.isAuthenticated) { | ||||
|     window.localStorage.setItem("locale", language); | ||||
|   } | ||||
|   dispatch({ | ||||
|     type: LANGUAGE, | ||||
|     payload: language, | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setRenderer = (renderer) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: RENDERER, | ||||
|     payload: renderer, | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setSounds = (sounds) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: SOUNDS, | ||||
|     payload: sounds, | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setStatistics = (showStatistics) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: STATISTICS, | ||||
|     payload: showStatistics, | ||||
|     type: VISIT | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| @ -1,32 +0,0 @@ | ||||
| import { GET_ERRORS, CLEAR_MESSAGES, GET_SUCCESS } from './types'; | ||||
| 
 | ||||
| // RETURN Errors
 | ||||
| export const returnErrors = (msg, status, id = null) => { | ||||
|   return { | ||||
|     type: GET_ERRORS, | ||||
|     payload: { | ||||
|       msg: msg, | ||||
|       status: status, | ||||
|       id: id | ||||
|     } | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| // RETURN Success
 | ||||
| export const returnSuccess = (msg, status, id = null) => { | ||||
|   return { | ||||
|     type: GET_SUCCESS, | ||||
|     payload: { | ||||
|       msg: msg, | ||||
|       status: status, | ||||
|       id: id | ||||
|     } | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| // CLEAR_MESSAGES
 | ||||
| export const clearMessages = () => { | ||||
|   return { | ||||
|     type: CLEAR_MESSAGES | ||||
|   }; | ||||
| }; | ||||
| @ -1,204 +0,0 @@ | ||||
| import { PROJECT_PROGRESS, GET_PROJECT, GET_PROJECTS, PROJECT_TYPE, PROJECT_DESCRIPTION } from './types'; | ||||
| 
 | ||||
| import axios from 'axios'; | ||||
| import { returnErrors, returnSuccess } from './messageActions'; | ||||
| 
 | ||||
| export const setType = (type) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: PROJECT_TYPE, | ||||
|     payload: type | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setDescription = (description) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: PROJECT_DESCRIPTION, | ||||
|     payload: description | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const getProject = (type, id) => (dispatch) => { | ||||
|   dispatch({ type: PROJECT_PROGRESS }); | ||||
|   dispatch(setType(type)); | ||||
|   const config = { | ||||
|     success: res => { | ||||
|       var data = type === 'share' ? 'content' : type; | ||||
|       var project = res.data[data]; | ||||
|       if (project) { | ||||
|         dispatch({ | ||||
|           type: GET_PROJECT, | ||||
|           payload: project | ||||
|         }); | ||||
|         dispatch({ | ||||
|           type: PROJECT_DESCRIPTION, | ||||
|           payload: project.description | ||||
|         }); | ||||
|         dispatch({ type: PROJECT_PROGRESS }); | ||||
|         dispatch(returnSuccess(res.data.message, res.status, 'GET_PROJECT_SUCCESS')); | ||||
|       } | ||||
|       else { | ||||
|         dispatch({ type: PROJECT_PROGRESS }); | ||||
|         dispatch(returnErrors(res.data.message, res.status, 'PROJECT_EMPTY')); | ||||
|       } | ||||
|     }, | ||||
|     error: err => { | ||||
|       if (err.response) { | ||||
|         dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_PROJECT_FAIL')); | ||||
|       } | ||||
|       dispatch({ type: PROJECT_PROGRESS }); | ||||
|     } | ||||
|   }; | ||||
|   axios.get(`${process.env.REACT_APP_BLOCKLY_API}/${type}/${id}`, config) | ||||
|     .then(res => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       err.config.error(err); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const getProjects = (type) => (dispatch) => { | ||||
|   dispatch({ type: PROJECT_PROGRESS }); | ||||
|   const config = { | ||||
|     success: res => { | ||||
|       var data = type === 'project' ? 'projects' : 'galleries'; | ||||
|       var projects = res.data[data]; | ||||
|       dispatch({ | ||||
|         type: GET_PROJECTS, | ||||
|         payload: projects | ||||
|       }); | ||||
|       dispatch({ type: PROJECT_PROGRESS }); | ||||
|       dispatch(returnSuccess(res.data.message, res.status)); | ||||
|     }, | ||||
|     error: err => { | ||||
|       if (err.response) { | ||||
|         dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_PROJECTS_FAIL')); | ||||
|       } | ||||
|       dispatch({ type: PROJECT_PROGRESS }); | ||||
|     } | ||||
|   }; | ||||
|   axios.get(`${process.env.REACT_APP_BLOCKLY_API}/${type}`, config) | ||||
|     .then(res => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       err.config.error(err); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const updateProject = (type, id) => (dispatch, getState) => { | ||||
|   var workspace = getState().workspace; | ||||
|   var body = { | ||||
|     xml: workspace.code.xml, | ||||
|     title: workspace.name | ||||
|   }; | ||||
|   var project = getState().project; | ||||
|   if (type === 'gallery') { | ||||
|     body.description = project.description; | ||||
|   } | ||||
|   const config = { | ||||
|     success: res => { | ||||
|       var project = res.data[type]; | ||||
|       var projects = getState().project.projects; | ||||
|       var index = projects.findIndex(res => res._id === project._id); | ||||
|       projects[index] = project; | ||||
|       dispatch({ | ||||
|         type: GET_PROJECTS, | ||||
|         payload: projects | ||||
|       }); | ||||
|       if (type === 'project') { | ||||
|         dispatch(returnSuccess(res.data.message, res.status, 'PROJECT_UPDATE_SUCCESS')); | ||||
|       } else { | ||||
|         dispatch(returnSuccess(res.data.message, res.status, 'GALLERY_UPDATE_SUCCESS')); | ||||
|       } | ||||
|     }, | ||||
|     error: err => { | ||||
|       if (err.response) { | ||||
|         if (type === 'project') { | ||||
|           dispatch(returnErrors(err.response.data.message, err.response.status, 'PROJECT_UPDATE_FAIL')); | ||||
|         } else { | ||||
|           dispatch(returnErrors(err.response.data.message, err.response.status, 'GALLERY_UPDATE_FAIL')); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|   axios.put(`${process.env.REACT_APP_BLOCKLY_API}/${type}/${id}`, body, config) | ||||
|     .then(res => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       err.config.error(err); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const deleteProject = (type, id) => (dispatch, getState) => { | ||||
|   const config = { | ||||
|     success: res => { | ||||
|       var projects = getState().project.projects; | ||||
|       var index = projects.findIndex(res => res._id === id); | ||||
|       projects.splice(index, 1) | ||||
|       dispatch({ | ||||
|         type: GET_PROJECTS, | ||||
|         payload: projects | ||||
|       }); | ||||
|       if (type === 'project') { | ||||
|         dispatch(returnSuccess(res.data.message, res.status, 'PROJECT_DELETE_SUCCESS')); | ||||
|       } else { | ||||
|         dispatch(returnSuccess(res.data.message, res.status, 'GALLERY_DELETE_SUCCESS')); | ||||
|       } | ||||
|     }, | ||||
|     error: err => { | ||||
|       dispatch(returnErrors(err.response.data.message, err.response.status, 'PROJECT_DELETE_FAIL')); | ||||
|     } | ||||
|   }; | ||||
|   axios.delete(`${process.env.REACT_APP_BLOCKLY_API}/${type}/${id}`, config) | ||||
|     .then(res => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       if (err.response && err.response.status !== 401) { | ||||
|         err.config.error(err); | ||||
|       } | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export const shareProject = (title, type, id) => (dispatch, getState) => { | ||||
|   var body = { | ||||
|     title: title | ||||
|   }; | ||||
|   if (type === 'project') { | ||||
|     body.projectId = id; | ||||
|   } else { | ||||
|     body.xml = getState().workspace.code.xml; | ||||
|   } | ||||
|   axios.post(`${process.env.REACT_APP_BLOCKLY_API}/share`, body) | ||||
|     .then(res => { | ||||
|       var shareContent = res.data.content; | ||||
|       if (body.projectId) { | ||||
|         var projects = getState().project.projects; | ||||
|         var index = projects.findIndex(res => res._id === id); | ||||
|         projects[index].shared = shareContent.expiresAt; | ||||
|         dispatch({ | ||||
|           type: GET_PROJECTS, | ||||
|           payload: projects | ||||
|         }); | ||||
|       } | ||||
|       dispatch(returnSuccess(res.data.message, shareContent._id, 'SHARE_SUCCESS')); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       if (err.response) { | ||||
|         dispatch(returnErrors(err.response.data.message, err.response.status, 'SHARE_FAIL')); | ||||
|       } | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export const resetProject = () => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: GET_PROJECTS, | ||||
|     payload: [] | ||||
|   }); | ||||
|   dispatch(setType('')); | ||||
|   dispatch(setDescription('')); | ||||
| }; | ||||
| @ -1,18 +0,0 @@ | ||||
| import axios from 'axios' | ||||
| 
 | ||||
| const fetchSensorWikiSuccess = sensors => ({ | ||||
|     type: 'FETCH_SENSORWIKI_SUCCESS', | ||||
|     payload: { sensors } | ||||
| }) | ||||
| 
 | ||||
| export const fetchSensors =  () => { | ||||
|     return async dispatch => { | ||||
|         try { | ||||
|             let sensors = await axios.get('https://api.sensors.wiki/sensors/all') | ||||
|             dispatch(fetchSensorWikiSuccess(sensors.data)) | ||||
|         } | ||||
|         catch(e){ | ||||
|             console.log(e) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1,345 +1,61 @@ | ||||
| import { | ||||
|   TUTORIAL_PROGRESS, | ||||
|   GET_TUTORIAL, | ||||
|   GET_TUTORIALS, | ||||
|   TUTORIAL_SUCCESS, | ||||
|   TUTORIAL_ERROR, | ||||
|   TUTORIAL_CHANGE, | ||||
|   TUTORIAL_XML, | ||||
|   TUTORIAL_STEP, | ||||
| } from "./types"; | ||||
| import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types'; | ||||
| 
 | ||||
| import axios from "axios"; | ||||
| import { returnErrors, returnSuccess } from "./messageActions"; | ||||
| 
 | ||||
| export const tutorialProgress = () => (dispatch) => { | ||||
|   dispatch({ type: TUTORIAL_PROGRESS }); | ||||
| }; | ||||
| 
 | ||||
| export const getTutorial = (id) => (dispatch, getState) => { | ||||
|   axios | ||||
|     .get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/${id}`) | ||||
|     .then((res) => { | ||||
|       var tutorial = res.data.tutorial; | ||||
|       existingTutorial(tutorial, getState().tutorial.status).then((status) => { | ||||
|         dispatch({ | ||||
|           type: TUTORIAL_SUCCESS, | ||||
|           payload: status, | ||||
|         }); | ||||
|         dispatch(updateStatus(status)); | ||||
|         dispatch({ | ||||
|           type: GET_TUTORIAL, | ||||
|           payload: tutorial, | ||||
|         }); | ||||
|         dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|         dispatch(returnSuccess(res.data.message, res.status)); | ||||
|       }); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       if (err.response) { | ||||
|         dispatch( | ||||
|           returnErrors( | ||||
|             err.response.data.message, | ||||
|             err.response.status, | ||||
|             "GET_TUTORIAL_FAIL" | ||||
|           ) | ||||
|         ); | ||||
|       } | ||||
|       dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const getTutorials = () => (dispatch, getState) => { | ||||
|   axios | ||||
|     .get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial`) | ||||
|     .then((res) => { | ||||
|       var tutorials = res.data.tutorials; | ||||
|       existingTutorials(tutorials, getState().tutorial.status).then( | ||||
|         (status) => { | ||||
|           dispatch({ | ||||
|             type: TUTORIAL_SUCCESS, | ||||
|             payload: status, | ||||
|           }); | ||||
|           dispatch(updateStatus(status)); | ||||
|           dispatch({ | ||||
|             type: GET_TUTORIALS, | ||||
|             payload: tutorials, | ||||
|           }); | ||||
|           dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|           dispatch(returnSuccess(res.data.message, res.status)); | ||||
|         } | ||||
|       ); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       if (err.response) { | ||||
|         dispatch( | ||||
|           returnErrors( | ||||
|             err.response.data.message, | ||||
|             err.response.status, | ||||
|             "GET_TUTORIALS_FAIL" | ||||
|           ) | ||||
|         ); | ||||
|       } | ||||
|       dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const getAllTutorials = () => (dispatch, getState) => { | ||||
|   axios | ||||
|     .get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/getAllTutorials`) | ||||
|     .then((res) => { | ||||
|       var tutorials = res.data.tutorials; | ||||
|       existingTutorials(tutorials, getState().tutorial.status).then( | ||||
|         (status) => { | ||||
|           dispatch({ | ||||
|             type: TUTORIAL_SUCCESS, | ||||
|             payload: status, | ||||
|           }); | ||||
|           dispatch(updateStatus(status)); | ||||
|           dispatch({ | ||||
|             type: GET_TUTORIALS, | ||||
|             payload: tutorials, | ||||
|           }); | ||||
|           dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|           dispatch(returnSuccess(res.data.message, res.status)); | ||||
|         } | ||||
|       ); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       if (err.response) { | ||||
|         dispatch( | ||||
|           returnErrors( | ||||
|             err.response.data.message, | ||||
|             err.response.status, | ||||
|             "GET_TUTORIALS_FAIL" | ||||
|           ) | ||||
|         ); | ||||
|       } | ||||
|       dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const getUserTutorials = () => (dispatch, getState) => { | ||||
|   axios | ||||
|     .get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/getUserTutorials`) | ||||
|     .then((res) => { | ||||
|       var tutorials = res.data.tutorials; | ||||
|       existingTutorials(tutorials, getState().tutorial.status).then( | ||||
|         (status) => { | ||||
|           dispatch({ | ||||
|             type: TUTORIAL_SUCCESS, | ||||
|             payload: status, | ||||
|           }); | ||||
|           dispatch(updateStatus(status)); | ||||
|           dispatch({ | ||||
|             type: GET_TUTORIALS, | ||||
|             payload: tutorials, | ||||
|           }); | ||||
|           dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|           dispatch(returnSuccess(res.data.message, res.status)); | ||||
|         } | ||||
|       ); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       console.log(err); | ||||
|       if (err.response) { | ||||
|         dispatch( | ||||
|           returnErrors( | ||||
|             err.response.data.message, | ||||
|             err.response.status, | ||||
|             "GET_TUTORIALS_FAIL" | ||||
|           ) | ||||
|         ); | ||||
|       } | ||||
|       dispatch({ type: TUTORIAL_PROGRESS }); | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const updateStatus = (status) => (dispatch, getState) => { | ||||
|   if (getState().auth.isAuthenticated) { | ||||
|     // update user account in database - sync with redux store
 | ||||
|     axios | ||||
|       .put(`${process.env.REACT_APP_BLOCKLY_API}/user/status`, { | ||||
|         status: status, | ||||
|       }) | ||||
|       .then((res) => {}) | ||||
|       .catch((err) => { | ||||
|         if (err.response) { | ||||
|           // dispatch(returnErrors(err.response.data.message, err.response.status, 'UPDATE_STATUS_FAIL'));
 | ||||
|         } | ||||
|       }); | ||||
|   } else { | ||||
|     // update locale storage - sync with redux store
 | ||||
|     window.localStorage.setItem("status", JSON.stringify(status)); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const deleteTutorial = (id) => (dispatch, getState) => { | ||||
|   var tutorial = getState().tutorial; | ||||
|   var id = getState().builder.id; | ||||
|   const config = { | ||||
|     success: (res) => { | ||||
|       var tutorials = tutorial.tutorials; | ||||
|       var index = tutorials.findIndex((res) => res._id === id); | ||||
|       tutorials.splice(index, 1); | ||||
|       dispatch({ | ||||
|         type: GET_TUTORIALS, | ||||
|         payload: tutorials, | ||||
|       }); | ||||
|       dispatch( | ||||
|         returnSuccess(res.data.message, res.status, "TUTORIAL_DELETE_SUCCESS") | ||||
|       ); | ||||
|     }, | ||||
|     error: (err) => { | ||||
|       dispatch( | ||||
|         returnErrors( | ||||
|           err.response.data.message, | ||||
|           err.response.status, | ||||
|           "TUTORIAL_DELETE_FAIL" | ||||
|         ) | ||||
|       ); | ||||
|     }, | ||||
|   }; | ||||
|   axios | ||||
|     .delete(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/${id}`, config) | ||||
|     .then((res) => { | ||||
|       res.config.success(res); | ||||
|     }) | ||||
|     .catch((err) => { | ||||
|       if (err.response && err.response.status !== 401) { | ||||
|         err.config.error(err); | ||||
|       } | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| export const resetTutorial = () => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: GET_TUTORIALS, | ||||
|     payload: [], | ||||
|   }); | ||||
|   dispatch({ | ||||
|     type: TUTORIAL_STEP, | ||||
|     payload: 0, | ||||
|   }); | ||||
| }; | ||||
| import tutorials from '../data/tutorials'; | ||||
| 
 | ||||
| export const tutorialChange = () => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: TUTORIAL_CHANGE, | ||||
|     type: TUTORIAL_CHANGE | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const tutorialCheck = (status, step) => (dispatch, getState) => { | ||||
|   var tutorialsStatus = getState().tutorial.status; | ||||
|   var id = getState().tutorial.tutorials[0]._id; | ||||
|   var tutorialsStatusIndex = tutorialsStatus.findIndex( | ||||
|     (tutorialStatus) => tutorialStatus._id === id | ||||
|   ); | ||||
|   var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex( | ||||
|     (task) => task._id === step._id | ||||
|   ); | ||||
|   var id = getState().tutorial.currentId; | ||||
|   var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); | ||||
|   var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === step.id); | ||||
|   tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { | ||||
|     ...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex], | ||||
|     type: status, | ||||
|     type: status | ||||
|   }; | ||||
|   dispatch({ | ||||
|     type: status === "success" ? TUTORIAL_SUCCESS : TUTORIAL_ERROR, | ||||
|     payload: tutorialsStatus, | ||||
|     type: status === 'success' ? TUTORIAL_SUCCESS : TUTORIAL_ERROR, | ||||
|     payload: tutorialsStatus | ||||
|   }); | ||||
|   dispatch(updateStatus(tutorialsStatus)); | ||||
|   dispatch(tutorialChange()); | ||||
|   dispatch(returnSuccess("", "", "TUTORIAL_CHECK_SUCCESS")); | ||||
| }; | ||||
| 
 | ||||
| export const storeTutorialXml = (code) => (dispatch, getState) => { | ||||
|   var tutorial = getState().tutorial.tutorials[0]; | ||||
|   if (tutorial) { | ||||
|     var id = tutorial._id; | ||||
|   var id = getState().tutorial.currentId; | ||||
|   if (id !== null) { | ||||
|     var activeStep = getState().tutorial.activeStep; | ||||
|     var steps = tutorial.steps; | ||||
|     if (steps && steps[activeStep].type === "task") { | ||||
|     var steps = tutorials.filter(tutorial => tutorial.id === id)[0].steps; | ||||
|     if (steps[activeStep].type === 'task') { | ||||
|       var tutorialsStatus = getState().tutorial.status; | ||||
|       var tutorialsStatusIndex = tutorialsStatus.findIndex( | ||||
|         (tutorialStatus) => tutorialStatus._id === id | ||||
|       ); | ||||
|       var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex( | ||||
|         (task) => task._id === steps[activeStep]._id | ||||
|       ); | ||||
|       var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); | ||||
|       var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === steps[activeStep].id); | ||||
|       tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { | ||||
|         ...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex], | ||||
|         xml: code, | ||||
|         xml: code | ||||
|       }; | ||||
|       dispatch({ | ||||
|         type: TUTORIAL_XML, | ||||
|         payload: tutorialsStatus, | ||||
|         payload: tutorialsStatus | ||||
|       }); | ||||
|       dispatch(updateStatus(tutorialsStatus)); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export const tutorialId = (id) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: TUTORIAL_ID, | ||||
|     payload: id | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const tutorialStep = (step) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: TUTORIAL_STEP, | ||||
|     payload: step, | ||||
|     payload: step | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| const existingTutorials = (tutorials, status) => | ||||
|   new Promise(function (resolve, reject) { | ||||
|     var newstatus; | ||||
|     new Promise(function (resolve, reject) { | ||||
|       var existingTutorialIds = tutorials.map((tutorial, i) => { | ||||
|         existingTutorial(tutorial, status).then((status) => { | ||||
|           newstatus = status; | ||||
|         }); | ||||
|         return tutorial._id; | ||||
|       }); | ||||
|       resolve(existingTutorialIds); | ||||
|     }).then((existingTutorialIds) => { | ||||
|       // deleting old tutorials which do not longer exist
 | ||||
|       if (existingTutorialIds.length > 0) { | ||||
|         status = newstatus.filter( | ||||
|           (status) => existingTutorialIds.indexOf(status._id) > -1 | ||||
|         ); | ||||
|       } | ||||
|       resolve(status); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| const existingTutorial = (tutorial, status) => | ||||
|   new Promise(function (resolve, reject) { | ||||
|     var tutorialsId = tutorial._id; | ||||
|     var statusIndex = status.findIndex((status) => status._id === tutorialsId); | ||||
|     if (statusIndex > -1) { | ||||
|       var tasks = tutorial.steps.filter((step) => step.type === "task"); | ||||
|       var existingTaskIds = tasks.map((task, j) => { | ||||
|         var tasksId = task._id; | ||||
|         if ( | ||||
|           status[statusIndex].tasks.findIndex( | ||||
|             (task) => task._id === tasksId | ||||
|           ) === -1 | ||||
|         ) { | ||||
|           // task does not exist
 | ||||
|           status[statusIndex].tasks.push({ _id: tasksId }); | ||||
|         } | ||||
|         return tasksId; | ||||
|       }); | ||||
|       // deleting old tasks which do not longer exist
 | ||||
|       if (existingTaskIds.length > 0) { | ||||
|         status[statusIndex].tasks = status[statusIndex].tasks.filter( | ||||
|           (task) => existingTaskIds.indexOf(task._id) > -1 | ||||
|         ); | ||||
|       } | ||||
|     } else { | ||||
|       status.push({ | ||||
|         _id: tutorialsId, | ||||
|         tasks: tutorial.steps | ||||
|           .filter((step) => step.type === "task") | ||||
|           .map((task) => { | ||||
|             return { _id: task._id }; | ||||
|           }), | ||||
|       }); | ||||
|     } | ||||
|     resolve(status); | ||||
|   }); | ||||
|  | ||||
| @ -1,63 +1,24 @@ | ||||
| import { | ||||
|   PROGRESS, | ||||
|   JSON_STRING, | ||||
|   BUILDER_CHANGE, | ||||
|   BUILDER_ERROR, | ||||
|   BUILDER_TITLE, | ||||
|   BUILDER_PUBLIC, | ||||
|   BUILDER_DIFFICULTY, | ||||
|   BUILDER_REVIEW, | ||||
|   BUILDER_ID, | ||||
|   BUILDER_ADD_STEP, | ||||
|   BUILDER_DELETE_STEP, | ||||
|   BUILDER_CHANGE_STEP, | ||||
|   BUILDER_CHANGE_ORDER, | ||||
|   BUILDER_DELETE_PROPERTY, | ||||
| } from "./types"; | ||||
| import { PROGRESS, JSON_STRING, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP, BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from './types'; | ||||
| 
 | ||||
| import data from "../data/hardware.json"; | ||||
| import data from '../data/hardware.json'; | ||||
| 
 | ||||
| export const changeTutorialBuilder = () => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_CHANGE, | ||||
|     type: BUILDER_CHANGE | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const jsonString = (json) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: JSON_STRING, | ||||
|     payload: json, | ||||
|     payload: json | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const tutorialTitle = (title) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_TITLE, | ||||
|     payload: title, | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| 
 | ||||
| export const tutorialPublic = (pub) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_PUBLIC, | ||||
|     payload: pub, | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| 
 | ||||
| export const tutorialDifficulty = (difficulty) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_DIFFICULTY, | ||||
|     payload: difficulty, | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| 
 | ||||
| export const tutorialReview = (review) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_REVIEW, | ||||
|     payload: review, | ||||
|     payload: title | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| @ -65,7 +26,7 @@ export const tutorialReview = (review) => (dispatch) => { | ||||
| export const tutorialSteps = (steps) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_ADD_STEP, | ||||
|     payload: steps, | ||||
|     payload: steps | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| @ -73,7 +34,7 @@ export const tutorialSteps = (steps) => (dispatch) => { | ||||
| export const tutorialId = (id) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_ID, | ||||
|     payload: id, | ||||
|     payload: id | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| @ -82,14 +43,14 @@ export const addStep = (index) => (dispatch, getState) => { | ||||
|   var steps = getState().builder.steps; | ||||
|   var step = { | ||||
|     id: index + 1, | ||||
|     type: "instruction", | ||||
|     headline: "", | ||||
|     text: "", | ||||
|     type: 'instruction', | ||||
|     headline: '', | ||||
|     text: '' | ||||
|   }; | ||||
|   steps.splice(index, 0, step); | ||||
|   dispatch({ | ||||
|     type: BUILDER_ADD_STEP, | ||||
|     payload: steps, | ||||
|     payload: steps | ||||
|   }); | ||||
|   dispatch(addErrorStep(index)); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| @ -100,7 +61,7 @@ export const addErrorStep = (index) => (dispatch, getState) => { | ||||
|   error.steps.splice(index, 0, {}); | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: error, | ||||
|     payload: error | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| @ -109,7 +70,7 @@ export const removeStep = (index) => (dispatch, getState) => { | ||||
|   steps.splice(index, 1); | ||||
|   dispatch({ | ||||
|     type: BUILDER_DELETE_STEP, | ||||
|     payload: steps, | ||||
|     payload: steps | ||||
|   }); | ||||
|   dispatch(removeErrorStep(index)); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| @ -120,47 +81,45 @@ export const removeErrorStep = (index) => (dispatch, getState) => { | ||||
|   error.steps.splice(index, 1); | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: error, | ||||
|     payload: error | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const changeContent = | ||||
|   (content, index, property1, property2) => (dispatch, getState) => { | ||||
|     var steps = getState().builder.steps; | ||||
|     var step = steps[index]; | ||||
|     if (property2) { | ||||
|       if (step[property1] && step[property1][property2]) { | ||||
|         step[property1][property2] = content; | ||||
|       } else { | ||||
|         step[property1] = { [property2]: content }; | ||||
|       } | ||||
| export const changeContent = (content, index, property1, property2) => (dispatch, getState) => { | ||||
|   var steps = getState().builder.steps; | ||||
|   var step = steps[index]; | ||||
|   if (property2) { | ||||
|     if (step[property1] && step[property1][property2]) { | ||||
|       step[property1][property2] = content; | ||||
|     } else { | ||||
|       step[property1] = content; | ||||
|       step[property1] = { [property2]: content }; | ||||
|     } | ||||
|     dispatch({ | ||||
|       type: BUILDER_CHANGE_STEP, | ||||
|       payload: steps, | ||||
|     }); | ||||
|     dispatch(changeTutorialBuilder()); | ||||
|   }; | ||||
|   } else { | ||||
|     step[property1] = content; | ||||
|   } | ||||
|   dispatch({ | ||||
|     type: BUILDER_CHANGE_STEP, | ||||
|     payload: steps | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| 
 | ||||
| export const deleteProperty = | ||||
|   (index, property1, property2) => (dispatch, getState) => { | ||||
|     var steps = getState().builder.steps; | ||||
|     var step = steps[index]; | ||||
|     if (property2) { | ||||
|       if (step[property1] && step[property1][property2]) { | ||||
|         delete step[property1][property2]; | ||||
|       } | ||||
|     } else { | ||||
|       delete step[property1]; | ||||
| export const deleteProperty = (index, property1, property2) => (dispatch, getState) => { | ||||
|   var steps = getState().builder.steps; | ||||
|   var step = steps[index]; | ||||
|   if (property2) { | ||||
|     if (step[property1] && step[property1][property2]) { | ||||
|       delete step[property1][property2]; | ||||
|     } | ||||
|     dispatch({ | ||||
|       type: BUILDER_DELETE_PROPERTY, | ||||
|       payload: steps, | ||||
|     }); | ||||
|     dispatch(changeTutorialBuilder()); | ||||
|   }; | ||||
|   } else { | ||||
|     delete step[property1]; | ||||
|   } | ||||
|   dispatch({ | ||||
|     type: BUILDER_DELETE_PROPERTY, | ||||
|     payload: steps | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| 
 | ||||
| export const changeStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | ||||
|   var steps = getState().builder.steps; | ||||
| @ -169,34 +128,34 @@ export const changeStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | ||||
|   steps.splice(toIndex, 0, step); | ||||
|   dispatch({ | ||||
|     type: BUILDER_CHANGE_ORDER, | ||||
|     payload: steps, | ||||
|     payload: steps | ||||
|   }); | ||||
|   dispatch(changeErrorStepIndex(fromIndex, toIndex)); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| 
 | ||||
| export const changeErrorStepIndex = | ||||
|   (fromIndex, toIndex) => (dispatch, getState) => { | ||||
|     var error = getState().builder.error; | ||||
|     var errorStep = error.steps[fromIndex]; | ||||
|     error.steps.splice(fromIndex, 1); | ||||
|     error.steps.splice(toIndex, 0, errorStep); | ||||
|     dispatch({ | ||||
|       type: BUILDER_ERROR, | ||||
|       payload: error, | ||||
|     }); | ||||
|   }; | ||||
| export const changeErrorStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | ||||
|   var error = getState().builder.error; | ||||
|   var errorStep = error.steps[fromIndex]; | ||||
|   error.steps.splice(fromIndex, 1); | ||||
|   error.steps.splice(toIndex, 0, errorStep); | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: error | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| export const setError = (index, property) => (dispatch, getState) => { | ||||
|   var error = getState().builder.error; | ||||
|   if (index !== undefined) { | ||||
|     error.steps[index][property] = true; | ||||
|   } else { | ||||
|   } | ||||
|   else { | ||||
|     error[property] = true; | ||||
|   } | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: error, | ||||
|     payload: error | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| @ -205,12 +164,13 @@ export const deleteError = (index, property) => (dispatch, getState) => { | ||||
|   var error = getState().builder.error; | ||||
|   if (index !== undefined) { | ||||
|     delete error.steps[index][property]; | ||||
|   } else { | ||||
|   } | ||||
|   else { | ||||
|     delete error[property]; | ||||
|   } | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: error, | ||||
|     payload: error | ||||
|   }); | ||||
|   dispatch(changeTutorialBuilder()); | ||||
| }; | ||||
| @ -220,11 +180,8 @@ export const setSubmitError = () => (dispatch, getState) => { | ||||
|   // if(builder.id === undefined || builder.id === ''){
 | ||||
|   //   dispatch(setError(undefined, 'id'));
 | ||||
|   // }
 | ||||
|   if (builder.title === "") { | ||||
|     dispatch(setError(undefined, "title")); | ||||
|   } | ||||
|   if (builder.title === null) { | ||||
|     dispatch(setError(undefined, "title")); | ||||
|   if (builder.id === undefined || builder.title === '') { | ||||
|     dispatch(setError(undefined, 'title')); | ||||
|   } | ||||
|   var type = builder.steps.map((step, i) => { | ||||
|     // media and xml are directly checked for errors in their components and
 | ||||
| @ -232,43 +189,36 @@ export const setSubmitError = () => (dispatch, getState) => { | ||||
|     step.id = i + 1; | ||||
|     if (i === 0) { | ||||
|       if (step.requirements && step.requirements.length > 0) { | ||||
|         var requirements = step.requirements.filter((requirement) => | ||||
|           /^[0-9a-fA-F]{24}$/.test(requirement) | ||||
|         ); | ||||
|         var requirements = step.requirements.filter(requirement => typeof (requirement) === 'number'); | ||||
|         if (requirements.length < step.requirements.length) { | ||||
|           dispatch(changeContent(requirements, i, "requirements")); | ||||
|           dispatch(changeContent(requirements, i, 'requirements')); | ||||
|         } | ||||
|       } | ||||
|       if (step.hardware === undefined || step.hardware.length < 1) { | ||||
|         dispatch(setError(i, "hardware")); | ||||
|       } else { | ||||
|         var hardwareIds = data.map((hardware) => hardware.id); | ||||
|         var hardware = step.hardware.filter((hardware) => | ||||
|           hardwareIds.includes(hardware) | ||||
|         ); | ||||
|         dispatch(setError(i, 'hardware')); | ||||
|       } | ||||
|       else { | ||||
|         var hardwareIds = data.map(hardware => hardware.id); | ||||
|         var hardware = step.hardware.filter(hardware => hardwareIds.includes(hardware)); | ||||
|         if (hardware.length < step.hardware.length) { | ||||
|           dispatch(changeContent(hardware, i, "hardware")); | ||||
|           dispatch(changeContent(hardware, i, 'hardware')); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if (step.headline === undefined || step.headline === "") { | ||||
|       dispatch(setError(i, "headline")); | ||||
|     if (step.headline === undefined || step.headline === '') { | ||||
|       dispatch(setError(i, 'headline')); | ||||
|     } | ||||
|     if (step.text === undefined || step.text === "") { | ||||
|       dispatch(setError(i, "text")); | ||||
|     if (step.text === undefined || step.text === '') { | ||||
|       dispatch(setError(i, 'text')); | ||||
|     } | ||||
|     return step.type; | ||||
|   }); | ||||
|   if ( | ||||
|     !( | ||||
|       type.filter((item) => item === "task").length > 0 && | ||||
|       type.filter((item) => item === "instruction").length > 0 | ||||
|     ) | ||||
|   ) { | ||||
|     dispatch(setError(undefined, "type")); | ||||
|   if (!(type.filter(item => item === 'task').length > 0 && type.filter(item => item === 'instruction').length > 0)) { | ||||
|     dispatch(setError(undefined, 'type')); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export const checkError = () => (dispatch, getState) => { | ||||
|   dispatch(setSubmitError()); | ||||
|   var error = getState().builder.error; | ||||
| @ -277,37 +227,39 @@ export const checkError = () => (dispatch, getState) => { | ||||
|   } | ||||
|   for (var i = 0; i < error.steps.length; i++) { | ||||
|     if (Object.keys(error.steps[i]).length > 0) { | ||||
|       return true; | ||||
|       return true | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| export const progress = (inProgress) => (dispatch) => { | ||||
|   dispatch({ | ||||
|     type: PROGRESS, | ||||
|     payload: inProgress, | ||||
|   }); | ||||
|     payload: inProgress | ||||
|   }) | ||||
| }; | ||||
| 
 | ||||
| export const resetTutorial = () => (dispatch, getState) => { | ||||
|   dispatch(jsonString("")); | ||||
|   dispatch(tutorialTitle("")); | ||||
|   dispatch(jsonString('')); | ||||
|   dispatch(tutorialTitle('')); | ||||
|   dispatch(tutorialId('')); | ||||
|   var steps = [ | ||||
|     { | ||||
|       type: "instruction", | ||||
|       headline: "", | ||||
|       text: "", | ||||
|       id: 1, | ||||
|       type: 'instruction', | ||||
|       headline: '', | ||||
|       text: '', | ||||
|       hardware: [], | ||||
|       requirements: [], | ||||
|     }, | ||||
|       requirements: [] | ||||
|     } | ||||
|   ]; | ||||
|   dispatch(tutorialSteps(steps)); | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: { | ||||
|       steps: [{}], | ||||
|     }, | ||||
|       steps: [{}] | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| @ -316,18 +268,16 @@ export const readJSON = (json) => (dispatch, getState) => { | ||||
|   dispatch({ | ||||
|     type: BUILDER_ERROR, | ||||
|     payload: { | ||||
|       steps: json.steps.map(() => { | ||||
|         return {}; | ||||
|       }), | ||||
|     }, | ||||
|       steps: json.steps.map(() => { return {}; }) | ||||
|     } | ||||
|   }); | ||||
|   // accept only valid attributes
 | ||||
|   var steps = json.steps.map((step, i) => { | ||||
|     var object = { | ||||
|       _id: step._id, | ||||
|       id: step.id, | ||||
|       type: step.type, | ||||
|       headline: step.headline, | ||||
|       text: step.text, | ||||
|       text: step.text | ||||
|     }; | ||||
|     if (i === 0) { | ||||
|       object.hardware = step.hardware; | ||||
| @ -336,18 +286,19 @@ export const readJSON = (json) => (dispatch, getState) => { | ||||
|     if (step.xml) { | ||||
|       object.xml = step.xml; | ||||
|     } | ||||
|     if (step.media && step.type === "instruction") { | ||||
|     if (step.media && step.type === 'instruction') { | ||||
|       object.media = {}; | ||||
|       if (step.media.picture) { | ||||
|         object.media.picture = step.media.picture; | ||||
|       } else if (step.media.youtube) { | ||||
|       } | ||||
|       else if (step.media.youtube) { | ||||
|         object.media.youtube = step.media.youtube; | ||||
|       } | ||||
|     } | ||||
|     return object; | ||||
|   }); | ||||
|   dispatch(tutorialTitle(json.title)); | ||||
|   dispatch(tutorialDifficulty(json.difficulty)); | ||||
|   dispatch(tutorialId(json.id)); | ||||
|   dispatch(tutorialSteps(steps)); | ||||
|   dispatch(setSubmitError()); | ||||
|   dispatch(progress(false)); | ||||
|  | ||||
| @ -1,68 +1,32 @@ | ||||
| // authentication
 | ||||
| export const USER_LOADING = "USER_LOADING"; | ||||
| export const USER_LOADED = "USER_LOADED"; | ||||
| export const AUTH_ERROR = "AUTH_ERROR"; | ||||
| export const LOGIN_SUCCESS = "LOGIN_SUCCESS"; | ||||
| export const LOGIN_FAIL = "LOGIN_FAIL"; | ||||
| export const LOGOUT_SUCCESS = "LOGOUT_SUCCESS"; | ||||
| export const LOGOUT_FAIL = "LOGOUT_FAIL"; | ||||
| export const REFRESH_TOKEN_FAIL = "REFRESH_TOKEN_FAIL"; | ||||
| export const REFRESH_TOKEN_SUCCESS = "REFRESH_TOKEN_SUCCESS"; | ||||
| export const NEW_CODE = 'NEW_CODE'; | ||||
| export const CHANGE_WORKSPACE = 'CHANGE_WORKSPACE'; | ||||
| export const CREATE_BLOCK = 'CREATE_BLOCK'; | ||||
| export const MOVE_BLOCK = 'MOVE_BLOCK'; | ||||
| export const CHANGE_BLOCK = 'CHANGE_BLOCK'; | ||||
| export const DELETE_BLOCK = 'DELETE_BLOCK'; | ||||
| export const CLEAR_STATS = 'CLEAR_STATS'; | ||||
| export const NAME = 'NAME'; | ||||
| 
 | ||||
| export const NEW_CODE = "NEW_CODE"; | ||||
| export const CHANGE_WORKSPACE = "CHANGE_WORKSPACE"; | ||||
| export const CREATE_BLOCK = "CREATE_BLOCK"; | ||||
| export const MOVE_BLOCK = "MOVE_BLOCK"; | ||||
| export const CHANGE_BLOCK = "CHANGE_BLOCK"; | ||||
| export const DELETE_BLOCK = "DELETE_BLOCK"; | ||||
| export const CLEAR_STATS = "CLEAR_STATS"; | ||||
| export const NAME = "NAME"; | ||||
| 
 | ||||
| export const TUTORIAL_PROGRESS = "TUTORIAL_PROGRESS"; | ||||
| export const GET_TUTORIAL = "GET_TUTORIAL"; | ||||
| export const GET_TUTORIALS = "GET_TUTORIALS"; | ||||
| export const GET_USERTUTORIALS = "GET_USERTUTORIALS"; | ||||
| export const GET_STATUS = "GET_STATUS"; | ||||
| export const TUTORIAL_SUCCESS = "TUTORIAL_SUCCESS"; | ||||
| export const TUTORIAL_ERROR = "TUTORIAL_ERROR"; | ||||
| export const TUTORIAL_CHANGE = "TUTORIAL_CHANGE"; | ||||
| export const TUTORIAL_XML = "TUTORIAL_XML"; | ||||
| export const TUTORIAL_ID = "TUTORIAL_ID"; | ||||
| export const TUTORIAL_STEP = "TUTORIAL_STEP"; | ||||
| export const JSON_STRING = "JSON_STRING"; | ||||
| export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS'; | ||||
| export const TUTORIAL_ERROR = 'TUTORIAL_ERROR'; | ||||
| export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE'; | ||||
| export const TUTORIAL_XML = 'TUTORIAL_XML'; | ||||
| export const TUTORIAL_ID = 'TUTORIAL_ID'; | ||||
| export const TUTORIAL_STEP = 'TUTORIAL_STEP'; | ||||
| export const JSON_STRING = 'JSON_STRING'; | ||||
| 
 | ||||
| export const BUILDER_CHANGE = "BUILDER_CHANGE"; | ||||
| export const BUILDER_TITLE = "BUILDER_TITLE"; | ||||
| export const BUILDER_DIFFICULTY = "BUILDER_DIFFICULTY"; | ||||
| export const BUILDER_PUBLIC = "BUILDER_PUBLIC"; | ||||
| export const BUILDER_REVIEW = "BUILDER_REVIEW"; | ||||
| export const BUILDER_ID = "BUILDER_ID"; | ||||
| export const BUILDER_ADD_STEP = "BUILDER_ADD_STEP"; | ||||
| export const BUILDER_DELETE_STEP = "BUILDER_DELETE_STEP"; | ||||
| export const BUILDER_CHANGE_STEP = "BUILDER_CHANGE_STEP"; | ||||
| export const BUILDER_CHANGE_ORDER = "BUILDER_CHANGE_ORDER"; | ||||
| export const BUILDER_DELETE_PROPERTY = "BUILDER_DELETE_PROPERTY"; | ||||
| export const BUILDER_ERROR = "BUILDER_ERROR"; | ||||
| export const PROGRESS = "PROGRESS"; | ||||
| 
 | ||||
| export const VISIT = "VISIT"; | ||||
| export const LANGUAGE = "LANGUAGE"; | ||||
| export const PLATFORM = "PLATFORM"; | ||||
| export const RENDERER = "RENDERER"; | ||||
| export const SOUNDS = "SOUNDS"; | ||||
| export const STATISTICS = "STATISTICS"; | ||||
| export const BUILDER_CHANGE = 'BUILDER_CHANGE'; | ||||
| export const BUILDER_TITLE = 'BUILDER_TITLE'; | ||||
| export const BUILDER_ID = 'BUILDER_ID'; | ||||
| export const BUILDER_ADD_STEP = 'BUILDER_ADD_STEP'; | ||||
| export const BUILDER_DELETE_STEP = 'BUILDER_DELETE_STEP'; | ||||
| export const BUILDER_CHANGE_STEP = 'BUILDER_CHANGE_STEP'; | ||||
| export const BUILDER_CHANGE_ORDER = 'BUILDER_CHANGE_ORDER'; | ||||
| export const BUILDER_DELETE_PROPERTY = 'BUILDER_DELETE_PROPERTY'; | ||||
| export const BUILDER_ERROR = 'BUILDER_ERROR'; | ||||
| export const PROGRESS = 'PROGRESS'; | ||||
| 
 | ||||
| // messages
 | ||||
| export const GET_ERRORS = "GET_ERRORS"; | ||||
| export const GET_SUCCESS = "GET_SUCCESS"; | ||||
| export const CLEAR_MESSAGES = "CLEAR_MESSAGES"; | ||||
| 
 | ||||
| // projects: share, gallery, project
 | ||||
| export const PROJECT_PROGRESS = "PROJECT_PROGRESS"; | ||||
| export const GET_PROJECT = "GET_PROJECT"; | ||||
| export const GET_PROJECTS = "GET_PROJECTS"; | ||||
| export const PROJECT_TYPE = "PROJECT_TYPE"; | ||||
| export const PROJECT_DESCRIPTION = "PROJECT_DESCRIPTION"; | ||||
| 
 | ||||
| //board
 | ||||
| export const BOARD = "BOARD"; | ||||
| export const VISIT = 'VISIT'; | ||||
|  | ||||
| @ -16,22 +16,6 @@ export const onChangeCode = () => (dispatch, getState) => { | ||||
|   code.arduino = Blockly.Arduino.workspaceToCode(workspace); | ||||
|   var xmlDom = Blockly.Xml.workspaceToDom(workspace); | ||||
|   code.xml = Blockly.Xml.domToPrettyText(xmlDom); | ||||
|   var selectedBlock = Blockly.getSelected(); | ||||
|   if (selectedBlock !== null) { | ||||
|     code.helpurl = selectedBlock.helpUrl | ||||
|     code.tooltip = selectedBlock.tooltip | ||||
|     if (selectedBlock.data) { | ||||
|       code.data = selectedBlock.data | ||||
|     } else { | ||||
|       code.data = null | ||||
|     } | ||||
|   } else if (selectedBlock === null) { | ||||
|     code.tooltip = Blockly.Msg.tooltip_hint | ||||
|     code.helpurl = '' | ||||
|     code.data = null | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   dispatch({ | ||||
|     type: NEW_CODE, | ||||
|     payload: code | ||||
|  | ||||
| @ -1,29 +0,0 @@ | ||||
| import React, { Component } from "react"; | ||||
| 
 | ||||
| import withStyles from '@mui/styles/withStyles'; | ||||
| import { alpha } from "@mui/material/styles"; | ||||
| 
 | ||||
| import Typography from "@mui/material/Typography"; | ||||
| 
 | ||||
| const styles = (theme) => ({ | ||||
|   alert: { | ||||
|     marginBottom: "20px", | ||||
|     border: `1px solid ${theme.palette.primary.main}`, | ||||
|     padding: "10px 20px", | ||||
|     borderRadius: "4px", | ||||
|     background: alpha(theme.palette.primary.main, 0.3), | ||||
|     color: "rgb(70,70,70)", | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| export class Alert extends Component { | ||||
|   render() { | ||||
|     return ( | ||||
|       <div className={this.props.classes.alert}> | ||||
|         <Typography>{this.props.children}</Typography> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export default withStyles(styles, { withTheme: true })(Alert); | ||||
| @ -21,74 +21,57 @@ | ||||
|  * @author samelh@google.com (Sam El-Husseini) | ||||
|  */ | ||||
| 
 | ||||
| import React from "react"; | ||||
| import React from 'react'; | ||||
| 
 | ||||
| import Blockly from "blockly/core"; | ||||
| import "blockly/blocks"; | ||||
| import Toolbox from "./toolbox/Toolbox"; | ||||
| import Blockly from 'blockly/core'; | ||||
| import locale from 'blockly/msg/en'; | ||||
| import 'blockly/blocks'; | ||||
| import Toolbox from './toolbox/Toolbox'; | ||||
| 
 | ||||
| import { Card } from "@mui/material"; | ||||
| import { | ||||
|   ScrollOptions, | ||||
|   ScrollBlockDragger, | ||||
|   ScrollMetricsManager, | ||||
| } from "@blockly/plugin-scroll-options"; | ||||
| import { Card } from '@material-ui/core'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.setLocale(locale); | ||||
| 
 | ||||
| class BlocklyComponent extends React.Component { | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
|     this.blocklyDiv = React.createRef(); | ||||
|     this.toolbox = React.createRef(); | ||||
|     this.state = { workspace: undefined }; | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     const { initialXml, children, ...rest } = this.props; | ||||
|     this.primaryWorkspace = Blockly.inject(this.blocklyDiv.current, { | ||||
|       toolbox: this.toolbox.current, | ||||
|       plugins: { | ||||
|         // These are both required. | ||||
|         blockDragger: ScrollBlockDragger, | ||||
|         metricsManager: ScrollMetricsManager, | ||||
|       }, | ||||
|       ...rest, | ||||
|     }); | ||||
|     // Initialize plugin. | ||||
| 
 | ||||
|     this.setState({ workspace: this.primaryWorkspace }); | ||||
|     const plugin = new ScrollOptions(this.workspace); | ||||
|     plugin.init({ enableWheelScroll: true, enableEdgeScroll: false }); | ||||
|     if (initialXml) { | ||||
|       Blockly.Xml.domToWorkspace( | ||||
|         Blockly.Xml.textToDom(initialXml), | ||||
|         this.primaryWorkspace | ||||
|       ); | ||||
|      | ||||
|     constructor(props) { | ||||
|         super(props); | ||||
|         this.blocklyDiv = React.createRef(); | ||||
|         this.toolbox = React.createRef(); | ||||
|         this.state = {workspace: undefined}; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   get workspace() { | ||||
|     return this.primaryWorkspace; | ||||
|   } | ||||
|     componentDidMount() { | ||||
|         const { initialXml, children, ...rest } = this.props; | ||||
|         this.primaryWorkspace = Blockly.inject( | ||||
|             this.blocklyDiv.current, | ||||
|             { | ||||
|                 toolbox: this.toolbox.current, | ||||
|                 ...rest | ||||
|             }, | ||||
|         ); | ||||
|         this.setState({workspace: this.primaryWorkspace}) | ||||
| 
 | ||||
|   setXml(xml) { | ||||
|     Blockly.Xml.domToWorkspace( | ||||
|       Blockly.Xml.textToDom(xml), | ||||
|       this.primaryWorkspace | ||||
|     ); | ||||
|   } | ||||
|         if (initialXml) { | ||||
|             Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), this.primaryWorkspace); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
|       <React.Fragment> | ||||
|         <Card | ||||
|           ref={this.blocklyDiv} | ||||
|           id="blocklyDiv" | ||||
|           style={this.props.style ? this.props.style : {}} | ||||
|         /> | ||||
|         <Toolbox toolbox={this.toolbox} workspace={this.state.workspace} /> | ||||
|       </React.Fragment> | ||||
|     ); | ||||
|   } | ||||
|     get workspace() { | ||||
|         return this.primaryWorkspace; | ||||
|     } | ||||
| 
 | ||||
|     setXml(xml) { | ||||
|         Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), this.primaryWorkspace); | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|         return <React.Fragment> | ||||
|             <Card ref={this.blocklyDiv} id="blocklyDiv" style={this.props.style ? this.props.style : {}}/> | ||||
|             <Toolbox toolbox={this.toolbox} workspace={this.state.workspace} /> | ||||
|         </React.Fragment>; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export default BlocklyComponent; | ||||
|  | ||||
| @ -53,6 +53,7 @@ class BlocklySvg extends Component { | ||||
|       var css = '<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' + cssContent + ']]></style></defs>'; | ||||
|       var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox(); | ||||
|       var content = new XMLSerializer().serializeToString(canvas); | ||||
| 
 | ||||
|       var xml = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
 | ||||
|                   width="${bbox.width}" height="${bbox.height}" viewBox="${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}"> | ||||
|                   ${css}">${content}</svg>`; | ||||
| @ -64,7 +65,7 @@ class BlocklySvg extends Component { | ||||
|   render() { | ||||
|     return ( | ||||
|       <div | ||||
|         style={{display: 'inline-flex', justifyContent: 'center', transform: 'scale(0.8) translate(0, calc(100% * -0.2 / 2))'}} | ||||
|         style={{display: 'flex', justifyContent: 'center', transform: 'scale(0.8) translate(0, calc(100% * -0.2 / 2))'}} | ||||
|         dangerouslySetInnerHTML={{ __html: this.state.svg }} | ||||
|       /> | ||||
|     ); | ||||
|  | ||||
| @ -1,23 +1,24 @@ | ||||
| import React, { Component } from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { connect } from "react-redux"; | ||||
| import { onChangeWorkspace, clearStats } from "../../actions/workspaceActions"; | ||||
| import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { onChangeWorkspace, clearStats } from '../../actions/workspaceActions'; | ||||
| // import * as De from 'blockly/msg/de';
 | ||||
| import {De} from './msg/de'; | ||||
| import BlocklyComponent from './BlocklyComponent'; | ||||
| import BlocklySvg from './BlocklySvg'; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import './blocks/index'; | ||||
| import './generator/index'; | ||||
| import { initialXml } from './initialXml.js'; | ||||
| 
 | ||||
| import BlocklyComponent from "./BlocklyComponent"; | ||||
| import BlocklySvg from "./BlocklySvg"; | ||||
| 
 | ||||
| import * as Blockly from "blockly/core"; | ||||
| import "./blocks/index"; | ||||
| import "./generator/index"; | ||||
| import { ZoomToFitControl } from "@blockly/zoom-to-fit"; | ||||
| import { initialXml } from "./initialXml.js"; | ||||
| import { getMaxInstances } from "./helpers/maxInstances"; | ||||
| import { Backpack } from "@blockly/workspace-backpack"; | ||||
| 
 | ||||
| class BlocklyWindow extends Component { | ||||
| 
 | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
|     this.simpleWorkspace = React.createRef(); | ||||
|     Blockly.setLocale(De); | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
| @ -26,7 +27,6 @@ class BlocklyWindow extends Component { | ||||
|     this.props.clearStats(); | ||||
|     workspace.addChangeListener((event) => { | ||||
|       this.props.onChangeWorkspace(event); | ||||
| 
 | ||||
|       // switch on that a block is displayed disabled or not depending on whether it is correctly connected
 | ||||
|       // for SVG display, a deactivated block in the display is undesirable
 | ||||
|       if (this.props.blockDisabled) { | ||||
| @ -34,26 +34,11 @@ class BlocklyWindow extends Component { | ||||
|       } | ||||
|     }); | ||||
|     Blockly.svgResize(workspace); | ||||
|     const zoomToFit = new ZoomToFitControl(workspace); | ||||
|     zoomToFit.init(); | ||||
|     // Initialize plugin.
 | ||||
|     const backpack = new Backpack(workspace); | ||||
|     backpack.init(); | ||||
|   } | ||||
| 
 | ||||
|   componentDidUpdate(props) { | ||||
|     const workspace = Blockly.getMainWorkspace(); | ||||
|     var xml = this.props.initialXml; | ||||
|     if (props.selectedBoard !== this.props.selectedBoard) { | ||||
|        xml = localStorage.getItem("autoSaveXML"); | ||||
|       // change board
 | ||||
|       if(!xml) xml = initialXml; | ||||
|       var xmlDom = Blockly.Xml.textToDom(xml); | ||||
|       Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace); | ||||
|       // var toolbox = workspace.getToolbox();
 | ||||
|       // workspace.updateToolbox(toolbox.toolboxDef_);
 | ||||
|     } | ||||
|   | ||||
|     // if svg is true, then the update process is done in the BlocklySvg component
 | ||||
|     if (props.initialXml !== xml && !this.props.svg) { | ||||
|       // guarantees that the current xml-code (this.props.initialXml) is rendered
 | ||||
| @ -61,95 +46,52 @@ class BlocklyWindow extends Component { | ||||
|       if (!xml) xml = initialXml; | ||||
|       Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace); | ||||
|     } | ||||
|     if (props.language !== this.props.language) { | ||||
|       // change language
 | ||||
|        xml = localStorage.getItem("autoSaveXML"); | ||||
|       if (!xml) xml = initialXml; | ||||
|        xmlDom = Blockly.Xml.textToDom(xml); | ||||
|       Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace); | ||||
|       // var toolbox = workspace.getToolbox();
 | ||||
|       // workspace.updateToolbox(toolbox.toolboxDef_);
 | ||||
|     } | ||||
|     Blockly.svgResize(workspace); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
|       <div> | ||||
|         <BlocklyComponent | ||||
|           ref={this.simpleWorkspace} | ||||
|         <BlocklyComponent ref={this.simpleWorkspace} | ||||
|           style={this.props.svg ? { height: 0 } : this.props.blocklyCSS} | ||||
|           readOnly={ | ||||
|             this.props.readOnly !== undefined ? this.props.readOnly : false | ||||
|           } | ||||
|           trashcan={ | ||||
|             this.props.trashcan !== undefined ? this.props.trashcan : true | ||||
|           } | ||||
|           renderer={this.props.renderer} | ||||
|           sounds={this.props.sounds} | ||||
|           maxInstances={getMaxInstances()} | ||||
|           zoom={{ | ||||
|             // https://developers.google.com/blockly/guides/configure/web/zoom
 | ||||
|             controls: | ||||
|               this.props.zoomControls !== undefined | ||||
|                 ? this.props.zoomControls | ||||
|                 : true, | ||||
|           readOnly={this.props.readOnly !== undefined ? this.props.readOnly : false} | ||||
|           trashcan={this.props.trashcan !== undefined ? this.props.trashcan : true} | ||||
|           renderer='geras' | ||||
|           zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom
 | ||||
|             controls: this.props.zoomControls !== undefined ? this.props.zoomControls : true, | ||||
|             wheel: false, | ||||
|             startScale: 1, | ||||
|             maxScale: 3, | ||||
|             minScale: 0.3, | ||||
|             scaleSpeed: 1.2, | ||||
|             scaleSpeed: 1.2 | ||||
|           }} | ||||
|           grid={ | ||||
|             this.props.grid !== undefined && !this.props.grid | ||||
|               ? {} | ||||
|               : { | ||||
|                   // https://developers.google.com/blockly/guides/configure/web/grid
 | ||||
|                   spacing: 20, | ||||
|                   length: 1, | ||||
|                   colour: "#4EAF47", // senseBox-green
 | ||||
|                   snap: false, | ||||
|                 } | ||||
|           } | ||||
|           media={"/media/blockly/"} | ||||
|           move={ | ||||
|             this.props.move !== undefined && !this.props.move | ||||
|               ? {} | ||||
|               : { | ||||
|                   // https://developers.google.com/blockly/guides/configure/web/move
 | ||||
|                   scrollbars: true, | ||||
|                   drag: true, | ||||
|                   wheel: true, | ||||
|                 } | ||||
|           } | ||||
|           initialXml={ | ||||
|             this.props.initialXml ? this.props.initialXml : initialXml | ||||
|           } | ||||
|         ></BlocklyComponent> | ||||
|         {this.props.svg && this.props.initialXml ? ( | ||||
|           <BlocklySvg initialXml={this.props.initialXml} /> | ||||
|         ) : null} | ||||
|           grid={this.props.grid !== undefined && !this.props.grid ? {} : | ||||
|             { // https://developers.google.com/blockly/guides/configure/web/grid
 | ||||
|               spacing: 20, | ||||
|               length: 1, | ||||
|               colour: '#4EAF47', // senseBox-green
 | ||||
|               snap: false | ||||
|             }} | ||||
|           media={'/media/blockly/'} | ||||
|           move={this.props.move !== undefined && !this.props.move ? {} : | ||||
|             { // https://developers.google.com/blockly/guides/configure/web/move
 | ||||
|               scrollbars: true, | ||||
|               drag: true, | ||||
|               wheel: false | ||||
|             }} | ||||
|           initialXml={this.props.initialXml ? this.props.initialXml : initialXml} | ||||
|         > | ||||
|         </BlocklyComponent > | ||||
|         {this.props.svg && this.props.initialXml ? <BlocklySvg initialXml={this.props.initialXml} /> : null} | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| BlocklyWindow.propTypes = { | ||||
|   onChangeWorkspace: PropTypes.func.isRequired, | ||||
|   clearStats: PropTypes.func.isRequired, | ||||
|   renderer: PropTypes.string.isRequired, | ||||
|   sounds: PropTypes.bool.isRequired, | ||||
|   language: PropTypes.string.isRequired, | ||||
|   selectedBoard: PropTypes.string.isRequired, | ||||
|   clearStats: PropTypes.func.isRequired | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = (state) => ({ | ||||
|   renderer: state.general.renderer, | ||||
|   sounds: state.general.sounds, | ||||
|   language: state.general.language, | ||||
|   selectedBoard: state.board.board, | ||||
| }); | ||||
| 
 | ||||
| export default connect(mapStateToProps, { onChangeWorkspace, clearStats })( | ||||
|   BlocklyWindow | ||||
| ); | ||||
| export default connect(null, { onChangeWorkspace, clearStats })(BlocklyWindow); | ||||
|  | ||||
| @ -1,88 +0,0 @@ | ||||
| import Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import { selectedBoard } from "../helpers/board"; | ||||
| import { FieldGridDropdown } from "@blockly/field-grid-dropdown"; | ||||
| 
 | ||||
| /** | ||||
|  * DS18B20 Temperatursonde | ||||
|  * | ||||
|  */ | ||||
| Blockly.Blocks["CleVerLab_dummy1"] = { | ||||
|  init: function () { | ||||
|     this.setColour(getColour().cleverlab); | ||||
|     this.appendDummyInput() | ||||
|         .appendField("tut nichts") | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.data = {name: "empty"}; | ||||
| }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks["CleVerLab_temperature"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().cleverlab); | ||||
|     this.appendDummyInput() | ||||
|       .appendField("Temperatur") | ||||
|       .appendField("Digital Port:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPorts), "DigitalPin"); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.data = {name: "ds18b20"}; | ||||
|   }, | ||||
| }; | ||||
| /** | ||||
|  * PH Wert | ||||
|  * | ||||
|  */ | ||||
| Blockly.Blocks["CleVerLab_pH"] = { | ||||
|   init: function () { | ||||
| 
 | ||||
|     this.setColour(getColour().cleverlab); | ||||
|     this.appendDummyInput() | ||||
|       .appendField("pH Wert") | ||||
|       .appendField("Digital Port:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "DigitalPin"); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.data = {name: "phoderso"}; | ||||
|   }, | ||||
| }; | ||||
| Blockly.Blocks["CleVerLab_cali1"] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField("Kalibriere pH Sensor"); | ||||
|         this.appendValueInput("VAR1", "Number") | ||||
|             .appendField("Referenzlösung pH 4.00 =") | ||||
|             .setAlign(Blockly.ALIGN_RIGHT); | ||||
|         this.appendValueInput("VAR2", "Number2") | ||||
|             .appendField("Referenzlösung pH 7.00 =") | ||||
|             .setAlign(Blockly.ALIGN_RIGHT); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().cleverlab); | ||||
|         this.setOutput(true, Types.NUMBER.typeName); | ||||
|         this.data = {name: "dsasda"}; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Pump | ||||
|  * | ||||
|  */ | ||||
| Blockly.Blocks['CleVerLab_pump'] = { | ||||
|   init: function() { | ||||
|     this.setColour(getColour().cleverlab); | ||||
|         var dropdown = new Blockly.FieldDropdown([ | ||||
|           [ 'START','HIGH'], | ||||
|           [ 'STOPP','LOW'] | ||||
|         ]); | ||||
|     this.appendDummyInput() | ||||
|         .appendField(dropdown, "Mode") | ||||
|         .appendField(" Pumpe ") | ||||
|         .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "DigitalPin"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     //this.setOutput(true, "Number");
 | ||||
|     this.setTooltip(''); | ||||
|     this.setHelpUrl(''); | ||||
|   } | ||||
| }; | ||||
| @ -1,31 +1,21 @@ | ||||
| import "./loops"; | ||||
| import "./sensebox"; | ||||
| import "./logic"; | ||||
| import "./sensebox-sensors"; | ||||
| import "./sensebox-telegram"; | ||||
| import "./sensebox-osem"; | ||||
| import "./sensebox-web"; | ||||
| import "./sensebox-display"; | ||||
| import "./sensebox-motors"; | ||||
| import "./sensebox-lora"; | ||||
| import "./sensebox-led"; | ||||
| import "./sensebox-rtc"; | ||||
| import "./sensebox-ntp"; | ||||
| import "./sensebox-ble"; | ||||
| import "./sensebox-sd"; | ||||
| import "./mqtt"; | ||||
| import "./text"; | ||||
| import "./io"; | ||||
| import "./audio"; | ||||
| import "./math"; | ||||
| import "./map"; | ||||
| import "./procedures"; | ||||
| import "./serial"; | ||||
| import "./time"; | ||||
| import "./variables"; | ||||
| import "./lists"; | ||||
| import "./watchdog"; | ||||
| import "./webserver"; | ||||
| import "./CleVerLab" | ||||
| import './loops'; | ||||
| import './sensebox'; | ||||
| import './logic'; | ||||
| import './sensebox-sensors'; | ||||
| import './sensebox-telegram'; | ||||
| import './sensebox-osem'; | ||||
| import './sensebox-web'; | ||||
| import './sensebox-display'; | ||||
| import './sensebox-lora'; | ||||
| import './sensebox-led'; | ||||
| import './sensebox-sd'; | ||||
| import './text'; | ||||
| import './io'; | ||||
| import './audio'; | ||||
| import './math'; | ||||
| import './map'; | ||||
| import './procedures'; | ||||
| import './time'; | ||||
| import './variables'; | ||||
| 
 | ||||
| import "../helpers/types"; | ||||
| import '../helpers/types' | ||||
| @ -10,271 +10,248 @@ | ||||
|  * | ||||
|  * TODO: maybe change this to a "PIN" BlocklyType | ||||
|  */ | ||||
| import Blockly from "blockly/core"; | ||||
| import { selectedBoard } from "../helpers/board"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import Blockly from 'blockly/core'; | ||||
| import { selectedBoard } from '../helpers/board' | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| Blockly.Blocks["io_digitalwrite"] = { | ||||
|   /** | ||||
|    * Block for creating a 'set pin' to a state. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DigitalWrite"); | ||||
|     this.setColour(250); | ||||
|     this.appendValueInput("STATE") | ||||
|       .appendField(Blockly.Msg.ARD_DIGITALWRITE) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPins), | ||||
|         "PIN" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|       .setCheck(Types.BOOLEAN.checkList); | ||||
|     this.setInputsInline(false); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.ARD_DIGITALWRITE_TIP); | ||||
|   }, | ||||
|   /** | ||||
|    * Updates the content of the the pin related fields. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateFields: function () { | ||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|       this, | ||||
|       "PIN", | ||||
|       "digitalPins" | ||||
|     ); | ||||
|   }, | ||||
| 
 | ||||
| Blockly.Blocks['io_digitalwrite'] = { | ||||
|     /** | ||||
|      * Block for creating a 'set pin' to a state. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite'); | ||||
|         this.setColour(250); | ||||
|         this.appendValueInput('STATE') | ||||
|             .appendField(Blockly.Msg.ARD_DIGITALWRITE) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().digitalPins), 'PIN') | ||||
|             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|             .setCheck(Types.BOOLEAN.checkList); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_DIGITALWRITE_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|             this, 'PIN', 'digitalPins'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_digitalread"] = { | ||||
|   /** | ||||
|    * Block for creating a 'read pin'. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DigitalRead"); | ||||
|     this.setColour(250); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.ARD_DIGITALREAD) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPins), | ||||
|         "PIN" | ||||
|       ); | ||||
|     this.setOutput(true, "boolean"); | ||||
|     this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP); | ||||
|   }, | ||||
|   /** @return {!string} The type of return value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.BOOLEAN; | ||||
|   }, | ||||
|   /** | ||||
|    * Updates the content of the the pin related fields. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateFields: function () { | ||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|       this, | ||||
|       "PIN", | ||||
|       "digitalPins" | ||||
|     ); | ||||
|   }, | ||||
| Blockly.Blocks['io_digitalread'] = { | ||||
|     /** | ||||
|      * Block for creating a 'read pin'. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalRead'); | ||||
|         this.setColour(250); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_DIGITALREAD) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().digitalPins), 'PIN'); | ||||
|         this.setOutput(true, 'boolean'); | ||||
|         this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP); | ||||
|     }, | ||||
|     /** @return {!string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.BOOLEAN; | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|             this, 'PIN', 'digitalPins'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_builtin_led"] = { | ||||
|   /** | ||||
|    * Block for setting built-in LED to a state. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DigitalWrite"); | ||||
|     this.setColour(250); | ||||
|     this.appendValueInput("STATE") | ||||
|       .appendField(Blockly.Msg.ARD_BUILTIN_LED) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().builtinLed), | ||||
|         "BUILT_IN_LED" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|       .setCheck(Types.BOOLEAN.compatibleTypes); | ||||
|     this.setInputsInline(false); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.ARD_BUILTIN_LED_TIP); | ||||
|   }, | ||||
|   /** | ||||
|    * Updates the content of the the pin related fields. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateFields: function () { | ||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|       this, | ||||
|       "BUILT_IN_LED", | ||||
|       "builtinLed" | ||||
|     ); | ||||
|   }, | ||||
|   /** @return {!string} The type of input value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.BOOLEAN; | ||||
|   }, | ||||
| Blockly.Blocks['io_builtin_led'] = { | ||||
|     /** | ||||
|      * Block for setting built-in LED to a state. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite'); | ||||
|         this.setColour(250); | ||||
|         this.appendValueInput('STATE') | ||||
|             .appendField(Blockly.Msg.ARD_BUILTIN_LED) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().builtinLed), 'BUILT_IN_LED') | ||||
|             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|             .setCheck(Types.BOOLEAN.compatibleTypes); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_BUILTIN_LED_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|             this, 'BUILT_IN_LED', 'builtinLed'); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.BOOLEAN; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_analogwrite"] = { | ||||
|   /** | ||||
|    * Block for creating a 'set pin' to an analogue value. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/AnalogWrite"); | ||||
|     this.setColour(250); | ||||
|     this.appendValueInput("NUM") | ||||
|       .appendField(Blockly.Msg.ARD_ANALOGWRITE) | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().pwmPins), "PIN") | ||||
|       .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.setInputsInline(false); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.ARD_ANALOGWRITE_TIP); | ||||
|   }, | ||||
|   /** | ||||
|    * Updates the content of the the pin related fields. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateFields: function () { | ||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, "PIN", "pwmPins"); | ||||
|   }, | ||||
|   /** @return {!string} The type of input value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER; | ||||
|   }, | ||||
| Blockly.Blocks['io_analogwrite'] = { | ||||
|     /** | ||||
|      * Block for creating a 'set pin' to an analogue value. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/AnalogWrite'); | ||||
|         this.setColour(250); | ||||
|         this.appendValueInput('NUM') | ||||
|             .appendField(Blockly.Msg.ARD_ANALOGWRITE) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().pwmPins), 'PIN') | ||||
|             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_ANALOGWRITE_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'pwmPins'); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_analogread"] = { | ||||
|   /** | ||||
|    * Block for reading an analogue input. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/AnalogRead"); | ||||
|     this.setColour(250); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.ARD_ANALOGREAD) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().analogPins), | ||||
|         "PIN" | ||||
|       ); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_ANALOGREAD_TIP); | ||||
|   }, | ||||
|   /** @return {!string} The type of return value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER.typeName; | ||||
|   }, | ||||
|   /** | ||||
|    * Updates the content of the the pin related fields. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateFields: function () { | ||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, "PIN", "analogPins"); | ||||
|   }, | ||||
| Blockly.Blocks['io_analogread'] = { | ||||
|     /** | ||||
|      * Block for reading an analogue input. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/AnalogRead'); | ||||
|         this.setColour(250); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_ANALOGREAD) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().analogPins), 'PIN'); | ||||
|         this.setOutput(true, Types.NUMBER.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_ANALOGREAD_TIP); | ||||
|     }, | ||||
|     /** @return {!string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'analogPins'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_highlow"] = { | ||||
|   /** | ||||
|    * Block for creating a pin state. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Constants"); | ||||
|     this.setColour(250); | ||||
|     this.appendDummyInput().appendField( | ||||
|       new Blockly.FieldDropdown([ | ||||
|         [Blockly.Msg.ARD_HIGH, "HIGH"], | ||||
|         [Blockly.Msg.ARD_LOW, "LOW"], | ||||
|       ]), | ||||
|       "STATE" | ||||
|     ); | ||||
|     this.setOutput(true, Types.BOOLEAN.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_HIGHLOW_TIP); | ||||
|   }, | ||||
|   /** @return {!string} The type of return value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.BOOLEAN; | ||||
|   }, | ||||
| Blockly.Blocks['io_highlow'] = { | ||||
|     /** | ||||
|      * Block for creating a pin state. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Constants'); | ||||
|         this.setColour(250); | ||||
|         this.appendDummyInput() | ||||
|             .appendField( | ||||
|                 new Blockly.FieldDropdown([[Blockly.Msg.ARD_HIGH, 'HIGH'], [Blockly.Msg.ARD_LOW, 'LOW']]), | ||||
|                 'STATE'); | ||||
|         this.setOutput(true, Types.BOOLEAN.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_HIGHLOW_TIP); | ||||
|     }, | ||||
|     /** @return {!string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.BOOLEAN; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_pulsein"] = { | ||||
|   /** | ||||
|    * Block for measuring the duration of a pulse in an input pin. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.jsonInit({ | ||||
|       type: "math_foo", | ||||
|       message0: Blockly.Msg.ARD_PULSE_READ, | ||||
|       args0: [ | ||||
|         { | ||||
|           type: "input_value", | ||||
|           name: "PULSETYPE", | ||||
|           check: Types.BOOLEAN.compatibleTypes, | ||||
|         }, | ||||
|         { | ||||
|           type: "field_dropdown", | ||||
|           name: "PULSEPIN", | ||||
|           options: selectedBoard().digitalPins, | ||||
|         }, | ||||
|       ], | ||||
|       output: Types.NUMBER.typeName, | ||||
|       inputsInline: true, | ||||
|       colour: 250, | ||||
|       tooltip: Blockly.Msg.ARD_PULSE_TIP, | ||||
|       helpUrl: "https://www.arduino.cc/en/Reference/PulseIn", | ||||
|     }); | ||||
|   }, | ||||
|   /** @return {!string} The type of input value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER.typeName; | ||||
|   }, | ||||
| Blockly.Blocks['io_pulsein'] = { | ||||
|     /** | ||||
|      * Block for measuring the duration of a pulse in an input pin. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.jsonInit({ | ||||
|             "type": "math_foo", | ||||
|             "message0": Blockly.Msg.ARD_PULSE_READ, | ||||
|             "args0": [{ | ||||
|                 "type": "input_value", | ||||
|                 "name": "PULSETYPE", | ||||
|                 "check": Types.BOOLEAN.compatibleTypes | ||||
|             }, { | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "PULSEPIN", | ||||
|                 "options": selectedBoard().digitalPins, | ||||
|             } | ||||
|             ], | ||||
|             "output": Types.NUMBER.typeId, | ||||
|             "inputsInline": true, | ||||
|             "colour": 250, | ||||
|             "tooltip": Blockly.Msg.ARD_PULSE_TIP, | ||||
|             "helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn' | ||||
|         }); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["io_pulsetimeout"] = { | ||||
|   /** | ||||
|    * Block for measuring (with a time-out) the duration of a pulse in an input | ||||
|    * pin. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.jsonInit({ | ||||
|       type: "math_foo", | ||||
|       message0: Blockly.Msg.ARD_PULSE_READ_TIMEOUT, | ||||
|       args0: [ | ||||
|         { | ||||
|           type: "input_value", | ||||
|           name: "PULSETYPE", | ||||
|           check: Types.BOOLEAN.compatibleTypes, | ||||
|         }, | ||||
|         { | ||||
|           type: "field_dropdown", | ||||
|           name: "PULSEPIN", | ||||
|           options: selectedBoard().digitalPins, | ||||
|         }, | ||||
|         { | ||||
|           type: "input_value", | ||||
|           name: "TIMEOUT", | ||||
|           check: Types.NUMBER.compatibleTypes, | ||||
|         }, | ||||
|       ], | ||||
|       output: Types.NUMBER.typeName, | ||||
|       inputsInline: true, | ||||
|       colour: 250, | ||||
|       tooltip: Blockly.Msg.ARD_PULSETIMEOUT_TIP, | ||||
|       helpUrl: "https://www.arduino.cc/en/Reference/PulseIn", | ||||
|     }); | ||||
|   }, | ||||
|   /** @return {!string} The type of input value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER.typeName; | ||||
|   }, | ||||
| Blockly.Blocks['io_pulsetimeout'] = { | ||||
|     /** | ||||
|      * Block for measuring (with a time-out) the duration of a pulse in an input | ||||
|      * pin. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.jsonInit({ | ||||
|             "type": "math_foo", | ||||
|             "message0": Blockly.Msg.ARD_PULSE_READ_TIMEOUT, | ||||
|             "args0": [{ | ||||
|                 "type": "input_value", | ||||
|                 "name": "PULSETYPE", | ||||
|                 "check": Types.BOOLEAN.compatibleTypes | ||||
|             }, { | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "PULSEPIN", | ||||
|                 "options": selectedBoard().digitalPins, | ||||
|             }, { | ||||
|                 "type": "input_value", | ||||
|                 "name": "TIMEOUT", | ||||
|                 "check": Types.NUMBER.compatibleTypes | ||||
|             } | ||||
|             ], | ||||
|             "output": Types.NUMBER.typeId, | ||||
|             "inputsInline": true, | ||||
|             "colour": 250, | ||||
|             "tooltip": Blockly.Msg.ARD_PULSETIMEOUT_TIP, | ||||
|             "helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn' | ||||
|         }); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @ -1,54 +0,0 @@ | ||||
| import Blockly, { FieldDropdown } from "blockly/core"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| 
 | ||||
| Blockly.Blocks["lists_create_empty"] = { | ||||
|   /** | ||||
|    * Elapsed time in milliseconds block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Millis"); | ||||
|     this.setColour(getColour().arrays); | ||||
|     this.appendDummyInput().appendField("create List with"); | ||||
|     this.appendValueInput("NUMBER"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField("Items of Type") | ||||
|       .appendField(new FieldDropdown(Types.VARIABLE_TYPES), "type"); | ||||
|     this.setOutput(true, Types.ARRAY.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["array_getIndex"] = { | ||||
|   /** | ||||
|    * Elapsed time in milliseconds block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Millis"); | ||||
|     this.setColour(getColour().arrays); | ||||
|     this.appendDummyInput().appendField( | ||||
|       new Blockly.FieldVariable("X", null, ["Array"], "Array"), | ||||
|       "FIELDNAME" | ||||
|     ); | ||||
|     this.setOutput(true, Types.ARRAY.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["lists_length"] = { | ||||
|   /** | ||||
|    * Elapsed time in milliseconds block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Millis"); | ||||
|     this.setColour(getColour().arrays); | ||||
|     this.appendValueInput("ARRAY") | ||||
|       .appendField("length of") | ||||
|       .setCheck(Types.ARRAY.compatibleTypes); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); | ||||
|   }, | ||||
| }; | ||||
| @ -2,7 +2,7 @@ | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import { getCompatibleTypes } from '../helpers/types' | ||||
| import * as Types from '../helpers/types'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['controls_whileUntil'] = { | ||||
|     /** | ||||
| @ -16,7 +16,7 @@ Blockly.Blocks['controls_whileUntil'] = { | ||||
|         this.setHelpUrl(Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL); | ||||
|         this.setColour(getColour().loops); | ||||
|         this.appendValueInput('BOOL') | ||||
|             .setCheck(getCompatibleTypes('boolean')) | ||||
|             .setCheck(getCompatibleTypes(Boolean)) | ||||
|             .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE'); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO); | ||||
| @ -47,25 +47,24 @@ Blockly.Blocks['controls_for'] = { | ||||
|                 { | ||||
|                     "type": "field_variable", | ||||
|                     "name": "VAR", | ||||
|                     "defaultType": Types.NUMBER.typeName, | ||||
|                     "variable": null | ||||
|                 }, | ||||
|                 { | ||||
|                     "type": "input_value", | ||||
|                     "name": "FROM", | ||||
|                     "check": getCompatibleTypes('int'), | ||||
|                     "check": getCompatibleTypes(Number), | ||||
|                     "align": "RIGHT" | ||||
|                 }, | ||||
|                 { | ||||
|                     "type": "input_value", | ||||
|                     "name": "TO", | ||||
|                     "check": getCompatibleTypes('int'), | ||||
|                     "check": getCompatibleTypes(Number), | ||||
|                     "align": "RIGHT" | ||||
|                 }, | ||||
|                 { | ||||
|                     "type": "input_value", | ||||
|                     "name": "BY", | ||||
|                     "check": getCompatibleTypes('int'), | ||||
|                     "check": getCompatibleTypes(Number), | ||||
|                     "align": "RIGHT" | ||||
|                 } | ||||
|             ], | ||||
| @ -98,13 +97,12 @@ Blockly.Blocks['controls_forEach'] = { | ||||
|                 { | ||||
|                     "type": "field_variable", | ||||
|                     "name": "VAR", | ||||
|                     "defaultType": Types.NUMBER.typeName, | ||||
|                     "variable": null | ||||
|                 }, | ||||
|                 { | ||||
|                     "type": "input_value", | ||||
|                     "name": "LIST", | ||||
|                     "check": getCompatibleTypes('Array') | ||||
|                     "check": getCompatibleTypes(Array) | ||||
|                 } | ||||
|             ], | ||||
|             "previousStatement": null, | ||||
| @ -197,7 +195,7 @@ Blockly.Blocks['controls_repeat_ext'] = { | ||||
|                 { | ||||
|                     "type": "input_value", | ||||
|                     "name": "TIMES", | ||||
|                     "check": getCompatibleTypes('int'), | ||||
|                     "check": getCompatibleTypes(Number), | ||||
|                 } | ||||
|             ], | ||||
|             "previousStatement": null, | ||||
|  | ||||
| @ -11,39 +11,40 @@ | ||||
|  * TODO: This block can be improved to set the new range properly. | ||||
|  */ | ||||
| 
 | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| 
 | ||||
| Blockly.Blocks["base_map"] = { | ||||
|   /** | ||||
|    * Block for creating a the map function. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/map"); | ||||
|     this.setColour(getColour().math); | ||||
|     this.appendValueInput("NUM") | ||||
|       .appendField(Blockly.Msg.ARD_MAP) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("FMIN") | ||||
|       .appendField(Blockly.Msg.ARD_MAP_FROMMIN) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("FMAX") | ||||
|       .appendField(Blockly.Msg.ARD_MAP_FROMMAX) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("DMIN") | ||||
|       .appendField(Blockly.Msg.ARD_MAP_TOMIN) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("DMAX") | ||||
|       .appendField(Blockly.Msg.ARD_MAP_TOMAX) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.setOutput(true); | ||||
|     this.setInputsInline(false); | ||||
|     this.setTooltip(Blockly.Msg.ARD_MAP_TIP); | ||||
|   }, | ||||
|   /** @return {string} The type of return value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER.typeName; | ||||
|   }, | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| Blockly.Blocks['base_map'] = { | ||||
|     /** | ||||
|      * Block for creating a the map function. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/map'); | ||||
|         this.setColour(getColour().math); | ||||
|         this.appendValueInput('NUM') | ||||
|             .appendField(Blockly.Msg.ARD_MAP) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('FMIN') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_FROMMIN) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('FMAX') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_FROMMAX) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('DMIN') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_TOMIN) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('DMAX') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_TOMAX) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.setOutput(true); | ||||
|         this.setInputsInline(false); | ||||
|         this.setTooltip(Blockly.Msg.ARD_MAP_TIP); | ||||
|     }, | ||||
|     /** @return {string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @ -287,8 +287,7 @@ Blockly.Blocks['math_change'] = { | ||||
|                 { | ||||
|                     "type": "field_variable", | ||||
|                     "name": "VAR", | ||||
|                     "defaultType": Types.NUMBER.typeName, | ||||
|                     "variable": null | ||||
|                     "variable": Blockly.Msg.MATH_CHANGE_TITLE_ITEM | ||||
|                 }, | ||||
|                 { | ||||
|                     "type": "input_value", | ||||
|  | ||||
| @ -1,86 +0,0 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| /** | ||||
|  * MQTT Blocks | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_mqtt_setup"] = { | ||||
|     init: function () { | ||||
| 
 | ||||
|         //this.setTooltip(Blockly.Msg.senseBox_wifi_);
 | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().mqtt); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_mqtt_init) | ||||
|             .appendField(new Blockly.FieldDropdown([["Adafruit IO", 'adafruitio'], ["DIOTY", 'dioty'], ["Other Service", 'custom']]), "service"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_mqtt_server) | ||||
|             .appendField(new Blockly.FieldTextInput("Server"), "server"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_mqtt_port) | ||||
|             .appendField(new Blockly.FieldTextInput("Port"), "port"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_mqtt_username) | ||||
|             .appendField(new Blockly.FieldTextInput("Username"), "username"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_mqtt_password, "passwordmsg") | ||||
|             .appendField(new Blockly.FieldTextInput("Password"), "password"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_mqtt_init_tooltip); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
|         let service = this.getFieldValue('service'); | ||||
|         switch (service) { | ||||
|             case 'adafruitio': | ||||
|                 this.getField('server').setValue("io.adafruit.com"); | ||||
|                 this.getField('port').setValue("1883"); | ||||
|                 this.getField('passwordmsg').setValue("Adafruit IO Key"); | ||||
|                 break; | ||||
|             case 'dioty': | ||||
|                 this.getField('server').setValue("mqtt.dioty.co"); | ||||
|                 this.getField('port').setValue("1883"); | ||||
|                 this.getField('passwordmsg').setValue(Blockly.Msg.senseBox_mqtt_password); | ||||
|                 break; | ||||
| 
 | ||||
|             case "custom": | ||||
|                 break; | ||||
|             default: | ||||
| 
 | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_mqtt_publish"] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().mqtt); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_mqtt_publish); | ||||
|         this.appendValueInput('value') | ||||
|             .setCheck(null) | ||||
|             .appendField('Feed/Topic') | ||||
|             .appendField(new Blockly.FieldTextInput('Name'), 'publishfeed'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_mqtt_publish_tooltip); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_mqtt_subscribe"] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().mqtt); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_mqtt_subscribe); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(new Blockly.FieldTextInput('Feedname'), 'subscribefeed'); | ||||
|         this.setOutput(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| @ -1,152 +0,0 @@ | ||||
| import * as Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_init"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_init) | ||||
|       .appendField(new Blockly.FieldTextInput("Geräte Name"), "devicename"); | ||||
| 
 | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_init_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_experiment"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.sensebox_phyphox_createExperiment | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_experimentTitle) | ||||
|       .appendField(new Blockly.FieldTextInput("Experiment Title"), "title"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_experimentDescription) | ||||
|       .appendField( | ||||
|         new Blockly.FieldTextInput( | ||||
|           Blockly.Msg.sensebox_phyphox_experiment_description | ||||
|         ), | ||||
|         "description" | ||||
|       ); | ||||
|     this.appendStatementInput("view").appendField( | ||||
|       Blockly.Msg.sensebox_phyphox_createView | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_experiment_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_graph"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_createGraph) | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_graphLabel) | ||||
|       .appendField(new Blockly.FieldTextInput("Label"), "label"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_unitx) | ||||
|       .appendField(new Blockly.FieldTextInput("Unit X"), "unitx"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_unity) | ||||
|       .appendField(new Blockly.FieldTextInput("Unit Y"), "unity"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_labelx) | ||||
|       .appendField(new Blockly.FieldTextInput("Label X"), "labelx"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_labely) | ||||
|       .appendField(new Blockly.FieldTextInput("Label Y"), "labely"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_graphStyle) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.sensebox_phyphox_style_line, "line"], | ||||
|           [Blockly.Msg.sensebox_phyphox_style_dots, "dots"], | ||||
|         ]), | ||||
|         "style" | ||||
|       ); | ||||
|     this.appendValueInput("channel0").appendField( | ||||
|       Blockly.Msg.sensebox_phyphox_channel0 | ||||
|     ); | ||||
|     this.appendValueInput("channel1").appendField( | ||||
|       Blockly.Msg.sensebox_phyphox_channel1 | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_graph_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_timestamp"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_phyphox_timestamp); | ||||
|     this.setOutput(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_timestamp_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_channel"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_channel) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           ["1", "1"], | ||||
|           ["2", "2"], | ||||
|           ["3", "3"], | ||||
|           ["4", "4"], | ||||
|           ["5", "5"], | ||||
|         ]), | ||||
|         "channel" | ||||
|       ); | ||||
| 
 | ||||
|     this.setOutput(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_channel_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_sendchannel"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.appendValueInput("value") | ||||
|       .appendField(Blockly.Msg.sensebox_phyphox_sendchannel) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           ["1", "1"], | ||||
|           ["2", "2"], | ||||
|           ["3", "3"], | ||||
|           ["4", "4"], | ||||
|           ["5", "5"], | ||||
|         ]), | ||||
|         "channel" | ||||
|       ); | ||||
| 
 | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_sendchannel_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_phyphox_experiment_send"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().phyphox); | ||||
|     this.appendStatementInput("sendValues").appendField( | ||||
|       Blockly.Msg.sensebox_phyphox_writeValues | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_phyphox_experiment_send_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_phyphox_helpurl); | ||||
|   }, | ||||
| }; | ||||
| @ -1,329 +1,254 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import { FieldSlider } from "@blockly/field-slider"; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import * as Types from '../helpers/types' | ||||
| import { FieldSlider } from '@blockly/field-slider'; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_beginDisplay"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_display_beginDisplay | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|   }, | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_beginDisplay'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_beginDisplay) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_clearDisplay"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_display_clearDisplay | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_display_clearDisplay'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_clearDisplay) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_printDisplay"] = { | ||||
|   init: function (block) { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_display_printDisplay | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_display_color) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_display_white, "WHITE,BLACK"], | ||||
|           [Blockly.Msg.senseBox_display_black, "BLACK,WHITE"], | ||||
|         ]), | ||||
|         "COLOR" | ||||
|       ); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_display_setSize) | ||||
|       .appendField(new FieldSlider(1, 1, 4), "SIZE"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|       .appendField(new FieldSlider(0, 0, 127), "X"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|       .appendField(new FieldSlider(0, 0, 63), "Y"); | ||||
|     this.appendValueInput("printDisplay") | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||
|       .setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|   }, | ||||
|   /** | ||||
| Blockly.Blocks['sensebox_display_printDisplay'] = { | ||||
|     init: function (block) { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_color) | ||||
|             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_display_white, "WHITE,BLACK"], [Blockly.Msg.senseBox_display_black, "BLACK,WHITE"]]), "COLOR"); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_setSize) | ||||
|             .appendField(new FieldSlider(1, 1, 4), "SIZE"); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|             .appendField(new FieldSlider(0, 0, 64), "X"); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|             .appendField(new FieldSlider(0, 0, 128), "Y"); | ||||
|         this.appendValueInput('printDisplay') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         let variableName = this.getField('COLOR'); | ||||
|         console.log(variableName.getValue()); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_plotDisplay'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotDisplay) | ||||
|         this.appendValueInput("Title", 'Text') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotTitle); | ||||
|         this.appendValueInput("YLabel", 'Text') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYLabel); | ||||
|         this.appendValueInput("XLabel", 'Text') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXLabel); | ||||
|         this.appendValueInput("XRange1", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXRange1); | ||||
|         this.appendValueInput("XRange2", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXRange2) | ||||
|         this.appendValueInput("YRange1", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYRange1); | ||||
|         this.appendValueInput("YRange2", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYRange2); | ||||
|         this.setInputsInline(false); | ||||
|         this.appendValueInput("XTick", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXTick); | ||||
|         this.appendValueInput("YTick", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYTick); | ||||
|         this.appendValueInput("TimeFrame", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotTimeFrame); | ||||
|         this.appendValueInput('plotDisplay') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_show'] = { | ||||
|     init: function () { | ||||
| 
 | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_display_show); | ||||
|         this.appendStatementInput('SHOW'); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_display_show_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_fillCircle'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_display_fillCircle); | ||||
|         this.appendValueInput('X') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('Y') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('Radius') | ||||
|             .appendField(Blockly.Msg.sensebox_display_fillCircle_radius) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendDummyInput('fill') | ||||
|             .appendField(Blockly.Msg.senseBox_display_filled) | ||||
|             .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_display_show"], | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_fastPrint"] = { | ||||
|   init: function (block) { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_show | ||||
|     ); | ||||
|     this.appendValueInput("Title1", "Title1").appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_title | ||||
|     ); | ||||
|     this.appendValueInput("Value1", "Value1").appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_value | ||||
|     ); | ||||
|     this.appendValueInput("Dimension1", "Dimension1").appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_dimension | ||||
|     ); | ||||
|     this.appendValueInput("Title2", "Title2").appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_title | ||||
|     ); | ||||
|     this.appendValueInput("Value2", "Value2").appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_value | ||||
|     ); | ||||
|     this.appendValueInput("Dimension2", "Dimension2").appendField( | ||||
|       Blockly.Msg.senseBox_display_fastPrint_dimension | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_display_fastPrint_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|   }, | ||||
|   /** | ||||
| Blockly.Blocks['sensebox_display_drawRectangle'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_display_drawRectangle); | ||||
|         this.appendValueInput('X') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('Y') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('width') | ||||
|             .appendField(Blockly.Msg.sensebox_display_drawRectangle_width) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('height') | ||||
|             .appendField(Blockly.Msg.sensebox_display_drawRectangle_height) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendDummyInput('fill') | ||||
|             .appendField(Blockly.Msg.senseBox_display_filled) | ||||
|             .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_display_show"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_plotDisplay"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_display_plotDisplay | ||||
|     ); | ||||
|     this.appendValueInput("Title", "Text").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotTitle | ||||
|     ); | ||||
|     this.appendValueInput("YLabel", "Text").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotYLabel | ||||
|     ); | ||||
|     this.appendValueInput("XLabel", "Text").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotXLabel | ||||
|     ); | ||||
|     this.appendValueInput("XRange1", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotXRange1 | ||||
|     ); | ||||
|     this.appendValueInput("XRange2", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotXRange2 | ||||
|     ); | ||||
|     this.appendValueInput("YRange1", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotYRange1 | ||||
|     ); | ||||
|     this.appendValueInput("YRange2", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotYRange2 | ||||
|     ); | ||||
|     this.setInputsInline(false); | ||||
|     this.appendValueInput("XTick", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotXTick | ||||
|     ); | ||||
|     this.appendValueInput("YTick", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotYTick | ||||
|     ); | ||||
|     this.appendValueInput("TimeFrame", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_display_plotTimeFrame | ||||
|     ); | ||||
|     this.appendValueInput("plotDisplay") | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||
|       .setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|   }, | ||||
|   /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_display_show"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_show"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_display_show); | ||||
|     this.appendStatementInput("SHOW"); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_display_show_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_fillCircle"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.sensebox_display_fillCircle | ||||
|     ); | ||||
|     this.appendValueInput("X") | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("Y") | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("Radius") | ||||
|       .appendField(Blockly.Msg.sensebox_display_fillCircle_radius) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendDummyInput("fill") | ||||
|       .appendField(Blockly.Msg.senseBox_display_filled) | ||||
|       .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||
|     this.setInputsInline(false); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_display_fillCircle_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_display_show"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_display_drawRectangle"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.sensebox_display_drawRectangle | ||||
|     ); | ||||
|     this.appendValueInput("X") | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("Y") | ||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("width") | ||||
|       .appendField(Blockly.Msg.sensebox_display_drawRectangle_width) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendValueInput("height") | ||||
|       .appendField(Blockly.Msg.sensebox_display_drawRectangle_height) | ||||
|       .setCheck(Types.NUMBER.compatibleTypes); | ||||
|     this.appendDummyInput("fill") | ||||
|       .appendField(Blockly.Msg.senseBox_display_filled) | ||||
|       .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||
|     this.setInputsInline(false); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_display_drawRectangle_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_display_show"], | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| import * as Blockly from 'blockly'; | ||||
| import { FieldSlider } from '@blockly/field-slider'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| import { selectedBoard } from '../helpers/board' | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_led'] = { | ||||
| @ -15,7 +16,7 @@ Blockly.Blocks['sensebox_led'] = { | ||||
|             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_on, "HIGH"], [Blockly.Msg.senseBox_off, "LOW"]]), "STAT"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_led_tooltip); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_led_tip); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| @ -26,147 +27,18 @@ Blockly.Blocks['sensebox_rgb_led'] = { | ||||
|             .appendField(Blockly.Msg.senseBox_rgb_led) | ||||
|             .appendField("Pin:") | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "PIN"); | ||||
| 
 | ||||
|         this.appendValueInput("COLOR", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_ws2818_rgb_led_color) | ||||
|             .setCheck("Colour"); | ||||
|         // this.appendValueInput("RED", 'Number')
 | ||||
|         //     .appendField(Blockly.Msg.COLOUR_RGB_RED);//Blockly.Msg.senseBox_basic_red
 | ||||
|         // this.appendValueInput("GREEN", 'Number')
 | ||||
|         //     .appendField(Blockly.Msg.COLOUR_RGB_GREEN);//Blockly.Msg.senseBox_basic_green
 | ||||
|         // this.appendValueInput("BLUE", 'Number')
 | ||||
|         //     .appendField(Blockly.Msg.COLOUR_RGB_BLUE);
 | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.COLOUR_RGB_RED)//Blockly.Msg.senseBox_basic_red
 | ||||
|             .appendField(new FieldSlider(255, 0, 255), "RED"); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.COLOUR_RGB_GREEN)//Blockly.Msg.senseBox_basic_green
 | ||||
|             .appendField(new FieldSlider(255, 0, 255), "GREEN"); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.COLOUR_RGB_BLUE)//Blockly.Msg.senseBox_basic_green
 | ||||
|             .appendField(new FieldSlider(255, 0, 255), "BLUE"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_rgb_led_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_ws2818_led_init'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_ws2818_rgb_led_init) | ||||
|             .appendField("Port:") | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPinsRGB), "Port") | ||||
|         this.appendValueInput("BRIGHTNESS", "brightness") | ||||
|             .appendField((Blockly.Msg.senseBox_ws2818_rgb_led_brightness)); | ||||
|         this.appendValueInput("NUMBER", "number") | ||||
|             .appendField((Blockly.Msg.senseBox_ws2818_rgb_led_number)); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_ws2818_rgb_led_init_tooltip); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_ws2818_led'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_ws2818_rgb_led) | ||||
|             .appendField("Port:") | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPinsRGB), "Port") | ||||
|         this.appendValueInput("POSITION", "position") | ||||
|             .appendField((Blockly.Msg.senseBox_ws2818_rgb_led_position)); | ||||
|         this.appendValueInput("COLOR", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_ws2818_rgb_led_color) | ||||
|             .setCheck("Colour"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_ws2818_rgb_led_tooltip); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
 | ||||
|     // Block for colour picker.
 | ||||
|     { | ||||
|         "type": "colour_picker", | ||||
|         "message0": "%1", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "field_colour", | ||||
|                 "name": "COLOUR", | ||||
|                 "colour": "#ff0000" | ||||
|             } | ||||
|         ], | ||||
|         "output": "Colour", | ||||
|         "helpUrl": "%{BKY_COLOUR_PICKER_HELPURL}", | ||||
|         "colour": getColour().sensebox, | ||||
|         "tooltip": "%{BKY_COLOUR_PICKER_TOOLTIP}", | ||||
|         "extensions": ["parent_tooltip_when_inline"] | ||||
|     }, | ||||
| 
 | ||||
|     // Block for random colour.
 | ||||
|     { | ||||
|         "type": "colour_random", | ||||
|         "message0": "%{BKY_COLOUR_RANDOM_TITLE}", | ||||
|         "output": "Colour", | ||||
|         "helpUrl": "%{BKY_COLOUR_RANDOM_HELPURL}", | ||||
|         "colour": getColour().sensebox, | ||||
|         "tooltip": "%{BKY_COLOUR_RANDOM_TOOLTIP}" | ||||
|     }, | ||||
| 
 | ||||
|     // Block for composing a colour from RGB components.
 | ||||
|     { | ||||
|         "type": "colour_rgb", | ||||
|         "message0": "%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "RED", | ||||
|                 "check": Types.getCompatibleTypes('int'), | ||||
|                 "align": "RIGHT" | ||||
|             }, | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "GREEN", | ||||
|                 "check": Types.getCompatibleTypes('int'), | ||||
|                 "align": "RIGHT" | ||||
|             }, | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "BLUE", | ||||
|                 "check": Types.getCompatibleTypes('int'), | ||||
|                 "align": "RIGHT" | ||||
|             } | ||||
|         ], | ||||
|         "output": "Colour", | ||||
|         "helpUrl": "%{BKY_COLOUR_RGB_HELPURL}", | ||||
|         "colour": getColour().sensebox, | ||||
|         "tooltip": "%{BKY_COLOUR_RGB_TOOLTIP}" | ||||
|     }, | ||||
| 
 | ||||
|     // Block for blending two colours together.
 | ||||
|     { | ||||
|         "type": "colour_blend", | ||||
|         "message0": "%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} " + | ||||
|             "%1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "COLOUR1", | ||||
|                 "check": "Colour", | ||||
|                 "align": "RIGHT" | ||||
|             }, | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "COLOUR2", | ||||
|                 "check": "Colour", | ||||
|                 "align": "RIGHT" | ||||
|             }, | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "RATIO", | ||||
|                 "check": "Number", | ||||
|                 "align": "RIGHT" | ||||
|             } | ||||
|         ], | ||||
|         "output": "Colour", | ||||
|         "helpUrl": "%{BKY_COLOUR_BLEND_HELPURL}", | ||||
|         "style": "colour_blocks", | ||||
|         "tooltip": "%{BKY_COLOUR_BLEND_TOOLTIP}" | ||||
|     } | ||||
| ]);  // END JSON EXTRACT (Do not delete this comment.)
 | ||||
| 
 | ||||
| }; | ||||
| @ -1,320 +1,253 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
| ----------------------------------LoRa-------------------------------------------------- | ||||
| */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_lora_initialize_otaa"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_LoRa_init_helpurl); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField("Initialize LoRa (OTAA)"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_device_id) | ||||
|       .appendField("{") | ||||
|       .appendField(new Blockly.FieldTextInput("DEVICE ID"), "DEVICEID") | ||||
|       .appendField("}"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_app_id) | ||||
|       .appendField("{") | ||||
|       .appendField(new Blockly.FieldTextInput("APP ID"), "APPID") | ||||
|       .appendField("}"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_app_key) | ||||
|       .appendField("{") | ||||
|       .appendField(new Blockly.FieldTextInput("APP KEY"), "APPKEY") | ||||
|       .appendField("}"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||
|       .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_lora_initialize_otaa'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("Initialize LoRa (OTAA)"); | ||||
| 
 | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_device_id) | ||||
|             .appendField(new Blockly.FieldTextInput("DEVICE ID"), "DEVICEID"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_app_id) | ||||
|             .appendField(new Blockly.FieldTextInput("APP ID"), "APPID"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_app_key) | ||||
|             .appendField(new Blockly.FieldTextInput("APP KEY"), "APPKEY"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||
|             .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_lora_initialize_abp"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_LoRa_init_helpurl); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField("Initialize LoRa (ABP)"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_nwskey_id) | ||||
|       .appendField("{") | ||||
|       .appendField(new Blockly.FieldTextInput("NWSKEY"), "NWSKEY") | ||||
|       .appendField("}"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_appskey_id) | ||||
|       .appendField("{") | ||||
|       .appendField(new Blockly.FieldTextInput("APPSKEY"), "APPSKEY") | ||||
|       .appendField("}"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_devaddr_id) | ||||
|       .appendField(new Blockly.FieldTextInput("DEVADDR"), "DEVADDR"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||
|       .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||
|     // this.appendStatementInput('DO')
 | ||||
|     //     .appendField(Blockly.Msg.senseBox_measurements)
 | ||||
|     //     .setCheck(null);
 | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_lora_initialize_abp'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("Initialize LoRa (ABP)"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_nwskey_id) | ||||
|             .appendField(new Blockly.FieldTextInput("NWSKEY"), "NWSKEY"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_appskey_id) | ||||
|             .appendField(new Blockly.FieldTextInput("APPSKEY"), "APPSKEY"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_devaddr_id) | ||||
|             .appendField(new Blockly.FieldTextInput("DEVADDR"), "DEVADDR"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||
|             .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||
|         // this.appendStatementInput('DO')
 | ||||
|         //     .appendField(Blockly.Msg.senseBox_measurements)
 | ||||
|         //     .setCheck(null);
 | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_lora_message_send"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tooltip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendStatementInput("DO") | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_send_message) | ||||
|       .setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_send_lora_sensor_value"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_sensor_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_measurement | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField("Bytes") | ||||
|       .appendField(new Blockly.FieldTextInput("2"), "MESSAGE_BYTES"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
| Blockly.Blocks['sensebox_lora_message_send'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_send_message) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_message_send"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_lora_ttn_mapper"] = { | ||||
|   init: function (block) { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField("TTN Mapper"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField("Fix Type Limit") | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown( | ||||
|           [ | ||||
|             ["0", "0"], | ||||
|             ["1", "1"], | ||||
|             ["2", "2"], | ||||
|             ["3", "3"], | ||||
|           ].reverse() | ||||
|         ), | ||||
|         "dropdown" | ||||
|       ); | ||||
|     // reverse() because i want 3 be be at first and i'm to lazy to write the array again
 | ||||
|     this.appendValueInput("Latitude") | ||||
|       .appendField(Blockly.Msg.senseBox_gps_lat) | ||||
|       .setCheck(null); | ||||
|     this.appendValueInput("Longitude") | ||||
|       .appendField(Blockly.Msg.senseBox_gps_lng) | ||||
|       .setCheck(null); | ||||
|     this.appendValueInput("Altitude") | ||||
|       .appendField(Blockly.Msg.senseBox_gps_alt) | ||||
|       .setCheck(null); | ||||
|     this.appendValueInput("pDOP").appendField("pDOP").setCheck(null); | ||||
|     this.appendValueInput("Fix Type").appendField("Fix Type").setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_lora_ttn_mapper_tip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_lora_ttn_mapper_helpurl); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_send_lora_sensor_value'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_sensor_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_measurement) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("Bytes") | ||||
|             .appendField(new Blockly.FieldTextInput("2"), "MESSAGE_BYTES"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_message_send'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_lora_cayenne_send"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendStatementInput("DO") | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_send_cayenne) | ||||
|       .setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_lora_cayenne_send'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_send_cayenne) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_temperature"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_temperature_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_temperature | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_temperature'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_temperature_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_temperature) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_humidity"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_humidity_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_humidity | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_humidity'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_humidity_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_humidity) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_pressure"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_pressure_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_pressure | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_pressure'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_pressure_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_pressure) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_luminosity"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_luminosity_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_luminosity | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_luminosity'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_luminosity_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_luminosity) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_sensor"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_analog_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_analog | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_sensor'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_analog_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_analog) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_accelerometer"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gyros_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("X").appendField(Blockly.Msg.senseBox_LoRa_cayenne_x); | ||||
|     this.appendValueInput("Y").appendField(Blockly.Msg.senseBox_LoRa_cayenne_y); | ||||
|     this.appendValueInput("Z").appendField(Blockly.Msg.senseBox_LoRa_cayenne_z); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_accelerometer'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gyros_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('X') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_x) | ||||
|         this.appendValueInput('Y') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_y) | ||||
|         this.appendValueInput('Z') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_z) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_lora_cayenne_gps"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gps_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("LAT").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_lat | ||||
|     ); | ||||
|     this.appendValueInput("LNG").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_lng | ||||
|     ); | ||||
|     this.appendValueInput("ALT").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_alt | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_lora_cayenne_concentration"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_concentration_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendValueInput("Value").appendField( | ||||
|       Blockly.Msg.senseBox_LoRa_cayenne_concentration | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], | ||||
| Blockly.Blocks['sensebox_lora_cayenne_gps'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gps_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('LAT') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_lat) | ||||
|         this.appendValueInput('LNG') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_lng) | ||||
|         this.appendValueInput('ALT') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_alt) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
|  | ||||
| @ -1,144 +0,0 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import { selectedBoard } from "../helpers/board"; | ||||
| import { FieldSlider } from "@blockly/field-slider"; | ||||
| 
 | ||||
| /** | ||||
|  * Servo Motor | ||||
|  *  | ||||
|  */ | ||||
| Blockly.Blocks["sensebox_motors_beginServoMotor"] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_beginServoMotor); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_beginServoMotor_pin) | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "pin") | ||||
|             .setAlign(Blockly.ALIGN_RIGHT); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_beginServoMotor_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_beginServoMotor_helpurl); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_motors_moveServoMotor"] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_moveServoMotor); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_moveServoMotor_pin) | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "pin") | ||||
|             .setAlign(Blockly.ALIGN_RIGHT); | ||||
|         this.appendValueInput("degrees", "Number") | ||||
|             .appendField(Blockly.Msg.sensebox_motors_moveServoMotor_degrees) | ||||
|             .setAlign(Blockly.ALIGN_RIGHT); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_moveServoMotor_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_moveServoMotor_helpurl); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * I2C Motor Board | ||||
|  *  | ||||
|  */ | ||||
| Blockly.Blocks["sensebox_motors_I2CMotorBoard_begin"] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_I2CMotorBoard_begin); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_I2CMotorBoard_begin_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_I2CMotorBoard_begin_helpurl); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_motors_I2CMotorBoard_moveDCMotor"] = { | ||||
|     init: function () { | ||||
|         var dropdownOptions = [[Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor_left, '1'], | ||||
|         [Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor_right, '2']]; | ||||
| 
 | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor) | ||||
|             .appendField(new Blockly.FieldDropdown(dropdownOptions), "motor") | ||||
|             .appendField(Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor_motor); | ||||
|         this.appendValueInput("speed", "Number") | ||||
|             .appendField(Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor_speed) | ||||
|             .setAlign(Blockly.ALIGN_RIGHT); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_I2CMotorBoard_moveDCMotor_helpurl); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_motors_I2CMotorBoard_stopDCMotor"] = { | ||||
|     init: function () { | ||||
|         var dropdownOptions = [[Blockly.Msg.sensebox_motors_I2CMotorBoard_stopDCMotor_left, '1'], | ||||
|         [Blockly.Msg.sensebox_motors_I2CMotorBoard_stopDCMotor_right, '2']]; | ||||
| 
 | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_I2CMotorBoard_stopDCMotor) | ||||
|             .appendField(new Blockly.FieldDropdown(dropdownOptions), "motor") | ||||
|             .appendField(Blockly.Msg.sensebox_motors_I2CMotorBoard_stopDCMotor_motor) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_I2CMotorBoard_stopDCMotor_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_I2CMotorBoard_stopDCMotor_helpurl); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Stepper Motor | ||||
|  *  | ||||
|  */ | ||||
| Blockly.Blocks["sensebox_motors_beginStepperMotor"] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_beginStepperMotor); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_beginStepperMotor_pins); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_RIGHT) | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "in1") | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "in2") | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "in3") | ||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "in4"); | ||||
|         this.setFieldValue("1", "in1"); | ||||
|         this.setFieldValue("2", "in2"); | ||||
|         this.setFieldValue("3", "in3"); | ||||
|         this.setFieldValue("4", "in4"); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_beginStepperMotor_rpm) | ||||
|             .appendField(new FieldSlider(3, 1, 3), "rpm"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_beginStepperMotor_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_beginStepperMotor_helpurl); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_motors_moveStepperMotor"] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_motors_moveStepperMotor); | ||||
|         this.appendValueInput("steps", "Number") | ||||
|             .setAlign(Blockly.ALIGN_RIGHT) | ||||
|             .appendField(Blockly.Msg.sensebox_motors_moveStepperMotor_step); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().motors); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_motors_moveStepperMotor_tooltip); | ||||
|         this.setHelpUrl(Blockly.Msg.sensebox_motors_moveStepperMotor_helpurl); | ||||
|     }, | ||||
| }; | ||||
| @ -1,42 +0,0 @@ | ||||
| import * as Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_ntp_init"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_ntp_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_ntp_init); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_ntp_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_ntp_get"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_ntp_get_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_ntp_get) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.sensebox_ntp_epochTime, "getEpochTime"], | ||||
|           [Blockly.Msg.sensebox_ntp_formattedTimeStamp, "getFormattedTime"], | ||||
|         ]), | ||||
|         "dropdown" | ||||
|       ); | ||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_get_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_ntp_get_timestamp"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_rtc_get_timestamp); | ||||
|     this.setOutput(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_get_timestamp_tooltip); | ||||
|   }, | ||||
| }; | ||||
| @ -1,199 +1,112 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| import store from "../../../store"; | ||||
| 
 | ||||
| var boxes = store.getState().auth.user | ||||
|   ? store.getState().auth.user.boxes | ||||
|   : null; | ||||
| store.subscribe(() => { | ||||
|   boxes = store.getState().auth.user ? store.getState().auth.user.boxes : null; | ||||
| }); | ||||
| var selectedBox = ""; | ||||
| Blockly.Blocks['sensebox_osem_connection'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_osem_connection_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_osem_connection) | ||||
|             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_osem_host, '"ingress.opensensemap.org"'], [Blockly.Msg.senseBox_osem_host_workshop, '"ingress.workshop.opensensemap.org"']]), "host") | ||||
|             .appendField('SSL') | ||||
|             .appendField(new Blockly.FieldCheckbox("TRUE"), "SSL"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_osem_exposure) | ||||
|             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_osem_stationary, 'Stationary'], [Blockly.Msg.senseBox_osem_mobile, 'Mobile']]), "type"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("senseBox ID") | ||||
|             .appendField(new Blockly.FieldTextInput("senseBox ID"), "BoxID"); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.senseBox_sensor) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_osem_connection"] = { | ||||
|   init: function () { | ||||
|     var ssl = "TRUE"; | ||||
|     this.setTooltip(Blockly.Msg.senseBox_osem_connection_tip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_osem_connection_helpurl); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_osem_connection) | ||||
|       .appendField("SSL") | ||||
|       .appendField(new Blockly.FieldCheckbox(ssl), "SSL"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_osem_restart) | ||||
|       .appendField(new Blockly.FieldCheckbox("TRUE"), "RESTART"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_osem_exposure) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_osem_stationary, "Stationary"], | ||||
|           [Blockly.Msg.senseBox_osem_mobile, "Mobile"], | ||||
|         ]), | ||||
|         "type" | ||||
|       ); | ||||
|     if (!boxes) { | ||||
|       this.appendDummyInput() | ||||
|         .setAlign(Blockly.ALIGN_LEFT) | ||||
|         .appendField("senseBox ID") | ||||
|         .appendField(new Blockly.FieldTextInput("senseBox ID"), "BoxID"); | ||||
|     } else { | ||||
|       var dropdown = []; | ||||
|       for (var i = 0; i < boxes.length; i++) { | ||||
|         dropdown.push([boxes[i].name, boxes[i]._id]); | ||||
|       } | ||||
|       this.appendDummyInput() | ||||
|         .setAlign(Blockly.ALIGN_LEFT) | ||||
|         .appendField("senseBox ID") | ||||
|         .appendField(new Blockly.FieldDropdown(dropdown), "BoxID"); | ||||
|     } | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_osem_access_token) | ||||
|       .appendField(new Blockly.FieldTextInput("access_token"), "access_token"); | ||||
|     this.appendStatementInput("DO") | ||||
|       .appendField(Blockly.Msg.senseBox_sensor) | ||||
|       .setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.getField("type").setValidator( | ||||
|       function (val) { | ||||
|         this.updateShape_(val === "Mobile"); | ||||
|       }.bind(this) | ||||
|     ); | ||||
|   }, | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|         //Blockly.Blocks.sensebox.getDescendants = blocks;
 | ||||
| 
 | ||||
|     }, | ||||
|     mutationToDom: function () { | ||||
|         var container = document.createElement('mutation'); | ||||
|         var input = this.getFieldValue('type'); | ||||
|         this.updateShape_(input); | ||||
|         container.setAttribute('type', input); | ||||
|         return container; | ||||
|     }, | ||||
| 
 | ||||
|     domToMutation: function (xmlElement) { | ||||
|         var connections = xmlElement.getAttribute('connections'); | ||||
|         this.updateShape_(connections); | ||||
|     }, | ||||
|     /** | ||||
|      * List of block types that are loops and thus do not need warnings. | ||||
|      * To add a new loop type add this to your code: | ||||
|      * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop'); | ||||
|      * Modify this block to have the correct number of pins available. | ||||
|      * @param {boolean} | ||||
|      * @private | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     selectedBox = this.getFieldValue("BoxID"); | ||||
|     if (selectedBox !== "" && boxes) { | ||||
|       var accessToken = boxes.find( | ||||
|         (element) => element._id === selectedBox | ||||
|       ).access_token; | ||||
|       if (accessToken !== undefined) { | ||||
|         this.getField("access_token").setValue(accessToken); | ||||
|       } else { | ||||
|         this.getField("access_token").setValue("access_token"); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   updateShape_(isMobile) { | ||||
|     if (isMobile) { | ||||
|       if (this.getInput("lat") == null) { | ||||
|         this.appendValueInput("lat", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_lat, | ||||
|           "gps" | ||||
|         ); | ||||
|         this.appendValueInput("lng", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_lng | ||||
|         ); | ||||
|         this.appendValueInput("altitude", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_alt | ||||
|         ); | ||||
|         this.appendValueInput("timeStamp", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_timeStamp | ||||
|         ); | ||||
|       } | ||||
|     } else { | ||||
|       this.removeInput("lat", true); | ||||
|       this.removeInput("lng", true); | ||||
|       this.removeInput("altitude", true); | ||||
|       this.removeInput("timeStamp", true); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_interval_timer"], | ||||
| }; | ||||
| Blockly.Blocks["sensebox_send_to_osem"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_send_to_osem_tip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_send_to_osem); | ||||
|     if (boxes) { | ||||
|       this.appendValueInput("Value") | ||||
|         .appendField("Phänomen") | ||||
|         .appendField( | ||||
|           new Blockly.FieldDropdown(this.generateOptions), | ||||
|           "SensorID" | ||||
|         ); | ||||
|     } else { | ||||
|       this.appendValueInput("Value") | ||||
|         .setAlign(Blockly.ALIGN_LEFT) | ||||
|         .appendField("Phänomen") | ||||
|         .appendField(new Blockly.FieldTextInput("sensorID"), "SensorID"); | ||||
|     } | ||||
| 
 | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| 
 | ||||
|   generateOptions: function () { | ||||
|     var dropdown = [["", ""]]; | ||||
|     var boxID = selectedBox; | ||||
|     if (boxID !== "" && boxes) { | ||||
|       let box = boxes.find((el) => el._id === boxID); | ||||
|       if (box !== undefined) { | ||||
|         for (var i = 0; i < box.sensors.length; i++) { | ||||
|           dropdown.push([box.sensors[i].title, box.sensors[i]._id]); | ||||
|     updateShape_: function () { | ||||
|         var extraFieldExist = this.getFieldValue('gps'); | ||||
|         var input = this.getFieldValue('type'); | ||||
|         if ((input === 'Mobile') && extraFieldExist === null) { | ||||
|             this.appendValueInput('lat', 'Number') | ||||
|                 .appendField(Blockly.Msg.senseBox_gps_lat, 'gps'); | ||||
|             this.appendValueInput('lng', 'Number') | ||||
|                 .appendField(Blockly.Msg.senseBox_gps_lng); | ||||
|             this.appendValueInput('altitude', 'Number') | ||||
|                 .appendField(Blockly.Msg.senseBox_gps_alt); | ||||
|             this.appendValueInput('timeStamp', 'Number') | ||||
|                 .appendField(Blockly.Msg.senseBox_gps_timeStamp); | ||||
|         } | ||||
|       } | ||||
|       if (dropdown.length > 1) { | ||||
|         var options = dropdown.slice(1); | ||||
|         return options; | ||||
|       } else { | ||||
|         return dropdown; | ||||
|       } | ||||
|     } | ||||
|     return dropdown; | ||||
|   }, | ||||
|   /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function () { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|     } | ||||
|   }, | ||||
|   /** | ||||
|    * List of block types that are loops and thus do not need warnings. | ||||
|    * To add a new loop type add this to your code: | ||||
|    * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop'); | ||||
|    */ | ||||
|   LOOP_TYPES: ["sensebox_osem_connection"], | ||||
| 
 | ||||
|         if (input === 'Stationary' && extraFieldExist !== null) { | ||||
|             this.removeInput('lat'); | ||||
|             this.removeInput('lng'); | ||||
|             this.removeInput('altitude'); | ||||
|             this.removeInput('timeStamp'); | ||||
|         } | ||||
|     }, | ||||
| }; | ||||
| Blockly.Blocks['sensebox_send_to_osem'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_send_to_osem_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_send_to_osem); | ||||
|         this.appendValueInput('Value') | ||||
|             .setCheck(null) | ||||
|             .appendField('Sensor ID') | ||||
|             .appendField(new Blockly.FieldTextInput('Sensor ID'), 'SensorID'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|   * Called whenever anything on the workspace changes. | ||||
|   * Add warning if block is not nested inside a the correct loop. | ||||
|   * @param {!Blockly.Events.Abstract} e Change event. | ||||
|   * @this Blockly.Block | ||||
|   */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_osem_connection'], | ||||
| }; | ||||
| @ -1,142 +0,0 @@ | ||||
| import * as Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_rtc_init"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_rtc_init); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_init_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_rtc_set"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_rtc_set); | ||||
|     this.appendValueInput("second").appendField( | ||||
|       Blockly.Msg.sensebox_rtc_second | ||||
|     ); | ||||
|     this.appendValueInput("minutes").appendField( | ||||
|       Blockly.Msg.sensebox_rtc_minutes | ||||
|     ); | ||||
|     this.appendValueInput("hour").appendField(Blockly.Msg.sensebox_rtc_hour); | ||||
|     this.appendValueInput("day").appendField(Blockly.Msg.sensebox_rtc_day); | ||||
|     this.appendValueInput("month").appendField(Blockly.Msg.sensebox_rtc_month); | ||||
|     this.appendValueInput("year").appendField(Blockly.Msg.sensebox_rtc_year); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_set_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_rtc_set_ntp"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendValueInput("time").appendField(Blockly.Msg.sensebox_rtc_set_ntp); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_set_ntp_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_rtc_get"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_rtc_get) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.sensebox_rtc_hour, "hour"], | ||||
|           [Blockly.Msg.sensebox_rtc_minutes, "minutes"], | ||||
|           [Blockly.Msg.sensebox_rtc_second, "seconds"], | ||||
|           [Blockly.Msg.sensebox_rtc_day, "day"], | ||||
|           [Blockly.Msg.sensebox_rtc_month, "month"], | ||||
|           [Blockly.Msg.sensebox_rtc_year, "year"], | ||||
|         ]), | ||||
|         "dropdown" | ||||
|       ); | ||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_get_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_rtc_get_timestamp"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_rtc_get_timestamp); | ||||
|     this.setOutput(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_rtc_get_timestamp_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  *  Internal RTC | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_internal_rtc_init"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_internal_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_internal_rtc_init); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_internal_rtc_init_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_internal_rtc_set"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendValueInput("time").appendField( | ||||
|       Blockly.Msg.sensebox_internal_rtc_set | ||||
|     ); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_internal_rtc_set_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_internal_rtc_get"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.sensebox_internal_rtc_get) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.sensebox_internal_rtc_epoch, "Epoch"], | ||||
|           [Blockly.Msg.sensebox_internal_rtc_year, "Year"], | ||||
|           [Blockly.Msg.sensebox_internal_rtc_month, "Month"], | ||||
|           [Blockly.Msg.sensebox_internal_rtc_day, "Day"], | ||||
|           [Blockly.Msg.sensebox_internal_rtc_hour, "Hours"], | ||||
|           [Blockly.Msg.sensebox_internal_rtc_minutes, "Minutes"], | ||||
|           [Blockly.Msg.sensebox_internal_rtc_seconds, "Seconds"], | ||||
|         ]), | ||||
|         "dropdown" | ||||
|       ); | ||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_internal_rtc_get_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_internal_rtc_get_timestamp"] = { | ||||
|   init: function () { | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_internal_rtc_helpurl); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.sensebox_internal_rtc_get_timestamp | ||||
|     ); | ||||
|     this.setOutput(true); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_internal_rtc_get_timestamp_tooltip); | ||||
|   }, | ||||
| }; | ||||
| @ -1,174 +1,80 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| var checkFileName = function (filename) { | ||||
|   var length = filename.length; | ||||
|   if (length > 8) { | ||||
|     alert("dateiname sollte kleiner als 8 Zeichen sein"); | ||||
|     return filename.slice(0, 8); | ||||
|   } | ||||
|   return filename; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sd_open_file"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sd_open_file) | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField( | ||||
|         new Blockly.FieldTextInput("Data", checkFileName), | ||||
|         "Filename" | ||||
|       ) | ||||
|       .appendField(".") | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           ["txt", "txt"], | ||||
|           ["csv", "csv"], | ||||
|         ]), | ||||
|         "extension" | ||||
|       ); | ||||
|     this.appendStatementInput("SD").setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sd_open_file_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sd_create_file"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sd_create_file) | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_output_filename) | ||||
|       .appendField( | ||||
|         new Blockly.FieldTextInput("Data", checkFileName), | ||||
|         "Filename" | ||||
|       ) | ||||
|       .appendField(".") | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           ["txt", "txt"], | ||||
|           ["csv", "csv"], | ||||
|         ]), | ||||
|         "extension" | ||||
|       ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sd_create_file_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sd_write_file"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sd_write_file) | ||||
|       .setAlign(Blockly.ALIGN_LEFT); | ||||
|     this.appendValueInput("DATA").setCheck(null); | ||||
|     this.appendDummyInput("CheckboxText") | ||||
|       .appendField(Blockly.Msg.senseBox_output_linebreak) | ||||
|       .appendField(new Blockly.FieldCheckbox("TRUE"), "linebreak"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sd_write_file_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||
|   }, | ||||
|   /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
| Blockly.Blocks['sensebox_sd_open_file'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_sd_open_file) | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField( | ||||
|                 new Blockly.FieldTextInput('Data.txt'), | ||||
|                 'Filename'); | ||||
|         this.appendStatementInput('SD') | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["sensebox_sd_open_file"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sd_osem"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.sensebox_sd_osem_tip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.sensebox_sd_osem); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_osem_exposure) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_osem_stationary, "Stationary"], | ||||
|           [Blockly.Msg.senseBox_osem_mobile, "Mobile"], | ||||
|         ]), | ||||
|         "type" | ||||
|       ); | ||||
|     this.appendValueInput("timeStamp", "Number").appendField( | ||||
|       Blockly.Msg.senseBox_gps_timeStamp | ||||
|     ); | ||||
|     this.appendStatementInput("DO") | ||||
|       .appendField(Blockly.Msg.sensebox_sd_measurement) | ||||
|       .setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.getField("type").setValidator( | ||||
|       function (val) { | ||||
|         this.updateShape_(val === "Mobile"); | ||||
|       }.bind(this) | ||||
|     ); | ||||
|   }, | ||||
| 
 | ||||
|   updateShape_(isMobile) { | ||||
|     if (isMobile) { | ||||
|       if (this.getInput("lat") == null) { | ||||
|         this.appendValueInput("lat", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_lat, | ||||
|           "gps" | ||||
|         ); | ||||
|         this.appendValueInput("lng", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_lng | ||||
|         ); | ||||
|         this.appendValueInput("altitude", "Number").appendField( | ||||
|           Blockly.Msg.senseBox_gps_alt | ||||
|         ); | ||||
|       } | ||||
|     } else { | ||||
|       this.removeInput("lat", true); | ||||
|       this.removeInput("lng", true); | ||||
|       this.removeInput("altitude", true); | ||||
| Blockly.Blocks['sensebox_sd_create_file'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_sd_create_file) | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_output_filename) | ||||
|             .appendField( | ||||
|                 new Blockly.FieldTextInput('Data.txt'), | ||||
|                 'Filename'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sd_save_for_osem"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.sensebox_sd_save_for_osem_tip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_sd_save_for_osem); | ||||
|     this.appendValueInput("Value") | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.sensebox_sd_save_for_osem_id) | ||||
|       .appendField(new Blockly.FieldTextInput("sensorID"), "SensorID"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_sd_write_file'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_sd_write_file) | ||||
|             .setAlign(Blockly.ALIGN_LEFT); | ||||
|         this.appendValueInput('DATA') | ||||
|             .setCheck(null); | ||||
|         this.appendDummyInput('CheckboxText') | ||||
|             .appendField(Blockly.Msg.senseBox_output_linebreak) | ||||
|             .appendField(new Blockly.FieldCheckbox('TRUE'), 'linebreak'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_sd_open_file'], | ||||
| }; | ||||
|  | ||||
| @ -1,260 +1,127 @@ | ||||
| import Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import { selectedBoard } from "../helpers/board"; | ||||
| import { FieldGridDropdown } from "@blockly/field-grid-dropdown"; | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| import * as Types from '../helpers/types' | ||||
| import { selectedBoard } from '../helpers/board' | ||||
| 
 | ||||
| /** | ||||
|  * HDC1080 Temperature and Humidity Sensor | ||||
|  * | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_temp_hum"] = { | ||||
| Blockly.Blocks['sensebox_sensor_temp_hum'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_temp_hum); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_temp_hum); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_temp, "Temperature"], | ||||
|           [Blockly.Msg.senseBox_hum, "Humidity"], | ||||
|         ]), | ||||
|         "NAME" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_hum, "Humidity"]]), "NAME"); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_temp_hum_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_temp_hum_helpurl); | ||||
|     this.data = {name: "hdc1080", connection: "I2C"}; | ||||
|   }, | ||||
|     this.setTooltip(Blockly.Msg.senseBox_temp_hum_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * VEML6070 and TSL4513 | ||||
|  * | ||||
|  * VEML6070 and TSL4513  | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_uv_light"] = { | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_uv_light'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_uv_light); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_uv_light); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_light, "Illuminance"], | ||||
|           [Blockly.Msg.senseBox_uv, "UvIntensity"], | ||||
|         ]), | ||||
|         "NAME" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_light, "Illuminance"], [Blockly.Msg.senseBox_uv, "UvIntensity"]]), "NAME"); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_uv_light_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_uv_light_helpurl); | ||||
|     this.data = {name: "veml6070"}; | ||||
|   }, | ||||
|     this.setTooltip(Blockly.Msg.senseBox_uv_light_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| /* | ||||
| BMX055 Three differen Blocks for Accelerometer, Gyroscope, Compass | ||||
| */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_bmx055_accelerometer"] = { | ||||
| Blockly.Blocks['sensebox_sensor_bmx055_accelerometer'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_bmx055_accelerometer | ||||
|     ); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_direction) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_direction_x, "X"], | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_direction_y, "Y"], | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_direction_z, "Z"], | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_direction_total, "Total"], | ||||
|         ]), | ||||
|         "VALUE" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_direction_x, "X"], [Blockly.Msg.senseBox_bmx055_accelerometer_direction_y, "Y"], [Blockly.Msg.senseBox_bmx055_accelerometer_direction_z, "Z"], [Blockly.Msg.senseBox_bmx055_accelerometer_direction_total, "Total"]]), "VALUE"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_range) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_range_2g, "0x3"], | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_range_4g, "0x5"], | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_range_8g, "0x8"], | ||||
|           [Blockly.Msg.senseBox_bmx055_accelerometer_range_16g, "0x0C"], | ||||
|         ]), | ||||
|         "RANGE" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_range_2g, "0x3"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_4g, "0x5"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_8g, "0x8"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_16g, "0x0C"]]), "RANGE"); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_bmx055_helpurl); | ||||
|     this.data = {name: "bmx055"}; | ||||
|   }, | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * SDS011 Fine Particular Matter Sensor | ||||
|  * | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_sds011"] = { | ||||
| Blockly.Blocks['sensebox_sensor_sds011'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_sds011); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sds011); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_sds011_pm25, "pm25"], | ||||
|           [Blockly.Msg.senseBox_sds011_pm10, "pm10"], | ||||
|         ]), | ||||
|         "NAME" | ||||
|       ) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_pm25, "Pm25"], [Blockly.Msg.senseBox_sds011_pm10, "Pm10"]]), "NAME") | ||||
|       .appendField(Blockly.Msg.senseBox_sds011_dimension) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown( | ||||
|           selectedBoard().serialSensors), | ||||
|         "SERIAL" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_serial1, "Serial1"], [Blockly.Msg.senseBox_sds011_serial2, "Serial2"]]), "SERIAL"); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sds011_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sds011_helpurl); | ||||
|     this.data = {name: "sds011"}; | ||||
|   }, | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sds011_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * BMP280 Pressure Sensor | ||||
|  * | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_pressure"] = { | ||||
| Blockly.Blocks['sensebox_sensor_pressure'] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [ | ||||
|       [Blockly.Msg.senseBox_pressure, "Pressure"], | ||||
|       [Blockly.Msg.senseBox_temp, "Temperature"], | ||||
|       [Blockly.Msg.senseBox_gps_alt, "Altitude"], | ||||
|     ]; | ||||
|     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function ( | ||||
|       option | ||||
|     ) { | ||||
|       var input = | ||||
|         option === "Pressure" || | ||||
|         option === "Temperature" || | ||||
|         option === "Altitude"; | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_pressure, "Pressure"], [Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_gps_alt, "Altitude"]]; | ||||
|     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function (option) { | ||||
|       var input = (option === 'Pressure') || (option === 'Temperature') || (option === 'Altitude'); | ||||
|       this.sourceBlock_.updateShape_(input); | ||||
|     }); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_pressure_sensor); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_pressure_sensor); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(dropdown, "NAME"); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_pressure_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_pressure_helpurl); | ||||
|     this.data = {name: "bmp280"}; | ||||
|     this.getField("NAME").setValidator( | ||||
|       function (val) { | ||||
|         this.updateShape_(val === "Altitude"); | ||||
|       }.bind(this) | ||||
|     ); | ||||
|   }, | ||||
|   updateShape_(isAltitude) { | ||||
|     if (isAltitude) { | ||||
|       if (this.getInput("extraField") == null) { | ||||
|         this.appendDummyInput("extraField") | ||||
|           .setAlign(Blockly.ALIGN_RIGHT) | ||||
|           .appendField(Blockly.Msg.senseBox_pressure_referencePressure) | ||||
|           .appendField(new Blockly.FieldTextInput("1013"), "referencePressure") | ||||
|           .appendField(Blockly.Msg.senseBox_pressure_referencePressure_dim); | ||||
|       } | ||||
|     } else { | ||||
|       this.removeInput("extraField", true); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * BME680 Environmental Sensor | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_bme680_bsec"] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [ | ||||
|       [Blockly.Msg.senseBox_temp, "temperature"], | ||||
|       [Blockly.Msg.senseBox_hum, "humidity"], | ||||
|       [Blockly.Msg.senseBox_bme_pressure, "pressure"], | ||||
|       [Blockly.Msg.senseBox_bme_iaq, "IAQ"], | ||||
|       [Blockly.Msg.senseBox_bme_iaq_accuracy, "IAQAccuracy"], | ||||
|       [Blockly.Msg.senseBox_bme_co2, "CO2"], | ||||
|       [Blockly.Msg.senseBox_bme_breatheVocEquivalent, "breathVocEquivalent"], | ||||
|     ]; | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_bme680); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown"); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bme_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_bme680_helpurl); | ||||
|     this.data = {name: "bme680"}; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Ultrasonic Sensor | ||||
|  * | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_ultrasonic_ranger"] = { | ||||
|   init: function () { | ||||
|     var dropdown = new FieldGridDropdown(selectedBoard().digitalPorts, function (option) { | ||||
|       var input = option === "A" || option === "B" || option === "C"; | ||||
|       this.sourceBlock_.updateShape_(input); | ||||
|     }); | ||||
| 
 | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic) | ||||
|       .appendField(dropdown, "port"); | ||||
|     this.appendDummyInput("TrigEcho") | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_trigger) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPins), | ||||
|         "ultrasonic_trigger" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_echo) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPins), | ||||
|         "ultrasonic_echo" | ||||
|       ); | ||||
|     this.appendDummyInput("maxDistance") | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_maxDistance) | ||||
|       .appendField(new Blockly.FieldTextInput("250"), "maxDistance") | ||||
|       .appendField("cm"); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_ultrasonic_helpurl); | ||||
|     this.data = {name: "hc-sr04"}; | ||||
|     this.setTooltip(Blockly.Msg.senseBox_pressure_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/luftdruck.html'); | ||||
|   }, | ||||
|   /** | ||||
|    * Parse XML to restore the number of pins available. | ||||
|    * @param {!Element} xmlElement XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
| 
 | ||||
|   domToMutation: function (xmlElement) { | ||||
|     xmlElement.getAttribute("port"); | ||||
|     (xmlElement.getAttribute('port')); | ||||
| 
 | ||||
|   }, | ||||
|   /** | ||||
|    * Create XML to represent number of pins selection. | ||||
| @ -262,8 +129,106 @@ Blockly.Blocks["sensebox_sensor_ultrasonic_ranger"] = { | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   mutationToDom: function () { | ||||
|     var container = document.createElement("mutation"); | ||||
|     var input = this.getFieldValue("port"); | ||||
|     var container = document.createElement('mutation'); | ||||
|     var input = this.getFieldValue('NAME'); | ||||
|     this.updateShape_(input); | ||||
|     container.setAttribute('NAME', input); | ||||
|     return container; | ||||
|   }, | ||||
|   /** | ||||
|    * Modify this block to have the correct number of pins available. | ||||
|    * @param {boolean} | ||||
|    * @private | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateShape_: function () { | ||||
|     var extraFieldExist = this.getFieldValue('referencePressure'); | ||||
|     var input = this.getFieldValue('NAME'); | ||||
|     if (input === 'Altitude' && extraFieldExist === null) { | ||||
|       this.appendDummyInput('extraField') | ||||
|         .setAlign(Blockly.ALIGN_RIGHT) | ||||
|         .appendField(Blockly.Msg.senseBox_pressure_referencePressure) | ||||
|         .appendField(new Blockly.FieldTextInput("1013"), "referencePressure") | ||||
|         .appendField(Blockly.Msg.senseBox_pressure_referencePressure_dim); | ||||
|     } | ||||
| 
 | ||||
|     if ((input === 'Pressure' || input === 'Temperature') && extraFieldExist !== null) { | ||||
|       this.removeInput('extraField'); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * BME680 Environmental Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_bme680_bsec'] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_temp, "temperature"], [Blockly.Msg.senseBox_hum, "humidity"], [Blockly.Msg.senseBox_pressure, "pressure"], [Blockly.Msg.senseBox_bme_iaq, "IAQ"], [Blockly.Msg.senseBox_bme_iaq_accuracy, "IAQAccuracy"], [Blockly.Msg.senseBox_bme_co2, "CO2"], [Blockly.Msg.senseBox_bme_breatheVocEquivalent, "breathVocEquivalent"]]; | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_bme680); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown") | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bme_tip); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Ultrasonic Sensor | ||||
|  *  | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_ultrasonic_ranger'] = { | ||||
|   init: function () { | ||||
| 
 | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_ultrasonic_port_A, 'A'], | ||||
|     [Blockly.Msg.senseBox_ultrasonic_port_B, 'B'], [Blockly.Msg.senseBox_ultrasonic_port_C, 'C']]; | ||||
|     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function (option) { | ||||
|       var input = (option === 'A') || (option === 'B') || (option === 'C'); | ||||
|       this.sourceBlock_.updateShape_(input); | ||||
|     }); | ||||
| 
 | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic) | ||||
|       .appendField(dropdown, "port"); | ||||
|     this.appendDummyInput('TrigEcho') | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_trigger) | ||||
|       .appendField(new Blockly.FieldDropdown( | ||||
|         selectedBoard().digitalPins), 'ultrasonic_trigger') | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_echo) | ||||
|       .appendField(new Blockly.FieldDropdown( | ||||
|         selectedBoard().digitalPins), 'ultrasonic_echo'); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tip); | ||||
|     this.setHelpUrl('https://sensebox.de/books'); | ||||
|   }, | ||||
|   /** | ||||
|    * Parse XML to restore the number of pins available. | ||||
|    * @param {!Element} xmlElement XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   domToMutation: function (xmlElement) { | ||||
|     (xmlElement.getAttribute('port')); | ||||
| 
 | ||||
|   }, | ||||
|   /** | ||||
|    * Create XML to represent number of pins selection. | ||||
|    * @return {!Element} XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   mutationToDom: function () { | ||||
|     var container = document.createElement('mutation'); | ||||
|     var input = this.getFieldValue('port'); | ||||
|     this.updateShape_(input); | ||||
|     container.setAttribute("port", input); | ||||
|     return container; | ||||
| @ -275,311 +240,84 @@ Blockly.Blocks["sensebox_sensor_ultrasonic_ranger"] = { | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateShape_: function () { | ||||
|     var input = this.getFieldValue("port"); | ||||
|     var input = this.getFieldValue('port'); | ||||
|     switch (input) { | ||||
|       case "A": | ||||
|         this.setFieldValue("1", "ultrasonic_trigger"); | ||||
|         this.setFieldValue("2", "ultrasonic_echo"); | ||||
|       case 'A': | ||||
|         this.setFieldValue('1', 'ultrasonic_trigger'); | ||||
|         this.setFieldValue('2', 'ultrasonic_echo'); | ||||
|         break; | ||||
|       case "B": | ||||
|         this.setFieldValue("3", "ultrasonic_trigger"); | ||||
|         this.setFieldValue("4", "ultrasonic_echo"); | ||||
|       case 'B': | ||||
|         this.setFieldValue('3', 'ultrasonic_trigger'); | ||||
|         this.setFieldValue('4', 'ultrasonic_echo'); | ||||
|         break; | ||||
|       case "C": | ||||
|         this.setFieldValue("5", "ultrasonic_trigger"); | ||||
|         this.setFieldValue("6", "ultrasonic_echo"); | ||||
|       case 'C': | ||||
|         this.setFieldValue('5', 'ultrasonic_trigger'); | ||||
|         this.setFieldValue('6', 'ultrasonic_echo'); | ||||
|         break; | ||||
|       default: | ||||
|         break; | ||||
|     } | ||||
|   }, | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Microphone | ||||
|  * | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_sound"] = { | ||||
| Blockly.Blocks['sensebox_sensor_sound'] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sound) | ||||
|       .appendField("Pin:") | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().analogPins), | ||||
|         "PIN" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN") | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sound_helpurl); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sound_tooltip); | ||||
|   }, | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sound_tip); | ||||
|     this.setTooltip('Dieser Sensor mist den Geräuschpegel.'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Button | ||||
|  * | ||||
|  * | ||||
|  *  | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_button"] = { | ||||
| Blockly.Blocks['sensebox_button'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_button) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_button_isPressed, "isPressed"], | ||||
|           [Blockly.Msg.senseBox_button_wasPressed, "wasPressed"], | ||||
|           [Blockly.Msg.senseBox_button_longPress, "longPress"], | ||||
|           [Blockly.Msg.senseBox_button_switch,"toggleButton"] | ||||
|         ]), | ||||
|         "FUNCTION" | ||||
|       ) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_button_isPressed, "isPressed"], [Blockly.Msg.senseBox_button_wasPressed, "wasPressed"], [Blockly.Msg.senseBox_button_switch, "Switch"]]), "FUNCTION") | ||||
|       .appendField("Pin:") | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPinsButton), | ||||
|         "PIN" | ||||
|       ); | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPinsButton), "PIN"); | ||||
|     this.setOutput(true, Types.BOOLEAN.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_button_tooltip); | ||||
|     this.getField("FUNCTION").setValidator( | ||||
|       function (val) { | ||||
|         this.updateShape_(val === "longPress"); | ||||
|       }.bind(this) | ||||
|     ); | ||||
|   }, | ||||
|   updateShape_(isLongPress) { | ||||
|     if (isLongPress) { | ||||
|       if (this.getInput("extraField") == null) { | ||||
|         this.appendDummyInput("extraField") | ||||
|           .setAlign(Blockly.ALIGN_RIGHT) | ||||
|           .appendField(Blockly.Msg.senseBox_button_longPress_time) | ||||
|           .appendField(new Blockly.FieldTextInput("1000"), "time") | ||||
|           .appendField("ms"); | ||||
|       } | ||||
|     } else { | ||||
|       this.removeInput("extraField", true); | ||||
|     } | ||||
|   }, | ||||
|     this.setTooltip(Blockly.Msg.senseBox_button_tip); | ||||
|     this.setHelpUrl('https://sensebox.de/books'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * SCD30 CO2 Sensor | ||||
|  * | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_scd30"] = { | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_scd30'] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [ | ||||
|       [Blockly.Msg.senseBox_scd_co2, "CO2"], | ||||
|       [Blockly.Msg.senseBox_temp, "temperature"], | ||||
|       [Blockly.Msg.senseBox_hum, "humidity"], | ||||
|     ]; | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_scd30); | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_temp, "temperature"], [Blockly.Msg.senseBox_hum, "humidity"], [Blockly.Msg.senseBox_bme_co2, "CO2"]]; | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_scd30); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown"); | ||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown") | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_scd_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_scd_helpurl); | ||||
|     this.data = {name: "scd30"}; | ||||
|   }, | ||||
|   onchange: function (e) { | ||||
|     var dropdown = this.getFieldValue("dropdown"); | ||||
|     if (dropdown === "temperature" || dropdown === "humidity") { | ||||
|       this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     } else if (dropdown === "CO2") { | ||||
|       this.setOutput(true, Types.NUMBER.typeName); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * GPS Module | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_gps"] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [ | ||||
|       [Blockly.Msg.senseBox_gps_lat, "latitude"], | ||||
|       [Blockly.Msg.senseBox_gps_lng, "longitude"], | ||||
|       [Blockly.Msg.senseBox_gps_alt, "altitude"], | ||||
|       [Blockly.Msg.senseBox_gps_timeStamp, "timestamp"], | ||||
|       [Blockly.Msg.senseBox_gps_speed, "speed"], | ||||
|       ["pDOP", "pDOP"], | ||||
|       ["Fix Type", "fixType"], | ||||
|     ]; | ||||
|     this.appendDummyInput().appendField("GPS Modul"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown"); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_gps_tooltip); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Block for Truebner STM50 | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_truebner_smt50"] = { | ||||
|   init: function () {  | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_smt50); | ||||
|     this.appendDummyInput() | ||||
|       .appendField("Port:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPorts), "Port"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_temp, "temp"], | ||||
|           [Blockly.Msg.senseBox_soil, "soil"], | ||||
|         ]), | ||||
|         "value" | ||||
|       ); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_smt50_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_smt50_helpurl); | ||||
|     this.data = {name: "smt50"}; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * DS18B20 Watertemperature | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_watertemperature"] = { | ||||
|   init: function () { | ||||
| 
 | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_watertemperature) | ||||
|       .appendField("Port:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPorts), "Port"); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_watertemperature_tip); | ||||
|     this.data = {name: "ds18b20"}; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Windspeed | ||||
|  * removed for now | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_windspeed'] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_windspeed) | ||||
|       .appendField("Pin:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN") | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bme_tip); | ||||
|   } | ||||
| }; | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * DF Robot Soundsensor | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_soundsensor_dfrobot"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_soundsensor_dfrobot) | ||||
|       .appendField("Port:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPorts), "Port"); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_soundsensor_dfrobot_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_soundsensor_dfrobot_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Infineon DPS310 Pressure Sensor | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_sensor_dps310"] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [ | ||||
|       [Blockly.Msg.senseBox_pressure, "Pressure"], | ||||
|       [Blockly.Msg.senseBox_temp, "Temperature"], | ||||
|       [Blockly.Msg.senseBox_gps_alt, "Altitude"], | ||||
|     ]; | ||||
|     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function ( | ||||
|       option | ||||
|     ) { | ||||
|       var input = | ||||
|         option === "Pressure" || | ||||
|         option === "Temperature" || | ||||
|         option === "Altitude"; | ||||
|       this.sourceBlock_.updateShape_(input); | ||||
|     }); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_sensor_dps310); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(dropdown, "NAME"); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sensor_dps310_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sensor_dps310_helpurl); | ||||
|     this.data = {name: "dps310"}; | ||||
|     this.getField("NAME").setValidator( | ||||
|       function (val) { | ||||
|         this.updateShape_(val === "Altitude"); | ||||
|       }.bind(this) | ||||
|     ); | ||||
|   }, | ||||
|   updateShape_(isAltitude) { | ||||
|     if (isAltitude) { | ||||
|       if (this.getInput("extraField") == null) { | ||||
|         this.appendDummyInput("extraField") | ||||
|           .setAlign(Blockly.ALIGN_RIGHT) | ||||
|           .appendField(Blockly.Msg.senseBox_pressure_referencePressure) | ||||
|           .appendField(new Blockly.FieldTextInput("1013"), "referencePressure") | ||||
|           .appendField(Blockly.Msg.senseBox_pressure_referencePressure_dim); | ||||
|       } | ||||
|     } else { | ||||
|       this.removeInput("extraField", true); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Sensirion SPS30 Fine Particular Matter Sensor | ||||
|  * added 02.12.2022  | ||||
|  */ | ||||
| 
 | ||||
|  Blockly.Blocks["sensebox_sensor_sps30"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_sps30); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_sps30_1p0, "1p0"], | ||||
|           [Blockly.Msg.senseBox_sps30_2p5, "2p5"], | ||||
|           [Blockly.Msg.senseBox_sps30_4p0, "4p0"], | ||||
|           [Blockly.Msg.senseBox_sps30_10p0, "10p0"], | ||||
|         ]), | ||||
|         "value" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.senseBox_sps30_dimension); | ||||
|     this.setOutput(true, Types.DECIMAL.typeName); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sps30_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sps30_helpurl); | ||||
|   }, | ||||
| }; | ||||
| @ -12,7 +12,6 @@ Blockly.Blocks["sensebox_telegram"] = { | ||||
|             .appendField("telegram") | ||||
|             .appendField(new Blockly.FieldTextInput("token"), "telegram_token"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_init_tooltip); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| @ -25,7 +24,6 @@ Blockly.Blocks["sensebox_telegram_do"] = { | ||||
|         this.appendStatementInput("telegram_do"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_do_tooltip) | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| @ -38,7 +36,6 @@ Blockly.Blocks["sensebox_telegram_do_on_message"] = { | ||||
|             .appendField(Blockly.Msg.senseBox_telegram_message) | ||||
|             .appendField(new Blockly.FieldTextInput("/message"), 'telegram_message'); | ||||
|         this.appendStatementInput("telegram_do_on_message").setCheck(null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_message_tooltip) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| @ -49,10 +46,8 @@ Blockly.Blocks["sensebox_telegram_send"] = { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_send); | ||||
|         this.appendValueInput("telegram_text_to_send").setCheck(null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_send_tooltip) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
| 
 | ||||
|     }, | ||||
|     LOOP_TYPES: ["sensebox_telegram_do_on_message"] | ||||
| }; | ||||
| @ -1,153 +1,58 @@ | ||||
| import Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_wifi"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_wifi_tooltip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_wifi_connect); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||
|       .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_output_password) | ||||
|       .appendField(new Blockly.FieldTextInput("Password"), "Password"); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_wifi_helpurl); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
|   onchange: function (e) { | ||||
|     var legal = false; | ||||
|     // Is the block nested in a loop?
 | ||||
|     var block = this; | ||||
|     do { | ||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|         legal = true; | ||||
|         break; | ||||
|       } | ||||
|       block = block.getSurroundParent(); | ||||
|     } while (block); | ||||
|     if (legal) { | ||||
|       this.setWarningText(null); | ||||
|     } else { | ||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
| Blockly.Blocks['sensebox_wifi'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_wifi_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_connect); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||
|             .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_output_password) | ||||
|             .appendField(new Blockly.FieldTextInput("Password"), "Password"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
| 
 | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
| 
 | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['arduino_functions'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_startap'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_wifi_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_startap); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||
|             .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
|   }, | ||||
|   LOOP_TYPES: ["arduino_functions"], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_startap"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_wifi_startap_tooltip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_wifi_startap); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||
|       .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_wifi_helpurl); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_ethernet"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_ethernet_tooltip); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_ethernet) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown([ | ||||
|           [Blockly.Msg.senseBox_ethernet_dhcp, "Dhcp"], | ||||
|           [Blockly.Msg.senseBox_ethernet_manuel_config, "Manual"], | ||||
|         ]), | ||||
|         "dhcp" | ||||
|       ); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_ethernet_mac) | ||||
|       .appendField( | ||||
|         new Blockly.FieldTextInput("0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED"), | ||||
|         "mac" | ||||
|       ); | ||||
| 
 | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_ethernet_helpurl); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.getField("dhcp").setValidator( | ||||
|       function (val) { | ||||
|         this.updateShape_(val === "Manual"); | ||||
|       }.bind(this) | ||||
|     ); | ||||
|   }, | ||||
| 
 | ||||
|   updateShape_(isManual) { | ||||
|     if (isManual) { | ||||
|       this.appendDummyInput("ip-field") | ||||
|         .appendField(Blockly.Msg.senseBox_ethernet_ip) | ||||
|         .appendField(new Blockly.FieldTextInput("192.168.1.100"), "ip"); | ||||
|       this.appendDummyInput("subnetmask-field") | ||||
|         .appendField(Blockly.Msg.senseBox_ethernet_subnetmask) | ||||
|         .appendField(new Blockly.FieldTextInput("255.255.255.0"), "subnetmask"); | ||||
|       this.appendDummyInput("gateway-field") | ||||
|         .appendField(Blockly.Msg.senseBox_ethernet_gateway) | ||||
|         .appendField(new Blockly.FieldTextInput("192.168.1.1"), "gateway"); | ||||
|       this.appendDummyInput("dns-field") | ||||
|         .appendField(Blockly.Msg.senseBox_ethernet_dns) | ||||
|         .appendField(new Blockly.FieldTextInput("8.8.8.8"), "dns"); | ||||
|     } else { | ||||
|       this.removeInput("ip-field", true); | ||||
|       this.removeInput("subnetmask-field", true); | ||||
|       this.removeInput("gateway-field", true); | ||||
|       this.removeInput("dns-field", true); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_ethernetIp"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_ethernet_ip); | ||||
| 
 | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_ethernetIp_helpurl); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_ethernet_ip_tooltip); | ||||
|     this.setOutput(true, null); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_wifi_status"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_wifi_status_tooltip); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_wifi_status); | ||||
|     this.setOutput(true, Types.BOOLEAN.typeName); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_wifi_status_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_get_ip"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_wifi_ip_tooltip); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_wifi_ip); | ||||
|     this.setOutput(true, Types.TEXT.typeName); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_wifi_ip_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_wifi_rssi"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_wifi_rssi_tooltip); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_wifi_rssi); | ||||
|     this.setOutput(true, Types.NUMBER.typeName); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_wifi_rssi_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| }; | ||||
| @ -1,36 +1,4 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_multiplexer_init"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_multiplexer_init); | ||||
|     this.appendValueInput("nrChannels").setCheck( | ||||
|       Types.getCompatibleTypes("int") | ||||
|     ); | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_multplexer_nchannels | ||||
|     ); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setInputsInline("true"); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_multiplexer_init_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_multiplexer_init_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_multiplexer_changeChannel"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField( | ||||
|       Blockly.Msg.senseBox_multiplexer_changeChannel | ||||
|     ); | ||||
|     this.appendValueInput("Channel").setCheck(Types.getCompatibleTypes("int")); | ||||
|     this.setInputsInline("true"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.sensebox_multiplexer_changeChannel_tooltip); | ||||
|     this.setHelpUrl(Blockly.Msg.sensebox_multiplexer_changeChannel_helpurl); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,47 +0,0 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import { selectedBoard } from "../helpers/board"; | ||||
| 
 | ||||
| Blockly.Blocks["init_serial_monitor"] = { | ||||
|   init: function () { | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setColour(getColour().serial); | ||||
|     this.setHelpUrl("http://arduino.cc/en/Serial/Begin"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.ARD_SERIAL_SETUP) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().serial), | ||||
|         "SERIAL_ID" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.ARD_SERIAL_SPEED) | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().serialSpeed), | ||||
|         "SPEED" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.ARD_SERIAL_BPS); | ||||
|     this.setInputsInline(true); | ||||
|     this.setTooltip(Blockly.Msg.ARD_SERIAL_SETUP_TIP); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["print_serial_monitor"] = { | ||||
|   init: function () { | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setNextStatement(true); | ||||
|     this.setColour(getColour().serial); | ||||
|     this.setHelpUrl("http://www.arduino.cc/en/Serial/Print"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField( | ||||
|         new Blockly.FieldDropdown(selectedBoard().serial), | ||||
|         "SERIAL_ID" | ||||
|       ) | ||||
|       .appendField(Blockly.Msg.ARD_SERIAL_PRINT); | ||||
|     this.appendValueInput("CONTENT"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(new Blockly.FieldCheckbox("TRUE"), "NEW_LINE") | ||||
|       .appendField(Blockly.Msg.ARD_SERIAL_PRINT_NEWLINE); | ||||
|     this.setInputsInline(true); | ||||
|     this.setTooltip(Blockly.Msg.ARD_SERIAL_PRINT_TIP); | ||||
|   }, | ||||
| }; | ||||
| @ -8,135 +8,123 @@ | ||||
|  *     The arduino built in functions syntax can be found in | ||||
|  *     http://arduino.cc/en/Reference/HomePage
 | ||||
|  */ | ||||
| import Blockly from "blockly"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import * as Types from "../helpers/types"; | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| Blockly.Blocks["time_delay"] = { | ||||
|   /** | ||||
|    * Delay block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Delay"); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendValueInput("DELAY_TIME_MILI") | ||||
|       .setCheck(Types.NUMBER.checkList) | ||||
|       .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MS); | ||||
|     this.setInputsInline(true); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_TIP); | ||||
|   }, | ||||
| 
 | ||||
| Blockly.Blocks['time_delay'] = { | ||||
|     /** | ||||
|      * Delay block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Delay'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendValueInput('DELAY_TIME_MILI') | ||||
|             .setCheck(Types.NUMBER.checkList) | ||||
|             .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_MS); | ||||
|         this.setInputsInline(true); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_TIP); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["time_delaymicros"] = { | ||||
|   /** | ||||
|    * delayMicroseconds block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DelayMicroseconds"); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendValueInput("DELAY_TIME_MICRO") | ||||
|       .setCheck(Types.NUMBER.checkList) | ||||
|       .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS); | ||||
|     this.setInputsInline(true); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP); | ||||
|   }, | ||||
| Blockly.Blocks['time_delaymicros'] = { | ||||
|     /** | ||||
|      * delayMicroseconds block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DelayMicroseconds'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendValueInput('DELAY_TIME_MICRO') | ||||
|             .setCheck(Types.NUMBER.checkList) | ||||
|             .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS); | ||||
|         this.setInputsInline(true); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["time_millis"] = { | ||||
|   /** | ||||
|    * Elapsed time in milliseconds block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Millis"); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MILLIS); | ||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); | ||||
|   }, | ||||
|   /** @return {string} The type of return value for the block, an integer. */ | ||||
|   getBlockType: function () { | ||||
|     return Blockly.Types.LARGE_NUMBER; | ||||
|   }, | ||||
| Blockly.Blocks['time_millis'] = { | ||||
|     /** | ||||
|      * Elapsed time in milliseconds block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Millis'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_MILLIS); | ||||
|         this.setOutput(true, Types.LARGE_NUMBER.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); | ||||
|     }, | ||||
|     /** @return {string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Blockly.Types.LARGE_NUMBER; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["time_micros"] = { | ||||
|   /** | ||||
|    * Elapsed time in microseconds block definition | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Micros"); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MICROS); | ||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MICROS_TIP); | ||||
|   }, | ||||
|   /** | ||||
|    * Should be a long (32bit), but  for for now an int. | ||||
|    * @return {string} The type of return value for the block, an integer. | ||||
|    */ | ||||
|   getBlockType: function () { | ||||
|     return Types.LARGE_NUMBER; | ||||
|   }, | ||||
| Blockly.Blocks['time_micros'] = { | ||||
|     /** | ||||
|      * Elapsed time in microseconds block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Micros'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_MICROS); | ||||
|         this.setOutput(true, Types.LARGE_NUMBER.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_MICROS_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Should be a long (32bit), but  for for now an int. | ||||
|      * @return {string} The type of return value for the block, an integer. | ||||
|      */ | ||||
|     getBlockType: function () { | ||||
|         return Types.LARGE_NUMBER; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["infinite_loop"] = { | ||||
|   /** | ||||
|    * Waits forever, end of program. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   init: function () { | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_INF); | ||||
|     this.setInputsInline(true); | ||||
|     this.setPreviousStatement(true); | ||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_INF_TIP); | ||||
|   }, | ||||
| Blockly.Blocks['infinite_loop'] = { | ||||
|     /** | ||||
|      * Waits forever, end of program. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_INF); | ||||
|         this.setInputsInline(true); | ||||
|         this.setPreviousStatement(true); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_INF_TIP); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // Blockly.Blocks["sensebox_interval_timer"] = {
 | ||||
| //   init: function () {
 | ||||
| //     this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip);
 | ||||
| //     this.setInputsInline(true);
 | ||||
| //     this.setHelpUrl("");
 | ||||
| //     this.setColour(getColour().time);
 | ||||
| //     this.appendDummyInput().appendField(Blockly.Msg.senseBox_interval_timer);
 | ||||
| //     this.appendDummyInput()
 | ||||
| //       .setAlign(Blockly.ALIGN_LEFT)
 | ||||
| //       .appendField(new Blockly.FieldTextInput("10000"), "interval")
 | ||||
| //       .appendField(Blockly.Msg.senseBox_interval);
 | ||||
| //     this.appendStatementInput("DO").setCheck(null);
 | ||||
| //     this.setPreviousStatement(true, null);
 | ||||
| //     this.setNextStatement(true, null);
 | ||||
| //   },
 | ||||
| // };
 | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_interval_timer"] = { | ||||
|   init: function () { | ||||
|     this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip); | ||||
|     this.setInputsInline(true); | ||||
|     this.setHelpUrl(""); | ||||
|     this.setColour(getColour().time); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_interval_timer) | ||||
|       .appendField(new Blockly.FieldTextInput("Interval"), "name"); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_interval_time) | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(new Blockly.FieldTextInput("10000"), "interval") | ||||
|       .appendField(Blockly.Msg.senseBox_interval); | ||||
|     this.appendStatementInput("DO").setCheck(null); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|   }, | ||||
| Blockly.Blocks['sensebox_interval_timer'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip); | ||||
|         this.setInputsInline(true); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_interval_timer); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(new Blockly.FieldTextInput("10000"), "interval") | ||||
|             .appendField(Blockly.Msg.senseBox_interval); | ||||
|         this.appendStatementInput('DO') | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @ -1,46 +1,43 @@ | ||||
| import Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| import { getCompatibleTypes } from "../helpers/types"; | ||||
| import Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import { getCompatibleTypes } from '../helpers/types' | ||||
| 
 | ||||
| Blockly.Blocks["variables_set_dynamic"] = { | ||||
|   init: function () { | ||||
|     // const type = myVar.type;
 | ||||
|     this.setColour(getColour().variables); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.appendValueInput("VALUE") | ||||
|       .appendField(Blockly.Msg.variables_set, Blockly.Msg.variables_set) | ||||
|       .appendField("", "type") | ||||
|       .appendField(new Blockly.FieldVariable("VAR"), "VAR") | ||||
|       .appendField(Blockly.Msg.variables_to); | ||||
|   }, | ||||
|   onchange: function (e) { | ||||
|     let variableID = this.getFieldValue("VAR"); | ||||
|     let variable = Blockly.getMainWorkspace() | ||||
|       .getVariableMap() | ||||
|       .getVariableById(variableID); | ||||
|     if (variable !== null) { | ||||
|       this.getField("type").setValue(variable.type); | ||||
|       this.getInput("VALUE").setCheck(getCompatibleTypes(variable.type)); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["variables_get_dynamic"] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().variables); | ||||
|     this.appendDummyInput() | ||||
|       .appendField("", "type") | ||||
|       .appendField(new Blockly.FieldVariable("VAR"), "VAR"); | ||||
|     this.setOutput(true); | ||||
|   }, | ||||
|   onchange: function (e) { | ||||
|     let variableID = this.getFieldValue("VAR"); | ||||
|     let variable = Blockly.getMainWorkspace() | ||||
|       .getVariableMap() | ||||
|       .getVariableById(variableID); | ||||
|     if (variable !== null) { | ||||
|       this.getField("type").setValue(variable.type); | ||||
| Blockly.Blocks['variables_set_dynamic'] = { | ||||
|     init: function () { | ||||
| 
 | ||||
|         // const type = myVar.type;
 | ||||
|         this.setColour(getColour().variables); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.appendValueInput('VALUE') | ||||
|             .appendField('set', 'set') | ||||
|             .appendField('', 'type') | ||||
|             .appendField(new Blockly.FieldVariable('VAR'), 'VAR') | ||||
|             .appendField('to'); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
|         let variableID = this.getFieldValue('VAR'); | ||||
|         let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID) | ||||
|         this.getField('type').setValue(variable.type); | ||||
|         this.getInput('VALUE').setCheck(getCompatibleTypes(variable.type)); | ||||
| 
 | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| Blockly.Blocks['variables_get_dynamic'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().variables); | ||||
|         this.appendDummyInput() | ||||
|             .appendField('', 'type') | ||||
|             .appendField(new Blockly.FieldVariable('VAR'), 'VAR'); | ||||
|         this.setOutput(true); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
|         let variableID = this.getFieldValue('VAR'); | ||||
|         let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID) | ||||
|         this.getField('type').setValue(variable.type); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,28 +0,0 @@ | ||||
| import Blockly from "blockly/core"; | ||||
| import { getColour } from "../helpers/colour"; | ||||
| 
 | ||||
| Blockly.Blocks["watchdog_enable"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField("Watchdog aktivieren") | ||||
|       .appendField(new Blockly.FieldTextInput("10000"), "TIME") | ||||
|       .appendField("ms"); | ||||
| 
 | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().io); | ||||
|     this.setTooltip(""); | ||||
|     this.setHelpUrl(""); | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["watchdog_reset"] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput().appendField("Watchdog zurücksetzen"); | ||||
|     this.setPreviousStatement(true, null); | ||||
|     this.setNextStatement(true, null); | ||||
|     this.setColour(getColour().io); | ||||
|     this.setTooltip(""); | ||||
|     this.setHelpUrl(""); | ||||
|   }, | ||||
| }; | ||||
| @ -1,334 +0,0 @@ | ||||
| import Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import { getCompatibleTypes } from '../helpers/types' | ||||
| import * as Types from '../helpers/types'; | ||||
| 
 | ||||
| /**  | ||||
|  * Webserver Blocks By Lucas Steinmann | ||||
|  *  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_initialize_http_server'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_init_http_server_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_init_http_server); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("Port") | ||||
|             .appendField(new Blockly.FieldNumber(80), "Port"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|     }, | ||||
|     LOOP_TYPES: ['arduino_functions'], | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_http_on_client_connect'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_on_client_connect_tip); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_http_on_client_connect); | ||||
|         this.appendStatementInput('ON_CONNECT'); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_http_method'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_http_method) | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_method_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
|     getBlockType: function () { | ||||
|         return Blockly.Types.TEXT; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_http_uri'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_http_uri) | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_uri_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_http_protocol_version'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_http_protocol_version) | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_protocol_version_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_ip_address'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_ip_address); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_ip_address_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_http_user_agent'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_http_user_agent) | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_user_agent_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_generate_html_doc'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_html_document); | ||||
|         this.appendValueInput('HEADER') | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .setCheck(getCompatibleTypes('String')) | ||||
|             .appendField(Blockly.Msg.senseBox_html_header); | ||||
|         this.appendValueInput('BODY') | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .setCheck(getCompatibleTypes('String')) | ||||
|             .appendField(Blockly.Msg.senseBox_html_body); | ||||
|         this.setInputsInline(false); | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_html_document_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_generate_http_succesful_response'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_http_success); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_http_success_l2); | ||||
|         this.appendValueInput('CONTENT') | ||||
|             .appendField(Blockly.Msg.senseBox_http_success_buildhtml) | ||||
|             .setCheck(getCompatibleTypes('String')); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_success_tip); | ||||
|         this.setInputsInline(false); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_generate_http_not_found_response'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_http_not_found); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_http_not_found_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_general_html_tag'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_html_general_tag_tip); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("<") | ||||
|             .appendField(new Blockly.FieldTextInput("Tag"), "TAG") | ||||
|             .appendField(">"); | ||||
|         this.appendValueInput('DO0') | ||||
|             .setCheck(getCompatibleTypes('String')); | ||||
|         this.setInputsInline(false); | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|         this.setPreviousStatement(false); | ||||
|         this.setNextStatement(false); | ||||
|         this.setMutator(new Blockly.Mutator(['additional_child'])); | ||||
|         this.additionalChildCount_ = 0; | ||||
|     }, | ||||
|     /** | ||||
|      * Create XML to represent the number of else-if and else inputs. | ||||
|      * @return {Element} XML storage element. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     mutationToDom: function () { | ||||
|         if (!this.additionalChildCount_) { | ||||
|             return null; | ||||
|         } | ||||
|         var container = document.createElement('mutation'); | ||||
|         if (this.additionalChildCount_) { | ||||
|             container.setAttribute('add_child', this.additionalChildCount_); | ||||
|         } | ||||
|         return container; | ||||
|     }, | ||||
|     /** | ||||
|      * Parse XML to restore the else-if and else inputs. | ||||
|      * @param {!Element} xmlElement XML storage element. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     domToMutation: function (xmlElement) { | ||||
|         this.additionalChildCount_ = parseInt(xmlElement.getAttribute('add_child'), 10) || 0; | ||||
|         this.updateShape_(); | ||||
|     }, | ||||
|     /** | ||||
|      * Populate the mutator's dialog with this block's components. | ||||
|      * @param {!Blockly.Workspace} workspace Mutator's workspace. | ||||
|      * @return {!Blockly.Block} Root block in mutator. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     decompose: function (workspace) { | ||||
|         var containerBlock = workspace.newBlock('first_child'); | ||||
|         containerBlock.initSvg(); | ||||
|         var connection = containerBlock.nextConnection; | ||||
|         for (var i = 1; i <= this.additionalChildCount_; i++) { | ||||
|             var elseifBlock = workspace.newBlock('additional_child'); | ||||
|             elseifBlock.initSvg(); | ||||
|             connection.connect(elseifBlock.previousConnection); | ||||
|             connection = elseifBlock.nextConnection; | ||||
|         } | ||||
|         return containerBlock; | ||||
|     }, | ||||
|     /** | ||||
|      * Reconfigure this block based on the mutator dialog's components. | ||||
|      * @param {!Blockly.Block} containerBlock Root block in mutator. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     compose: function (containerBlock) { | ||||
|         var clauseBlock = containerBlock.nextConnection.targetBlock(); | ||||
|         // Count number of inputs.
 | ||||
|         this.additionalChildCount_ = 0; | ||||
|         var statementConnections = [null]; | ||||
|         while (clauseBlock) { | ||||
|             switch (clauseBlock.type) { | ||||
|                 case 'additional_child': | ||||
|                     this.additionalChildCount_++; | ||||
|                     statementConnections.push(clauseBlock.statementConnection_); | ||||
|                     break; | ||||
|                 default: | ||||
|                     throw new Error("Unknown block type."); | ||||
|             } | ||||
|             clauseBlock = clauseBlock.nextConnection && | ||||
|                 clauseBlock.nextConnection.targetBlock(); | ||||
|         } | ||||
|         this.updateShape_(); | ||||
|         // Reconnect any child blocks.
 | ||||
|         for (var i = 1; i <= this.additionalChildCount_; i++) { | ||||
|             Blockly.Mutator.reconnect(statementConnections[i], this, 'DO' + i); | ||||
|         } | ||||
|     }, | ||||
|     /** | ||||
|      * Store pointers to any connected child blocks. | ||||
|      * @param {!Blockly.Block} containerBlock Root block in mutator. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     saveConnections: function (containerBlock) { | ||||
|         var clauseBlock = containerBlock.nextConnection.targetBlock(); | ||||
|         var i = 1; | ||||
|         while (clauseBlock) { | ||||
|             switch (clauseBlock.type) { | ||||
|                 case 'additional_child': | ||||
|                     var inputDo = this.getInput('DO' + i); | ||||
|                     clauseBlock.statementConnection_ = | ||||
|                         inputDo && inputDo.connection.targetConnection; | ||||
|                     i++; | ||||
|                     break; | ||||
|                 default: | ||||
|                     throw new Error('Unknown block type.'); | ||||
|             } | ||||
|             clauseBlock = clauseBlock.nextConnection && | ||||
|                 clauseBlock.nextConnection.targetBlock(); | ||||
|         } | ||||
|     }, | ||||
|     /** | ||||
|      * Modify this block to have the correct number of inputs. | ||||
|      * @private | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateShape_: function () { | ||||
|         // Delete everything.
 | ||||
|         var i = 1; | ||||
|         while (this.getInput('DO' + i)) { | ||||
|             this.removeInput('DO' + i); | ||||
|             i++; | ||||
|         } | ||||
|         // Rebuild block.
 | ||||
|         for (i = 1; i <= this.additionalChildCount_; i++) { | ||||
|             this.appendValueInput('DO' + i, Blockly.Arduino.ORDER_NONE); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['first_child'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("<Tag>"); | ||||
|         this.setNextStatement(true); | ||||
|         this.setInputsInline(true); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_tag_first_mutator_tip); | ||||
|         this.contextMenu = false; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['additional_child'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("<Tag>"); | ||||
|         this.setPreviousStatement(true); | ||||
|         this.setInputsInline(true); | ||||
|         this.setNextStatement(true); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_tag_optional_mutator_tip); | ||||
|         this.contextMenu = false; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // Additional Webserver Blocks
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_web_readHTML'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_sd_web_readHTML) | ||||
|             .setAlign(Blockly.ALIGN_LEFT); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.sensebox_web_readHTML_filename) | ||||
|             .appendField(new Blockly.FieldTextInput("index.txt"), "FILENAME"); | ||||
|         this.setOutput(true, Types.TEXT.typeName); | ||||
|         this.setColour(getColour().webserver); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| @ -1,61 +0,0 @@ | ||||
| import Blockly from "blockly"; | ||||
| 
 | ||||
|  /** | ||||
|   * starte/stoppe Pumpe | ||||
|   * | ||||
|   */ | ||||
| Blockly.Arduino.CleVerLab_pump = function (block) { | ||||
|     var pin = block.getFieldValue('DigitalPin'); | ||||
|     var state = block.getFieldValue("Mode"); | ||||
|     Blockly['Arduino'].setupCode_['pinMode'] = 'pinMode(' + pin + ', OUTPUT);'; | ||||
|     var code = 'digitalWrite(' + pin + ', ' + state + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| /** | ||||
|  * PH wert | ||||
|  * | ||||
|  */ | ||||
| Blockly.Arduino.CleVerLab_temperature = function () { | ||||
|   var dropdown_pin = this.getFieldValue("DigitalPort"); | ||||
|   Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>"; | ||||
|   Blockly.Arduino.libraries_["library_oneWire"] = | ||||
|     "#include <OneWire.h> // http://librarymanager/All#OneWire"; | ||||
|   Blockly.Arduino.libraries_["library_oneDallasTemperature"] = | ||||
|     "#include <DallasTemperature.h> // http://librarymanager/All#DallasTemperature"; | ||||
|   Blockly.Arduino.definitions_["define_OneWire"] = | ||||
|     "#define ONE_WIRE_BUS " + | ||||
|     dropdown_pin + | ||||
|     "\nOneWire oneWire(ONE_WIRE_BUS);\nDallasTemperature sensors(&oneWire);"; | ||||
|   Blockly.Arduino.setupCode_["sensebox_oneWireSetup"] = "sensors.begin();"; | ||||
|   Blockly.Arduino.codeFunctions_["sensebox_requestTemp"] = | ||||
|     "float getWaterTemp(){\nsensors.requestTemperatures();\nsensors.getTempCByIndex(0);\n}"; | ||||
|   var code = "getWaterTemp()"; | ||||
|   return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| Blockly.Arduino.CleVerLab_pH = function () { | ||||
|    var dropdown_pin = this.getFieldValue("DigitalPin"); | ||||
|    Blockly.Arduino.definitions_["define_pHgetter"] = | ||||
|      "#define SensorPin " + dropdown_pin +"\n#define samplingInterval 20\n#define printInterval 800\n#define ArrayLenth  40    //times of collection\nint pHArray[ArrayLenth];   //Store the average value of the sensor feedback\nint pHArrayIndex=0;\nfloat slope = 1.00;\nfloat b =0.00;"; | ||||
|    Blockly.Arduino.codeFunctions_["sensebox_requestpH"] = | ||||
|      "float getpH(){\nstatic unsigned long samplingTime = millis();\nstatic unsigned long printTime = millis();\nstatic float pHValue,voltage;\n//nif(millis()-samplingTime > samplingInterval){\n//pHArray[pHArrayIndex++]=analogRead(SensorPin);\nfor (int i = 1; i <= 10; i += 1) {\nvoltage = voltage + analogRead(SensorPin);\n}\n voltage = (voltage / 10)*5.0/1024; \nsamplingTime=millis();\n\nreturn pHValue = 3.5*voltage*slope+b;\n}\n"; | ||||
|     Blockly.Arduino.codeFunctions_["avergearraypH"] = | ||||
|         "double avergearray(int* arr, int number) {\n int i;\n int max, min;\n double avg;\n long amount = 0;\n if (number <= 0) {\n return 0;\n }\n if (number < 5) {\n for (i = 0; i < number; i++) {\n amount += arr[i];\n }\n avg = amount / number;\n return avg;\n }\n else {\n if (arr[0] < arr[1]) {\n min = arr[0];\n max = arr[1];\n }\n else {\n min = arr[1];\n max = arr[0];\n }\n for (i = 2; i < number; i++) {\n if (arr[i] < min) {\n amount += min;\n min = arr[i];\n }\n else {\n if (arr[i] > max) {\n amount += max;\n max = arr[i];\n }\n else {\n amount += arr[i];\n }\n }\n }\n avg = (double)amount / (number - 2);\n }\n return avg;\n}"; | ||||
|    var code = "getpH()"; | ||||
|    return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.CleVerLab_cali1 = function () { | ||||
|    var var1 = Blockly.Arduino.valueToCode(this, 'VAR1', Blockly.Arduino.ORDER_ATOMIC) || "4.00"; | ||||
|    var var2 = Blockly.Arduino.valueToCode(this, 'VAR2', Blockly.Arduino.ORDER_ATOMIC) || "7.00"; | ||||
|    //var var1 = this.getFieldValue("VAR1");
 | ||||
|    //var var2 = this.getFieldValue("VAR2");
 | ||||
|    Blockly.Arduino.definitions_["define_pHKali"] = "#define pH4 4.00\n#define pH7 7.00\nfloat pH4is = "+ var1+";\nfloat pH7is = "+ var2 +";"; | ||||
|    Blockly.Arduino.setupCode_["asdsadsa"] ="slope = (2.00-(4.00/3.50))/(pH7is/3.50 - pH4is/3.50);\n b = 7 - (pH7is * slope);"; | ||||
|    var code = "0"; | ||||
|    return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -1,6 +1,6 @@ | ||||
| /** | ||||
|  * @license | ||||
|  * | ||||
|  *  | ||||
|  * Copyright 2019 Google LLC | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| @ -24,24 +24,13 @@ | ||||
| // More on generating code:
 | ||||
| // https://developers.google.com/blockly/guides/create-custom-blocks/generating-code
 | ||||
| 
 | ||||
| import * as Blockly from "blockly/core"; | ||||
| 
 | ||||
| import store from "../../../store"; | ||||
| 
 | ||||
| var ota = store.getState().general.platform | ||||
|   ? store.getState().general.platform | ||||
|   : null; | ||||
| store.subscribe(() => { | ||||
|   ota = store.getState().general.platform | ||||
|     ? store.getState().general.platform | ||||
|     : null; | ||||
| }); | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| /** | ||||
|  * Arduino code generator. | ||||
|  * @type !Blockly.Generator | ||||
|  */ | ||||
| Blockly["Arduino"] = new Blockly.Generator("Arduino"); | ||||
| Blockly['Arduino'] = new Blockly.Generator('Arduino'); | ||||
| 
 | ||||
| /** | ||||
|  * List of illegal variable names. | ||||
| @ -50,105 +39,153 @@ Blockly["Arduino"] = new Blockly.Generator("Arduino"); | ||||
|  * accidentally clobbering a built-in object or function. | ||||
|  * @private | ||||
|  */ | ||||
| Blockly["Arduino"].addReservedWords( | ||||
|   // http://arduino.cc/en/Reference/HomePage
 | ||||
|   "setup,loop,if,else,for,switch,case,while," + | ||||
|     "do,break,continue,return,goto,define,include," + | ||||
|     "HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false," + | ||||
|     "interger, constants,floating,point,void,boolean,char," + | ||||
|     "unsigned,byte,int,word,long,float,double,string,String,array," + | ||||
|     "static, volatile,const,sizeof,pinMode,digitalWrite,digitalRead," + | ||||
|     "analogReference,analogRead,analogWrite,tone,noTone,shiftOut,shitIn," + | ||||
|     "pulseIn,millis,micros,delay,delayMicroseconds,min,max,abs,constrain," + | ||||
|     "map,pow,sqrt,sin,cos,tan,randomSeed,random,lowByte,highByte,bitRead," + | ||||
|     "bitWrite,bitSet,bitClear,ultraSonicDistance,parseDouble,setNeoPixelColor," + | ||||
|     "bit,attachInterrupt,detachInterrupt,interrupts,noInterrupts,short,isBtnPressed" | ||||
| Blockly['Arduino'].addReservedWords( | ||||
|     // http://arduino.cc/en/Reference/HomePage
 | ||||
|     'setup,loop,if,else,for,switch,case,while,' + | ||||
|     'do,break,continue,return,goto,define,include,' + | ||||
|     'HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false,' + | ||||
|     'interger, constants,floating,point,void,bookean,char,' + | ||||
|     'unsigned,byte,int,word,long,float,double,string,String,array,' + | ||||
|     'static, volatile,const,sizeof,pinMode,digitalWrite,digitalRead,' + | ||||
|     'analogReference,analogRead,analogWrite,tone,noTone,shiftOut,shitIn,' + | ||||
|     'pulseIn,millis,micros,delay,delayMicroseconds,min,max,abs,constrain,' + | ||||
|     'map,pow,sqrt,sin,cos,tan,randomSeed,random,lowByte,highByte,bitRead,' + | ||||
|     'bitWrite,bitSet,bitClear,ultraSonicDistance,parseDouble,setNeoPixelColor,' + | ||||
|     'bit,attachInterrupt,detachInterrupt,interrupts,noInterrupts', | ||||
|     'short', | ||||
|     'isBtnPressed' | ||||
| ); | ||||
| 
 | ||||
| /** | ||||
|  * Order of operation ENUMs. | ||||
|  * | ||||
|  */ | ||||
| Blockly["Arduino"].ORDER_ATOMIC = 0; // 0 "" ...
 | ||||
| Blockly["Arduino"].ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] .
 | ||||
| Blockly["Arduino"].ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr
 | ||||
| Blockly["Arduino"].ORDER_MULTIPLICATIVE = 3; // * / % ~/
 | ||||
| Blockly["Arduino"].ORDER_ADDITIVE = 4; // + -
 | ||||
| Blockly["Arduino"].ORDER_LOGICAL_NOT = 4.4; // !
 | ||||
| Blockly["Arduino"].ORDER_SHIFT = 5; // << >>
 | ||||
| Blockly["Arduino"].ORDER_MODULUS = 5.3; // %
 | ||||
| Blockly["Arduino"].ORDER_RELATIONAL = 6; // is is! >= > <= <
 | ||||
| Blockly["Arduino"].ORDER_EQUALITY = 7; // === !== === !==
 | ||||
| Blockly["Arduino"].ORDER_BITWISE_AND = 8; // &
 | ||||
| Blockly["Arduino"].ORDER_BITWISE_XOR = 9; // ^
 | ||||
| Blockly["Arduino"].ORDER_BITWISE_OR = 10; // |
 | ||||
| Blockly["Arduino"].ORDER_LOGICAL_AND = 11; // &&
 | ||||
| Blockly["Arduino"].ORDER_LOGICAL_OR = 12; // ||
 | ||||
| Blockly["Arduino"].ORDER_CONDITIONAL = 13; // expr ? expr : expr
 | ||||
| Blockly["Arduino"].ORDER_ASSIGNMENT = 14; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
 | ||||
| Blockly["Arduino"].ORDER_COMMA = 18; // ,
 | ||||
| Blockly["Arduino"].ORDER_NONE = 99; // (...)
 | ||||
| Blockly['Arduino'].ORDER_ATOMIC = 0; // 0 "" ...
 | ||||
| Blockly['Arduino'].ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] .
 | ||||
| Blockly['Arduino'].ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr
 | ||||
| Blockly['Arduino'].ORDER_MULTIPLICATIVE = 3; // * / % ~/
 | ||||
| Blockly['Arduino'].ORDER_ADDITIVE = 4; // + -
 | ||||
| Blockly['Arduino'].ORDER_LOGICAL_NOT = 4.4; // !
 | ||||
| Blockly['Arduino'].ORDER_SHIFT = 5; // << >>
 | ||||
| Blockly['Arduino'].ORDER_MODULUS = 5.3; // %
 | ||||
| Blockly['Arduino'].ORDER_RELATIONAL = 6; // is is! >= > <= <
 | ||||
| Blockly['Arduino'].ORDER_EQUALITY = 7; // === !== === !==
 | ||||
| Blockly['Arduino'].ORDER_BITWISE_AND = 8; // &
 | ||||
| Blockly['Arduino'].ORDER_BITWISE_XOR = 9; // ^
 | ||||
| Blockly['Arduino'].ORDER_BITWISE_OR = 10; // |
 | ||||
| Blockly['Arduino'].ORDER_LOGICAL_AND = 11; // &&
 | ||||
| Blockly['Arduino'].ORDER_LOGICAL_OR = 12; // ||
 | ||||
| Blockly['Arduino'].ORDER_CONDITIONAL = 13; // expr ? expr : expr
 | ||||
| Blockly['Arduino'].ORDER_ASSIGNMENT = 14; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
 | ||||
| Blockly['Arduino'].ORDER_COMMA = 18; // ,
 | ||||
| Blockly['Arduino'].ORDER_NONE = 99; // (...)
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * @param {} workspace | ||||
|  * | ||||
|  *  | ||||
|  * @param {} workspace  | ||||
|  *  | ||||
|  * Blockly Types | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Initialise the database of variable names. | ||||
|  * @param {!Blockly.Workspace} workspace Workspace to generate code from. | ||||
|  */ | ||||
| Blockly["Arduino"].init = function (workspace) { | ||||
|   // Create a dictionary of definitions to be printed before the code.
 | ||||
|   Blockly["Arduino"].libraries_ = Object.create(null); | ||||
| Blockly['Arduino'].init = function (workspace) { | ||||
|     // Create a dictionary of definitions to be printed before the code.
 | ||||
|     Blockly['Arduino'].libraries_ = Object.create(null); | ||||
| 
 | ||||
|   Blockly["Arduino"].definitions_ = Object.create(null); | ||||
|     Blockly['Arduino'].definitions_ = Object.create(null); | ||||
| 
 | ||||
|   // creates a list of code to be setup before the setup block
 | ||||
|   Blockly["Arduino"].setupCode_ = Object.create(null); | ||||
|     // creates a list of code to be setup before the setup block
 | ||||
|     Blockly['Arduino'].setupCode_ = Object.create(null); | ||||
| 
 | ||||
|   // creates a list of code to be setup before the setup block
 | ||||
|   Blockly["Arduino"].phyphoxSetupCode_ = Object.create(null); | ||||
|     // creates a list of code for the loop to be runned once
 | ||||
|     Blockly['Arduino'].loopCodeOnce_ = Object.create(null) | ||||
| 
 | ||||
|   // creates a list of code to be setup before the setup block
 | ||||
|   Blockly["Arduino"].loraSetupCode_ = Object.create(null); | ||||
|     // creates a list of code for the loop to be runned once
 | ||||
|     Blockly['Arduino'].codeFunctions_ = Object.create(null) | ||||
| 
 | ||||
|   // creates a list of code for the loop to be runned once
 | ||||
|   Blockly["Arduino"].loopCodeOnce_ = Object.create(null); | ||||
|     // creates a list of code variables  
 | ||||
|     Blockly['Arduino'].variables_ = Object.create(null) | ||||
| 
 | ||||
|   // creates a list of code for the loop to be runned once
 | ||||
|   Blockly["Arduino"].codeFunctions_ = Object.create(null); | ||||
|     // Create a dictionary mapping desired function names in definitions_
 | ||||
|     // to actual function names (to avoid collisions with user functions).
 | ||||
|     Blockly['Arduino'].functionNames_ = Object.create(null); | ||||
| 
 | ||||
|   // creates a list of code variables
 | ||||
|   Blockly["Arduino"].variables_ = Object.create(null); | ||||
|     Blockly['Arduino'].variablesInitCode_ = ''; | ||||
| 
 | ||||
|   // Create a dictionary mapping desired function names in definitions_
 | ||||
|   // to actual function names (to avoid collisions with user functions).
 | ||||
|   Blockly["Arduino"].functionNames_ = Object.create(null); | ||||
|     if (!Blockly['Arduino'].variableDB_) { | ||||
|         Blockly['Arduino'].variableDB_ = new Blockly.Names( | ||||
|             Blockly['Arduino'].RESERVED_WORDS_ | ||||
|         ); | ||||
|     } else { | ||||
|         Blockly['Arduino'].variableDB_.reset(); | ||||
|     } | ||||
| 
 | ||||
|   Blockly["Arduino"].variablesInitCode_ = ""; | ||||
|     Blockly['Arduino'].variableDB_.setVariableMap(workspace.getVariableMap()); | ||||
| 
 | ||||
|   if (!Blockly["Arduino"].nameDB_) { | ||||
|     Blockly["Arduino"].nameDB_ = new Blockly.Names( | ||||
|       Blockly["Arduino"].RESERVED_WORDS_ | ||||
|     ); | ||||
|   } else { | ||||
|     Blockly["Arduino"].nameDB_.reset(); | ||||
|   } | ||||
|     // We don't have developer variables for now
 | ||||
|     // // Add developer variables (not created or named by the user).
 | ||||
|     // var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
 | ||||
|     // for (var i = 0; i < devVarList.length; i++) {
 | ||||
|     //     defvars.push(Blockly['Arduino'].variableDB_.getName(devVarList[i],
 | ||||
|     //         Blockly.Names.DEVELOPER_VARIABLE_TYPE));
 | ||||
|     // }
 | ||||
| 
 | ||||
|   Blockly["Arduino"].nameDB_.setVariableMap(workspace.getVariableMap()); | ||||
|     const doubleVariables = workspace.getVariablesOfType('Number'); | ||||
|     let i = 0; | ||||
|     let variableCode = ''; | ||||
|     for (i = 0; i < doubleVariables.length; i += 1) { | ||||
|         variableCode += | ||||
|             'double ' + | ||||
|             Blockly['Arduino'].variableDB_.getName( | ||||
|                 doubleVariables[i].getId(), | ||||
|                 Blockly.Variables.NAME_TYPE | ||||
|             ) + | ||||
|             ' = 0; \n\n'; | ||||
|     } | ||||
| 
 | ||||
|   // We don't have developer variables for now
 | ||||
|   // // Add developer variables (not created or named by the user).
 | ||||
|   // var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
 | ||||
|   // for (var i = 0; i < devVarList.length; i++) {
 | ||||
|   //     defvars.push(Blockly['Arduino'].nameDB_.getName(devVarList[i],
 | ||||
|   //         Blockly.Names.DEVELOPER_VARIABLE_TYPE));
 | ||||
|   // }
 | ||||
|     const stringVariables = workspace.getVariablesOfType('String'); | ||||
|     for (i = 0; i < stringVariables.length; i += 1) { | ||||
|         variableCode += | ||||
|             'String ' + | ||||
|             Blockly['Arduino'].variableDB_.getName( | ||||
|                 stringVariables[i].getId(), | ||||
|                 Blockly.Variables.NAME_TYPE | ||||
|             ) + | ||||
|             ' = ""; \n\n'; | ||||
|     } | ||||
| 
 | ||||
|     const booleanVariables = workspace.getVariablesOfType('Boolean'); | ||||
|     for (i = 0; i < booleanVariables.length; i += 1) { | ||||
|         variableCode += | ||||
|             'boolean ' + | ||||
|             Blockly['Arduino'].variableDB_.getDistinctName( | ||||
|                 booleanVariables[i].getId(), | ||||
|                 Blockly.Variables.NAME_TYPE | ||||
|             ) + | ||||
|             ' = false; \n\n'; | ||||
|     } | ||||
| 
 | ||||
|     const colourVariables = workspace.getVariablesOfType('Colour'); | ||||
|     for (i = 0; i < colourVariables.length; i += 1) { | ||||
|         variableCode += | ||||
|             'RGB ' + | ||||
|             Blockly['Arduino'].variableDB_.getName( | ||||
|                 colourVariables[i].getId(), | ||||
|                 Blockly.Variables.NAME_TYPE | ||||
|             ) + | ||||
|             ' = {0, 0, 0}; \n\n'; | ||||
|     } | ||||
| 
 | ||||
|     Blockly['Arduino'].variablesInitCode_ = variableCode; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -156,120 +193,81 @@ Blockly["Arduino"].init = function (workspace) { | ||||
|  * @param {string} code Generated code. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly["Arduino"].finish = function (code) { | ||||
|   let libraryCode = ""; | ||||
|   let variablesCode = ""; | ||||
|   let codeFunctions = ""; | ||||
|   let functionsCode = ""; | ||||
|   let definitionsCode = ""; | ||||
|   let phyphoxSetupCode = ""; | ||||
|   let loopCodeOnce = ""; | ||||
|   let setupCode = ""; | ||||
|   let preSetupCode = ""; | ||||
|   let loraSetupCode = ""; | ||||
|   let devVariables = "\n"; | ||||
| Blockly['Arduino'].finish = function (code) { | ||||
|     let libraryCode = ''; | ||||
|     let variablesCode = ''; | ||||
|     let codeFunctions = ''; | ||||
|     let functionsCode = ''; | ||||
|     let definitionsCode = ''; | ||||
|     let loopCodeOnce = ''; | ||||
|     let setupCode = ''; | ||||
|     let preSetupCode = ''; | ||||
|     let devVariables = '\n'; | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].libraries_) { | ||||
|     libraryCode += Blockly["Arduino"].libraries_[key] + "\n"; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].libraries_) { | ||||
|         libraryCode += Blockly['Arduino'].libraries_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].variables_) { | ||||
|     variablesCode += Blockly["Arduino"].variables_[key] + "\n"; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].variables_) { | ||||
|         variablesCode += Blockly['Arduino'].variables_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].definitions_) { | ||||
|     definitionsCode += Blockly["Arduino"].definitions_[key] + "\n"; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].definitions_) { | ||||
|         definitionsCode += Blockly['Arduino'].definitions_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].loopCodeOnce_) { | ||||
|     loopCodeOnce += Blockly["Arduino"].loopCodeOnce_[key] + "\n"; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].loopCodeOnce_) { | ||||
|         loopCodeOnce += Blockly['Arduino'].loopCodeOnce_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].codeFunctions_) { | ||||
|     codeFunctions += Blockly["Arduino"].codeFunctions_[key] + "\n"; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].codeFunctions_) { | ||||
|         codeFunctions += Blockly['Arduino'].codeFunctions_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].functionNames_) { | ||||
|     functionsCode += Blockly["Arduino"].functionNames_[key] + "\n"; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].functionNames_) { | ||||
|         functionsCode += Blockly['Arduino'].functionNames_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].setupCode_) { | ||||
|     preSetupCode += Blockly["Arduino"].setupCode_[key] + "\n" || ""; | ||||
|   } | ||||
| 
 | ||||
|   for (const key in Blockly["Arduino"].loraSetupCode_) { | ||||
|     loraSetupCode += Blockly["Arduino"].loraSetupCode_[key] + "\n" || ""; | ||||
|   } | ||||
| 
 | ||||
|   setupCode = | ||||
|     "\nvoid setup() { \n" + preSetupCode + "\n" + loraSetupCode + "\n}\n"; | ||||
|   for (const key in Blockly["Arduino"].phyphoxSetupCode_) { | ||||
|     phyphoxSetupCode += Blockly["Arduino"].phyphoxSetupCode_[key] + "\n" || ""; | ||||
|   } | ||||
|     for (const key in Blockly['Arduino'].setupCode_) { | ||||
|         preSetupCode += Blockly['Arduino'].setupCode_[key] || ''; | ||||
|     } | ||||
|     setupCode = '\nvoid setup() { \n' + preSetupCode + '\n}\n'; | ||||
| 
 | ||||
|     let loopCode = '\nvoid loop() { \n' + loopCodeOnce + code + '\n}\n'; | ||||
| 
 | ||||
|   setupCode = | ||||
|     "\nvoid setup() { \n" + | ||||
|     preSetupCode + | ||||
|     "\n" + | ||||
|     phyphoxSetupCode + | ||||
|     "\n" + | ||||
|     loraSetupCode + | ||||
|     "\n}\n"; | ||||
| 
 | ||||
|   let loopCode = "\nvoid loop() { \n" + loopCodeOnce + code + "\n}\n"; | ||||
|   // only add OTA code if tablet mode is enabled
 | ||||
|   if (ota === true) { | ||||
|     code = | ||||
|       devVariables + | ||||
|       "\n" + | ||||
|       "#include <SenseBoxOTA.h>" + | ||||
|       "\n" + | ||||
|       libraryCode + | ||||
|       "\n" + | ||||
|       variablesCode + | ||||
|       "\n" + | ||||
|       definitionsCode + | ||||
|       "\n" + | ||||
|       codeFunctions + | ||||
|       "\n" + | ||||
|       Blockly["Arduino"].variablesInitCode_ + | ||||
|       "\n" + | ||||
|       functionsCode + | ||||
|       "\n" + | ||||
|       setupCode + | ||||
|       "\n" + | ||||
|       loopCode; | ||||
|   } else { | ||||
|     // Convert the definitions dictionary into a list.
 | ||||
|     code = | ||||
|       devVariables + | ||||
|       "\n" + | ||||
|       libraryCode + | ||||
|       "\n" + | ||||
|       variablesCode + | ||||
|       "\n" + | ||||
|       definitionsCode + | ||||
|       "\n" + | ||||
|       codeFunctions + | ||||
|       "\n" + | ||||
|       Blockly["Arduino"].variablesInitCode_ + | ||||
|       "\n" + | ||||
|       functionsCode + | ||||
|       "\n" + | ||||
|       setupCode + | ||||
|       "\n" + | ||||
|       loopCode; | ||||
|   } | ||||
|         devVariables + | ||||
|         '\n' + | ||||
|         libraryCode + | ||||
|         '\n' + | ||||
|         variablesCode + | ||||
|         '\n' + | ||||
|         definitionsCode + | ||||
|         '\n' + | ||||
|         codeFunctions + | ||||
|         '\n' + | ||||
|         Blockly['Arduino'].variablesInitCode_ + | ||||
|         '\n' + | ||||
|         functionsCode + | ||||
|         '\n' + | ||||
|         setupCode + | ||||
|         '\n' + | ||||
|         loopCode | ||||
|         ; | ||||
| 
 | ||||
|   // Clean up temporary data.
 | ||||
|   delete Blockly["Arduino"].definitions_; | ||||
|   delete Blockly["Arduino"].functionNames_; | ||||
|   delete Blockly["Arduino"].loopCodeOnce_; | ||||
|   delete Blockly["Arduino"].variablesInitCode_; | ||||
|   delete Blockly["Arduino"].libraries_; | ||||
|   Blockly["Arduino"].nameDB_.reset(); | ||||
|     // Clean up temporary data.
 | ||||
|     delete Blockly['Arduino'].definitions_; | ||||
|     delete Blockly['Arduino'].functionNames_; | ||||
|     delete Blockly['Arduino'].loopCodeOnce_; | ||||
|     delete Blockly['Arduino'].variablesInitCode_; | ||||
|     delete Blockly['Arduino'].libraries_; | ||||
|     Blockly['Arduino'].variableDB_.reset(); | ||||
| 
 | ||||
|   return code; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -278,8 +276,8 @@ Blockly["Arduino"].finish = function (code) { | ||||
|  * @param {string} line Line of generated code. | ||||
|  * @return {string} Legal line of code. | ||||
|  */ | ||||
| Blockly["Arduino"].scrubNakedValue = function (line) { | ||||
|   return line + ";\n"; | ||||
| Blockly['Arduino'].scrubNakedValue = function (line) { | ||||
|     return line + ';\n'; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -289,14 +287,14 @@ Blockly["Arduino"].scrubNakedValue = function (line) { | ||||
|  * @return {string} Arduino string. | ||||
|  * @private | ||||
|  */ | ||||
| Blockly["Arduino"].quote_ = function (string) { | ||||
|   // Can't use goog.string.quote since Google's style guide recommends
 | ||||
|   // JS string literals use single quotes.
 | ||||
|   string = string | ||||
|     .replace(/\\/g, "\\\\") | ||||
|     .replace(/\n/g, "\\\n") | ||||
|     .replace(/'/g, "\\'"); | ||||
|   return '"' + string + '"'; | ||||
| Blockly['Arduino'].quote_ = function (string) { | ||||
|     // Can't use goog.string.quote since Google's style guide recommends
 | ||||
|     // JS string literals use single quotes.
 | ||||
|     string = string | ||||
|         .replace(/\\/g, '\\\\') | ||||
|         .replace(/\n/g, '\\\n') | ||||
|         .replace(/'/g, "\\'"); | ||||
|     return '"' + string + '"'; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -309,42 +307,43 @@ Blockly["Arduino"].quote_ = function (string) { | ||||
|  * @return {string} Arduino code with comments and subsequent blocks added. | ||||
|  * @private | ||||
|  */ | ||||
| Blockly["Arduino"].scrub_ = function (block, code) { | ||||
|   let commentCode = ""; | ||||
|   // Only collect comments for blocks that aren't inline.
 | ||||
|   if (!block.outputConnection || !block.outputConnection.targetConnection) { | ||||
|     // Collect comment for this block.
 | ||||
|     let comment = block.getCommentText(); | ||||
|     //@ts-ignore
 | ||||
|     comment = comment | ||||
|       ? Blockly.utils.string.wrap(comment, Blockly["Arduino"].COMMENT_WRAP - 3) | ||||
|       : null; | ||||
|     if (comment) { | ||||
|       if (block.getProcedureDef) { | ||||
|         // Use a comment block for function comments.
 | ||||
|         commentCode += | ||||
|           "/**\n" + | ||||
|           Blockly["Arduino"].prefixLines(comment + "\n", " * ") + | ||||
|           " */\n"; | ||||
|       } else { | ||||
|         commentCode += Blockly["Arduino"].prefixLines(comment + "\n", "// "); | ||||
|       } | ||||
|     } | ||||
|     // Collect comments for all value arguments.
 | ||||
|     // Don't collect comments for nested statements.
 | ||||
|     for (let i = 0; i < block.inputList.length; i++) { | ||||
|       if (block.inputList[i].type === Blockly.INPUT_VALUE) { | ||||
|         const childBlock = block.inputList[i].connection.targetBlock(); | ||||
|         if (childBlock) { | ||||
|           const comment = Blockly["Arduino"].allNestedComments(childBlock); | ||||
|           if (comment) { | ||||
|             commentCode += Blockly["Arduino"].prefixLines(comment, "// "); | ||||
|           } | ||||
| Blockly['Arduino'].scrub_ = function (block, code) { | ||||
|     let commentCode = ''; | ||||
|     // Only collect comments for blocks that aren't inline.
 | ||||
|     if (!block.outputConnection || !block.outputConnection.targetConnection) { | ||||
|         // Collect comment for this block.
 | ||||
|         let comment = block.getCommentText(); | ||||
|         //@ts-ignore
 | ||||
|         comment = comment ? Blockly.utils.string.wrap( | ||||
|             comment, | ||||
|             Blockly['Arduino'].COMMENT_WRAP - 3 | ||||
|         ) : null; | ||||
|         if (comment) { | ||||
|             if (block.getProcedureDef) { | ||||
|                 // Use a comment block for function comments.
 | ||||
|                 commentCode += | ||||
|                     '/**\n' + | ||||
|                     Blockly['Arduino'].prefixLines(comment + '\n', ' * ') + | ||||
|                     ' */\n'; | ||||
|             } else { | ||||
|                 commentCode += Blockly['Arduino'].prefixLines(comment + '\n', '// '); | ||||
|             } | ||||
|         } | ||||
|         // Collect comments for all value arguments.
 | ||||
|         // Don't collect comments for nested statements.
 | ||||
|         for (let i = 0; i < block.inputList.length; i++) { | ||||
|             if (block.inputList[i].type === Blockly.INPUT_VALUE) { | ||||
|                 const childBlock = block.inputList[i].connection.targetBlock(); | ||||
|                 if (childBlock) { | ||||
|                     const comment = Blockly['Arduino'].allNestedComments(childBlock); | ||||
|                     if (comment) { | ||||
|                         commentCode += Blockly['Arduino'].prefixLines(comment, '// '); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); | ||||
|   const nextCode = Blockly["Arduino"].blockToCode(nextBlock); | ||||
|   return commentCode + code + nextCode; | ||||
| }; | ||||
|     const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); | ||||
|     const nextCode = Blockly['Arduino'].blockToCode(nextBlock); | ||||
|     return commentCode + code + nextCode; | ||||
| }; | ||||
| @ -1,30 +1,21 @@ | ||||
| import "./generator"; | ||||
| import "./loops"; | ||||
| import "./sensebox-sensors"; | ||||
| import "./sensebox-telegram"; | ||||
| import "./sensebox-osem"; | ||||
| import "./sensebox-web"; | ||||
| import "./sensebox-display"; | ||||
| import "./sensebox-motors"; | ||||
| import "./sensebox-lora"; | ||||
| import "./sensebox-led"; | ||||
| import "./sensebox"; | ||||
| import "./sensebox-rtc"; | ||||
| import "./sensebox-ntp"; | ||||
| import "./sensebox-ble"; | ||||
| import "./sensebox-sd"; | ||||
| import "./mqtt"; | ||||
| import "./logic"; | ||||
| import "./text"; | ||||
| import "./math"; | ||||
| import "./map"; | ||||
| import "./io"; | ||||
| import "./audio"; | ||||
| import "./procedures"; | ||||
| import "./serial"; | ||||
| import "./time"; | ||||
| import "./variables"; | ||||
| import "./lists"; | ||||
| import "./watchdog"; | ||||
| import "./webserver"; | ||||
| import "./CleVerLab" | ||||
| import './generator'; | ||||
| import './loops'; | ||||
| import './sensebox-sensors'; | ||||
| import './sensebox-telegram'; | ||||
| import './sensebox-osem'; | ||||
| import './sensebox-web'; | ||||
| import './sensebox-display'; | ||||
| import './sensebox-lora'; | ||||
| import './sensebox-led'; | ||||
| import './sensebox-sd'; | ||||
| import './logic'; | ||||
| import './text'; | ||||
| import './math'; | ||||
| import './map'; | ||||
| import './io'; | ||||
| import './audio'; | ||||
| import './procedures'; | ||||
| import './time'; | ||||
| import './variables'; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,19 +0,0 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Arduino['lists_create_empty'] = function () { | ||||
|     var code = ''; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino['array_getIndex'] = function () { | ||||
|     var code = ''; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Arduino['lists_length'] = function () { | ||||
|     var array = Blockly.Arduino.valueToCode(this, 'ARRAY', Blockly.Arduino.ORDER_ATOMIC); | ||||
|     var code = `${array}.length`; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| } | ||||
| @ -74,14 +74,14 @@ Blockly.Arduino['controls_if'] = function (Block) { | ||||
|             conditionCode + | ||||
|             ') {\n' + | ||||
|             branchCode + | ||||
|             '}\n'; | ||||
|             '}'; | ||||
| 
 | ||||
|         ++n; | ||||
|     } while (Block.getInput('IF' + n)); | ||||
| 
 | ||||
|     if (Block.getInput('ELSE')) { | ||||
|         branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE'); | ||||
|         code += ' else {\n' + branchCode + '}\n'; | ||||
|         code += ' else {\n' + branchCode + '}'; | ||||
|     } | ||||
|     return code + '\n'; | ||||
| }; | ||||
| @ -106,14 +106,14 @@ Blockly.Arduino['controls_ifelse'] = function (Block) { | ||||
|             conditionCode + | ||||
|             ') {\n' + | ||||
|             branchCode + | ||||
|             '}\n'; | ||||
|             '}'; | ||||
| 
 | ||||
|         ++n; | ||||
|     } while (Block.getInput('IF' + n)); | ||||
| 
 | ||||
|     if (Block.getInput('ELSE')) { | ||||
|         branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE'); | ||||
|         code += ' else {\n' + branchCode + '}\n'; | ||||
|         code += ' else {\n' + branchCode + '}'; | ||||
|     } | ||||
|     return code + '\n'; | ||||
| } | ||||
| @ -127,6 +127,9 @@ Blockly.Arduino['logic_negate'] = function (Block) { | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Arduino['switch_case'] = function (block) { | ||||
|     var n = 0; | ||||
|     var argument = Blockly.Arduino.valueToCode(this, 'CONDITION', | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import * as Blockly from "blockly/core"; | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
| @ -18,15 +19,15 @@ import * as Blockly from "blockly/core"; | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_number"] = function (block) { | ||||
|   // Numeric value.
 | ||||
|   var code = parseFloat(block.getFieldValue("NUM")); | ||||
|   if (code === Infinity) { | ||||
|     code = "INFINITY"; | ||||
|   } else if (code === -Infinity) { | ||||
|     code = "-INFINITY"; | ||||
|   } | ||||
|   return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| Blockly.Arduino['math_number'] = function (block) { | ||||
|     // Numeric value.
 | ||||
|     var code = parseFloat(block.getFieldValue('NUM')); | ||||
|     if (code === Infinity) { | ||||
|         code = 'INFINITY'; | ||||
|     } else if (code === -Infinity) { | ||||
|         code = '-INFINITY'; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -36,27 +37,27 @@ Blockly.Arduino["math_number"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_arithmetic"] = function (block) { | ||||
|   var OPERATORS = { | ||||
|     ADD: [" + ", Blockly.Arduino.ORDER_ADDITIVE], | ||||
|     MINUS: [" - ", Blockly.Arduino.ORDER_ADDITIVE], | ||||
|     MULTIPLY: [" * ", Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|     DIVIDE: [" / ", Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|     POWER: [null, Blockly.Arduino.ORDER_NONE], // Handle power separately.
 | ||||
|   }; | ||||
|   var tuple = OPERATORS[block.getFieldValue("OP")]; | ||||
|   var operator = tuple[0]; | ||||
|   var order = tuple[1]; | ||||
|   var argument0 = Blockly.Arduino.valueToCode(block, "A", order) || "0"; | ||||
|   var argument1 = Blockly.Arduino.valueToCode(block, "B", order) || "0"; | ||||
|   var code; | ||||
|   // Power in C++ requires a special case since it has no operator.
 | ||||
|   if (!operator) { | ||||
|     code = "Math.pow(" + argument0 + ", " + argument1 + ")"; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|   } | ||||
|   code = argument0 + operator + argument1; | ||||
|   return [code, order]; | ||||
| Blockly.Arduino['math_arithmetic'] = function (block) { | ||||
|     var OPERATORS = { | ||||
|         ADD: [' + ', Blockly.Arduino.ORDER_ADDITIVE], | ||||
|         MINUS: [' - ', Blockly.Arduino.ORDER_ADDITIVE], | ||||
|         MULTIPLY: [' * ', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|         DIVIDE: [' / ', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|         POWER: [null, Blockly.Arduino.ORDER_NONE]  // Handle power separately.
 | ||||
|     }; | ||||
|     var tuple = OPERATORS[block.getFieldValue('OP')]; | ||||
|     var operator = tuple[0]; | ||||
|     var order = tuple[1]; | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'A', order) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'B', order) || '0'; | ||||
|     var code; | ||||
|     // Power in C++ requires a special case since it has no operator.
 | ||||
|     if (!operator) { | ||||
|         code = 'Math.pow(' + argument0 + ', ' + argument1 + ')'; | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|     } | ||||
|     code = argument0 + operator + argument1; | ||||
|     return [code, order]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -65,103 +66,90 @@ Blockly.Arduino["math_arithmetic"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_single"] = function (block) { | ||||
|   var operator = block.getFieldValue("OP"); | ||||
|   var code; | ||||
|   var arg; | ||||
|   if (operator === "NEG") { | ||||
|     // Negation is a special case given its different operator precedents.
 | ||||
|     arg = | ||||
|       Blockly.Arduino.valueToCode( | ||||
|         block, | ||||
|         "NUM", | ||||
|         Blockly.Arduino.ORDER_UNARY_PREFIX | ||||
|       ) || "0"; | ||||
|     if (arg[0] === "-") { | ||||
|       // --3 is not legal in C++ in this context.
 | ||||
|       arg = " " + arg; | ||||
| Blockly.Arduino['math_single'] = function (block) { | ||||
|     var operator = block.getFieldValue('OP'); | ||||
|     var code; | ||||
|     var arg; | ||||
|     if (operator === 'NEG') { | ||||
|         // Negation is a special case given its different operator precedents.
 | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_UNARY_PREFIX) || '0'; | ||||
|         if (arg[0] === '-') { | ||||
|             // --3 is not legal in C++ in this context.
 | ||||
|             arg = ' ' + arg; | ||||
|         } | ||||
|         code = '-' + arg; | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_PREFIX]; | ||||
|     } | ||||
|     code = "-" + arg; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_PREFIX]; | ||||
|   } | ||||
|   if (operator === "ABS" || operator.substring(0, 5) === "ROUND") { | ||||
|     arg = | ||||
|       Blockly.Arduino.valueToCode( | ||||
|         block, | ||||
|         "NUM", | ||||
|         Blockly.Arduino.ORDER_UNARY_POSTFIX | ||||
|       ) || "0"; | ||||
|   } else if (operator === "SIN" || operator === "COS" || operator === "TAN") { | ||||
|     arg = | ||||
|       Blockly.Arduino.valueToCode( | ||||
|         block, | ||||
|         "NUM", | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE | ||||
|       ) || "0"; | ||||
|   } else { | ||||
|     arg = | ||||
|       Blockly.Arduino.valueToCode(block, "NUM", Blockly.Arduino.ORDER_NONE) || | ||||
|       "0"; | ||||
|   } | ||||
|   // First, handle cases which generate values that don't need parentheses.
 | ||||
|   switch (operator) { | ||||
|     case "ABS": | ||||
|       code = "abs(" + arg + ")"; | ||||
|       break; | ||||
|     case "ROOT": | ||||
|       code = "sqrt(" + arg + ")"; | ||||
|       break; | ||||
|     case "LN": | ||||
|       code = "log(" + arg + ")"; | ||||
|       break; | ||||
|     case "EXP": | ||||
|       code = "exp(" + arg + ")"; | ||||
|       break; | ||||
|     case "POW10": | ||||
|       code = "pow(10," + arg + ")"; | ||||
|       break; | ||||
|     case "ROUND": | ||||
|       code = "round(" + arg + ")"; | ||||
|       break; | ||||
|     case "ROUNDUP": | ||||
|       code = "ceil(" + arg + ")"; | ||||
|       break; | ||||
|     case "ROUNDDOWN": | ||||
|       code = "floor(" + arg + ")"; | ||||
|       break; | ||||
|     case "SIN": | ||||
|       code = "sin(" + arg + " / 180 * Math.PI)"; | ||||
|       break; | ||||
|     case "COS": | ||||
|       code = "cos(" + arg + " / 180 * Math.PI)"; | ||||
|       break; | ||||
|     case "TAN": | ||||
|       code = "tan(" + arg + " / 180 * Math.PI)"; | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
|   if (code) { | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|   } | ||||
|   // Second, handle cases which generate values that may need parentheses.
 | ||||
|   switch (operator) { | ||||
|     case "LOG10": | ||||
|       code = "log(" + arg + ") / log(10)"; | ||||
|       break; | ||||
|     case "ASIN": | ||||
|       code = "asin(" + arg + ") / M_PI * 180"; | ||||
|       break; | ||||
|     case "ACOS": | ||||
|       code = "acos(" + arg + ") / M_PI * 180"; | ||||
|       break; | ||||
|     case "ATAN": | ||||
|       code = "atan(" + arg + ") / M_PI * 180"; | ||||
|       break; | ||||
|     default: | ||||
|       throw new Error("Unknown math operator: " + operator); | ||||
|   } | ||||
|   return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||
|     if (operator === 'ABS' || operator.substring(0, 5) === 'ROUND') { | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_UNARY_POSTFIX) || '0'; | ||||
|     } else if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     } else { | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     } | ||||
|     // First, handle cases which generate values that don't need parentheses.
 | ||||
|     switch (operator) { | ||||
|         case 'ABS': | ||||
|             code = 'abs(' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROOT': | ||||
|             code = 'sqrt(' + arg + ')'; | ||||
|             break; | ||||
|         case 'LN': | ||||
|             code = 'log(' + arg + ')'; | ||||
|             break; | ||||
|         case 'EXP': | ||||
|             code = 'exp(' + arg + ')'; | ||||
|             break; | ||||
|         case 'POW10': | ||||
|             code = 'pow(10,' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROUND': | ||||
|             code = 'round(' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROUNDUP': | ||||
|             code = 'ceil(' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROUNDDOWN': | ||||
|             code = 'floor(' + arg + ')'; | ||||
|             break; | ||||
|         case 'SIN': | ||||
|             code = 'sin(' + arg + ' / 180 * Math.PI)'; | ||||
|             break; | ||||
|         case 'COS': | ||||
|             code = 'cos(' + arg + ' / 180 * Math.PI)'; | ||||
|             break; | ||||
|         case 'TAN': | ||||
|             code = 'tan(' + arg + ' / 180 * Math.PI)'; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     if (code) { | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|     } | ||||
|     // Second, handle cases which generate values that may need parentheses.
 | ||||
|     switch (operator) { | ||||
|         case 'LOG10': | ||||
|             code = 'log(' + arg + ') / log(10)'; | ||||
|             break; | ||||
|         case 'ASIN': | ||||
|             code = 'asin(' + arg + ') / M_PI * 180'; | ||||
|             break; | ||||
|         case 'ACOS': | ||||
|             code = 'acos(' + arg + ') / M_PI * 180'; | ||||
|             break; | ||||
|         case 'ATAN': | ||||
|             code = 'atan(' + arg + ') / M_PI * 180'; | ||||
|             break; | ||||
|         default: | ||||
|             throw new Error('Unknown math operator: ' + operator); | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -173,16 +161,16 @@ Blockly.Arduino["math_single"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino["math_constant"] = function (block) { | ||||
|   var CONSTANTS = { | ||||
|     PI: ["M_PI", Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|     E: ["M_E", Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|     GOLDEN_RATIO: ["(1 + sqrt(5)) / 2", Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|     SQRT2: ["M_SQRT2", Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|     SQRT1_2: ["M_SQRT1_2", Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|     INFINITY: ["INFINITY", Blockly.Arduino.ORDER_ATOMIC], | ||||
|   }; | ||||
|   return CONSTANTS[block.getFieldValue("CONSTANT")]; | ||||
| Blockly.Arduino['math_constant'] = function (block) { | ||||
|     var CONSTANTS = { | ||||
|         'PI': ['M_PI', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'E': ['M_E', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|         'SQRT2': ['M_SQRT2', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'SQRT1_2': ['M_SQRT1_2', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'INFINITY': ['INFINITY', Blockly.Arduino.ORDER_ATOMIC] | ||||
|     }; | ||||
|     return CONSTANTS[block.getFieldValue('CONSTANT')]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -192,72 +180,63 @@ Blockly.Arduino["math_constant"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_number_property"] = function (block) { | ||||
|   var number_to_check = | ||||
|     Blockly.Arduino.valueToCode( | ||||
|       block, | ||||
|       "NUMBER_TO_CHECK", | ||||
|       Blockly.Arduino.ORDER_MULTIPLICATIVE | ||||
|     ) || "0"; | ||||
|   var dropdown_property = block.getFieldValue("PROPERTY"); | ||||
|   var code; | ||||
|   if (dropdown_property === "PRIME") { | ||||
|     var func = [ | ||||
|       "boolean " + Blockly.Arduino.DEF_FUNC_NAME + "(int n) {", | ||||
|       "  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods", | ||||
|       "  if (n == 2 || n == 3) {", | ||||
|       "    return true;", | ||||
|       "  }", | ||||
|       "  // False if n is NaN, negative, is 1.", | ||||
|       "  // And false if n is divisible by 2 or 3.", | ||||
|       "  if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || " + | ||||
|         "(n % 3 == 0)) {", | ||||
|       "    return false;", | ||||
|       "  }", | ||||
|       "  // Check all the numbers of form 6k +/- 1, up to sqrt(n).", | ||||
|       "  for (int x = 6; x <= sqrt(n) + 1; x += 6) {", | ||||
|       "    if (n % (x - 1) == 0 || n % (x + 1) == 0) {", | ||||
|       "      return false;", | ||||
|       "    }", | ||||
|       "  }", | ||||
|       "  return true;", | ||||
|       "}", | ||||
|     ]; | ||||
|     var funcName = Blockly.Arduino.addFunction("mathIsPrime", func.join("\n")); | ||||
|     Blockly.Arduino.addInclude("math", "#include <math.h>"); | ||||
|     code = funcName + "(" + number_to_check + ")"; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|   } | ||||
|   switch (dropdown_property) { | ||||
|     case "EVEN": | ||||
|       code = number_to_check + " % 2 == 0"; | ||||
|       break; | ||||
|     case "ODD": | ||||
|       code = number_to_check + " % 2 == 1"; | ||||
|       break; | ||||
|     case "WHOLE": | ||||
|       Blockly.Arduino.addInclude("math", "#include <math.h>"); | ||||
|       code = "(floor(" + number_to_check + ") == " + number_to_check + ")"; | ||||
|       break; | ||||
|     case "POSITIVE": | ||||
|       code = number_to_check + " > 0"; | ||||
|       break; | ||||
|     case "NEGATIVE": | ||||
|       code = number_to_check + " < 0"; | ||||
|       break; | ||||
|     case "DIVISIBLE_BY": | ||||
|       var divisor = | ||||
|         Blockly.Arduino.valueToCode( | ||||
|           block, | ||||
|           "DIVISOR", | ||||
|           Blockly.Arduino.ORDER_MULTIPLICATIVE | ||||
|         ) || "0"; | ||||
|       code = number_to_check + " % " + divisor + " == 0"; | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
|   return [code, Blockly.Arduino.ORDER_EQUALITY]; | ||||
| Blockly.Arduino['math_number_property'] = function (block) { | ||||
|     var number_to_check = Blockly.Arduino.valueToCode(block, 'NUMBER_TO_CHECK', | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     var dropdown_property = block.getFieldValue('PROPERTY'); | ||||
|     var code; | ||||
|     if (dropdown_property === 'PRIME') { | ||||
|         var func = [ | ||||
|             'boolean ' + Blockly.Arduino.DEF_FUNC_NAME + '(int n) {', | ||||
|             '  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods', | ||||
|             '  if (n == 2 || n == 3) {', | ||||
|             '    return true;', | ||||
|             '  }', | ||||
|             '  // False if n is NaN, negative, is 1.', | ||||
|             '  // And false if n is divisible by 2 or 3.', | ||||
|             '  if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || ' + | ||||
|             '(n % 3 == 0)) {', | ||||
|             '    return false;', | ||||
|             '  }', | ||||
|             '  // Check all the numbers of form 6k +/- 1, up to sqrt(n).', | ||||
|             '  for (int x = 6; x <= sqrt(n) + 1; x += 6) {', | ||||
|             '    if (n % (x - 1) == 0 || n % (x + 1) == 0) {', | ||||
|             '      return false;', | ||||
|             '    }', | ||||
|             '  }', | ||||
|             '  return true;', | ||||
|             '}']; | ||||
|         var funcName = Blockly.Arduino.addFunction('mathIsPrime', func.join('\n')); | ||||
|         Blockly.Arduino.addInclude('math', '#include <math.h>'); | ||||
|         code = funcName + '(' + number_to_check + ')'; | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|     } | ||||
|     switch (dropdown_property) { | ||||
|         case 'EVEN': | ||||
|             code = number_to_check + ' % 2 == 0'; | ||||
|             break; | ||||
|         case 'ODD': | ||||
|             code = number_to_check + ' % 2 == 1'; | ||||
|             break; | ||||
|         case 'WHOLE': | ||||
|             Blockly.Arduino.addInclude('math', '#include <math.h>'); | ||||
|             code = '(floor(' + number_to_check + ') == ' + number_to_check + ')'; | ||||
|             break; | ||||
|         case 'POSITIVE': | ||||
|             code = number_to_check + ' > 0'; | ||||
|             break; | ||||
|         case 'NEGATIVE': | ||||
|             code = number_to_check + ' < 0'; | ||||
|             break; | ||||
|         case 'DIVISIBLE_BY': | ||||
|             var divisor = Blockly.Arduino.valueToCode(block, 'DIVISOR', | ||||
|                 Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|             code = number_to_check + ' % ' + divisor + ' == 0'; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_EQUALITY]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -268,30 +247,19 @@ Blockly.Arduino["math_number_property"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_change"] = function (block) { | ||||
|   var argument0 = | ||||
|     Blockly.Arduino.valueToCode( | ||||
|       block, | ||||
|       "DELTA", | ||||
|       Blockly.Arduino.ORDER_ADDITIVE | ||||
|     ) || "0"; | ||||
|   var id = block.getFieldValue("VAR") | ||||
|   const varName = Blockly.Variables.getVariable( | ||||
|       Blockly.getMainWorkspace(), | ||||
|       id | ||||
|     ).name; | ||||
|   // var varName = Blockly.Arduino.nameDB_.getName(
 | ||||
|   //   block.getFieldValue("VAR"),
 | ||||
|   //   Blockly.Variables.NAME_TYPE
 | ||||
|   // );
 | ||||
|   return varName + " += " + argument0 + ";\n"; | ||||
| Blockly.Arduino['math_change'] = function (block) { | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'DELTA', | ||||
|         Blockly.Arduino.ORDER_ADDITIVE) || '0'; | ||||
|     var varName = Blockly.Arduino.variableDB_.getName( | ||||
|         block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); | ||||
|     return varName + ' += ' + argument0 + ';\n'; | ||||
| }; | ||||
| 
 | ||||
| /** Rounding functions have a single operand. */ | ||||
| Blockly.Arduino["math_round"] = Blockly.Arduino["math_single"]; | ||||
| Blockly.Arduino['math_round'] = Blockly.Arduino['math_single']; | ||||
| 
 | ||||
| /** Trigonometry functions have a single operand. */ | ||||
| Blockly.Arduino["math_trig"] = Blockly.Arduino["math_single"]; | ||||
| Blockly.Arduino['math_trig'] = Blockly.Arduino['math_single']; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for the math function to a list. | ||||
| @ -300,7 +268,7 @@ Blockly.Arduino["math_trig"] = Blockly.Arduino["math_single"]; | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_on_list"] = Blockly.Arduino.noGeneratorCodeInline; | ||||
| Blockly.Arduino['math_on_list'] = Blockly.Arduino.noGeneratorCodeInline; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for the math modulo function (calculates remainder of X/Y). | ||||
| @ -308,21 +276,13 @@ Blockly.Arduino["math_on_list"] = Blockly.Arduino.noGeneratorCodeInline; | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_modulo"] = function (block) { | ||||
|   var argument0 = | ||||
|     Blockly.Arduino.valueToCode( | ||||
|       block, | ||||
|       "DIVIDEND", | ||||
|       Blockly.Arduino.ORDER_MULTIPLICATIVE | ||||
|     ) || "0"; | ||||
|   var argument1 = | ||||
|     Blockly.Arduino.valueToCode( | ||||
|       block, | ||||
|       "DIVISOR", | ||||
|       Blockly.Arduino.ORDER_MULTIPLICATIVE | ||||
|     ) || "0"; | ||||
|   var code = argument0 + " % " + argument1; | ||||
|   return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||
| Blockly.Arduino['math_modulo'] = function (block) { | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'DIVIDEND', | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'DIVISOR', | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     var code = argument0 + ' % ' + argument1; | ||||
|     return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -331,34 +291,18 @@ Blockly.Arduino["math_modulo"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_constrain"] = function (block) { | ||||
|   // Constrain a number between two limits.
 | ||||
|   var argument0 = | ||||
|     Blockly.Arduino.valueToCode(block, "VALUE", Blockly.Arduino.ORDER_NONE) || | ||||
|     "0"; | ||||
|   var argument1 = | ||||
|     Blockly.Arduino.valueToCode(block, "LOW", Blockly.Arduino.ORDER_NONE) || | ||||
|     "0"; | ||||
|   var argument2 = | ||||
|     Blockly.Arduino.valueToCode(block, "HIGH", Blockly.Arduino.ORDER_NONE) || | ||||
|     "0"; | ||||
|   var code = | ||||
|     "(" + | ||||
|     argument0 + | ||||
|     " < " + | ||||
|     argument1 + | ||||
|     " ? " + | ||||
|     argument1 + | ||||
|     " : ( " + | ||||
|     argument0 + | ||||
|     " > " + | ||||
|     argument2 + | ||||
|     " ? " + | ||||
|     argument2 + | ||||
|     " : " + | ||||
|     argument0 + | ||||
|     "))"; | ||||
|   return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| Blockly.Arduino['math_constrain'] = function (block) { | ||||
|     // Constrain a number between two limits.
 | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'VALUE', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'LOW', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var argument2 = Blockly.Arduino.valueToCode(block, 'HIGH', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var code = '(' + argument0 + ' < ' + argument1 + ' ? ' + argument1 + | ||||
|         ' : ( ' + argument0 + ' > ' + argument2 + ' ? ' + argument2 + ' : ' + | ||||
|         argument0 + '))'; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -368,26 +312,28 @@ Blockly.Arduino["math_constrain"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino["math_random_int"] = function (block) { | ||||
|   var argument0 = | ||||
|     Blockly.Arduino.valueToCode(block, "FROM", Blockly.Arduino.ORDER_NONE) || | ||||
|     "0"; | ||||
|   var argument1 = | ||||
|     Blockly.Arduino.valueToCode(block, "TO", Blockly.Arduino.ORDER_NONE) || "0"; | ||||
|   Blockly.Arduino.setupCode_["init_rand"] = "randomSeed(analogRead(0));"; | ||||
|   Blockly.Arduino.functionNames_[ | ||||
|     "math_random_int" | ||||
|   ] = `int mathRandomInt (int min, int max) {\n | ||||
|       if (min > max) { | ||||
|         int temp = min; | ||||
|         min = max; | ||||
|         max = temp; | ||||
|       } | ||||
|       return min + (rand() % (max - min + 1)); | ||||
|     } | ||||
|     `;
 | ||||
|   var code = `mathRandomInt(${argument0},${argument1});`; | ||||
|   return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| Blockly.Arduino['math_random_int'] = function (block) { | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'FROM', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'TO', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var functionName = Blockly.Arduino.variableDB_.getDistinctName( | ||||
|         'math_random_int', Blockly.Generator.NAME_TYPE); | ||||
|     Blockly.Arduino.setups_['init_rand'] = 'randomSeed(analogRead(0));'; | ||||
|     Blockly.Arduino.math_random_int.random_function = functionName; | ||||
|     var func = [ | ||||
|         'int ' + Blockly.Arduino.DEF_FUNC_NAME + '(int min, int max) {', | ||||
|         '  if (min > max) {', | ||||
|         '    // Swap min and max to ensure min is smaller.', | ||||
|         '    int temp = min;', | ||||
|         '    min = max;', | ||||
|         '    max = temp;', | ||||
|         '  }', | ||||
|         '  return min + (rand() % (max - min + 1));', | ||||
|         '}']; | ||||
|     var funcName = Blockly.Arduino.addFunction('mathRandomInt', func.join('\n')); | ||||
|     var code = funcName + '(' + argument0 + ', ' + argument1 + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
| @ -396,6 +342,6 @@ Blockly.Arduino["math_random_int"] = function (block) { | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino["math_random_float"] = function (block) { | ||||
|   return ["(rand() / RAND_MAX)", Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| Blockly.Arduino['math_random_float'] = function (block) { | ||||
|     return ['(rand() / RAND_MAX)', Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| }; | ||||
|  | ||||