Compare commits
	
		
			1 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 1e95d57139 | 
							
								
								
									
										6
									
								
								.env
									
									
									
									
									
								
							
							
						
						| @ -1,8 +1,2 @@ | |||||||
| REACT_APP_COMPILER_URL=https://compiler.sensebox.de | REACT_APP_COMPILER_URL=https://compiler.sensebox.de | ||||||
| REACT_APP_BOARD=sensebox-mcu | 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-debug.log* | ||||||
| yarn-error.log* | yarn-error.log* | ||||||
| package-lock.json | 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 | # 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). | 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 | ## 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 | 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 install`` | ||||||
|     * run ``npm start`` |     * run ``npm start`` | ||||||
| 4. open  [localhost:3000](http://localhost:3000) | 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/). | 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 | ## 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", |   "name": "blockly-react", | ||||||
|   "version": "1.0.0", |   "version": "0.1.0", | ||||||
|   "private": true, |   "private": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@blockly/block-plus-minus": "^4.0.4", |     "@blockly/block-plus-minus": "^2.0.10", | ||||||
|     "@blockly/field-grid-dropdown": "^2.0.4", |     "@blockly/field-slider": "^2.1.1", | ||||||
|     "@blockly/field-slider": "4.0.4", |     "@blockly/plugin-typed-variable-modal": "^3.1.1", | ||||||
|     "@blockly/plugin-scroll-options": "^3.0.5", |     "@fortawesome/fontawesome-svg-core": "^1.2.30", | ||||||
|     "@blockly/plugin-typed-variable-modal": "^5.0.6", |     "@fortawesome/free-solid-svg-icons": "^5.14.0", | ||||||
|     "@blockly/workspace-backpack": "^3.0.4", |     "@fortawesome/react-fontawesome": "^0.1.11", | ||||||
|     "@blockly/zoom-to-fit": "^3.0.4", |     "@material-ui/core": "^4.11.0", | ||||||
|     "@emotion/react": "^11.10.5", |     "@testing-library/jest-dom": "^4.2.4", | ||||||
|     "@emotion/styled": "^11.10.5", |     "@testing-library/react": "^9.5.0", | ||||||
|     "@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", |  | ||||||
|     "@testing-library/user-event": "^7.2.1", |     "@testing-library/user-event": "^7.2.1", | ||||||
|     "axios": "^0.22.0", |     "blockly": "^3.20200924.0", | ||||||
|     "blockly": "^9.2.0", |     "file-saver": "^2.0.2", | ||||||
|     "file-saver": "^2.0.5", |     "moment": "^2.28.0", | ||||||
|     "markdown-it": "^12.3.2", |     "prismjs": "^1.20.0", | ||||||
|     "mnemonic-id": "^3.2.7", |     "react": "^16.13.1", | ||||||
|     "moment": "^2.29.4", |     "react-dom": "^16.13.1", | ||||||
|     "prismjs": "^1.27.0", |     "react-redux": "^7.2.0", | ||||||
|     "qrcode.react": "^3.1.0", |     "react-router-dom": "^5.2.0", | ||||||
|     "react": "^17.0.2", |     "react-scripts": "3.4.1", | ||||||
|     "react-cookie-consent": "^7.2.1", |     "redux": "^4.0.5", | ||||||
|     "react-dom": "^17.0.2", |     "redux-thunk": "^2.3.0" | ||||||
|     "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" |  | ||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start": "node_modules/react-scripts/bin/react-scripts.js start", |     "start": "react-scripts start", | ||||||
|     "dev": "set \"REACT_APP_BLOCKLY_API=http://localhost:8080\" && npm start", |  | ||||||
|     "build": "react-scripts build", |     "build": "react-scripts build", | ||||||
|     "test": "react-scripts test", |     "test": "react-scripts test", | ||||||
|     "eject": "react-scripts eject" |     "eject": "react-scripts eject" | ||||||
| @ -66,12 +34,16 @@ | |||||||
|   "eslintConfig": { |   "eslintConfig": { | ||||||
|     "extends": "react-app" |     "extends": "react-app" | ||||||
|   }, |   }, | ||||||
|   "browserslist": [ |   "browserslist": { | ||||||
|     ">0.2%", |     "production": [ | ||||||
|     "not dead", |       ">0.2%", | ||||||
|     "not op_mini all" |       "not dead", | ||||||
|   ], |       "not op_mini all" | ||||||
|   "devDependencies": { |     ], | ||||||
|     "@babel/plugin-proposal-private-property-in-object": "7.21.11" |     "development": [ | ||||||
|  |       "last 1 chrome version", | ||||||
|  |       "last 1 firefox version", | ||||||
|  |       "last 1 safari version" | ||||||
|  |     ] | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -24,13 +24,6 @@ | |||||||
|   </head> |   </head> | ||||||
|   <body> |   <body> | ||||||
|     <noscript>You need to enable JavaScript to run this app.</noscript> |     <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> |     <div id="root"></div> | ||||||
|     <!-- |     <!-- | ||||||
|       This HTML file is a template. |       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 { | .wrapper { | ||||||
|   min-height: calc( |   min-height: calc(100vh - 60px); /* will cover the 100% of viewport - height of footer (padding-bottom) */ | ||||||
|     100vh - 60px |  | ||||||
|   ); /* will cover the 100% of viewport - height of footer (padding-bottom) */ |  | ||||||
|   overflow: hidden; |   overflow: hidden; | ||||||
|   display: block; |   display: block; | ||||||
|   position: relative; |   position: relative; | ||||||
|   padding-bottom: 60px; /* height of your footer + 30px*/ |   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 { createBrowserHistory } from "history"; | ||||||
| 
 | 
 | ||||||
| import { Provider } from "react-redux"; | import { Provider } from 'react-redux'; | ||||||
| import store from "./store"; | import store from './store'; | ||||||
| import { loadUser } from "./actions/authActions"; |  | ||||||
| 
 | 
 | ||||||
| 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: { |   palette: { | ||||||
|     primary: { |     primary: { | ||||||
|       main: "#4EAF47", |       main: '#4EAF47', | ||||||
|       contrastText: "#ffffff", |       contrastText: '#ffffff' | ||||||
|     }, |     }, | ||||||
|     secondary: { |     secondary: { | ||||||
|       main: "#DDDDDD", |       main: '#DDDDDD' | ||||||
|     }, |     } | ||||||
|     button: { |   } | ||||||
|       compile: "#e27136", |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| class App extends Component { | const customHistory = createBrowserHistory(); | ||||||
|   componentDidMount() { |  | ||||||
|     store.dispatch(loadUser()); |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   render() { | 
 | ||||||
|     const customHistory = createBrowserHistory(); | function App() { | ||||||
|     return ( |   return ( | ||||||
|       <StyledEngineProvider injectFirst> |     <ThemeProvider theme={theme}> | ||||||
|         <ThemeProvider theme={theme}> |       <Provider store={store}> | ||||||
|           <Provider store={store}> |         <Router history={customHistory}> | ||||||
|             <Router history={customHistory}> |           <div className="wrapper"> | ||||||
|               <Content /> |             <Navbar /> | ||||||
|             </Router> |             <Routes /> | ||||||
|           </Provider> |             <Footer /> | ||||||
|         </ThemeProvider> |           </div> | ||||||
|       </StyledEngineProvider> |         </Router> | ||||||
|     ); |       </Provider> | ||||||
|   } |     </ThemeProvider> | ||||||
|  |   ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default App; | 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 { | import { VISIT } from './types'; | ||||||
|   VISIT, | 
 | ||||||
|   LANGUAGE, |  | ||||||
|   RENDERER, |  | ||||||
|   SOUNDS, |  | ||||||
|   STATISTICS, |  | ||||||
|   PLATFORM, |  | ||||||
| } from "./types"; |  | ||||||
| 
 | 
 | ||||||
| export const visitPage = () => (dispatch) => { | export const visitPage = () => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: VISIT, |     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, |  | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -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 { | import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types'; | ||||||
|   TUTORIAL_PROGRESS, |  | ||||||
|   GET_TUTORIAL, |  | ||||||
|   GET_TUTORIALS, |  | ||||||
|   TUTORIAL_SUCCESS, |  | ||||||
|   TUTORIAL_ERROR, |  | ||||||
|   TUTORIAL_CHANGE, |  | ||||||
|   TUTORIAL_XML, |  | ||||||
|   TUTORIAL_STEP, |  | ||||||
| } from "./types"; |  | ||||||
| 
 | 
 | ||||||
| import axios from "axios"; | import tutorials from '../data/tutorials'; | ||||||
| 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, |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| export const tutorialChange = () => (dispatch) => { | export const tutorialChange = () => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: TUTORIAL_CHANGE, |     type: TUTORIAL_CHANGE | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const tutorialCheck = (status, step) => (dispatch, getState) => { | export const tutorialCheck = (status, step) => (dispatch, getState) => { | ||||||
|   var tutorialsStatus = getState().tutorial.status; |   var tutorialsStatus = getState().tutorial.status; | ||||||
|   var id = getState().tutorial.tutorials[0]._id; |   var id = getState().tutorial.currentId; | ||||||
|   var tutorialsStatusIndex = tutorialsStatus.findIndex( |   var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); | ||||||
|     (tutorialStatus) => tutorialStatus._id === id |   var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === step.id); | ||||||
|   ); |  | ||||||
|   var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex( |  | ||||||
|     (task) => task._id === step._id |  | ||||||
|   ); |  | ||||||
|   tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { |   tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { | ||||||
|     ...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex], |     ...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex], | ||||||
|     type: status, |     type: status | ||||||
|   }; |   }; | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: status === "success" ? TUTORIAL_SUCCESS : TUTORIAL_ERROR, |     type: status === 'success' ? TUTORIAL_SUCCESS : TUTORIAL_ERROR, | ||||||
|     payload: tutorialsStatus, |     payload: tutorialsStatus | ||||||
|   }); |   }); | ||||||
|   dispatch(updateStatus(tutorialsStatus)); |  | ||||||
|   dispatch(tutorialChange()); |   dispatch(tutorialChange()); | ||||||
|   dispatch(returnSuccess("", "", "TUTORIAL_CHECK_SUCCESS")); |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const storeTutorialXml = (code) => (dispatch, getState) => { | export const storeTutorialXml = (code) => (dispatch, getState) => { | ||||||
|   var tutorial = getState().tutorial.tutorials[0]; |   var id = getState().tutorial.currentId; | ||||||
|   if (tutorial) { |   if (id !== null) { | ||||||
|     var id = tutorial._id; |  | ||||||
|     var activeStep = getState().tutorial.activeStep; |     var activeStep = getState().tutorial.activeStep; | ||||||
|     var steps = tutorial.steps; |     var steps = tutorials.filter(tutorial => tutorial.id === id)[0].steps; | ||||||
|     if (steps && steps[activeStep].type === "task") { |     if (steps[activeStep].type === 'task') { | ||||||
|       var tutorialsStatus = getState().tutorial.status; |       var tutorialsStatus = getState().tutorial.status; | ||||||
|       var tutorialsStatusIndex = tutorialsStatus.findIndex( |       var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); | ||||||
|         (tutorialStatus) => tutorialStatus._id === id |       var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === steps[activeStep].id); | ||||||
|       ); |  | ||||||
|       var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex( |  | ||||||
|         (task) => task._id === steps[activeStep]._id |  | ||||||
|       ); |  | ||||||
|       tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { |       tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { | ||||||
|         ...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex], |         ...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex], | ||||||
|         xml: code, |         xml: code | ||||||
|       }; |       }; | ||||||
|       dispatch({ |       dispatch({ | ||||||
|         type: TUTORIAL_XML, |         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) => { | export const tutorialStep = (step) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: TUTORIAL_STEP, |     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 { | 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'; | ||||||
|   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 data from "../data/hardware.json"; | import data from '../data/hardware.json'; | ||||||
| 
 | 
 | ||||||
| export const changeTutorialBuilder = () => (dispatch) => { | export const changeTutorialBuilder = () => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_CHANGE, |     type: BUILDER_CHANGE | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const jsonString = (json) => (dispatch) => { | export const jsonString = (json) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: JSON_STRING, |     type: JSON_STRING, | ||||||
|     payload: json, |     payload: json | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const tutorialTitle = (title) => (dispatch) => { | export const tutorialTitle = (title) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_TITLE, |     type: BUILDER_TITLE, | ||||||
|     payload: 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, |  | ||||||
|   }); |   }); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| }; | }; | ||||||
| @ -65,7 +26,7 @@ export const tutorialReview = (review) => (dispatch) => { | |||||||
| export const tutorialSteps = (steps) => (dispatch) => { | export const tutorialSteps = (steps) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ADD_STEP, |     type: BUILDER_ADD_STEP, | ||||||
|     payload: steps, |     payload: steps | ||||||
|   }); |   }); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| }; | }; | ||||||
| @ -73,7 +34,7 @@ export const tutorialSteps = (steps) => (dispatch) => { | |||||||
| export const tutorialId = (id) => (dispatch) => { | export const tutorialId = (id) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ID, |     type: BUILDER_ID, | ||||||
|     payload: id, |     payload: id | ||||||
|   }); |   }); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| }; | }; | ||||||
| @ -82,14 +43,14 @@ export const addStep = (index) => (dispatch, getState) => { | |||||||
|   var steps = getState().builder.steps; |   var steps = getState().builder.steps; | ||||||
|   var step = { |   var step = { | ||||||
|     id: index + 1, |     id: index + 1, | ||||||
|     type: "instruction", |     type: 'instruction', | ||||||
|     headline: "", |     headline: '', | ||||||
|     text: "", |     text: '' | ||||||
|   }; |   }; | ||||||
|   steps.splice(index, 0, step); |   steps.splice(index, 0, step); | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ADD_STEP, |     type: BUILDER_ADD_STEP, | ||||||
|     payload: steps, |     payload: steps | ||||||
|   }); |   }); | ||||||
|   dispatch(addErrorStep(index)); |   dispatch(addErrorStep(index)); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| @ -100,7 +61,7 @@ export const addErrorStep = (index) => (dispatch, getState) => { | |||||||
|   error.steps.splice(index, 0, {}); |   error.steps.splice(index, 0, {}); | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ERROR, |     type: BUILDER_ERROR, | ||||||
|     payload: error, |     payload: error | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -109,7 +70,7 @@ export const removeStep = (index) => (dispatch, getState) => { | |||||||
|   steps.splice(index, 1); |   steps.splice(index, 1); | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_DELETE_STEP, |     type: BUILDER_DELETE_STEP, | ||||||
|     payload: steps, |     payload: steps | ||||||
|   }); |   }); | ||||||
|   dispatch(removeErrorStep(index)); |   dispatch(removeErrorStep(index)); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| @ -120,47 +81,45 @@ export const removeErrorStep = (index) => (dispatch, getState) => { | |||||||
|   error.steps.splice(index, 1); |   error.steps.splice(index, 1); | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ERROR, |     type: BUILDER_ERROR, | ||||||
|     payload: error, |     payload: error | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const changeContent = | export const changeContent = (content, index, property1, property2) => (dispatch, getState) => { | ||||||
|   (content, index, property1, property2) => (dispatch, getState) => { |   var steps = getState().builder.steps; | ||||||
|     var steps = getState().builder.steps; |   var step = steps[index]; | ||||||
|     var step = steps[index]; |   if (property2) { | ||||||
|     if (property2) { |     if (step[property1] && step[property1][property2]) { | ||||||
|       if (step[property1] && step[property1][property2]) { |       step[property1][property2] = content; | ||||||
|         step[property1][property2] = content; |  | ||||||
|       } else { |  | ||||||
|         step[property1] = { [property2]: content }; |  | ||||||
|       } |  | ||||||
|     } else { |     } else { | ||||||
|       step[property1] = content; |       step[property1] = { [property2]: content }; | ||||||
|     } |     } | ||||||
|     dispatch({ |   } else { | ||||||
|       type: BUILDER_CHANGE_STEP, |     step[property1] = content; | ||||||
|       payload: steps, |   } | ||||||
|     }); |   dispatch({ | ||||||
|     dispatch(changeTutorialBuilder()); |     type: BUILDER_CHANGE_STEP, | ||||||
|   }; |     payload: steps | ||||||
|  |   }); | ||||||
|  |   dispatch(changeTutorialBuilder()); | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| export const deleteProperty = | export const deleteProperty = (index, property1, property2) => (dispatch, getState) => { | ||||||
|   (index, property1, property2) => (dispatch, getState) => { |   var steps = getState().builder.steps; | ||||||
|     var steps = getState().builder.steps; |   var step = steps[index]; | ||||||
|     var step = steps[index]; |   if (property2) { | ||||||
|     if (property2) { |     if (step[property1] && step[property1][property2]) { | ||||||
|       if (step[property1] && step[property1][property2]) { |       delete step[property1][property2]; | ||||||
|         delete step[property1][property2]; |  | ||||||
|       } |  | ||||||
|     } else { |  | ||||||
|       delete step[property1]; |  | ||||||
|     } |     } | ||||||
|     dispatch({ |   } else { | ||||||
|       type: BUILDER_DELETE_PROPERTY, |     delete step[property1]; | ||||||
|       payload: steps, |   } | ||||||
|     }); |   dispatch({ | ||||||
|     dispatch(changeTutorialBuilder()); |     type: BUILDER_DELETE_PROPERTY, | ||||||
|   }; |     payload: steps | ||||||
|  |   }); | ||||||
|  |   dispatch(changeTutorialBuilder()); | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| export const changeStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | export const changeStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | ||||||
|   var steps = getState().builder.steps; |   var steps = getState().builder.steps; | ||||||
| @ -169,34 +128,34 @@ export const changeStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | |||||||
|   steps.splice(toIndex, 0, step); |   steps.splice(toIndex, 0, step); | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_CHANGE_ORDER, |     type: BUILDER_CHANGE_ORDER, | ||||||
|     payload: steps, |     payload: steps | ||||||
|   }); |   }); | ||||||
|   dispatch(changeErrorStepIndex(fromIndex, toIndex)); |   dispatch(changeErrorStepIndex(fromIndex, toIndex)); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const changeErrorStepIndex = | export const changeErrorStepIndex = (fromIndex, toIndex) => (dispatch, getState) => { | ||||||
|   (fromIndex, toIndex) => (dispatch, getState) => { |   var error = getState().builder.error; | ||||||
|     var error = getState().builder.error; |   var errorStep = error.steps[fromIndex]; | ||||||
|     var errorStep = error.steps[fromIndex]; |   error.steps.splice(fromIndex, 1); | ||||||
|     error.steps.splice(fromIndex, 1); |   error.steps.splice(toIndex, 0, errorStep); | ||||||
|     error.steps.splice(toIndex, 0, errorStep); |   dispatch({ | ||||||
|     dispatch({ |     type: BUILDER_ERROR, | ||||||
|       type: BUILDER_ERROR, |     payload: error | ||||||
|       payload: error, |   }); | ||||||
|     }); | }; | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
| export const setError = (index, property) => (dispatch, getState) => { | export const setError = (index, property) => (dispatch, getState) => { | ||||||
|   var error = getState().builder.error; |   var error = getState().builder.error; | ||||||
|   if (index !== undefined) { |   if (index !== undefined) { | ||||||
|     error.steps[index][property] = true; |     error.steps[index][property] = true; | ||||||
|   } else { |   } | ||||||
|  |   else { | ||||||
|     error[property] = true; |     error[property] = true; | ||||||
|   } |   } | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ERROR, |     type: BUILDER_ERROR, | ||||||
|     payload: error, |     payload: error | ||||||
|   }); |   }); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| }; | }; | ||||||
| @ -205,12 +164,13 @@ export const deleteError = (index, property) => (dispatch, getState) => { | |||||||
|   var error = getState().builder.error; |   var error = getState().builder.error; | ||||||
|   if (index !== undefined) { |   if (index !== undefined) { | ||||||
|     delete error.steps[index][property]; |     delete error.steps[index][property]; | ||||||
|   } else { |   } | ||||||
|  |   else { | ||||||
|     delete error[property]; |     delete error[property]; | ||||||
|   } |   } | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ERROR, |     type: BUILDER_ERROR, | ||||||
|     payload: error, |     payload: error | ||||||
|   }); |   }); | ||||||
|   dispatch(changeTutorialBuilder()); |   dispatch(changeTutorialBuilder()); | ||||||
| }; | }; | ||||||
| @ -220,11 +180,8 @@ export const setSubmitError = () => (dispatch, getState) => { | |||||||
|   // if(builder.id === undefined || builder.id === ''){
 |   // if(builder.id === undefined || builder.id === ''){
 | ||||||
|   //   dispatch(setError(undefined, 'id'));
 |   //   dispatch(setError(undefined, 'id'));
 | ||||||
|   // }
 |   // }
 | ||||||
|   if (builder.title === "") { |   if (builder.id === undefined || builder.title === '') { | ||||||
|     dispatch(setError(undefined, "title")); |     dispatch(setError(undefined, 'title')); | ||||||
|   } |  | ||||||
|   if (builder.title === null) { |  | ||||||
|     dispatch(setError(undefined, "title")); |  | ||||||
|   } |   } | ||||||
|   var type = builder.steps.map((step, i) => { |   var type = builder.steps.map((step, i) => { | ||||||
|     // media and xml are directly checked for errors in their components and
 |     // 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; |     step.id = i + 1; | ||||||
|     if (i === 0) { |     if (i === 0) { | ||||||
|       if (step.requirements && step.requirements.length > 0) { |       if (step.requirements && step.requirements.length > 0) { | ||||||
|         var requirements = step.requirements.filter((requirement) => |         var requirements = step.requirements.filter(requirement => typeof (requirement) === 'number'); | ||||||
|           /^[0-9a-fA-F]{24}$/.test(requirement) |  | ||||||
|         ); |  | ||||||
|         if (requirements.length < step.requirements.length) { |         if (requirements.length < step.requirements.length) { | ||||||
|           dispatch(changeContent(requirements, i, "requirements")); |           dispatch(changeContent(requirements, i, 'requirements')); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       if (step.hardware === undefined || step.hardware.length < 1) { |       if (step.hardware === undefined || step.hardware.length < 1) { | ||||||
|         dispatch(setError(i, "hardware")); |         dispatch(setError(i, 'hardware')); | ||||||
|       } else { |       } | ||||||
|         var hardwareIds = data.map((hardware) => hardware.id); |       else { | ||||||
|         var hardware = step.hardware.filter((hardware) => |         var hardwareIds = data.map(hardware => hardware.id); | ||||||
|           hardwareIds.includes(hardware) |         var hardware = step.hardware.filter(hardware => hardwareIds.includes(hardware)); | ||||||
|         ); |  | ||||||
|         if (hardware.length < step.hardware.length) { |         if (hardware.length < step.hardware.length) { | ||||||
|           dispatch(changeContent(hardware, i, "hardware")); |           dispatch(changeContent(hardware, i, 'hardware')); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     if (step.headline === undefined || step.headline === "") { |     if (step.headline === undefined || step.headline === '') { | ||||||
|       dispatch(setError(i, "headline")); |       dispatch(setError(i, 'headline')); | ||||||
|     } |     } | ||||||
|     if (step.text === undefined || step.text === "") { |     if (step.text === undefined || step.text === '') { | ||||||
|       dispatch(setError(i, "text")); |       dispatch(setError(i, 'text')); | ||||||
|     } |     } | ||||||
|     return step.type; |     return step.type; | ||||||
|   }); |   }); | ||||||
|   if ( |   if (!(type.filter(item => item === 'task').length > 0 && type.filter(item => item === 'instruction').length > 0)) { | ||||||
|     !( |     dispatch(setError(undefined, 'type')); | ||||||
|       type.filter((item) => item === "task").length > 0 && |  | ||||||
|       type.filter((item) => item === "instruction").length > 0 |  | ||||||
|     ) |  | ||||||
|   ) { |  | ||||||
|     dispatch(setError(undefined, "type")); |  | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| export const checkError = () => (dispatch, getState) => { | export const checkError = () => (dispatch, getState) => { | ||||||
|   dispatch(setSubmitError()); |   dispatch(setSubmitError()); | ||||||
|   var error = getState().builder.error; |   var error = getState().builder.error; | ||||||
| @ -277,37 +227,39 @@ export const checkError = () => (dispatch, getState) => { | |||||||
|   } |   } | ||||||
|   for (var i = 0; i < error.steps.length; i++) { |   for (var i = 0; i < error.steps.length; i++) { | ||||||
|     if (Object.keys(error.steps[i]).length > 0) { |     if (Object.keys(error.steps[i]).length > 0) { | ||||||
|       return true; |       return true | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   return false; |   return false; | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| export const progress = (inProgress) => (dispatch) => { | export const progress = (inProgress) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: PROGRESS, |     type: PROGRESS, | ||||||
|     payload: inProgress, |     payload: inProgress | ||||||
|   }); |   }) | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const resetTutorial = () => (dispatch, getState) => { | export const resetTutorial = () => (dispatch, getState) => { | ||||||
|   dispatch(jsonString("")); |   dispatch(jsonString('')); | ||||||
|   dispatch(tutorialTitle("")); |   dispatch(tutorialTitle('')); | ||||||
|  |   dispatch(tutorialId('')); | ||||||
|   var steps = [ |   var steps = [ | ||||||
|     { |     { | ||||||
|       type: "instruction", |       id: 1, | ||||||
|       headline: "", |       type: 'instruction', | ||||||
|       text: "", |       headline: '', | ||||||
|  |       text: '', | ||||||
|       hardware: [], |       hardware: [], | ||||||
|       requirements: [], |       requirements: [] | ||||||
|     }, |     } | ||||||
|   ]; |   ]; | ||||||
|   dispatch(tutorialSteps(steps)); |   dispatch(tutorialSteps(steps)); | ||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ERROR, |     type: BUILDER_ERROR, | ||||||
|     payload: { |     payload: { | ||||||
|       steps: [{}], |       steps: [{}] | ||||||
|     }, |     } | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -316,18 +268,16 @@ export const readJSON = (json) => (dispatch, getState) => { | |||||||
|   dispatch({ |   dispatch({ | ||||||
|     type: BUILDER_ERROR, |     type: BUILDER_ERROR, | ||||||
|     payload: { |     payload: { | ||||||
|       steps: json.steps.map(() => { |       steps: json.steps.map(() => { return {}; }) | ||||||
|         return {}; |     } | ||||||
|       }), |  | ||||||
|     }, |  | ||||||
|   }); |   }); | ||||||
|   // accept only valid attributes
 |   // accept only valid attributes
 | ||||||
|   var steps = json.steps.map((step, i) => { |   var steps = json.steps.map((step, i) => { | ||||||
|     var object = { |     var object = { | ||||||
|       _id: step._id, |       id: step.id, | ||||||
|       type: step.type, |       type: step.type, | ||||||
|       headline: step.headline, |       headline: step.headline, | ||||||
|       text: step.text, |       text: step.text | ||||||
|     }; |     }; | ||||||
|     if (i === 0) { |     if (i === 0) { | ||||||
|       object.hardware = step.hardware; |       object.hardware = step.hardware; | ||||||
| @ -336,18 +286,19 @@ export const readJSON = (json) => (dispatch, getState) => { | |||||||
|     if (step.xml) { |     if (step.xml) { | ||||||
|       object.xml = step.xml; |       object.xml = step.xml; | ||||||
|     } |     } | ||||||
|     if (step.media && step.type === "instruction") { |     if (step.media && step.type === 'instruction') { | ||||||
|       object.media = {}; |       object.media = {}; | ||||||
|       if (step.media.picture) { |       if (step.media.picture) { | ||||||
|         object.media.picture = 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; |         object.media.youtube = step.media.youtube; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return object; |     return object; | ||||||
|   }); |   }); | ||||||
|   dispatch(tutorialTitle(json.title)); |   dispatch(tutorialTitle(json.title)); | ||||||
|   dispatch(tutorialDifficulty(json.difficulty)); |   dispatch(tutorialId(json.id)); | ||||||
|   dispatch(tutorialSteps(steps)); |   dispatch(tutorialSteps(steps)); | ||||||
|   dispatch(setSubmitError()); |   dispatch(setSubmitError()); | ||||||
|   dispatch(progress(false)); |   dispatch(progress(false)); | ||||||
|  | |||||||
| @ -1,68 +1,32 @@ | |||||||
| // authentication
 | export const NEW_CODE = 'NEW_CODE'; | ||||||
| export const USER_LOADING = "USER_LOADING"; | export const CHANGE_WORKSPACE = 'CHANGE_WORKSPACE'; | ||||||
| export const USER_LOADED = "USER_LOADED"; | export const CREATE_BLOCK = 'CREATE_BLOCK'; | ||||||
| export const AUTH_ERROR = "AUTH_ERROR"; | export const MOVE_BLOCK = 'MOVE_BLOCK'; | ||||||
| export const LOGIN_SUCCESS = "LOGIN_SUCCESS"; | export const CHANGE_BLOCK = 'CHANGE_BLOCK'; | ||||||
| export const LOGIN_FAIL = "LOGIN_FAIL"; | export const DELETE_BLOCK = 'DELETE_BLOCK'; | ||||||
| export const LOGOUT_SUCCESS = "LOGOUT_SUCCESS"; | export const CLEAR_STATS = 'CLEAR_STATS'; | ||||||
| export const LOGOUT_FAIL = "LOGOUT_FAIL"; | export const NAME = 'NAME'; | ||||||
| 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 TUTORIAL_PROGRESS = "TUTORIAL_PROGRESS"; | export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS'; | ||||||
| export const GET_TUTORIAL = "GET_TUTORIAL"; | export const TUTORIAL_ERROR = 'TUTORIAL_ERROR'; | ||||||
| export const GET_TUTORIALS = "GET_TUTORIALS"; | export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE'; | ||||||
| export const GET_USERTUTORIALS = "GET_USERTUTORIALS"; | export const TUTORIAL_XML = 'TUTORIAL_XML'; | ||||||
| export const GET_STATUS = "GET_STATUS"; | export const TUTORIAL_ID = 'TUTORIAL_ID'; | ||||||
| export const TUTORIAL_SUCCESS = "TUTORIAL_SUCCESS"; | export const TUTORIAL_STEP = 'TUTORIAL_STEP'; | ||||||
| export const TUTORIAL_ERROR = "TUTORIAL_ERROR"; | export const JSON_STRING = 'JSON_STRING'; | ||||||
| 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 BUILDER_CHANGE = 'BUILDER_CHANGE'; | ||||||
| export const LANGUAGE = "LANGUAGE"; | export const BUILDER_TITLE = 'BUILDER_TITLE'; | ||||||
| export const PLATFORM = "PLATFORM"; | export const BUILDER_ID = 'BUILDER_ID'; | ||||||
| export const RENDERER = "RENDERER"; | export const BUILDER_ADD_STEP = 'BUILDER_ADD_STEP'; | ||||||
| export const SOUNDS = "SOUNDS"; | export const BUILDER_DELETE_STEP = 'BUILDER_DELETE_STEP'; | ||||||
| export const STATISTICS = "STATISTICS"; | 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 VISIT = 'VISIT'; | ||||||
| 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"; |  | ||||||
|  | |||||||
| @ -16,22 +16,6 @@ export const onChangeCode = () => (dispatch, getState) => { | |||||||
|   code.arduino = Blockly.Arduino.workspaceToCode(workspace); |   code.arduino = Blockly.Arduino.workspaceToCode(workspace); | ||||||
|   var xmlDom = Blockly.Xml.workspaceToDom(workspace); |   var xmlDom = Blockly.Xml.workspaceToDom(workspace); | ||||||
|   code.xml = Blockly.Xml.domToPrettyText(xmlDom); |   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({ |   dispatch({ | ||||||
|     type: NEW_CODE, |     type: NEW_CODE, | ||||||
|     payload: 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) |  * @author samelh@google.com (Sam El-Husseini) | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import React from "react"; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import Blockly from "blockly/core"; | import Blockly from 'blockly/core'; | ||||||
| import "blockly/blocks"; | import locale from 'blockly/msg/en'; | ||||||
| import Toolbox from "./toolbox/Toolbox"; | import 'blockly/blocks'; | ||||||
|  | import Toolbox from './toolbox/Toolbox'; | ||||||
| 
 | 
 | ||||||
| import { Card } from "@mui/material"; | import { Card } from '@material-ui/core'; | ||||||
| import { | 
 | ||||||
|   ScrollOptions, | 
 | ||||||
|   ScrollBlockDragger, | Blockly.setLocale(locale); | ||||||
|   ScrollMetricsManager, |  | ||||||
| } from "@blockly/plugin-scroll-options"; |  | ||||||
| 
 | 
 | ||||||
| class BlocklyComponent extends React.Component { | class BlocklyComponent extends React.Component { | ||||||
|   constructor(props) { |      | ||||||
|     super(props); |     constructor(props) { | ||||||
|     this.blocklyDiv = React.createRef(); |         super(props); | ||||||
|     this.toolbox = React.createRef(); |         this.blocklyDiv = React.createRef(); | ||||||
|     this.state = { workspace: undefined }; |         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 |  | ||||||
|       ); |  | ||||||
|     } |     } | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   get workspace() { |     componentDidMount() { | ||||||
|     return this.primaryWorkspace; |         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) { |         if (initialXml) { | ||||||
|     Blockly.Xml.domToWorkspace( |             Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), this.primaryWorkspace); | ||||||
|       Blockly.Xml.textToDom(xml), |         } | ||||||
|       this.primaryWorkspace |     } | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   render() { |     get workspace() { | ||||||
|     return ( |         return this.primaryWorkspace; | ||||||
|       <React.Fragment> |     } | ||||||
|         <Card | 
 | ||||||
|           ref={this.blocklyDiv} |     setXml(xml) { | ||||||
|           id="blocklyDiv" |         Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), this.primaryWorkspace); | ||||||
|           style={this.props.style ? this.props.style : {}} |     } | ||||||
|         /> | 
 | ||||||
|         <Toolbox toolbox={this.toolbox} workspace={this.state.workspace} /> |     render() { | ||||||
|       </React.Fragment> |         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; | 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 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 bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox(); | ||||||
|       var content = new XMLSerializer().serializeToString(canvas); |       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"
 |       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}"> |                   width="${bbox.width}" height="${bbox.height}" viewBox="${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}"> | ||||||
|                   ${css}">${content}</svg>`; |                   ${css}">${content}</svg>`; | ||||||
| @ -64,7 +65,7 @@ class BlocklySvg extends Component { | |||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div |       <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 }} |         dangerouslySetInnerHTML={{ __html: this.state.svg }} | ||||||
|       /> |       /> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -1,23 +1,24 @@ | |||||||
| import React, { Component } from "react"; | import React, { Component } from 'react'; | ||||||
| import PropTypes from "prop-types"; | import PropTypes from 'prop-types'; | ||||||
| import { connect } from "react-redux"; | import { connect } from 'react-redux'; | ||||||
| import { onChangeWorkspace, clearStats } from "../../actions/workspaceActions"; | 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 { | class BlocklyWindow extends Component { | ||||||
|  | 
 | ||||||
|   constructor(props) { |   constructor(props) { | ||||||
|     super(props); |     super(props); | ||||||
|     this.simpleWorkspace = React.createRef(); |     this.simpleWorkspace = React.createRef(); | ||||||
|  |     Blockly.setLocale(De); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
| @ -26,7 +27,6 @@ class BlocklyWindow extends Component { | |||||||
|     this.props.clearStats(); |     this.props.clearStats(); | ||||||
|     workspace.addChangeListener((event) => { |     workspace.addChangeListener((event) => { | ||||||
|       this.props.onChangeWorkspace(event); |       this.props.onChangeWorkspace(event); | ||||||
| 
 |  | ||||||
|       // switch on that a block is displayed disabled or not depending on whether it is correctly connected
 |       // 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
 |       // for SVG display, a deactivated block in the display is undesirable
 | ||||||
|       if (this.props.blockDisabled) { |       if (this.props.blockDisabled) { | ||||||
| @ -34,26 +34,11 @@ class BlocklyWindow extends Component { | |||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|     Blockly.svgResize(workspace); |     Blockly.svgResize(workspace); | ||||||
|     const zoomToFit = new ZoomToFitControl(workspace); |  | ||||||
|     zoomToFit.init(); |  | ||||||
|     // Initialize plugin.
 |  | ||||||
|     const backpack = new Backpack(workspace); |  | ||||||
|     backpack.init(); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props) { |   componentDidUpdate(props) { | ||||||
|     const workspace = Blockly.getMainWorkspace(); |     const workspace = Blockly.getMainWorkspace(); | ||||||
|     var xml = this.props.initialXml; |     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 svg is true, then the update process is done in the BlocklySvg component
 | ||||||
|     if (props.initialXml !== xml && !this.props.svg) { |     if (props.initialXml !== xml && !this.props.svg) { | ||||||
|       // guarantees that the current xml-code (this.props.initialXml) is rendered
 |       // guarantees that the current xml-code (this.props.initialXml) is rendered
 | ||||||
| @ -61,95 +46,52 @@ class BlocklyWindow extends Component { | |||||||
|       if (!xml) xml = initialXml; |       if (!xml) xml = initialXml; | ||||||
|       Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace); |       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); |     Blockly.svgResize(workspace); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div> | ||||||
|         <BlocklyComponent |         <BlocklyComponent ref={this.simpleWorkspace} | ||||||
|           ref={this.simpleWorkspace} |  | ||||||
|           style={this.props.svg ? { height: 0 } : this.props.blocklyCSS} |           style={this.props.svg ? { height: 0 } : this.props.blocklyCSS} | ||||||
|           readOnly={ |           readOnly={this.props.readOnly !== undefined ? this.props.readOnly : false} | ||||||
|             this.props.readOnly !== undefined ? this.props.readOnly : false |           trashcan={this.props.trashcan !== undefined ? this.props.trashcan : true} | ||||||
|           } |           renderer='geras' | ||||||
|           trashcan={ |           zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom
 | ||||||
|             this.props.trashcan !== undefined ? this.props.trashcan : true |             controls: this.props.zoomControls !== undefined ? this.props.zoomControls : 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, |  | ||||||
|             wheel: false, |             wheel: false, | ||||||
|             startScale: 1, |             startScale: 1, | ||||||
|             maxScale: 3, |             maxScale: 3, | ||||||
|             minScale: 0.3, |             minScale: 0.3, | ||||||
|             scaleSpeed: 1.2, |             scaleSpeed: 1.2 | ||||||
|           }} |           }} | ||||||
|           grid={ |           grid={this.props.grid !== undefined && !this.props.grid ? {} : | ||||||
|             this.props.grid !== undefined && !this.props.grid |             { // https://developers.google.com/blockly/guides/configure/web/grid
 | ||||||
|               ? {} |               spacing: 20, | ||||||
|               : { |               length: 1, | ||||||
|                   // https://developers.google.com/blockly/guides/configure/web/grid
 |               colour: '#4EAF47', // senseBox-green
 | ||||||
|                   spacing: 20, |               snap: false | ||||||
|                   length: 1, |             }} | ||||||
|                   colour: "#4EAF47", // senseBox-green
 |           media={'/media/blockly/'} | ||||||
|                   snap: false, |           move={this.props.move !== undefined && !this.props.move ? {} : | ||||||
|                 } |             { // https://developers.google.com/blockly/guides/configure/web/move
 | ||||||
|           } |               scrollbars: true, | ||||||
|           media={"/media/blockly/"} |               drag: true, | ||||||
|           move={ |               wheel: false | ||||||
|             this.props.move !== undefined && !this.props.move |             }} | ||||||
|               ? {} |           initialXml={this.props.initialXml ? this.props.initialXml : initialXml} | ||||||
|               : { |         > | ||||||
|                   // https://developers.google.com/blockly/guides/configure/web/move
 |         </BlocklyComponent > | ||||||
|                   scrollbars: true, |         {this.props.svg && this.props.initialXml ? <BlocklySvg initialXml={this.props.initialXml} /> : null} | ||||||
|                   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} |  | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   } |   }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BlocklyWindow.propTypes = { | BlocklyWindow.propTypes = { | ||||||
|   onChangeWorkspace: PropTypes.func.isRequired, |   onChangeWorkspace: PropTypes.func.isRequired, | ||||||
|   clearStats: PropTypes.func.isRequired, |   clearStats: PropTypes.func.isRequired | ||||||
|   renderer: PropTypes.string.isRequired, |  | ||||||
|   sounds: PropTypes.bool.isRequired, |  | ||||||
|   language: PropTypes.string.isRequired, |  | ||||||
|   selectedBoard: PropTypes.string.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 })( | export default connect(null, { onChangeWorkspace, clearStats })(BlocklyWindow); | ||||||
|   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 './loops'; | ||||||
| import "./sensebox"; | import './sensebox'; | ||||||
| import "./logic"; | import './logic'; | ||||||
| import "./sensebox-sensors"; | import './sensebox-sensors'; | ||||||
| import "./sensebox-telegram"; | import './sensebox-telegram'; | ||||||
| import "./sensebox-osem"; | import './sensebox-osem'; | ||||||
| import "./sensebox-web"; | import './sensebox-web'; | ||||||
| import "./sensebox-display"; | import './sensebox-display'; | ||||||
| import "./sensebox-motors"; | import './sensebox-lora'; | ||||||
| import "./sensebox-lora"; | import './sensebox-led'; | ||||||
| import "./sensebox-led"; | import './sensebox-sd'; | ||||||
| import "./sensebox-rtc"; | import './text'; | ||||||
| import "./sensebox-ntp"; | import './io'; | ||||||
| import "./sensebox-ble"; | import './audio'; | ||||||
| import "./sensebox-sd"; | import './math'; | ||||||
| import "./mqtt"; | import './map'; | ||||||
| import "./text"; | import './procedures'; | ||||||
| import "./io"; | import './time'; | ||||||
| import "./audio"; | import './variables'; | ||||||
| import "./math"; |  | ||||||
| import "./map"; |  | ||||||
| import "./procedures"; |  | ||||||
| import "./serial"; |  | ||||||
| import "./time"; |  | ||||||
| import "./variables"; |  | ||||||
| import "./lists"; |  | ||||||
| import "./watchdog"; |  | ||||||
| import "./webserver"; |  | ||||||
| import "./CleVerLab" |  | ||||||
| 
 | 
 | ||||||
| import "../helpers/types"; | import '../helpers/types' | ||||||
| @ -10,271 +10,248 @@ | |||||||
|  * |  * | ||||||
|  * TODO: maybe change this to a "PIN" BlocklyType |  * TODO: maybe change this to a "PIN" BlocklyType | ||||||
|  */ |  */ | ||||||
| import Blockly from "blockly/core"; | import Blockly from 'blockly/core'; | ||||||
| import { selectedBoard } from "../helpers/board"; | import { selectedBoard } from '../helpers/board' | ||||||
| import * as Types from "../helpers/types"; | import * as Types from '../helpers/types' | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_digitalwrite"] = { | 
 | ||||||
|   /** | Blockly.Blocks['io_digitalwrite'] = { | ||||||
|    * Block for creating a 'set pin' to a state. |     /** | ||||||
|    * @this Blockly.Block |      * Block for creating a 'set pin' to a state. | ||||||
|    */ |      * @this Blockly.Block | ||||||
|   init: function () { |      */ | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DigitalWrite"); |     init: function () { | ||||||
|     this.setColour(250); |         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite'); | ||||||
|     this.appendValueInput("STATE") |         this.setColour(250); | ||||||
|       .appendField(Blockly.Msg.ARD_DIGITALWRITE) |         this.appendValueInput('STATE') | ||||||
|       .appendField( |             .appendField(Blockly.Msg.ARD_DIGITALWRITE) | ||||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPins), |             .appendField(new Blockly.FieldDropdown( | ||||||
|         "PIN" |                 selectedBoard().digitalPins), 'PIN') | ||||||
|       ) |             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||||
|       .appendField(Blockly.Msg.ARD_WRITE_TO) |             .setCheck(Types.BOOLEAN.checkList); | ||||||
|       .setCheck(Types.BOOLEAN.checkList); |         this.setInputsInline(false); | ||||||
|     this.setInputsInline(false); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |         this.setTooltip(Blockly.Msg.ARD_DIGITALWRITE_TIP); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_DIGITALWRITE_TIP); |     }, | ||||||
|   }, |     /** | ||||||
|   /** |      * Updates the content of the the pin related fields. | ||||||
|    * Updates the content of the the pin related fields. |      * @this Blockly.Block | ||||||
|    * @this Blockly.Block |      */ | ||||||
|    */ |     updateFields: function () { | ||||||
|   updateFields: function () { |         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown( |             this, 'PIN', 'digitalPins'); | ||||||
|       this, |     } | ||||||
|       "PIN", |  | ||||||
|       "digitalPins" |  | ||||||
|     ); |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_digitalread"] = { | Blockly.Blocks['io_digitalread'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for creating a 'read pin'. |      * Block for creating a 'read pin'. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DigitalRead"); |         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalRead'); | ||||||
|     this.setColour(250); |         this.setColour(250); | ||||||
|     this.appendDummyInput() |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.ARD_DIGITALREAD) |             .appendField(Blockly.Msg.ARD_DIGITALREAD) | ||||||
|       .appendField( |             .appendField(new Blockly.FieldDropdown( | ||||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPins), |                 selectedBoard().digitalPins), 'PIN'); | ||||||
|         "PIN" |         this.setOutput(true, 'boolean'); | ||||||
|       ); |         this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP); | ||||||
|     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 {!string} The type of return value for the block, an integer. */ |         return Types.BOOLEAN; | ||||||
|   getBlockType: function () { |     }, | ||||||
|     return Types.BOOLEAN; |     /** | ||||||
|   }, |      * Updates the content of the the pin related fields. | ||||||
|   /** |      * @this Blockly.Block | ||||||
|    * Updates the content of the the pin related fields. |      */ | ||||||
|    * @this Blockly.Block |     updateFields: function () { | ||||||
|    */ |         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||||
|   updateFields: function () { |             this, 'PIN', 'digitalPins'); | ||||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown( |     } | ||||||
|       this, |  | ||||||
|       "PIN", |  | ||||||
|       "digitalPins" |  | ||||||
|     ); |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_builtin_led"] = { | Blockly.Blocks['io_builtin_led'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for setting built-in LED to a state. |      * Block for setting built-in LED to a state. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DigitalWrite"); |         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite'); | ||||||
|     this.setColour(250); |         this.setColour(250); | ||||||
|     this.appendValueInput("STATE") |         this.appendValueInput('STATE') | ||||||
|       .appendField(Blockly.Msg.ARD_BUILTIN_LED) |             .appendField(Blockly.Msg.ARD_BUILTIN_LED) | ||||||
|       .appendField( |             .appendField(new Blockly.FieldDropdown( | ||||||
|         new Blockly.FieldDropdown(selectedBoard().builtinLed), |                 selectedBoard().builtinLed), 'BUILT_IN_LED') | ||||||
|         "BUILT_IN_LED" |             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||||
|       ) |             .setCheck(Types.BOOLEAN.compatibleTypes); | ||||||
|       .appendField(Blockly.Msg.ARD_WRITE_TO) |         this.setInputsInline(false); | ||||||
|       .setCheck(Types.BOOLEAN.compatibleTypes); |         this.setPreviousStatement(true, null); | ||||||
|     this.setInputsInline(false); |         this.setNextStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setTooltip(Blockly.Msg.ARD_BUILTIN_LED_TIP); | ||||||
|     this.setNextStatement(true, null); |     }, | ||||||
|     this.setTooltip(Blockly.Msg.ARD_BUILTIN_LED_TIP); |     /** | ||||||
|   }, |      * Updates the content of the the pin related fields. | ||||||
|   /** |      * @this Blockly.Block | ||||||
|    * Updates the content of the the pin related fields. |      */ | ||||||
|    * @this Blockly.Block |     updateFields: function () { | ||||||
|    */ |         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||||
|   updateFields: function () { |             this, 'BUILT_IN_LED', 'builtinLed'); | ||||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown( |     }, | ||||||
|       this, |     /** @return {!string} The type of input value for the block, an integer. */ | ||||||
|       "BUILT_IN_LED", |     getBlockType: function () { | ||||||
|       "builtinLed" |         return Types.BOOLEAN; | ||||||
|     ); |     }, | ||||||
|   }, |  | ||||||
|   /** @return {!string} The type of input value for the block, an integer. */ |  | ||||||
|   getBlockType: function () { |  | ||||||
|     return Types.BOOLEAN; |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_analogwrite"] = { | Blockly.Blocks['io_analogwrite'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for creating a 'set pin' to an analogue value. |      * Block for creating a 'set pin' to an analogue value. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/AnalogWrite"); |         this.setHelpUrl('http://arduino.cc/en/Reference/AnalogWrite'); | ||||||
|     this.setColour(250); |         this.setColour(250); | ||||||
|     this.appendValueInput("NUM") |         this.appendValueInput('NUM') | ||||||
|       .appendField(Blockly.Msg.ARD_ANALOGWRITE) |             .appendField(Blockly.Msg.ARD_ANALOGWRITE) | ||||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().pwmPins), "PIN") |             .appendField(new Blockly.FieldDropdown( | ||||||
|       .appendField(Blockly.Msg.ARD_WRITE_TO) |                 selectedBoard().pwmPins), 'PIN') | ||||||
|       .setCheck(Types.NUMBER.compatibleTypes); |             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||||
|     this.setInputsInline(false); |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|     this.setPreviousStatement(true, null); |         this.setInputsInline(false); | ||||||
|     this.setNextStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_ANALOGWRITE_TIP); |         this.setNextStatement(true, null); | ||||||
|   }, |         this.setTooltip(Blockly.Msg.ARD_ANALOGWRITE_TIP); | ||||||
|   /** |     }, | ||||||
|    * Updates the content of the the pin related fields. |     /** | ||||||
|    * @this Blockly.Block |      * Updates the content of the the pin related fields. | ||||||
|    */ |      * @this Blockly.Block | ||||||
|   updateFields: function () { |      */ | ||||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, "PIN", "pwmPins"); |     updateFields: function () { | ||||||
|   }, |         Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'pwmPins'); | ||||||
|   /** @return {!string} The type of input value for the block, an integer. */ |     }, | ||||||
|   getBlockType: function () { |     /** @return {!string} The type of input value for the block, an integer. */ | ||||||
|     return Types.NUMBER; |     getBlockType: function () { | ||||||
|   }, |         return Types.NUMBER; | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_analogread"] = { | Blockly.Blocks['io_analogread'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for reading an analogue input. |      * Block for reading an analogue input. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/AnalogRead"); |         this.setHelpUrl('http://arduino.cc/en/Reference/AnalogRead'); | ||||||
|     this.setColour(250); |         this.setColour(250); | ||||||
|     this.appendDummyInput() |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.ARD_ANALOGREAD) |             .appendField(Blockly.Msg.ARD_ANALOGREAD) | ||||||
|       .appendField( |             .appendField(new Blockly.FieldDropdown( | ||||||
|         new Blockly.FieldDropdown(selectedBoard().analogPins), |                 selectedBoard().analogPins), 'PIN'); | ||||||
|         "PIN" |         this.setOutput(true, Types.NUMBER.typeId); | ||||||
|       ); |         this.setTooltip(Blockly.Msg.ARD_ANALOGREAD_TIP); | ||||||
|     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 {!string} The type of return value for the block, an integer. */ |         return Types.NUMBER.typeId; | ||||||
|   getBlockType: function () { |     }, | ||||||
|     return Types.NUMBER.typeName; |     /** | ||||||
|   }, |      * Updates the content of the the pin related fields. | ||||||
|   /** |      * @this Blockly.Block | ||||||
|    * Updates the content of the the pin related fields. |      */ | ||||||
|    * @this Blockly.Block |     updateFields: function () { | ||||||
|    */ |         Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'analogPins'); | ||||||
|   updateFields: function () { |     } | ||||||
|     Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, "PIN", "analogPins"); |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_highlow"] = { | Blockly.Blocks['io_highlow'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for creating a pin state. |      * Block for creating a pin state. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Constants"); |         this.setHelpUrl('http://arduino.cc/en/Reference/Constants'); | ||||||
|     this.setColour(250); |         this.setColour(250); | ||||||
|     this.appendDummyInput().appendField( |         this.appendDummyInput() | ||||||
|       new Blockly.FieldDropdown([ |             .appendField( | ||||||
|         [Blockly.Msg.ARD_HIGH, "HIGH"], |                 new Blockly.FieldDropdown([[Blockly.Msg.ARD_HIGH, 'HIGH'], [Blockly.Msg.ARD_LOW, 'LOW']]), | ||||||
|         [Blockly.Msg.ARD_LOW, "LOW"], |                 'STATE'); | ||||||
|       ]), |         this.setOutput(true, Types.BOOLEAN.typeId); | ||||||
|       "STATE" |         this.setTooltip(Blockly.Msg.ARD_HIGHLOW_TIP); | ||||||
|     ); |     }, | ||||||
|     this.setOutput(true, Types.BOOLEAN.typeName); |     /** @return {!string} The type of return value for the block, an integer. */ | ||||||
|     this.setTooltip(Blockly.Msg.ARD_HIGHLOW_TIP); |     getBlockType: function () { | ||||||
|   }, |         return Types.BOOLEAN; | ||||||
|   /** @return {!string} The type of return value for the block, an integer. */ |     } | ||||||
|   getBlockType: function () { |  | ||||||
|     return Types.BOOLEAN; |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_pulsein"] = { | Blockly.Blocks['io_pulsein'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for measuring the duration of a pulse in an input pin. |      * Block for measuring the duration of a pulse in an input pin. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.jsonInit({ |         this.jsonInit({ | ||||||
|       type: "math_foo", |             "type": "math_foo", | ||||||
|       message0: Blockly.Msg.ARD_PULSE_READ, |             "message0": Blockly.Msg.ARD_PULSE_READ, | ||||||
|       args0: [ |             "args0": [{ | ||||||
|         { |                 "type": "input_value", | ||||||
|           type: "input_value", |                 "name": "PULSETYPE", | ||||||
|           name: "PULSETYPE", |                 "check": Types.BOOLEAN.compatibleTypes | ||||||
|           check: Types.BOOLEAN.compatibleTypes, |             }, { | ||||||
|         }, |                 "type": "field_dropdown", | ||||||
|         { |                 "name": "PULSEPIN", | ||||||
|           type: "field_dropdown", |                 "options": selectedBoard().digitalPins, | ||||||
|           name: "PULSEPIN", |             } | ||||||
|           options: selectedBoard().digitalPins, |             ], | ||||||
|         }, |             "output": Types.NUMBER.typeId, | ||||||
|       ], |             "inputsInline": true, | ||||||
|       output: Types.NUMBER.typeName, |             "colour": 250, | ||||||
|       inputsInline: true, |             "tooltip": Blockly.Msg.ARD_PULSE_TIP, | ||||||
|       colour: 250, |             "helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn' | ||||||
|       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 {!string} The type of input value for the block, an integer. */ |         return Types.NUMBER.typeId; | ||||||
|   getBlockType: function () { |     } | ||||||
|     return Types.NUMBER.typeName; |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["io_pulsetimeout"] = { | Blockly.Blocks['io_pulsetimeout'] = { | ||||||
|   /** |     /** | ||||||
|    * Block for measuring (with a time-out) the duration of a pulse in an input |      * Block for measuring (with a time-out) the duration of a pulse in an input | ||||||
|    * pin. |      * pin. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.jsonInit({ |         this.jsonInit({ | ||||||
|       type: "math_foo", |             "type": "math_foo", | ||||||
|       message0: Blockly.Msg.ARD_PULSE_READ_TIMEOUT, |             "message0": Blockly.Msg.ARD_PULSE_READ_TIMEOUT, | ||||||
|       args0: [ |             "args0": [{ | ||||||
|         { |                 "type": "input_value", | ||||||
|           type: "input_value", |                 "name": "PULSETYPE", | ||||||
|           name: "PULSETYPE", |                 "check": Types.BOOLEAN.compatibleTypes | ||||||
|           check: Types.BOOLEAN.compatibleTypes, |             }, { | ||||||
|         }, |                 "type": "field_dropdown", | ||||||
|         { |                 "name": "PULSEPIN", | ||||||
|           type: "field_dropdown", |                 "options": selectedBoard().digitalPins, | ||||||
|           name: "PULSEPIN", |             }, { | ||||||
|           options: selectedBoard().digitalPins, |                 "type": "input_value", | ||||||
|         }, |                 "name": "TIMEOUT", | ||||||
|         { |                 "check": Types.NUMBER.compatibleTypes | ||||||
|           type: "input_value", |             } | ||||||
|           name: "TIMEOUT", |             ], | ||||||
|           check: Types.NUMBER.compatibleTypes, |             "output": Types.NUMBER.typeId, | ||||||
|         }, |             "inputsInline": true, | ||||||
|       ], |             "colour": 250, | ||||||
|       output: Types.NUMBER.typeName, |             "tooltip": Blockly.Msg.ARD_PULSETIMEOUT_TIP, | ||||||
|       inputsInline: true, |             "helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn' | ||||||
|       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; | ||||||
|   /** @return {!string} The type of input value for the block, an integer. */ |     } | ||||||
|   getBlockType: function () { |  | ||||||
|     return Types.NUMBER.typeName; |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -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 Blockly from 'blockly'; | ||||||
| import { getColour } from '../helpers/colour'; | import { getColour } from '../helpers/colour'; | ||||||
| import { getCompatibleTypes } from '../helpers/types' | import { getCompatibleTypes } from '../helpers/types' | ||||||
| import * as Types from '../helpers/types'; | 
 | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks['controls_whileUntil'] = { | Blockly.Blocks['controls_whileUntil'] = { | ||||||
|     /** |     /** | ||||||
| @ -16,7 +16,7 @@ Blockly.Blocks['controls_whileUntil'] = { | |||||||
|         this.setHelpUrl(Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL); |         this.setHelpUrl(Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL); | ||||||
|         this.setColour(getColour().loops); |         this.setColour(getColour().loops); | ||||||
|         this.appendValueInput('BOOL') |         this.appendValueInput('BOOL') | ||||||
|             .setCheck(getCompatibleTypes('boolean')) |             .setCheck(getCompatibleTypes(Boolean)) | ||||||
|             .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE'); |             .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE'); | ||||||
|         this.appendStatementInput('DO') |         this.appendStatementInput('DO') | ||||||
|             .appendField(Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO); |             .appendField(Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO); | ||||||
| @ -47,25 +47,24 @@ Blockly.Blocks['controls_for'] = { | |||||||
|                 { |                 { | ||||||
|                     "type": "field_variable", |                     "type": "field_variable", | ||||||
|                     "name": "VAR", |                     "name": "VAR", | ||||||
|                     "defaultType": Types.NUMBER.typeName, |  | ||||||
|                     "variable": null |                     "variable": null | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
|                     "type": "input_value", |                     "type": "input_value", | ||||||
|                     "name": "FROM", |                     "name": "FROM", | ||||||
|                     "check": getCompatibleTypes('int'), |                     "check": getCompatibleTypes(Number), | ||||||
|                     "align": "RIGHT" |                     "align": "RIGHT" | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
|                     "type": "input_value", |                     "type": "input_value", | ||||||
|                     "name": "TO", |                     "name": "TO", | ||||||
|                     "check": getCompatibleTypes('int'), |                     "check": getCompatibleTypes(Number), | ||||||
|                     "align": "RIGHT" |                     "align": "RIGHT" | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
|                     "type": "input_value", |                     "type": "input_value", | ||||||
|                     "name": "BY", |                     "name": "BY", | ||||||
|                     "check": getCompatibleTypes('int'), |                     "check": getCompatibleTypes(Number), | ||||||
|                     "align": "RIGHT" |                     "align": "RIGHT" | ||||||
|                 } |                 } | ||||||
|             ], |             ], | ||||||
| @ -98,13 +97,12 @@ Blockly.Blocks['controls_forEach'] = { | |||||||
|                 { |                 { | ||||||
|                     "type": "field_variable", |                     "type": "field_variable", | ||||||
|                     "name": "VAR", |                     "name": "VAR", | ||||||
|                     "defaultType": Types.NUMBER.typeName, |  | ||||||
|                     "variable": null |                     "variable": null | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
|                     "type": "input_value", |                     "type": "input_value", | ||||||
|                     "name": "LIST", |                     "name": "LIST", | ||||||
|                     "check": getCompatibleTypes('Array') |                     "check": getCompatibleTypes(Array) | ||||||
|                 } |                 } | ||||||
|             ], |             ], | ||||||
|             "previousStatement": null, |             "previousStatement": null, | ||||||
| @ -197,7 +195,7 @@ Blockly.Blocks['controls_repeat_ext'] = { | |||||||
|                 { |                 { | ||||||
|                     "type": "input_value", |                     "type": "input_value", | ||||||
|                     "name": "TIMES", |                     "name": "TIMES", | ||||||
|                     "check": getCompatibleTypes('int'), |                     "check": getCompatibleTypes(Number), | ||||||
|                 } |                 } | ||||||
|             ], |             ], | ||||||
|             "previousStatement": null, |             "previousStatement": null, | ||||||
|  | |||||||
| @ -11,39 +11,40 @@ | |||||||
|  * TODO: This block can be improved to set the new range properly. |  * 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"] = { | import * as Blockly from 'blockly/core'; | ||||||
|   /** | import { getColour } from '../helpers/colour'; | ||||||
|    * Block for creating a the map function. | import * as Types from '../helpers/types' | ||||||
|    * @this Blockly.Block | 
 | ||||||
|    */ | Blockly.Blocks['base_map'] = { | ||||||
|   init: function () { |     /** | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/map"); |      * Block for creating a the map function. | ||||||
|     this.setColour(getColour().math); |      * @this Blockly.Block | ||||||
|     this.appendValueInput("NUM") |      */ | ||||||
|       .appendField(Blockly.Msg.ARD_MAP) |     init: function () { | ||||||
|       .setCheck(Types.NUMBER.compatibleTypes); |         this.setHelpUrl('http://arduino.cc/en/Reference/map'); | ||||||
|     this.appendValueInput("FMIN") |         this.setColour(getColour().math); | ||||||
|       .appendField(Blockly.Msg.ARD_MAP_FROMMIN) |         this.appendValueInput('NUM') | ||||||
|       .setCheck(Types.NUMBER.compatibleTypes); |             .appendField(Blockly.Msg.ARD_MAP) | ||||||
|     this.appendValueInput("FMAX") |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|       .appendField(Blockly.Msg.ARD_MAP_FROMMAX) |         this.appendValueInput('FMIN') | ||||||
|       .setCheck(Types.NUMBER.compatibleTypes); |             .appendField(Blockly.Msg.ARD_MAP_FROMMIN) | ||||||
|     this.appendValueInput("DMIN") |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|       .appendField(Blockly.Msg.ARD_MAP_TOMIN) |         this.appendValueInput('FMAX') | ||||||
|       .setCheck(Types.NUMBER.compatibleTypes); |             .appendField(Blockly.Msg.ARD_MAP_FROMMAX) | ||||||
|     this.appendValueInput("DMAX") |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|       .appendField(Blockly.Msg.ARD_MAP_TOMAX) |         this.appendValueInput('DMIN') | ||||||
|       .setCheck(Types.NUMBER.compatibleTypes); |             .appendField(Blockly.Msg.ARD_MAP_TOMIN) | ||||||
|     this.setOutput(true); |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|     this.setInputsInline(false); |         this.appendValueInput('DMAX') | ||||||
|     this.setTooltip(Blockly.Msg.ARD_MAP_TIP); |             .appendField(Blockly.Msg.ARD_MAP_TOMAX) | ||||||
|   }, |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|   /** @return {string} The type of return value for the block, an integer. */ |         this.setOutput(true); | ||||||
|   getBlockType: function () { |         this.setInputsInline(false); | ||||||
|     return Types.NUMBER.typeName; |         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", |                     "type": "field_variable", | ||||||
|                     "name": "VAR", |                     "name": "VAR", | ||||||
|                     "defaultType": Types.NUMBER.typeName, |                     "variable": Blockly.Msg.MATH_CHANGE_TITLE_ITEM | ||||||
|                     "variable": null |  | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
|                     "type": "input_value", |                     "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 * as Blockly from 'blockly/core'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour'; | ||||||
| import * as Types from "../helpers/types"; | import * as Types from '../helpers/types' | ||||||
| import { FieldSlider } from "@blockly/field-slider"; | import { FieldSlider } from '@blockly/field-slider'; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_display_beginDisplay"] = { | 
 | ||||||
|   init: function () { | Blockly.Blocks['sensebox_display_beginDisplay'] = { | ||||||
|     this.appendDummyInput().appendField( |     init: function () { | ||||||
|       Blockly.Msg.senseBox_display_beginDisplay |         this.appendDummyInput() | ||||||
|     ); |             .appendField(Blockly.Msg.senseBox_display_beginDisplay) | ||||||
|     this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tooltip); |         this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); |         this.setHelpUrl('https://sensebox.de/books'); | ||||||
|   }, |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_display_clearDisplay"] = { | Blockly.Blocks['sensebox_display_clearDisplay'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.appendDummyInput().appendField( |         this.appendDummyInput() | ||||||
|       Blockly.Msg.senseBox_display_clearDisplay |             .appendField(Blockly.Msg.senseBox_display_clearDisplay) | ||||||
|     ); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |         this.setColour(getColour().sensebox); | ||||||
|     this.setColour(getColour().sensebox); |         this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tip); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tooltip); |         this.setHelpUrl('https://sensebox.de/books'); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); |     } | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_display_printDisplay"] = { | Blockly.Blocks['sensebox_display_printDisplay'] = { | ||||||
|   init: function (block) { |     init: function (block) { | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendDummyInput().appendField( |         this.appendDummyInput() | ||||||
|       Blockly.Msg.senseBox_display_printDisplay |             .appendField(Blockly.Msg.senseBox_display_printDisplay); | ||||||
|     ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_display_color) | ||||||
|       .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"); | ||||||
|       .appendField( |         this.appendDummyInput() | ||||||
|         new Blockly.FieldDropdown([ |             .appendField(Blockly.Msg.senseBox_display_setSize) | ||||||
|           [Blockly.Msg.senseBox_display_white, "WHITE,BLACK"], |             .appendField(new FieldSlider(1, 1, 4), "SIZE"); | ||||||
|           [Blockly.Msg.senseBox_display_black, "BLACK,WHITE"], |         this.appendDummyInput() | ||||||
|         ]), |             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||||
|         "COLOR" |             .appendField(new FieldSlider(0, 0, 64), "X"); | ||||||
|       ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||||
|       .appendField(Blockly.Msg.senseBox_display_setSize) |             .appendField(new FieldSlider(0, 0, 128), "Y"); | ||||||
|       .appendField(new FieldSlider(1, 1, 4), "SIZE"); |         this.appendValueInput('printDisplay') | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_x) |             .setCheck(null); | ||||||
|       .appendField(new FieldSlider(0, 0, 127), "X"); |         this.setPreviousStatement(true, null); | ||||||
|     this.appendDummyInput() |         this.setNextStatement(true, null); | ||||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_y) |         let variableName = this.getField('COLOR'); | ||||||
|       .appendField(new FieldSlider(0, 0, 63), "Y"); |         console.log(variableName.getValue()); | ||||||
|     this.appendValueInput("printDisplay") |         this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip); | ||||||
|       .appendField(Blockly.Msg.senseBox_display_printDisplay_value) |         this.setHelpUrl('https://sensebox.de/books'); | ||||||
|       .setCheck(null); |     }, | ||||||
|     this.setPreviousStatement(true, null); |     /** | ||||||
|     this.setNextStatement(true, null); |      * Called whenever anything on the workspace changes. | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tooltip); |      * Add warning if block is not nested inside a the correct loop. | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); |      * @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. |    * Called whenever anything on the workspace changes. | ||||||
|    * Add warning if block is not nested inside a the correct loop. |    * Add warning if block is not nested inside a the correct loop. | ||||||
|    * @param {!Blockly.Events.Abstract} e Change event. |    * @param {!Blockly.Events.Abstract} e Change event. | ||||||
|    * @this Blockly.Block |    * @this Blockly.Block | ||||||
|    */ |    */ | ||||||
|   onchange: function (e) { |     onchange: function (e) { | ||||||
|     var legal = false; |         var legal = false; | ||||||
|     // Is the block nested in a loop?
 |         // Is the block nested in a loop?
 | ||||||
|     var block = this; |         var block = this; | ||||||
|     do { |         do { | ||||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { |             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||||
|         legal = true; |                 legal = true; | ||||||
|         break; |                 break; | ||||||
|       } |             } | ||||||
|       block = block.getSurroundParent(); |             block = block.getSurroundParent(); | ||||||
|     } while (block); |         } while (block); | ||||||
|     if (legal) { |         if (legal) { | ||||||
|       this.setWarningText(null); |             this.setWarningText(null); | ||||||
|     } else { |         } else { | ||||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); |             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||||
|     } |         } | ||||||
|   }, |     }, | ||||||
|   LOOP_TYPES: ["sensebox_display_show"], |     LOOP_TYPES: ['sensebox_display_show'], | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_display_fastPrint"] = { | Blockly.Blocks['sensebox_display_drawRectangle'] = { | ||||||
|   init: function (block) { |     init: function () { | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendDummyInput().appendField( |         this.appendDummyInput() | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_show |             .appendField(Blockly.Msg.sensebox_display_drawRectangle); | ||||||
|     ); |         this.appendValueInput('X') | ||||||
|     this.appendValueInput("Title1", "Title1").appendField( |             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_title |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|     ); |         this.appendValueInput('Y') | ||||||
|     this.appendValueInput("Value1", "Value1").appendField( |             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_value |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|     ); |         this.appendValueInput('width') | ||||||
|     this.appendValueInput("Dimension1", "Dimension1").appendField( |             .appendField(Blockly.Msg.sensebox_display_drawRectangle_width) | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_dimension |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|     ); |         this.appendValueInput('height') | ||||||
|     this.appendValueInput("Title2", "Title2").appendField( |             .appendField(Blockly.Msg.sensebox_display_drawRectangle_height) | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_title |             .setCheck(Types.NUMBER.compatibleTypes); | ||||||
|     ); |         this.appendDummyInput('fill') | ||||||
|     this.appendValueInput("Value2", "Value2").appendField( |             .appendField(Blockly.Msg.senseBox_display_filled) | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_value |             .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||||
|     ); |         this.setInputsInline(false); | ||||||
|     this.appendValueInput("Dimension2", "Dimension2").appendField( |         this.setPreviousStatement(true, null); | ||||||
|       Blockly.Msg.senseBox_display_fastPrint_dimension |         this.setNextStatement(true, null); | ||||||
|     ); |     }, | ||||||
|     this.setPreviousStatement(true, null); |     /** | ||||||
|     this.setNextStatement(true, null); |  | ||||||
|     this.setTooltip(Blockly.Msg.sensebox_display_fastPrint_tooltip); |  | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl); |  | ||||||
|   }, |  | ||||||
|   /** |  | ||||||
|    * Called whenever anything on the workspace changes. |    * Called whenever anything on the workspace changes. | ||||||
|    * Add warning if block is not nested inside a the correct loop. |    * Add warning if block is not nested inside a the correct loop. | ||||||
|    * @param {!Blockly.Events.Abstract} e Change event. |    * @param {!Blockly.Events.Abstract} e Change event. | ||||||
|    * @this Blockly.Block |    * @this Blockly.Block | ||||||
|    */ |    */ | ||||||
|   onchange: function (e) { |     onchange: function (e) { | ||||||
|     var legal = false; |         var legal = false; | ||||||
|     // Is the block nested in a loop?
 |         // Is the block nested in a loop?
 | ||||||
|     var block = this; |         var block = this; | ||||||
|     do { |         do { | ||||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { |             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||||
|         legal = true; |                 legal = true; | ||||||
|         break; |                 break; | ||||||
|       } |             } | ||||||
|       block = block.getSurroundParent(); |             block = block.getSurroundParent(); | ||||||
|     } while (block); |         } while (block); | ||||||
|     if (legal) { |         if (legal) { | ||||||
|       this.setWarningText(null); |             this.setWarningText(null); | ||||||
|     } else { |         } else { | ||||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); |             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||||
|     } |         } | ||||||
|   }, |     }, | ||||||
|   LOOP_TYPES: ["sensebox_display_show"], |     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"], |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| import * as Blockly from 'blockly'; | import * as Blockly from 'blockly'; | ||||||
|  | import { FieldSlider } from '@blockly/field-slider'; | ||||||
| import { getColour } from '../helpers/colour' | import { getColour } from '../helpers/colour' | ||||||
| import { selectedBoard } from '../helpers/board' | import { selectedBoard } from '../helpers/board' | ||||||
| import * as Types from '../helpers/types' | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks['sensebox_led'] = { | 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"); |             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_on, "HIGH"], [Blockly.Msg.senseBox_off, "LOW"]]), "STAT"); | ||||||
|         this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|         this.setNextStatement(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(Blockly.Msg.senseBox_rgb_led) | ||||||
|             .appendField("Pin:") |             .appendField("Pin:") | ||||||
|             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "PIN"); |             .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "PIN"); | ||||||
| 
 |         this.appendDummyInput() | ||||||
|         this.appendValueInput("COLOR", 'Number') |             .appendField(Blockly.Msg.COLOUR_RGB_RED)//Blockly.Msg.senseBox_basic_red
 | ||||||
|             .appendField(Blockly.Msg.senseBox_ws2818_rgb_led_color) |             .appendField(new FieldSlider(255, 0, 255), "RED"); | ||||||
|             .setCheck("Colour"); |         this.appendDummyInput() | ||||||
|         // this.appendValueInput("RED", 'Number')
 |             .appendField(Blockly.Msg.COLOUR_RGB_GREEN)//Blockly.Msg.senseBox_basic_green
 | ||||||
|         //     .appendField(Blockly.Msg.COLOUR_RGB_RED);//Blockly.Msg.senseBox_basic_red
 |             .appendField(new FieldSlider(255, 0, 255), "GREEN"); | ||||||
|         // this.appendValueInput("GREEN", 'Number')
 |         this.appendDummyInput() | ||||||
|         //     .appendField(Blockly.Msg.COLOUR_RGB_GREEN);//Blockly.Msg.senseBox_basic_green
 |             .appendField(Blockly.Msg.COLOUR_RGB_BLUE)//Blockly.Msg.senseBox_basic_green
 | ||||||
|         // this.appendValueInput("BLUE", 'Number')
 |             .appendField(new FieldSlider(255, 0, 255), "BLUE"); | ||||||
|         //     .appendField(Blockly.Msg.COLOUR_RGB_BLUE);
 |  | ||||||
|         this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|         this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|         this.setTooltip(Blockly.Msg.senseBox_rgb_led_tip); |         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 * as Blockly from 'blockly/core'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour'; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| ----------------------------------LoRa-------------------------------------------------- | ----------------------------------LoRa-------------------------------------------------- | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_lora_initialize_otaa"] = { | Blockly.Blocks['sensebox_lora_initialize_otaa'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tooltip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_LoRa_init_helpurl); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendDummyInput().appendField("Initialize LoRa (OTAA)"); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .appendField("Initialize LoRa (OTAA)"); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) | 
 | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_device_id) |         this.appendDummyInput() | ||||||
|       .appendField("{") |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(new Blockly.FieldTextInput("DEVICE ID"), "DEVICEID") |             .appendField(Blockly.Msg.senseBox_LoRa_device_id) | ||||||
|       .appendField("}"); |             .appendField(new Blockly.FieldTextInput("DEVICE ID"), "DEVICEID"); | ||||||
|     this.appendDummyInput() |         this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_app_id) |             .appendField(Blockly.Msg.senseBox_LoRa_app_id) | ||||||
|       .appendField("{") |             .appendField(new Blockly.FieldTextInput("APP ID"), "APPID"); | ||||||
|       .appendField(new Blockly.FieldTextInput("APP ID"), "APPID") |         this.appendDummyInput() | ||||||
|       .appendField("}"); |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_LoRa_app_key) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(new Blockly.FieldTextInput("APP KEY"), "APPKEY"); | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_app_key) |         this.appendDummyInput() | ||||||
|       .appendField("{") |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(new Blockly.FieldTextInput("APP KEY"), "APPKEY") |             .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||||
|       .appendField("}"); |             .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||||
|     this.appendDummyInput() |         this.setPreviousStatement(true, null); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.setNextStatement(true, null); | ||||||
|       .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"] = { | Blockly.Blocks['sensebox_lora_initialize_abp'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tooltip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_LoRa_init_helpurl); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendDummyInput().appendField("Initialize LoRa (ABP)"); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .appendField("Initialize LoRa (ABP)"); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_nwskey_id) |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField("{") |             .appendField(Blockly.Msg.senseBox_LoRa_nwskey_id) | ||||||
|       .appendField(new Blockly.FieldTextInput("NWSKEY"), "NWSKEY") |             .appendField(new Blockly.FieldTextInput("NWSKEY"), "NWSKEY"); | ||||||
|       .appendField("}"); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(Blockly.Msg.senseBox_LoRa_appskey_id) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_appskey_id) |             .appendField(new Blockly.FieldTextInput("APPSKEY"), "APPSKEY"); | ||||||
|       .appendField("{") |         this.appendDummyInput() | ||||||
|       .appendField(new Blockly.FieldTextInput("APPSKEY"), "APPSKEY") |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField("}"); |             .appendField(Blockly.Msg.senseBox_LoRa_devaddr_id) | ||||||
|     this.appendDummyInput() |             .appendField(new Blockly.FieldTextInput("DEVADDR"), "DEVADDR"); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_devaddr_id) |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(new Blockly.FieldTextInput("DEVADDR"), "DEVADDR"); |             .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||||
|     this.appendDummyInput() |             .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         // this.appendStatementInput('DO')
 | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_interval) |         //     .appendField(Blockly.Msg.senseBox_measurements)
 | ||||||
|       .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); |         //     .setCheck(null);
 | ||||||
|     // this.appendStatementInput('DO')
 |         this.setPreviousStatement(true, null); | ||||||
|     //     .appendField(Blockly.Msg.senseBox_measurements)
 |         this.setNextStatement(true, null); | ||||||
|     //     .setCheck(null);
 |     }, | ||||||
|     this.setPreviousStatement(true, null); |  | ||||||
|     this.setNextStatement(true, null); |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_lora_message_send"] = { | Blockly.Blocks['sensebox_lora_message_send'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tooltip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendStatementInput("DO") |         this.appendStatementInput('DO') | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_send_message) |             .appendField(Blockly.Msg.senseBox_LoRa_send_message) | ||||||
|       .setCheck(null); |             .setCheck(null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(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); |  | ||||||
|     } |     } | ||||||
|   }, |  | ||||||
|   LOOP_TYPES: ["sensebox_lora_message_send"], |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_lora_ttn_mapper"] = { | Blockly.Blocks['sensebox_send_lora_sensor_value'] = { | ||||||
|   init: function (block) { |     init: function () { | ||||||
|     this.setColour(getColour().sensebox); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_sensor_tip); | ||||||
|     this.appendDummyInput().appendField("TTN Mapper"); |         this.setHelpUrl(''); | ||||||
|     this.appendDummyInput() |         this.setColour(getColour().sensebox); | ||||||
|       .setAlign(Blockly.ALIGN_RIGHT) |         this.appendValueInput('Value') | ||||||
|       .appendField("Fix Type Limit") |             .appendField(Blockly.Msg.senseBox_measurement) | ||||||
|       .appendField( |         this.appendDummyInput() | ||||||
|         new Blockly.FieldDropdown( |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|           [ |             .appendField("Bytes") | ||||||
|             ["0", "0"], |             .appendField(new Blockly.FieldTextInput("2"), "MESSAGE_BYTES"); | ||||||
|             ["1", "1"], |         this.setPreviousStatement(true, null); | ||||||
|             ["2", "2"], |         this.setNextStatement(true, null); | ||||||
|             ["3", "3"], |     }, | ||||||
|           ].reverse() |     /** | ||||||
|         ), |      * Called whenever anything on the workspace changes. | ||||||
|         "dropdown" |      * Add warning if block is not nested inside a the correct loop. | ||||||
|       ); |      * @param {!Blockly.Events.Abstract} e Change event. | ||||||
|     // reverse() because i want 3 be be at first and i'm to lazy to write the array again
 |      * @this Blockly.Block | ||||||
|     this.appendValueInput("Latitude") |      */ | ||||||
|       .appendField(Blockly.Msg.senseBox_gps_lat) |     onchange: function (e) { | ||||||
|       .setCheck(null); |         var legal = false; | ||||||
|     this.appendValueInput("Longitude") |         // Is the block nested in a loop?
 | ||||||
|       .appendField(Blockly.Msg.senseBox_gps_lng) |         var block = this; | ||||||
|       .setCheck(null); |         do { | ||||||
|     this.appendValueInput("Altitude") |             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||||
|       .appendField(Blockly.Msg.senseBox_gps_alt) |                 legal = true; | ||||||
|       .setCheck(null); |                 break; | ||||||
|     this.appendValueInput("pDOP").appendField("pDOP").setCheck(null); |             } | ||||||
|     this.appendValueInput("Fix Type").appendField("Fix Type").setCheck(null); |             block = block.getSurroundParent(); | ||||||
|     this.setPreviousStatement(true, null); |         } while (block); | ||||||
|     this.setNextStatement(true, null); |         if (legal) { | ||||||
|     this.setTooltip(Blockly.Msg.sensebox_lora_ttn_mapper_tip); |             this.setWarningText(null); | ||||||
|     this.setHelpUrl(Blockly.Msg.sensebox_lora_ttn_mapper_helpurl); |         } else { | ||||||
|   }, |             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     LOOP_TYPES: ['sensebox_lora_message_send'], | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_send"] = { | Blockly.Blocks['sensebox_lora_cayenne_send'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendStatementInput("DO") |         this.appendStatementInput('DO') | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_send_cayenne) |             .appendField(Blockly.Msg.senseBox_LoRa_send_cayenne) | ||||||
|       .setCheck(null); |             .setCheck(null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|   }, |     } | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_temperature"] = { | Blockly.Blocks['sensebox_lora_cayenne_temperature'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_temperature_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_temperature_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("Value").appendField( |         this.appendValueInput('Value') | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_temperature |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_temperature) | ||||||
|     ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     }, | ||||||
|   }, |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], |  | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_humidity"] = { | Blockly.Blocks['sensebox_lora_cayenne_humidity'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_humidity_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_humidity_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("Value").appendField( |         this.appendValueInput('Value') | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_humidity |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_humidity) | ||||||
|     ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     }, | ||||||
|   }, |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], |  | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_pressure"] = { | Blockly.Blocks['sensebox_lora_cayenne_pressure'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_pressure_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_pressure_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("Value").appendField( |         this.appendValueInput('Value') | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_pressure |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_pressure) | ||||||
|     ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     }, | ||||||
|   }, |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], |  | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_luminosity"] = { | Blockly.Blocks['sensebox_lora_cayenne_luminosity'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_luminosity_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_luminosity_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("Value").appendField( |         this.appendValueInput('Value') | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_luminosity |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_luminosity) | ||||||
|     ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     }, | ||||||
|   }, |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], |  | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_sensor"] = { | Blockly.Blocks['sensebox_lora_cayenne_sensor'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_analog_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_analog_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("Value").appendField( |         this.appendValueInput('Value') | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_analog |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_analog) | ||||||
|     ); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |         this.setPreviousStatement(true, null); | ||||||
|     this.setPreviousStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     }, | ||||||
|   }, |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], |  | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_accelerometer"] = { | Blockly.Blocks['sensebox_lora_cayenne_accelerometer'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gyros_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gyros_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("X").appendField(Blockly.Msg.senseBox_LoRa_cayenne_x); |         this.appendValueInput('X') | ||||||
|     this.appendValueInput("Y").appendField(Blockly.Msg.senseBox_LoRa_cayenne_y); |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_x) | ||||||
|     this.appendValueInput("Z").appendField(Blockly.Msg.senseBox_LoRa_cayenne_z); |         this.appendValueInput('Y') | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_y) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.appendValueInput('Z') | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_z) | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |         this.appendDummyInput() | ||||||
|     this.setPreviousStatement(true, null); |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|     this.setNextStatement(true, null); |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|   }, |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|   LOOP_TYPES: ["sensebox_lora_cayenne_send"], |         this.setPreviousStatement(true, null); | ||||||
|  |         this.setNextStatement(true, null); | ||||||
|  |     }, | ||||||
|  |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
| }; | }; | ||||||
| Blockly.Blocks["sensebox_lora_cayenne_gps"] = { | Blockly.Blocks['sensebox_lora_cayenne_gps'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gps_tip); |         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gps_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendValueInput("LAT").appendField( |         this.appendValueInput('LAT') | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_lat |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_lat) | ||||||
|     ); |         this.appendValueInput('LNG') | ||||||
|     this.appendValueInput("LNG").appendField( |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_lng) | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_lng |         this.appendValueInput('ALT') | ||||||
|     ); |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_alt) | ||||||
|     this.appendValueInput("ALT").appendField( |         this.appendDummyInput() | ||||||
|       Blockly.Msg.senseBox_LoRa_cayenne_alt |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|     ); |             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||||
|     this.appendDummyInput() |             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.setPreviousStatement(true, null); | ||||||
|       .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) |         this.setNextStatement(true, null); | ||||||
|       .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); |     }, | ||||||
|     this.setPreviousStatement(true, null); |     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||||
|     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"], |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -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 * as Blockly from 'blockly/core'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour'; | ||||||
| 
 | 
 | ||||||
| import store from "../../../store"; |  | ||||||
| 
 | 
 | ||||||
| var boxes = store.getState().auth.user | Blockly.Blocks['sensebox_osem_connection'] = { | ||||||
|   ? store.getState().auth.user.boxes |     init: function () { | ||||||
|   : null; |         this.setTooltip(Blockly.Msg.senseBox_osem_connection_tip); | ||||||
| store.subscribe(() => { |         this.setHelpUrl(''); | ||||||
|   boxes = store.getState().auth.user ? store.getState().auth.user.boxes : null; |         this.setColour(getColour().sensebox); | ||||||
| }); |         this.appendDummyInput() | ||||||
| var selectedBox = ""; |             .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"] = { |         //Blockly.Blocks.sensebox.getDescendants = blocks;
 | ||||||
|   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); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|  |     }, | ||||||
|  |     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. |      * Modify this block to have the correct number of pins available. | ||||||
|      * To add a new loop type add this to your code: |      * @param {boolean} | ||||||
|      * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop'); |      * @private | ||||||
|  |      * @this Blockly.Block | ||||||
|      */ |      */ | ||||||
|     selectedBox = this.getFieldValue("BoxID"); |     updateShape_: function () { | ||||||
|     if (selectedBox !== "" && boxes) { |         var extraFieldExist = this.getFieldValue('gps'); | ||||||
|       var accessToken = boxes.find( |         var input = this.getFieldValue('type'); | ||||||
|         (element) => element._id === selectedBox |         if ((input === 'Mobile') && extraFieldExist === null) { | ||||||
|       ).access_token; |             this.appendValueInput('lat', 'Number') | ||||||
|       if (accessToken !== undefined) { |                 .appendField(Blockly.Msg.senseBox_gps_lat, 'gps'); | ||||||
|         this.getField("access_token").setValue(accessToken); |             this.appendValueInput('lng', 'Number') | ||||||
|       } else { |                 .appendField(Blockly.Msg.senseBox_gps_lng); | ||||||
|         this.getField("access_token").setValue("access_token"); |             this.appendValueInput('altitude', 'Number') | ||||||
|       } |                 .appendField(Blockly.Msg.senseBox_gps_alt); | ||||||
|     } |             this.appendValueInput('timeStamp', 'Number') | ||||||
|   }, |                 .appendField(Blockly.Msg.senseBox_gps_timeStamp); | ||||||
|   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]); |  | ||||||
|         } |         } | ||||||
|       } | 
 | ||||||
|       if (dropdown.length > 1) { |         if (input === 'Stationary' && extraFieldExist !== null) { | ||||||
|         var options = dropdown.slice(1); |             this.removeInput('lat'); | ||||||
|         return options; |             this.removeInput('lng'); | ||||||
|       } else { |             this.removeInput('altitude'); | ||||||
|         return dropdown; |             this.removeInput('timeStamp'); | ||||||
|       } |         } | ||||||
|     } |     }, | ||||||
|     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"], |  | ||||||
| }; | }; | ||||||
|  | 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 * as Blockly from 'blockly/core'; | ||||||
| import { getColour } from "../helpers/colour"; | 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"] = { | Blockly.Blocks['sensebox_sd_open_file'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.appendDummyInput() |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_sd_open_file) |             .appendField(Blockly.Msg.senseBox_sd_open_file) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField( |             .appendField( | ||||||
|         new Blockly.FieldTextInput("Data", checkFileName), |                 new Blockly.FieldTextInput('Data.txt'), | ||||||
|         "Filename" |                 'Filename'); | ||||||
|       ) |         this.appendStatementInput('SD') | ||||||
|       .appendField(".") |             .setCheck(null); | ||||||
|       .appendField( |         this.setPreviousStatement(true, null); | ||||||
|         new Blockly.FieldDropdown([ |         this.setNextStatement(true, null); | ||||||
|           ["txt", "txt"], |         this.setColour(getColour().sensebox); | ||||||
|           ["csv", "csv"], |         this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip); | ||||||
|         ]), |         this.setHelpUrl('https://sensebox.de/books'); | ||||||
|         "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); |  | ||||||
|     } |     } | ||||||
|   }, |  | ||||||
|   LOOP_TYPES: ["sensebox_sd_open_file"], |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sd_osem"] = { | Blockly.Blocks['sensebox_sd_create_file'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.sensebox_sd_osem_tip); |         this.appendDummyInput() | ||||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); |             .appendField(Blockly.Msg.senseBox_sd_create_file) | ||||||
|     this.setColour(getColour().sensebox); |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_output_filename) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |             .appendField( | ||||||
|       .appendField(Blockly.Msg.sensebox_sd_osem); |                 new Blockly.FieldTextInput('Data.txt'), | ||||||
|     this.appendDummyInput() |                 'Filename'); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.setPreviousStatement(true, null); | ||||||
|       .appendField(Blockly.Msg.senseBox_osem_exposure) |         this.setNextStatement(true, null); | ||||||
|       .appendField( |         this.setColour(getColour().sensebox); | ||||||
|         new Blockly.FieldDropdown([ |         this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip); | ||||||
|           [Blockly.Msg.senseBox_osem_stationary, "Stationary"], |         this.setHelpUrl('https://sensebox.de/books'); | ||||||
|           [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_save_for_osem"] = { | Blockly.Blocks['sensebox_sd_write_file'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.sensebox_sd_save_for_osem_tip); |         this.appendDummyInput() | ||||||
|     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); |             .appendField(Blockly.Msg.senseBox_sd_write_file) | ||||||
|     this.setColour(getColour().sensebox); |             .setAlign(Blockly.ALIGN_LEFT); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.sensebox_sd_save_for_osem); |         this.appendValueInput('DATA') | ||||||
|     this.appendValueInput("Value") |             .setCheck(null); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.appendDummyInput('CheckboxText') | ||||||
|       .appendField(Blockly.Msg.sensebox_sd_save_for_osem_id) |             .appendField(Blockly.Msg.senseBox_output_linebreak) | ||||||
|       .appendField(new Blockly.FieldTextInput("sensorID"), "SensorID"); |             .appendField(new Blockly.FieldCheckbox('TRUE'), 'linebreak'); | ||||||
|     this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(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 Blockly from 'blockly'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour' | ||||||
| import * as Types from "../helpers/types"; | import * as Types from '../helpers/types' | ||||||
| import { selectedBoard } from "../helpers/board"; | import { selectedBoard } from '../helpers/board' | ||||||
| import { FieldGridDropdown } from "@blockly/field-grid-dropdown"; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * HDC1080 Temperature and Humidity Sensor |  * HDC1080 Temperature and Humidity Sensor | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sensor_temp_hum"] = { | Blockly.Blocks['sensebox_sensor_temp_hum'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_temp_hum); |     this.appendDummyInput() | ||||||
|  |       .appendField(Blockly.Msg.senseBox_temp_hum); | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_RIGHT) |       .setAlign(Blockly.ALIGN_RIGHT) | ||||||
|       .appendField(Blockly.Msg.senseBox_value) |       .appendField(Blockly.Msg.senseBox_value) | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_hum, "Humidity"]]), "NAME"); | ||||||
|         new Blockly.FieldDropdown([ |  | ||||||
|           [Blockly.Msg.senseBox_temp, "Temperature"], |  | ||||||
|           [Blockly.Msg.senseBox_hum, "Humidity"], |  | ||||||
|         ]), |  | ||||||
|         "NAME" |  | ||||||
|       ); |  | ||||||
|     this.setOutput(true, Types.DECIMAL.typeName); |     this.setOutput(true, Types.DECIMAL.typeName); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_temp_hum_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_temp_hum_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_temp_hum_helpurl); |     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||||
|     this.data = {name: "hdc1080", connection: "I2C"}; |   } | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * VEML6070 and TSL4513 |  * VEML6070 and TSL4513  | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sensor_uv_light"] = { | 
 | ||||||
|  | Blockly.Blocks['sensebox_sensor_uv_light'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_uv_light); |     this.appendDummyInput() | ||||||
|  |       .appendField(Blockly.Msg.senseBox_uv_light); | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_RIGHT) |       .setAlign(Blockly.ALIGN_RIGHT) | ||||||
|       .appendField(Blockly.Msg.senseBox_value) |       .appendField(Blockly.Msg.senseBox_value) | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_light, "Illuminance"], [Blockly.Msg.senseBox_uv, "UvIntensity"]]), "NAME"); | ||||||
|         new Blockly.FieldDropdown([ |  | ||||||
|           [Blockly.Msg.senseBox_light, "Illuminance"], |  | ||||||
|           [Blockly.Msg.senseBox_uv, "UvIntensity"], |  | ||||||
|         ]), |  | ||||||
|         "NAME" |  | ||||||
|       ); |  | ||||||
|     this.setOutput(true, Types.DECIMAL.typeName); |     this.setOutput(true, Types.DECIMAL.typeName); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_uv_light_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_uv_light_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_uv_light_helpurl); |     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||||
|     this.data = {name: "veml6070"}; |   } | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| BMX055 Three differen Blocks for Accelerometer, Gyroscope, Compass | BMX055 Three differen Blocks for Accelerometer, Gyroscope, Compass | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sensor_bmx055_accelerometer"] = { | Blockly.Blocks['sensebox_sensor_bmx055_accelerometer'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput().appendField( |     this.appendDummyInput() | ||||||
|       Blockly.Msg.senseBox_bmx055_accelerometer |       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer); | ||||||
|     ); |  | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_direction) |       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_direction) | ||||||
|       .appendField( |       .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"); | ||||||
|         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() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_range) |       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_range) | ||||||
|       .appendField( |       .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"); | ||||||
|         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.setOutput(true, Types.DECIMAL.typeName); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_bmx055_helpurl); |     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||||
|     this.data = {name: "bmx055"}; |   } | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * SDS011 Fine Particular Matter Sensor |  * SDS011 Fine Particular Matter Sensor | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sensor_sds011"] = { | Blockly.Blocks['sensebox_sensor_sds011'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_sds011); |     this.appendDummyInput() | ||||||
|  |       .appendField(Blockly.Msg.senseBox_sds011); | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_RIGHT) |       .setAlign(Blockly.ALIGN_RIGHT) | ||||||
|       .appendField(Blockly.Msg.senseBox_value) |       .appendField(Blockly.Msg.senseBox_value) | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_pm25, "Pm25"], [Blockly.Msg.senseBox_sds011_pm10, "Pm10"]]), "NAME") | ||||||
|         new Blockly.FieldDropdown([ |  | ||||||
|           [Blockly.Msg.senseBox_sds011_pm25, "pm25"], |  | ||||||
|           [Blockly.Msg.senseBox_sds011_pm10, "pm10"], |  | ||||||
|         ]), |  | ||||||
|         "NAME" |  | ||||||
|       ) |  | ||||||
|       .appendField(Blockly.Msg.senseBox_sds011_dimension) |       .appendField(Blockly.Msg.senseBox_sds011_dimension) | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_serial1, "Serial1"], [Blockly.Msg.senseBox_sds011_serial2, "Serial2"]]), "SERIAL"); | ||||||
|         new Blockly.FieldDropdown( |  | ||||||
|           selectedBoard().serialSensors), |  | ||||||
|         "SERIAL" |  | ||||||
|       ); |  | ||||||
|     this.setOutput(true, Types.DECIMAL.typeName); |     this.setOutput(true, Types.DECIMAL.typeName); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_sds011_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_sds011_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sds011_helpurl); |     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||||
|     this.data = {name: "sds011"}; |   } | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * BMP280 Pressure Sensor |  * BMP280 Pressure Sensor | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sensor_pressure"] = { | Blockly.Blocks['sensebox_sensor_pressure'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     var dropdownOptions = [ |     var dropdownOptions = [[Blockly.Msg.senseBox_pressure, "Pressure"], [Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_gps_alt, "Altitude"]]; | ||||||
|       [Blockly.Msg.senseBox_pressure, "Pressure"], |     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function (option) { | ||||||
|       [Blockly.Msg.senseBox_temp, "Temperature"], |       var input = (option === 'Pressure') || (option === 'Temperature') || (option === 'Altitude'); | ||||||
|       [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.sourceBlock_.updateShape_(input); | ||||||
|     }); |     }); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_pressure_sensor); |     this.appendDummyInput() | ||||||
|  |       .appendField(Blockly.Msg.senseBox_pressure_sensor); | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_RIGHT) |       .setAlign(Blockly.ALIGN_RIGHT) | ||||||
|       .appendField(Blockly.Msg.senseBox_value) |       .appendField(Blockly.Msg.senseBox_value) | ||||||
|       .appendField(dropdown, "NAME"); |       .appendField(dropdown, "NAME"); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setOutput(true, Types.DECIMAL.typeName); |     this.setOutput(true, Types.DECIMAL.typeName); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_pressure_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_pressure_tip); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_pressure_helpurl); |     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/luftdruck.html'); | ||||||
|     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"}; |  | ||||||
|   }, |   }, | ||||||
|   /** |   /** | ||||||
|    * Parse XML to restore the number of pins available. |    * Parse XML to restore the number of pins available. | ||||||
|    * @param {!Element} xmlElement XML storage element. |    * @param {!Element} xmlElement XML storage element. | ||||||
|    * @this Blockly.Block |    * @this Blockly.Block | ||||||
|    */ |    */ | ||||||
|  | 
 | ||||||
|   domToMutation: function (xmlElement) { |   domToMutation: function (xmlElement) { | ||||||
|     xmlElement.getAttribute("port"); |     (xmlElement.getAttribute('port')); | ||||||
|  | 
 | ||||||
|   }, |   }, | ||||||
|   /** |   /** | ||||||
|    * Create XML to represent number of pins selection. |    * Create XML to represent number of pins selection. | ||||||
| @ -262,8 +129,106 @@ Blockly.Blocks["sensebox_sensor_ultrasonic_ranger"] = { | |||||||
|    * @this Blockly.Block |    * @this Blockly.Block | ||||||
|    */ |    */ | ||||||
|   mutationToDom: function () { |   mutationToDom: function () { | ||||||
|     var container = document.createElement("mutation"); |     var container = document.createElement('mutation'); | ||||||
|     var input = this.getFieldValue("port"); |     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); |     this.updateShape_(input); | ||||||
|     container.setAttribute("port", input); |     container.setAttribute("port", input); | ||||||
|     return container; |     return container; | ||||||
| @ -275,311 +240,84 @@ Blockly.Blocks["sensebox_sensor_ultrasonic_ranger"] = { | |||||||
|    * @this Blockly.Block |    * @this Blockly.Block | ||||||
|    */ |    */ | ||||||
|   updateShape_: function () { |   updateShape_: function () { | ||||||
|     var input = this.getFieldValue("port"); |     var input = this.getFieldValue('port'); | ||||||
|     switch (input) { |     switch (input) { | ||||||
|       case "A": |       case 'A': | ||||||
|         this.setFieldValue("1", "ultrasonic_trigger"); |         this.setFieldValue('1', 'ultrasonic_trigger'); | ||||||
|         this.setFieldValue("2", "ultrasonic_echo"); |         this.setFieldValue('2', 'ultrasonic_echo'); | ||||||
|         break; |         break; | ||||||
|       case "B": |       case 'B': | ||||||
|         this.setFieldValue("3", "ultrasonic_trigger"); |         this.setFieldValue('3', 'ultrasonic_trigger'); | ||||||
|         this.setFieldValue("4", "ultrasonic_echo"); |         this.setFieldValue('4', 'ultrasonic_echo'); | ||||||
|         break; |         break; | ||||||
|       case "C": |       case 'C': | ||||||
|         this.setFieldValue("5", "ultrasonic_trigger"); |         this.setFieldValue('5', 'ultrasonic_trigger'); | ||||||
|         this.setFieldValue("6", "ultrasonic_echo"); |         this.setFieldValue('6', 'ultrasonic_echo'); | ||||||
|         break; |         break; | ||||||
|       default: |       default: | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   }, |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Microphone |  * Microphone | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_sensor_sound"] = { | Blockly.Blocks['sensebox_sensor_sound'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_sound) |       .appendField(Blockly.Msg.senseBox_sound) | ||||||
|       .appendField("Pin:") |       .appendField("Pin:") | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN") | ||||||
|         new Blockly.FieldDropdown(selectedBoard().analogPins), |  | ||||||
|         "PIN" |  | ||||||
|       ); |  | ||||||
|     this.setOutput(true, Types.NUMBER.typeName); |     this.setOutput(true, Types.NUMBER.typeName); | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sound_helpurl); |     this.setHelpUrl(Blockly.Msg.senseBox_sound_tip); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_sound_tooltip); |     this.setTooltip('Dieser Sensor mist den Geräuschpegel.'); | ||||||
|   }, |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Button |  * Button | ||||||
|  * |  *  | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_button"] = { | Blockly.Blocks['sensebox_button'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_button) |       .appendField(Blockly.Msg.senseBox_button) | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_button_isPressed, "isPressed"], [Blockly.Msg.senseBox_button_wasPressed, "wasPressed"], [Blockly.Msg.senseBox_button_switch, "Switch"]]), "FUNCTION") | ||||||
|         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("Pin:") |       .appendField("Pin:") | ||||||
|       .appendField( |       .appendField(new Blockly.FieldDropdown(selectedBoard().digitalPinsButton), "PIN"); | ||||||
|         new Blockly.FieldDropdown(selectedBoard().digitalPinsButton), |  | ||||||
|         "PIN" |  | ||||||
|       ); |  | ||||||
|     this.setOutput(true, Types.BOOLEAN.typeName); |     this.setOutput(true, Types.BOOLEAN.typeName); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_button_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_button_tip); | ||||||
|     this.getField("FUNCTION").setValidator( |     this.setHelpUrl('https://sensebox.de/books'); | ||||||
|       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); |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * SCD30 CO2 Sensor |  * SCD30 CO2 Sensor | ||||||
|  * |  *  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_scd30"] = { | 
 | ||||||
|  | Blockly.Blocks['sensebox_scd30'] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     var dropdownOptions = [ |     var dropdownOptions = [[Blockly.Msg.senseBox_temp, "temperature"], [Blockly.Msg.senseBox_hum, "humidity"], [Blockly.Msg.senseBox_bme_co2, "CO2"]]; | ||||||
|       [Blockly.Msg.senseBox_scd_co2, "CO2"], |     this.appendDummyInput() | ||||||
|       [Blockly.Msg.senseBox_temp, "temperature"], |       .appendField(Blockly.Msg.senseBox_scd30); | ||||||
|       [Blockly.Msg.senseBox_hum, "humidity"], |  | ||||||
|     ]; |  | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_scd30); |  | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .setAlign(Blockly.ALIGN_RIGHT) |       .setAlign(Blockly.ALIGN_RIGHT) | ||||||
|       .appendField(Blockly.Msg.senseBox_value) |       .appendField(Blockly.Msg.senseBox_value) | ||||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown"); |       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown") | ||||||
|     this.setOutput(true, Types.NUMBER.typeName); |     this.setOutput(true, Types.NUMBER.typeName); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_scd_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_bme_tip); | ||||||
|     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); |  | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 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("telegram") | ||||||
|             .appendField(new Blockly.FieldTextInput("token"), "telegram_token"); |             .appendField(new Blockly.FieldTextInput("token"), "telegram_token"); | ||||||
|         this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_init_tooltip); |  | ||||||
|         this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| @ -25,7 +24,6 @@ Blockly.Blocks["sensebox_telegram_do"] = { | |||||||
|         this.appendStatementInput("telegram_do"); |         this.appendStatementInput("telegram_do"); | ||||||
|         this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|         this.setNextStatement(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(Blockly.Msg.senseBox_telegram_message) | ||||||
|             .appendField(new Blockly.FieldTextInput("/message"), 'telegram_message'); |             .appendField(new Blockly.FieldTextInput("/message"), 'telegram_message'); | ||||||
|         this.appendStatementInput("telegram_do_on_message").setCheck(null); |         this.appendStatementInput("telegram_do_on_message").setCheck(null); | ||||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_message_tooltip) |  | ||||||
|         this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|         this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|     } |     } | ||||||
| @ -49,10 +46,8 @@ Blockly.Blocks["sensebox_telegram_send"] = { | |||||||
|         this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_send); |         this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_send); | ||||||
|         this.appendValueInput("telegram_text_to_send").setCheck(null); |         this.appendValueInput("telegram_text_to_send").setCheck(null); | ||||||
|         this.setTooltip(Blockly.Msg.senseBox_telegram_send_tooltip) |  | ||||||
|         this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|         this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
| 
 |  | ||||||
|     }, |     }, | ||||||
|     LOOP_TYPES: ["sensebox_telegram_do_on_message"] |     LOOP_TYPES: ["sensebox_telegram_do_on_message"] | ||||||
| }; | }; | ||||||
| @ -1,153 +1,58 @@ | |||||||
| import Blockly from "blockly"; | import Blockly from 'blockly'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour' | ||||||
| import * as Types from "../helpers/types"; |  | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["sensebox_wifi"] = { | Blockly.Blocks['sensebox_wifi'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_wifi_tooltip); |         this.setTooltip(Blockly.Msg.senseBox_wifi_tip); | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().sensebox); |         this.setColour(getColour().sensebox); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.senseBox_wifi_connect); |         this.appendDummyInput() | ||||||
|     this.appendDummyInput() |             .appendField(Blockly.Msg.senseBox_wifi_connect); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_wifi_ssid) |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); |             .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||||
|     this.appendDummyInput() |             .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |         this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_output_password) |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(new Blockly.FieldTextInput("Password"), "Password"); |             .appendField(Blockly.Msg.senseBox_output_password) | ||||||
|     this.setHelpUrl(Blockly.Msg.senseBox_wifi_helpurl); |             .appendField(new Blockly.FieldTextInput("Password"), "Password"); | ||||||
|     this.setPreviousStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |         this.setNextStatement(true, null); | ||||||
|   }, |     }, | ||||||
|   onchange: function (e) { |     onchange: function (e) { | ||||||
|     var legal = false; |         var legal = false; | ||||||
|     // Is the block nested in a loop?
 |         // Is the block nested in a loop?
 | ||||||
|     var block = this; |         var block = this; | ||||||
|     do { |         do { | ||||||
|       if (this.LOOP_TYPES.indexOf(block.type) !== -1) { |             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||||
|         legal = true; |                 legal = true; | ||||||
|         break; |                 break; | ||||||
|       } |             } | ||||||
|       block = block.getSurroundParent(); |             block = block.getSurroundParent(); | ||||||
|     } while (block); |         } while (block); | ||||||
|     if (legal) { |         if (legal) { | ||||||
|       this.setWarningText(null); |             this.setWarningText(null); | ||||||
|     } else { | 
 | ||||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); |         } 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 |  *     The arduino built in functions syntax can be found in | ||||||
|  *     http://arduino.cc/en/Reference/HomePage
 |  *     http://arduino.cc/en/Reference/HomePage
 | ||||||
|  */ |  */ | ||||||
| import Blockly from "blockly"; | import Blockly from 'blockly'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour' | ||||||
| import * as Types from "../helpers/types"; | import * as Types from '../helpers/types' | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["time_delay"] = { | 
 | ||||||
|   /** | Blockly.Blocks['time_delay'] = { | ||||||
|    * Delay block definition |     /** | ||||||
|    * @this Blockly.Block |      * Delay block definition | ||||||
|    */ |      * @this Blockly.Block | ||||||
|   init: function () { |      */ | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Delay"); |     init: function () { | ||||||
|     this.setColour(getColour().time); |         this.setHelpUrl('http://arduino.cc/en/Reference/Delay'); | ||||||
|     this.appendValueInput("DELAY_TIME_MILI") |         this.setColour(getColour().time); | ||||||
|       .setCheck(Types.NUMBER.checkList) |         this.appendValueInput('DELAY_TIME_MILI') | ||||||
|       .appendField(Blockly.Msg.ARD_TIME_DELAY); |             .setCheck(Types.NUMBER.checkList) | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MS); |             .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||||
|     this.setInputsInline(true); |         this.appendDummyInput() | ||||||
|     this.setPreviousStatement(true, null); |             .appendField(Blockly.Msg.ARD_TIME_MS); | ||||||
|     this.setNextStatement(true, null); |         this.setInputsInline(true); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_TIP); |         this.setPreviousStatement(true, null); | ||||||
|   }, |         this.setNextStatement(true, null); | ||||||
|  |         this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_TIP); | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["time_delaymicros"] = { | Blockly.Blocks['time_delaymicros'] = { | ||||||
|   /** |     /** | ||||||
|    * delayMicroseconds block definition |      * delayMicroseconds block definition | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/DelayMicroseconds"); |         this.setHelpUrl('http://arduino.cc/en/Reference/DelayMicroseconds'); | ||||||
|     this.setColour(getColour().time); |         this.setColour(getColour().time); | ||||||
|     this.appendValueInput("DELAY_TIME_MICRO") |         this.appendValueInput('DELAY_TIME_MICRO') | ||||||
|       .setCheck(Types.NUMBER.checkList) |             .setCheck(Types.NUMBER.checkList) | ||||||
|       .appendField(Blockly.Msg.ARD_TIME_DELAY); |             .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS); |         this.appendDummyInput() | ||||||
|     this.setInputsInline(true); |             .appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS); | ||||||
|     this.setPreviousStatement(true, null); |         this.setInputsInline(true); | ||||||
|     this.setNextStatement(true, null); |         this.setPreviousStatement(true, null); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP); |         this.setNextStatement(true, null); | ||||||
|   }, |         this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP); | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["time_millis"] = { | Blockly.Blocks['time_millis'] = { | ||||||
|   /** |     /** | ||||||
|    * Elapsed time in milliseconds block definition |      * Elapsed time in milliseconds block definition | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Millis"); |         this.setHelpUrl('http://arduino.cc/en/Reference/Millis'); | ||||||
|     this.setColour(getColour().time); |         this.setColour(getColour().time); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MILLIS); |         this.appendDummyInput() | ||||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); |             .appendField(Blockly.Msg.ARD_TIME_MILLIS); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); |         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 {string} The type of return value for the block, an integer. */ | ||||||
|     return Blockly.Types.LARGE_NUMBER; |     getBlockType: function () { | ||||||
|   }, |         return Blockly.Types.LARGE_NUMBER; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["time_micros"] = { | Blockly.Blocks['time_micros'] = { | ||||||
|   /** |     /** | ||||||
|    * Elapsed time in microseconds block definition |      * Elapsed time in microseconds block definition | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl("http://arduino.cc/en/Reference/Micros"); |         this.setHelpUrl('http://arduino.cc/en/Reference/Micros'); | ||||||
|     this.setColour(getColour().time); |         this.setColour(getColour().time); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MICROS); |         this.appendDummyInput() | ||||||
|     this.setOutput(true, Types.LARGE_NUMBER.typeName); |             .appendField(Blockly.Msg.ARD_TIME_MICROS); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_MICROS_TIP); |         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. |      * 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; |     getBlockType: function () { | ||||||
|   }, |         return Types.LARGE_NUMBER; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks["infinite_loop"] = { | Blockly.Blocks['infinite_loop'] = { | ||||||
|   /** |     /** | ||||||
|    * Waits forever, end of program. |      * Waits forever, end of program. | ||||||
|    * @this Blockly.Block |      * @this Blockly.Block | ||||||
|    */ |      */ | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setHelpUrl(""); |         this.setHelpUrl(''); | ||||||
|     this.setColour(getColour().time); |         this.setColour(getColour().time); | ||||||
|     this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_INF); |         this.appendDummyInput() | ||||||
|     this.setInputsInline(true); |             .appendField(Blockly.Msg.ARD_TIME_INF); | ||||||
|     this.setPreviousStatement(true); |         this.setInputsInline(true); | ||||||
|     this.setTooltip(Blockly.Msg.ARD_TIME_INF_TIP); |         this.setPreviousStatement(true); | ||||||
|   }, |         this.setTooltip(Blockly.Msg.ARD_TIME_INF_TIP); | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Blockly.Blocks["sensebox_interval_timer"] = {
 | Blockly.Blocks['sensebox_interval_timer'] = { | ||||||
| //   init: function () {
 |     init: function () { | ||||||
| //     this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip);
 |         this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip); | ||||||
| //     this.setInputsInline(true);
 |         this.setInputsInline(true); | ||||||
| //     this.setHelpUrl("");
 |         this.setHelpUrl(''); | ||||||
| //     this.setColour(getColour().time);
 |         this.setColour(getColour().time); | ||||||
| //     this.appendDummyInput().appendField(Blockly.Msg.senseBox_interval_timer);
 |         this.appendDummyInput() | ||||||
| //     this.appendDummyInput()
 |             .appendField(Blockly.Msg.senseBox_interval_timer); | ||||||
| //       .setAlign(Blockly.ALIGN_LEFT)
 |         this.appendDummyInput() | ||||||
| //       .appendField(new Blockly.FieldTextInput("10000"), "interval")
 |             .setAlign(Blockly.ALIGN_LEFT) | ||||||
| //       .appendField(Blockly.Msg.senseBox_interval);
 |             .appendField(new Blockly.FieldTextInput("10000"), "interval") | ||||||
| //     this.appendStatementInput("DO").setCheck(null);
 |             .appendField(Blockly.Msg.senseBox_interval); | ||||||
| //     this.setPreviousStatement(true, null);
 |         this.appendStatementInput('DO') | ||||||
| //     this.setNextStatement(true, null);
 |             .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); |  | ||||||
|   }, |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,46 +1,43 @@ | |||||||
| import Blockly from "blockly/core"; | import Blockly from 'blockly/core'; | ||||||
| import { getColour } from "../helpers/colour"; | import { getColour } from '../helpers/colour'; | ||||||
| import { getCompatibleTypes } from "../helpers/types"; | 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"] = { | Blockly.Blocks['variables_set_dynamic'] = { | ||||||
|   init: function () { |     init: function () { | ||||||
|     this.setColour(getColour().variables); | 
 | ||||||
|     this.appendDummyInput() |         // const type = myVar.type;
 | ||||||
|       .appendField("", "type") |         this.setColour(getColour().variables); | ||||||
|       .appendField(new Blockly.FieldVariable("VAR"), "VAR"); |         this.setPreviousStatement(true, null); | ||||||
|     this.setOutput(true); |         this.setNextStatement(true, null); | ||||||
|   }, |         this.appendValueInput('VALUE') | ||||||
|   onchange: function (e) { |             .appendField('set', 'set') | ||||||
|     let variableID = this.getFieldValue("VAR"); |             .appendField('', 'type') | ||||||
|     let variable = Blockly.getMainWorkspace() |             .appendField(new Blockly.FieldVariable('VAR'), 'VAR') | ||||||
|       .getVariableMap() |             .appendField('to'); | ||||||
|       .getVariableById(variableID); |     }, | ||||||
|     if (variable !== null) { |     onchange: function (e) { | ||||||
|       this.getField("type").setValue(variable.type); |         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 |  * @license | ||||||
|  * |  *  | ||||||
|  * Copyright 2019 Google LLC |  * Copyright 2019 Google LLC | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
| @ -24,24 +24,13 @@ | |||||||
| // More on generating code:
 | // More on generating code:
 | ||||||
| // https://developers.google.com/blockly/guides/create-custom-blocks/generating-code
 | // https://developers.google.com/blockly/guides/create-custom-blocks/generating-code
 | ||||||
| 
 | 
 | ||||||
| import * as Blockly from "blockly/core"; | 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; |  | ||||||
| }); |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Arduino code generator. |  * Arduino code generator. | ||||||
|  * @type !Blockly.Generator |  * @type !Blockly.Generator | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"] = new Blockly.Generator("Arduino"); | Blockly['Arduino'] = new Blockly.Generator('Arduino'); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * List of illegal variable names. |  * List of illegal variable names. | ||||||
| @ -50,105 +39,153 @@ Blockly["Arduino"] = new Blockly.Generator("Arduino"); | |||||||
|  * accidentally clobbering a built-in object or function. |  * accidentally clobbering a built-in object or function. | ||||||
|  * @private |  * @private | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].addReservedWords( | Blockly['Arduino'].addReservedWords( | ||||||
|   // http://arduino.cc/en/Reference/HomePage
 |     // http://arduino.cc/en/Reference/HomePage
 | ||||||
|   "setup,loop,if,else,for,switch,case,while," + |     'setup,loop,if,else,for,switch,case,while,' + | ||||||
|     "do,break,continue,return,goto,define,include," + |     'do,break,continue,return,goto,define,include,' + | ||||||
|     "HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false," + |     'HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false,' + | ||||||
|     "interger, constants,floating,point,void,boolean,char," + |     'interger, constants,floating,point,void,bookean,char,' + | ||||||
|     "unsigned,byte,int,word,long,float,double,string,String,array," + |     'unsigned,byte,int,word,long,float,double,string,String,array,' + | ||||||
|     "static, volatile,const,sizeof,pinMode,digitalWrite,digitalRead," + |     'static, volatile,const,sizeof,pinMode,digitalWrite,digitalRead,' + | ||||||
|     "analogReference,analogRead,analogWrite,tone,noTone,shiftOut,shitIn," + |     'analogReference,analogRead,analogWrite,tone,noTone,shiftOut,shitIn,' + | ||||||
|     "pulseIn,millis,micros,delay,delayMicroseconds,min,max,abs,constrain," + |     'pulseIn,millis,micros,delay,delayMicroseconds,min,max,abs,constrain,' + | ||||||
|     "map,pow,sqrt,sin,cos,tan,randomSeed,random,lowByte,highByte,bitRead," + |     'map,pow,sqrt,sin,cos,tan,randomSeed,random,lowByte,highByte,bitRead,' + | ||||||
|     "bitWrite,bitSet,bitClear,ultraSonicDistance,parseDouble,setNeoPixelColor," + |     'bitWrite,bitSet,bitClear,ultraSonicDistance,parseDouble,setNeoPixelColor,' + | ||||||
|     "bit,attachInterrupt,detachInterrupt,interrupts,noInterrupts,short,isBtnPressed" |     'bit,attachInterrupt,detachInterrupt,interrupts,noInterrupts', | ||||||
|  |     'short', | ||||||
|  |     'isBtnPressed' | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Order of operation ENUMs. |  * Order of operation ENUMs. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].ORDER_ATOMIC = 0; // 0 "" ...
 | Blockly['Arduino'].ORDER_ATOMIC = 0; // 0 "" ...
 | ||||||
| Blockly["Arduino"].ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] .
 | Blockly['Arduino'].ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] .
 | ||||||
| Blockly["Arduino"].ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr
 | Blockly['Arduino'].ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr
 | ||||||
| Blockly["Arduino"].ORDER_MULTIPLICATIVE = 3; // * / % ~/
 | Blockly['Arduino'].ORDER_MULTIPLICATIVE = 3; // * / % ~/
 | ||||||
| Blockly["Arduino"].ORDER_ADDITIVE = 4; // + -
 | Blockly['Arduino'].ORDER_ADDITIVE = 4; // + -
 | ||||||
| Blockly["Arduino"].ORDER_LOGICAL_NOT = 4.4; // !
 | Blockly['Arduino'].ORDER_LOGICAL_NOT = 4.4; // !
 | ||||||
| Blockly["Arduino"].ORDER_SHIFT = 5; // << >>
 | Blockly['Arduino'].ORDER_SHIFT = 5; // << >>
 | ||||||
| Blockly["Arduino"].ORDER_MODULUS = 5.3; // %
 | Blockly['Arduino'].ORDER_MODULUS = 5.3; // %
 | ||||||
| Blockly["Arduino"].ORDER_RELATIONAL = 6; // is is! >= > <= <
 | Blockly['Arduino'].ORDER_RELATIONAL = 6; // is is! >= > <= <
 | ||||||
| Blockly["Arduino"].ORDER_EQUALITY = 7; // === !== === !==
 | Blockly['Arduino'].ORDER_EQUALITY = 7; // === !== === !==
 | ||||||
| Blockly["Arduino"].ORDER_BITWISE_AND = 8; // &
 | Blockly['Arduino'].ORDER_BITWISE_AND = 8; // &
 | ||||||
| Blockly["Arduino"].ORDER_BITWISE_XOR = 9; // ^
 | Blockly['Arduino'].ORDER_BITWISE_XOR = 9; // ^
 | ||||||
| Blockly["Arduino"].ORDER_BITWISE_OR = 10; // |
 | Blockly['Arduino'].ORDER_BITWISE_OR = 10; // |
 | ||||||
| Blockly["Arduino"].ORDER_LOGICAL_AND = 11; // &&
 | Blockly['Arduino'].ORDER_LOGICAL_AND = 11; // &&
 | ||||||
| Blockly["Arduino"].ORDER_LOGICAL_OR = 12; // ||
 | Blockly['Arduino'].ORDER_LOGICAL_OR = 12; // ||
 | ||||||
| Blockly["Arduino"].ORDER_CONDITIONAL = 13; // expr ? expr : expr
 | Blockly['Arduino'].ORDER_CONDITIONAL = 13; // expr ? expr : expr
 | ||||||
| Blockly["Arduino"].ORDER_ASSIGNMENT = 14; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
 | Blockly['Arduino'].ORDER_ASSIGNMENT = 14; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
 | ||||||
| Blockly["Arduino"].ORDER_COMMA = 18; // ,
 | Blockly['Arduino'].ORDER_COMMA = 18; // ,
 | ||||||
| Blockly["Arduino"].ORDER_NONE = 99; // (...)
 | Blockly['Arduino'].ORDER_NONE = 99; // (...)
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * |  *  | ||||||
|  * @param {} workspace |  * @param {} workspace  | ||||||
|  * |  *  | ||||||
|  * Blockly Types |  * Blockly Types | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Initialise the database of variable names. |  * Initialise the database of variable names. | ||||||
|  * @param {!Blockly.Workspace} workspace Workspace to generate code from. |  * @param {!Blockly.Workspace} workspace Workspace to generate code from. | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].init = function (workspace) { | Blockly['Arduino'].init = function (workspace) { | ||||||
|   // Create a dictionary of definitions to be printed before the code.
 |     // Create a dictionary of definitions to be printed before the code.
 | ||||||
|   Blockly["Arduino"].libraries_ = Object.create(null); |     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
 |     // creates a list of code to be setup before the setup block
 | ||||||
|   Blockly["Arduino"].setupCode_ = Object.create(null); |     Blockly['Arduino'].setupCode_ = Object.create(null); | ||||||
| 
 | 
 | ||||||
|   // creates a list of code to be setup before the setup block
 |     // creates a list of code for the loop to be runned once
 | ||||||
|   Blockly["Arduino"].phyphoxSetupCode_ = Object.create(null); |     Blockly['Arduino'].loopCodeOnce_ = Object.create(null) | ||||||
| 
 | 
 | ||||||
|   // creates a list of code to be setup before the setup block
 |     // creates a list of code for the loop to be runned once
 | ||||||
|   Blockly["Arduino"].loraSetupCode_ = Object.create(null); |     Blockly['Arduino'].codeFunctions_ = Object.create(null) | ||||||
| 
 | 
 | ||||||
|   // creates a list of code for the loop to be runned once
 |     // creates a list of code variables  
 | ||||||
|   Blockly["Arduino"].loopCodeOnce_ = Object.create(null); |     Blockly['Arduino'].variables_ = Object.create(null) | ||||||
| 
 | 
 | ||||||
|   // creates a list of code for the loop to be runned once
 |     // Create a dictionary mapping desired function names in definitions_
 | ||||||
|   Blockly["Arduino"].codeFunctions_ = Object.create(null); |     // to actual function names (to avoid collisions with user functions).
 | ||||||
|  |     Blockly['Arduino'].functionNames_ = Object.create(null); | ||||||
| 
 | 
 | ||||||
|   // creates a list of code variables
 |     Blockly['Arduino'].variablesInitCode_ = ''; | ||||||
|   Blockly["Arduino"].variables_ = Object.create(null); |  | ||||||
| 
 | 
 | ||||||
|   // Create a dictionary mapping desired function names in definitions_
 |     if (!Blockly['Arduino'].variableDB_) { | ||||||
|   // to actual function names (to avoid collisions with user functions).
 |         Blockly['Arduino'].variableDB_ = new Blockly.Names( | ||||||
|   Blockly["Arduino"].functionNames_ = Object.create(null); |             Blockly['Arduino'].RESERVED_WORDS_ | ||||||
|  |         ); | ||||||
|  |     } else { | ||||||
|  |         Blockly['Arduino'].variableDB_.reset(); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|   Blockly["Arduino"].variablesInitCode_ = ""; |     Blockly['Arduino'].variableDB_.setVariableMap(workspace.getVariableMap()); | ||||||
| 
 | 
 | ||||||
|   if (!Blockly["Arduino"].nameDB_) { |     // We don't have developer variables for now
 | ||||||
|     Blockly["Arduino"].nameDB_ = new Blockly.Names( |     // // Add developer variables (not created or named by the user).
 | ||||||
|       Blockly["Arduino"].RESERVED_WORDS_ |     // var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
 | ||||||
|     ); |     // for (var i = 0; i < devVarList.length; i++) {
 | ||||||
|   } else { |     //     defvars.push(Blockly['Arduino'].variableDB_.getName(devVarList[i],
 | ||||||
|     Blockly["Arduino"].nameDB_.reset(); |     //         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
 |     const stringVariables = workspace.getVariablesOfType('String'); | ||||||
|   // // Add developer variables (not created or named by the user).
 |     for (i = 0; i < stringVariables.length; i += 1) { | ||||||
|   // var devVarList = Blockly.Variables.allDeveloperVariables(workspace);
 |         variableCode += | ||||||
|   // for (var i = 0; i < devVarList.length; i++) {
 |             'String ' + | ||||||
|   //     defvars.push(Blockly['Arduino'].nameDB_.getName(devVarList[i],
 |             Blockly['Arduino'].variableDB_.getName( | ||||||
|   //         Blockly.Names.DEVELOPER_VARIABLE_TYPE));
 |                 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. |  * @param {string} code Generated code. | ||||||
|  * @return {string} Completed code. |  * @return {string} Completed code. | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].finish = function (code) { | Blockly['Arduino'].finish = function (code) { | ||||||
|   let libraryCode = ""; |     let libraryCode = ''; | ||||||
|   let variablesCode = ""; |     let variablesCode = ''; | ||||||
|   let codeFunctions = ""; |     let codeFunctions = ''; | ||||||
|   let functionsCode = ""; |     let functionsCode = ''; | ||||||
|   let definitionsCode = ""; |     let definitionsCode = ''; | ||||||
|   let phyphoxSetupCode = ""; |     let loopCodeOnce = ''; | ||||||
|   let loopCodeOnce = ""; |     let setupCode = ''; | ||||||
|   let setupCode = ""; |     let preSetupCode = ''; | ||||||
|   let preSetupCode = ""; |     let devVariables = '\n'; | ||||||
|   let loraSetupCode = ""; |  | ||||||
|   let devVariables = "\n"; |  | ||||||
| 
 | 
 | ||||||
|   for (const key in Blockly["Arduino"].libraries_) { |     for (const key in Blockly['Arduino'].libraries_) { | ||||||
|     libraryCode += Blockly["Arduino"].libraries_[key] + "\n"; |         libraryCode += Blockly['Arduino'].libraries_[key] + '\n'; | ||||||
|   } |     } | ||||||
| 
 | 
 | ||||||
|   for (const key in Blockly["Arduino"].variables_) { |     for (const key in Blockly['Arduino'].variables_) { | ||||||
|     variablesCode += Blockly["Arduino"].variables_[key] + "\n"; |         variablesCode += Blockly['Arduino'].variables_[key] + '\n'; | ||||||
|   } |     } | ||||||
| 
 | 
 | ||||||
|   for (const key in Blockly["Arduino"].definitions_) { |     for (const key in Blockly['Arduino'].definitions_) { | ||||||
|     definitionsCode += Blockly["Arduino"].definitions_[key] + "\n"; |         definitionsCode += Blockly['Arduino'].definitions_[key] + '\n'; | ||||||
|   } |     } | ||||||
| 
 | 
 | ||||||
|   for (const key in Blockly["Arduino"].loopCodeOnce_) { |     for (const key in Blockly['Arduino'].loopCodeOnce_) { | ||||||
|     loopCodeOnce += Blockly["Arduino"].loopCodeOnce_[key] + "\n"; |         loopCodeOnce += Blockly['Arduino'].loopCodeOnce_[key] + '\n'; | ||||||
|   } |     } | ||||||
| 
 | 
 | ||||||
|   for (const key in Blockly["Arduino"].codeFunctions_) { |     for (const key in Blockly['Arduino'].codeFunctions_) { | ||||||
|     codeFunctions += Blockly["Arduino"].codeFunctions_[key] + "\n"; |         codeFunctions += Blockly['Arduino'].codeFunctions_[key] + '\n'; | ||||||
|   } |     } | ||||||
| 
 | 
 | ||||||
|   for (const key in Blockly["Arduino"].functionNames_) { |     for (const key in Blockly['Arduino'].functionNames_) { | ||||||
|     functionsCode += Blockly["Arduino"].functionNames_[key] + "\n"; |         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 = |     for (const key in Blockly['Arduino'].setupCode_) { | ||||||
|     "\nvoid setup() { \n" + preSetupCode + "\n" + loraSetupCode + "\n}\n"; |         preSetupCode += Blockly['Arduino'].setupCode_[key] || ''; | ||||||
|   for (const key in Blockly["Arduino"].phyphoxSetupCode_) { |     } | ||||||
|     phyphoxSetupCode += Blockly["Arduino"].phyphoxSetupCode_[key] + "\n" || ""; |     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.
 |     // Convert the definitions dictionary into a list.
 | ||||||
|     code = |     code = | ||||||
|       devVariables + |         devVariables + | ||||||
|       "\n" + |         '\n' + | ||||||
|       libraryCode + |         libraryCode + | ||||||
|       "\n" + |         '\n' + | ||||||
|       variablesCode + |         variablesCode + | ||||||
|       "\n" + |         '\n' + | ||||||
|       definitionsCode + |         definitionsCode + | ||||||
|       "\n" + |         '\n' + | ||||||
|       codeFunctions + |         codeFunctions + | ||||||
|       "\n" + |         '\n' + | ||||||
|       Blockly["Arduino"].variablesInitCode_ + |         Blockly['Arduino'].variablesInitCode_ + | ||||||
|       "\n" + |         '\n' + | ||||||
|       functionsCode + |         functionsCode + | ||||||
|       "\n" + |         '\n' + | ||||||
|       setupCode + |         setupCode + | ||||||
|       "\n" + |         '\n' + | ||||||
|       loopCode; |         loopCode | ||||||
|   } |         ; | ||||||
| 
 | 
 | ||||||
|   // Clean up temporary data.
 |     // Clean up temporary data.
 | ||||||
|   delete Blockly["Arduino"].definitions_; |     delete Blockly['Arduino'].definitions_; | ||||||
|   delete Blockly["Arduino"].functionNames_; |     delete Blockly['Arduino'].functionNames_; | ||||||
|   delete Blockly["Arduino"].loopCodeOnce_; |     delete Blockly['Arduino'].loopCodeOnce_; | ||||||
|   delete Blockly["Arduino"].variablesInitCode_; |     delete Blockly['Arduino'].variablesInitCode_; | ||||||
|   delete Blockly["Arduino"].libraries_; |     delete Blockly['Arduino'].libraries_; | ||||||
|   Blockly["Arduino"].nameDB_.reset(); |     Blockly['Arduino'].variableDB_.reset(); | ||||||
| 
 | 
 | ||||||
|   return code; |     return code; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -278,8 +276,8 @@ Blockly["Arduino"].finish = function (code) { | |||||||
|  * @param {string} line Line of generated code. |  * @param {string} line Line of generated code. | ||||||
|  * @return {string} Legal line of code. |  * @return {string} Legal line of code. | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].scrubNakedValue = function (line) { | Blockly['Arduino'].scrubNakedValue = function (line) { | ||||||
|   return line + ";\n"; |     return line + ';\n'; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -289,14 +287,14 @@ Blockly["Arduino"].scrubNakedValue = function (line) { | |||||||
|  * @return {string} Arduino string. |  * @return {string} Arduino string. | ||||||
|  * @private |  * @private | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].quote_ = function (string) { | Blockly['Arduino'].quote_ = function (string) { | ||||||
|   // Can't use goog.string.quote since Google's style guide recommends
 |     // Can't use goog.string.quote since Google's style guide recommends
 | ||||||
|   // JS string literals use single quotes.
 |     // JS string literals use single quotes.
 | ||||||
|   string = string |     string = string | ||||||
|     .replace(/\\/g, "\\\\") |         .replace(/\\/g, '\\\\') | ||||||
|     .replace(/\n/g, "\\\n") |         .replace(/\n/g, '\\\n') | ||||||
|     .replace(/'/g, "\\'"); |         .replace(/'/g, "\\'"); | ||||||
|   return '"' + string + '"'; |     return '"' + string + '"'; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -309,42 +307,43 @@ Blockly["Arduino"].quote_ = function (string) { | |||||||
|  * @return {string} Arduino code with comments and subsequent blocks added. |  * @return {string} Arduino code with comments and subsequent blocks added. | ||||||
|  * @private |  * @private | ||||||
|  */ |  */ | ||||||
| Blockly["Arduino"].scrub_ = function (block, code) { | Blockly['Arduino'].scrub_ = function (block, code) { | ||||||
|   let commentCode = ""; |     let commentCode = ''; | ||||||
|   // Only collect comments for blocks that aren't inline.
 |     // Only collect comments for blocks that aren't inline.
 | ||||||
|   if (!block.outputConnection || !block.outputConnection.targetConnection) { |     if (!block.outputConnection || !block.outputConnection.targetConnection) { | ||||||
|     // Collect comment for this block.
 |         // Collect comment for this block.
 | ||||||
|     let comment = block.getCommentText(); |         let comment = block.getCommentText(); | ||||||
|     //@ts-ignore
 |         //@ts-ignore
 | ||||||
|     comment = comment |         comment = comment ? Blockly.utils.string.wrap( | ||||||
|       ? Blockly.utils.string.wrap(comment, Blockly["Arduino"].COMMENT_WRAP - 3) |             comment, | ||||||
|       : null; |             Blockly['Arduino'].COMMENT_WRAP - 3 | ||||||
|     if (comment) { |         ) : null; | ||||||
|       if (block.getProcedureDef) { |         if (comment) { | ||||||
|         // Use a comment block for function comments.
 |             if (block.getProcedureDef) { | ||||||
|         commentCode += |                 // Use a comment block for function comments.
 | ||||||
|           "/**\n" + |                 commentCode += | ||||||
|           Blockly["Arduino"].prefixLines(comment + "\n", " * ") + |                     '/**\n' + | ||||||
|           " */\n"; |                     Blockly['Arduino'].prefixLines(comment + '\n', ' * ') + | ||||||
|       } else { |                     ' */\n'; | ||||||
|         commentCode += Blockly["Arduino"].prefixLines(comment + "\n", "// "); |             } else { | ||||||
|       } |                 commentCode += Blockly['Arduino'].prefixLines(comment + '\n', '// '); | ||||||
|     } |             } | ||||||
|     // Collect comments for all value arguments.
 |         } | ||||||
|     // Don't collect comments for nested statements.
 |         // Collect comments for all value arguments.
 | ||||||
|     for (let i = 0; i < block.inputList.length; i++) { |         // Don't collect comments for nested statements.
 | ||||||
|       if (block.inputList[i].type === Blockly.INPUT_VALUE) { |         for (let i = 0; i < block.inputList.length; i++) { | ||||||
|         const childBlock = block.inputList[i].connection.targetBlock(); |             if (block.inputList[i].type === Blockly.INPUT_VALUE) { | ||||||
|         if (childBlock) { |                 const childBlock = block.inputList[i].connection.targetBlock(); | ||||||
|           const comment = Blockly["Arduino"].allNestedComments(childBlock); |                 if (childBlock) { | ||||||
|           if (comment) { |                     const comment = Blockly['Arduino'].allNestedComments(childBlock); | ||||||
|             commentCode += Blockly["Arduino"].prefixLines(comment, "// "); |                     if (comment) { | ||||||
|           } |                         commentCode += Blockly['Arduino'].prefixLines(comment, '// '); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |     const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); | ||||||
|   const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); |     const nextCode = Blockly['Arduino'].blockToCode(nextBlock); | ||||||
|   const nextCode = Blockly["Arduino"].blockToCode(nextBlock); |     return commentCode + code + nextCode; | ||||||
|   return commentCode + code + nextCode; | }; | ||||||
| }; |  | ||||||
| @ -1,30 +1,21 @@ | |||||||
| import "./generator"; | import './generator'; | ||||||
| import "./loops"; | import './loops'; | ||||||
| import "./sensebox-sensors"; | import './sensebox-sensors'; | ||||||
| import "./sensebox-telegram"; | import './sensebox-telegram'; | ||||||
| import "./sensebox-osem"; | import './sensebox-osem'; | ||||||
| import "./sensebox-web"; | import './sensebox-web'; | ||||||
| import "./sensebox-display"; | import './sensebox-display'; | ||||||
| import "./sensebox-motors"; | import './sensebox-lora'; | ||||||
| import "./sensebox-lora"; | import './sensebox-led'; | ||||||
| import "./sensebox-led"; | import './sensebox-sd'; | ||||||
| import "./sensebox"; | import './logic'; | ||||||
| import "./sensebox-rtc"; | import './text'; | ||||||
| import "./sensebox-ntp"; | import './math'; | ||||||
| import "./sensebox-ble"; | import './map'; | ||||||
| import "./sensebox-sd"; | import './io'; | ||||||
| import "./mqtt"; | import './audio'; | ||||||
| import "./logic"; | import './procedures'; | ||||||
| import "./text"; | import './time'; | ||||||
| import "./math"; | import './variables'; | ||||||
| import "./map"; | 
 | ||||||
| import "./io"; | 
 | ||||||
| import "./audio"; |  | ||||||
| import "./procedures"; |  | ||||||
| import "./serial"; |  | ||||||
| import "./time"; |  | ||||||
| import "./variables"; |  | ||||||
| import "./lists"; |  | ||||||
| import "./watchdog"; |  | ||||||
| import "./webserver"; |  | ||||||
| import "./CleVerLab" |  | ||||||
|  | |||||||
| @ -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 + |             conditionCode + | ||||||
|             ') {\n' + |             ') {\n' + | ||||||
|             branchCode + |             branchCode + | ||||||
|             '}\n'; |             '}'; | ||||||
| 
 | 
 | ||||||
|         ++n; |         ++n; | ||||||
|     } while (Block.getInput('IF' + n)); |     } while (Block.getInput('IF' + n)); | ||||||
| 
 | 
 | ||||||
|     if (Block.getInput('ELSE')) { |     if (Block.getInput('ELSE')) { | ||||||
|         branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE'); |         branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE'); | ||||||
|         code += ' else {\n' + branchCode + '}\n'; |         code += ' else {\n' + branchCode + '}'; | ||||||
|     } |     } | ||||||
|     return code + '\n'; |     return code + '\n'; | ||||||
| }; | }; | ||||||
| @ -106,14 +106,14 @@ Blockly.Arduino['controls_ifelse'] = function (Block) { | |||||||
|             conditionCode + |             conditionCode + | ||||||
|             ') {\n' + |             ') {\n' + | ||||||
|             branchCode + |             branchCode + | ||||||
|             '}\n'; |             '}'; | ||||||
| 
 | 
 | ||||||
|         ++n; |         ++n; | ||||||
|     } while (Block.getInput('IF' + n)); |     } while (Block.getInput('IF' + n)); | ||||||
| 
 | 
 | ||||||
|     if (Block.getInput('ELSE')) { |     if (Block.getInput('ELSE')) { | ||||||
|         branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE'); |         branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE'); | ||||||
|         code += ' else {\n' + branchCode + '}\n'; |         code += ' else {\n' + branchCode + '}'; | ||||||
|     } |     } | ||||||
|     return code + '\n'; |     return code + '\n'; | ||||||
| } | } | ||||||
| @ -127,6 +127,9 @@ Blockly.Arduino['logic_negate'] = function (Block) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| Blockly.Arduino['switch_case'] = function (block) { | Blockly.Arduino['switch_case'] = function (block) { | ||||||
|     var n = 0; |     var n = 0; | ||||||
|     var argument = Blockly.Arduino.valueToCode(this, 'CONDITION', |     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"): |  * @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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_number"] = function (block) { | Blockly.Arduino['math_number'] = function (block) { | ||||||
|   // Numeric value.
 |     // Numeric value.
 | ||||||
|   var code = parseFloat(block.getFieldValue("NUM")); |     var code = parseFloat(block.getFieldValue('NUM')); | ||||||
|   if (code === Infinity) { |     if (code === Infinity) { | ||||||
|     code = "INFINITY"; |         code = 'INFINITY'; | ||||||
|   } else if (code === -Infinity) { |     } else if (code === -Infinity) { | ||||||
|     code = "-INFINITY"; |         code = '-INFINITY'; | ||||||
|   } |     } | ||||||
|   return [code, Blockly.Arduino.ORDER_ATOMIC]; |     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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_arithmetic"] = function (block) { | Blockly.Arduino['math_arithmetic'] = function (block) { | ||||||
|   var OPERATORS = { |     var OPERATORS = { | ||||||
|     ADD: [" + ", Blockly.Arduino.ORDER_ADDITIVE], |         ADD: [' + ', Blockly.Arduino.ORDER_ADDITIVE], | ||||||
|     MINUS: [" - ", Blockly.Arduino.ORDER_ADDITIVE], |         MINUS: [' - ', Blockly.Arduino.ORDER_ADDITIVE], | ||||||
|     MULTIPLY: [" * ", Blockly.Arduino.ORDER_MULTIPLICATIVE], |         MULTIPLY: [' * ', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||||
|     DIVIDE: [" / ", Blockly.Arduino.ORDER_MULTIPLICATIVE], |         DIVIDE: [' / ', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||||
|     POWER: [null, Blockly.Arduino.ORDER_NONE], // Handle power separately.
 |         POWER: [null, Blockly.Arduino.ORDER_NONE]  // Handle power separately.
 | ||||||
|   }; |     }; | ||||||
|   var tuple = OPERATORS[block.getFieldValue("OP")]; |     var tuple = OPERATORS[block.getFieldValue('OP')]; | ||||||
|   var operator = tuple[0]; |     var operator = tuple[0]; | ||||||
|   var order = tuple[1]; |     var order = tuple[1]; | ||||||
|   var argument0 = Blockly.Arduino.valueToCode(block, "A", order) || "0"; |     var argument0 = Blockly.Arduino.valueToCode(block, 'A', order) || '0'; | ||||||
|   var argument1 = Blockly.Arduino.valueToCode(block, "B", order) || "0"; |     var argument1 = Blockly.Arduino.valueToCode(block, 'B', order) || '0'; | ||||||
|   var code; |     var code; | ||||||
|   // Power in C++ requires a special case since it has no operator.
 |     // Power in C++ requires a special case since it has no operator.
 | ||||||
|   if (!operator) { |     if (!operator) { | ||||||
|     code = "Math.pow(" + argument0 + ", " + argument1 + ")"; |         code = 'Math.pow(' + argument0 + ', ' + argument1 + ')'; | ||||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; |         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||||
|   } |     } | ||||||
|   code = argument0 + operator + argument1; |     code = argument0 + operator + argument1; | ||||||
|   return [code, order]; |     return [code, order]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -65,103 +66,90 @@ Blockly.Arduino["math_arithmetic"] = function (block) { | |||||||
|  * @param {!Blockly.Block} block Block to generate the code from. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_single"] = function (block) { | Blockly.Arduino['math_single'] = function (block) { | ||||||
|   var operator = block.getFieldValue("OP"); |     var operator = block.getFieldValue('OP'); | ||||||
|   var code; |     var code; | ||||||
|   var arg; |     var arg; | ||||||
|   if (operator === "NEG") { |     if (operator === 'NEG') { | ||||||
|     // Negation is a special case given its different operator precedents.
 |         // Negation is a special case given its different operator precedents.
 | ||||||
|     arg = |         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||||
|       Blockly.Arduino.valueToCode( |             Blockly.Arduino.ORDER_UNARY_PREFIX) || '0'; | ||||||
|         block, |         if (arg[0] === '-') { | ||||||
|         "NUM", |             // --3 is not legal in C++ in this context.
 | ||||||
|         Blockly.Arduino.ORDER_UNARY_PREFIX |             arg = ' ' + arg; | ||||||
|       ) || "0"; |         } | ||||||
|     if (arg[0] === "-") { |         code = '-' + arg; | ||||||
|       // --3 is not legal in C++ in this context.
 |         return [code, Blockly.Arduino.ORDER_UNARY_PREFIX]; | ||||||
|       arg = " " + arg; |  | ||||||
|     } |     } | ||||||
|     code = "-" + arg; |     if (operator === 'ABS' || operator.substring(0, 5) === 'ROUND') { | ||||||
|     return [code, Blockly.Arduino.ORDER_UNARY_PREFIX]; |         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||||
|   } |             Blockly.Arduino.ORDER_UNARY_POSTFIX) || '0'; | ||||||
|   if (operator === "ABS" || operator.substring(0, 5) === "ROUND") { |     } else if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { | ||||||
|     arg = |         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||||
|       Blockly.Arduino.valueToCode( |             Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||||
|         block, |     } else { | ||||||
|         "NUM", |         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||||
|         Blockly.Arduino.ORDER_UNARY_POSTFIX |             Blockly.Arduino.ORDER_NONE) || '0'; | ||||||
|       ) || "0"; |     } | ||||||
|   } else if (operator === "SIN" || operator === "COS" || operator === "TAN") { |     // First, handle cases which generate values that don't need parentheses.
 | ||||||
|     arg = |     switch (operator) { | ||||||
|       Blockly.Arduino.valueToCode( |         case 'ABS': | ||||||
|         block, |             code = 'abs(' + arg + ')'; | ||||||
|         "NUM", |             break; | ||||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE |         case 'ROOT': | ||||||
|       ) || "0"; |             code = 'sqrt(' + arg + ')'; | ||||||
|   } else { |             break; | ||||||
|     arg = |         case 'LN': | ||||||
|       Blockly.Arduino.valueToCode(block, "NUM", Blockly.Arduino.ORDER_NONE) || |             code = 'log(' + arg + ')'; | ||||||
|       "0"; |             break; | ||||||
|   } |         case 'EXP': | ||||||
|   // First, handle cases which generate values that don't need parentheses.
 |             code = 'exp(' + arg + ')'; | ||||||
|   switch (operator) { |             break; | ||||||
|     case "ABS": |         case 'POW10': | ||||||
|       code = "abs(" + arg + ")"; |             code = 'pow(10,' + arg + ')'; | ||||||
|       break; |             break; | ||||||
|     case "ROOT": |         case 'ROUND': | ||||||
|       code = "sqrt(" + arg + ")"; |             code = 'round(' + arg + ')'; | ||||||
|       break; |             break; | ||||||
|     case "LN": |         case 'ROUNDUP': | ||||||
|       code = "log(" + arg + ")"; |             code = 'ceil(' + arg + ')'; | ||||||
|       break; |             break; | ||||||
|     case "EXP": |         case 'ROUNDDOWN': | ||||||
|       code = "exp(" + arg + ")"; |             code = 'floor(' + arg + ')'; | ||||||
|       break; |             break; | ||||||
|     case "POW10": |         case 'SIN': | ||||||
|       code = "pow(10," + arg + ")"; |             code = 'sin(' + arg + ' / 180 * Math.PI)'; | ||||||
|       break; |             break; | ||||||
|     case "ROUND": |         case 'COS': | ||||||
|       code = "round(" + arg + ")"; |             code = 'cos(' + arg + ' / 180 * Math.PI)'; | ||||||
|       break; |             break; | ||||||
|     case "ROUNDUP": |         case 'TAN': | ||||||
|       code = "ceil(" + arg + ")"; |             code = 'tan(' + arg + ' / 180 * Math.PI)'; | ||||||
|       break; |             break; | ||||||
|     case "ROUNDDOWN": |         default: | ||||||
|       code = "floor(" + arg + ")"; |             break; | ||||||
|       break; |     } | ||||||
|     case "SIN": |     if (code) { | ||||||
|       code = "sin(" + arg + " / 180 * Math.PI)"; |         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||||
|       break; |     } | ||||||
|     case "COS": |     // Second, handle cases which generate values that may need parentheses.
 | ||||||
|       code = "cos(" + arg + " / 180 * Math.PI)"; |     switch (operator) { | ||||||
|       break; |         case 'LOG10': | ||||||
|     case "TAN": |             code = 'log(' + arg + ') / log(10)'; | ||||||
|       code = "tan(" + arg + " / 180 * Math.PI)"; |             break; | ||||||
|       break; |         case 'ASIN': | ||||||
|     default: |             code = 'asin(' + arg + ') / M_PI * 180'; | ||||||
|       break; |             break; | ||||||
|   } |         case 'ACOS': | ||||||
|   if (code) { |             code = 'acos(' + arg + ') / M_PI * 180'; | ||||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; |             break; | ||||||
|   } |         case 'ATAN': | ||||||
|   // Second, handle cases which generate values that may need parentheses.
 |             code = 'atan(' + arg + ') / M_PI * 180'; | ||||||
|   switch (operator) { |             break; | ||||||
|     case "LOG10": |         default: | ||||||
|       code = "log(" + arg + ") / log(10)"; |             throw new Error('Unknown math operator: ' + operator); | ||||||
|       break; |     } | ||||||
|     case "ASIN": |     return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||||
|       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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {string} Completed code. |  * @return {string} Completed code. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_constant"] = function (block) { | Blockly.Arduino['math_constant'] = function (block) { | ||||||
|   var CONSTANTS = { |     var CONSTANTS = { | ||||||
|     PI: ["M_PI", Blockly.Arduino.ORDER_UNARY_POSTFIX], |         'PI': ['M_PI', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||||
|     E: ["M_E", Blockly.Arduino.ORDER_UNARY_POSTFIX], |         'E': ['M_E', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||||
|     GOLDEN_RATIO: ["(1 + sqrt(5)) / 2", Blockly.Arduino.ORDER_MULTIPLICATIVE], |         'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||||
|     SQRT2: ["M_SQRT2", Blockly.Arduino.ORDER_UNARY_POSTFIX], |         'SQRT2': ['M_SQRT2', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||||
|     SQRT1_2: ["M_SQRT1_2", Blockly.Arduino.ORDER_UNARY_POSTFIX], |         'SQRT1_2': ['M_SQRT1_2', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||||
|     INFINITY: ["INFINITY", Blockly.Arduino.ORDER_ATOMIC], |         'INFINITY': ['INFINITY', Blockly.Arduino.ORDER_ATOMIC] | ||||||
|   }; |     }; | ||||||
|   return CONSTANTS[block.getFieldValue("CONSTANT")]; |     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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_number_property"] = function (block) { | Blockly.Arduino['math_number_property'] = function (block) { | ||||||
|   var number_to_check = |     var number_to_check = Blockly.Arduino.valueToCode(block, 'NUMBER_TO_CHECK', | ||||||
|     Blockly.Arduino.valueToCode( |         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||||
|       block, |     var dropdown_property = block.getFieldValue('PROPERTY'); | ||||||
|       "NUMBER_TO_CHECK", |     var code; | ||||||
|       Blockly.Arduino.ORDER_MULTIPLICATIVE |     if (dropdown_property === 'PRIME') { | ||||||
|     ) || "0"; |         var func = [ | ||||||
|   var dropdown_property = block.getFieldValue("PROPERTY"); |             'boolean ' + Blockly.Arduino.DEF_FUNC_NAME + '(int n) {', | ||||||
|   var code; |             '  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods', | ||||||
|   if (dropdown_property === "PRIME") { |             '  if (n == 2 || n == 3) {', | ||||||
|     var func = [ |             '    return true;', | ||||||
|       "boolean " + Blockly.Arduino.DEF_FUNC_NAME + "(int n) {", |             '  }', | ||||||
|       "  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods", |             '  // False if n is NaN, negative, is 1.', | ||||||
|       "  if (n == 2 || n == 3) {", |             '  // And false if n is divisible by 2 or 3.', | ||||||
|       "    return true;", |             '  if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || ' + | ||||||
|       "  }", |             '(n % 3 == 0)) {', | ||||||
|       "  // False if n is NaN, negative, is 1.", |             '    return false;', | ||||||
|       "  // And false if n is divisible by 2 or 3.", |             '  }', | ||||||
|       "  if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || " + |             '  // Check all the numbers of form 6k +/- 1, up to sqrt(n).', | ||||||
|         "(n % 3 == 0)) {", |             '  for (int x = 6; x <= sqrt(n) + 1; x += 6) {', | ||||||
|       "    return false;", |             '    if (n % (x - 1) == 0 || n % (x + 1) == 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 true;', | ||||||
|       "      return false;", |             '}']; | ||||||
|       "    }", |         var funcName = Blockly.Arduino.addFunction('mathIsPrime', func.join('\n')); | ||||||
|       "  }", |         Blockly.Arduino.addInclude('math', '#include <math.h>'); | ||||||
|       "  return true;", |         code = funcName + '(' + number_to_check + ')'; | ||||||
|       "}", |         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||||
|     ]; |     } | ||||||
|     var funcName = Blockly.Arduino.addFunction("mathIsPrime", func.join("\n")); |     switch (dropdown_property) { | ||||||
|     Blockly.Arduino.addInclude("math", "#include <math.h>"); |         case 'EVEN': | ||||||
|     code = funcName + "(" + number_to_check + ")"; |             code = number_to_check + ' % 2 == 0'; | ||||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; |             break; | ||||||
|   } |         case 'ODD': | ||||||
|   switch (dropdown_property) { |             code = number_to_check + ' % 2 == 1'; | ||||||
|     case "EVEN": |             break; | ||||||
|       code = number_to_check + " % 2 == 0"; |         case 'WHOLE': | ||||||
|       break; |             Blockly.Arduino.addInclude('math', '#include <math.h>'); | ||||||
|     case "ODD": |             code = '(floor(' + number_to_check + ') == ' + number_to_check + ')'; | ||||||
|       code = number_to_check + " % 2 == 1"; |             break; | ||||||
|       break; |         case 'POSITIVE': | ||||||
|     case "WHOLE": |             code = number_to_check + ' > 0'; | ||||||
|       Blockly.Arduino.addInclude("math", "#include <math.h>"); |             break; | ||||||
|       code = "(floor(" + number_to_check + ") == " + number_to_check + ")"; |         case 'NEGATIVE': | ||||||
|       break; |             code = number_to_check + ' < 0'; | ||||||
|     case "POSITIVE": |             break; | ||||||
|       code = number_to_check + " > 0"; |         case 'DIVISIBLE_BY': | ||||||
|       break; |             var divisor = Blockly.Arduino.valueToCode(block, 'DIVISOR', | ||||||
|     case "NEGATIVE": |                 Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||||
|       code = number_to_check + " < 0"; |             code = number_to_check + ' % ' + divisor + ' == 0'; | ||||||
|       break; |             break; | ||||||
|     case "DIVISIBLE_BY": |         default: | ||||||
|       var divisor = |             break; | ||||||
|         Blockly.Arduino.valueToCode( |     } | ||||||
|           block, |     return [code, Blockly.Arduino.ORDER_EQUALITY]; | ||||||
|           "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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_change"] = function (block) { | Blockly.Arduino['math_change'] = function (block) { | ||||||
|   var argument0 = |     var argument0 = Blockly.Arduino.valueToCode(block, 'DELTA', | ||||||
|     Blockly.Arduino.valueToCode( |         Blockly.Arduino.ORDER_ADDITIVE) || '0'; | ||||||
|       block, |     var varName = Blockly.Arduino.variableDB_.getName( | ||||||
|       "DELTA", |         block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); | ||||||
|       Blockly.Arduino.ORDER_ADDITIVE |     return varName + ' += ' + argument0 + ';\n'; | ||||||
|     ) || "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"; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** Rounding functions have a single operand. */ | /** 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. */ | /** 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. |  * 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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @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). |  * 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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_modulo"] = function (block) { | Blockly.Arduino['math_modulo'] = function (block) { | ||||||
|   var argument0 = |     var argument0 = Blockly.Arduino.valueToCode(block, 'DIVIDEND', | ||||||
|     Blockly.Arduino.valueToCode( |         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||||
|       block, |     var argument1 = Blockly.Arduino.valueToCode(block, 'DIVISOR', | ||||||
|       "DIVIDEND", |         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||||
|       Blockly.Arduino.ORDER_MULTIPLICATIVE |     var code = argument0 + ' % ' + argument1; | ||||||
|     ) || "0"; |     return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||||
|   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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_constrain"] = function (block) { | Blockly.Arduino['math_constrain'] = function (block) { | ||||||
|   // Constrain a number between two limits.
 |     // Constrain a number between two limits.
 | ||||||
|   var argument0 = |     var argument0 = Blockly.Arduino.valueToCode(block, 'VALUE', | ||||||
|     Blockly.Arduino.valueToCode(block, "VALUE", Blockly.Arduino.ORDER_NONE) || |         Blockly.Arduino.ORDER_NONE) || '0'; | ||||||
|     "0"; |     var argument1 = Blockly.Arduino.valueToCode(block, 'LOW', | ||||||
|   var argument1 = |         Blockly.Arduino.ORDER_NONE) || '0'; | ||||||
|     Blockly.Arduino.valueToCode(block, "LOW", Blockly.Arduino.ORDER_NONE) || |     var argument2 = Blockly.Arduino.valueToCode(block, 'HIGH', | ||||||
|     "0"; |         Blockly.Arduino.ORDER_NONE) || '0'; | ||||||
|   var argument2 = |     var code = '(' + argument0 + ' < ' + argument1 + ' ? ' + argument1 + | ||||||
|     Blockly.Arduino.valueToCode(block, "HIGH", Blockly.Arduino.ORDER_NONE) || |         ' : ( ' + argument0 + ' > ' + argument2 + ' ? ' + argument2 + ' : ' + | ||||||
|     "0"; |         argument0 + '))'; | ||||||
|   var code = |     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||||
|     "(" + |  | ||||||
|     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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {array} Completed code with order of operation. |  * @return {array} Completed code with order of operation. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_random_int"] = function (block) { | Blockly.Arduino['math_random_int'] = function (block) { | ||||||
|   var argument0 = |     var argument0 = Blockly.Arduino.valueToCode(block, 'FROM', | ||||||
|     Blockly.Arduino.valueToCode(block, "FROM", Blockly.Arduino.ORDER_NONE) || |         Blockly.Arduino.ORDER_NONE) || '0'; | ||||||
|     "0"; |     var argument1 = Blockly.Arduino.valueToCode(block, 'TO', | ||||||
|   var argument1 = |         Blockly.Arduino.ORDER_NONE) || '0'; | ||||||
|     Blockly.Arduino.valueToCode(block, "TO", Blockly.Arduino.ORDER_NONE) || "0"; |     var functionName = Blockly.Arduino.variableDB_.getDistinctName( | ||||||
|   Blockly.Arduino.setupCode_["init_rand"] = "randomSeed(analogRead(0));"; |         'math_random_int', Blockly.Generator.NAME_TYPE); | ||||||
|   Blockly.Arduino.functionNames_[ |     Blockly.Arduino.setups_['init_rand'] = 'randomSeed(analogRead(0));'; | ||||||
|     "math_random_int" |     Blockly.Arduino.math_random_int.random_function = functionName; | ||||||
|   ] = `int mathRandomInt (int min, int max) {\n |     var func = [ | ||||||
|       if (min > max) { |         'int ' + Blockly.Arduino.DEF_FUNC_NAME + '(int min, int max) {', | ||||||
|         int temp = min; |         '  if (min > max) {', | ||||||
|         min = max; |         '    // Swap min and max to ensure min is smaller.', | ||||||
|         max = temp; |         '    int temp = min;', | ||||||
|       } |         '    min = max;', | ||||||
|       return min + (rand() % (max - min + 1)); |         '    max = temp;', | ||||||
|     } |         '  }', | ||||||
|     `;
 |         '  return min + (rand() % (max - min + 1));', | ||||||
|   var code = `mathRandomInt(${argument0},${argument1});`; |         '}']; | ||||||
|   return [code, Blockly.Arduino.ORDER_ATOMIC]; |     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. |  * @param {!Blockly.Block} block Block to generate the code from. | ||||||
|  * @return {string} Completed code. |  * @return {string} Completed code. | ||||||
|  */ |  */ | ||||||
| Blockly.Arduino["math_random_float"] = function (block) { | Blockly.Arduino['math_random_float'] = function (block) { | ||||||
|   return ["(rand() / RAND_MAX)", Blockly.Arduino.ORDER_UNARY_POSTFIX]; |     return ['(rand() / RAND_MAX)', Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||||
| }; | }; | ||||||
|  | |||||||