Compare commits

..
Author SHA1 Message Date
Mario Pesch 5901caa278 add multi interval feature 2021-04-22 15:28:30 +02:00
Mario Pesch b74aef8167 update blockly to latest release 2021-04-22 15:28:12 +02:00
Mario PeschandGitHub bc5cbb6b33 Merge pull request #77 from sensebox/fix/remove-warnings
resolve warnings
2021-03-21 11:48:18 +01:00
Mario Pesch 31e0880e7a resolve warnings 2021-03-19 15:27:18 +01:00
Mario PeschandGitHub 09a9318b24 Merge pull request #76 from sensebox/fix-double-wirelib
fix duplicate wire library
2021-03-19 11:21:41 +01:00
mariopesch 8dea4d97c5 fix npm (hopefully) 2021-03-19 11:12:01 +01:00
mariopesch d442b2f100 fix duplicate wire library 2021-03-19 10:54:17 +01:00
Mario PeschandGitHub a163c76463 Merge pull request #70 from sensebox/fix/gps-library
update to new gps library
2021-03-13 19:24:11 +01:00
Mario PeschandGitHub 7a34575314 Merge pull request #73 from sensebox/add/copyToClipboardButton
add copy to clipboard Button
2021-03-13 19:23:57 +01:00
Mario 5c843db50b add copy to clipboard Button 2021-03-13 19:20:29 +01:00
Mario 2e00fdaa1c update to new gps library 2021-03-11 10:57:43 +01:00
Mario PeschandGitHub a8f57b200c Merge pull request #68 from sensebox/dependabot/npm_and_yarn/prismjs-1.23.0
Bump prismjs from 1.21.0 to 1.23.0
2021-03-10 14:01:21 +01:00
Mario PeschandGitHub 4626addcfb Merge pull request #67 from sensebox/fix/update-lightsensor-code
update code for new lightsensor
2021-03-10 14:01:01 +01:00
dependabot[bot]andGitHub 421f7d00b1 Bump prismjs from 1.21.0 to 1.23.0
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.21.0 to 1.23.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.21.0...v1.23.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-01 21:31:05 +00:00
Mario 6d7e2782d6 update code for new lightsensor
need to use Board Support Package V1.4.0 with MCU Lib V1.4.0
2021-02-15 17:16:46 +01:00
Mario PeschandGitHub 5e4021d6d9 Merge pull request #65 from sensebox/fix-mqtt
fix for custom mqtt server
2021-02-15 16:21:26 +01:00
Mario 269afa4b76 fix for custom mqtt server 2021-02-15 10:47:01 +01:00
Mario PeschandGitHub 1963ca3051 Merge pull request #56 from sensebox/feat/add-sentry
Feat/add sentry
2021-01-20 11:56:27 +01:00
Mario 0d8c30c1ee add account information 2021-01-20 11:33:06 +01:00
Mario 957ccd566e add sentry 2021-01-19 19:54:33 +01:00
Mario 126dc3ecf4 add missing imports 2021-01-13 15:37:41 +01:00
Mario PeschandGitHub 851400e1c1 Merge pull request #55 from sensebox/fix-languageselection
fix the language selection
2021-01-13 15:05:15 +01:00
Mario b25a4d602a fix the language selection 2021-01-13 14:08:36 +01:00
Mario PeschandGitHub 97e28b62f8 Merge pull request #53 from sensebox/add-help-card
add tooltip viewer
2021-01-12 10:27:22 +01:00
Mario de9141c25c small fixes 2021-01-12 10:18:11 +01:00
Mario 7a31d94a21 complete sensor translations 2021-01-11 14:13:02 +01:00
Mario 8f47ae4fc8 reorder language files 2021-01-08 16:55:58 +01:00
Mario PeschandGitHub 4256d340c4 Merge pull request #47 from sensebox/dependabot/npm_and_yarn/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8
2021-01-06 11:32:54 +01:00
Mario 48e63fe898 update RGB-Block 2020-12-29 15:13:33 +01:00
Mario f6f6d6f1da add tooltip viewer 2020-12-22 09:36:13 +01:00
Mario PeschandGitHub 5eb6a94a0b Merge pull request #52 from sensebox/new-blocks
add new blocks
2020-12-21 12:12:31 +01:00
Mario 40f8c62696 remove field slider from rgb block 2020-12-21 11:57:32 +01:00
Mario 842b4522f0 add soundsensor 2020-12-21 11:22:54 +01:00
Mario c52e9db4c8 add watertemperature sensor 2020-12-21 10:59:05 +01:00
Mario 5658aa603c add soil moisture sensor 2020-12-21 10:43:08 +01:00
Mario PeschandGitHub 59fa90d43f Merge pull request #51 from sensebox/add-faq
Add faq
2020-12-21 10:24:29 +01:00
Mario 7940885388 add help text 2020-12-21 10:18:11 +01:00
Mario bf82a396fc add en translations 2020-12-21 10:12:00 +01:00
Mario 889fba21cc add faq page 2020-12-19 10:32:42 +01:00
Mario PeschandGitHub d91d22cdee Merge pull request #50 from sensebox/add-default-types
add default types
2020-12-18 10:21:09 +01:00
Mario a70e333d4d add default types 2020-12-18 10:17:20 +01:00
Mario PeschandGitHub ad1e5f1b82 Merge pull request #49 from sensebox/add-tour
Add tour
2020-12-18 09:17:54 +01:00
Mario 3e01ede7f1 add container to imprint and privacy 2020-12-17 14:46:15 +01:00
Mario 41739e7fb3 add news page 2020-12-17 14:43:35 +01:00
Mario fdcd5c9c5d add tour in de and en 2020-12-17 11:02:29 +01:00
Delucse b4a9f76d99 password placeholder 2020-12-15 22:30:55 +01:00
Delucse 1e9361b730 example of multilanguage tour 2020-12-15 16:18:47 +01:00
Delucse e4bab3d9ca add assessment tour 2020-12-15 16:09:29 +01:00
Delucse dce73e6a54 hide assessment-tour on various pages 2020-12-15 15:55:16 +01:00
Mario PeschandGitHub 307607191e Merge pull request #48 from sensebox/backend-connection
Backend connection
2020-12-15 15:22:23 +01:00
Mario 127c9551a0 hide tour on various pages 2020-12-15 15:19:06 +01:00
Mario 8504dacc38 add tour 2020-12-15 15:01:26 +01:00
Delucse 0239ae28aa create tutorial buttons 2020-12-15 11:33:04 +01:00
Delucse 84ce074aec aprovement of adding badge to tutorial 2020-12-15 11:18:59 +01:00
Mario 7d876e8bf9 codeviewer translations 2020-12-15 10:39:22 +01:00
Mario 813582bf9d translations for login page 2020-12-15 10:27:50 +01:00
Mario 256593164f add navbar translations 2020-12-15 10:04:33 +01:00
Mario 9d65f7b944 add en translations 2020-12-15 09:51:12 +01:00
Delucse b04a5bc591 store locale in localStorage only if user is not logged in 2020-12-14 20:04:49 +01:00
Delucse 49730f51ac public route 2020-12-14 19:26:07 +01:00
Delucse 4588e2a69b Merge branch 'add-translations' into backend-connection 2020-12-14 15:23:01 +01:00
Delucse a99ecc36a4 routing improvement 2020-12-14 15:15:08 +01:00
Delucse 5a7e62adcf Merge branch 'add-translations' of https://github.com/sensebox/React-Ardublockly into add-translations 2020-12-14 14:48:16 +01:00
Delucse c6a1e854d2 get locale from user if exists 2020-12-14 14:48:12 +01:00
Mario e5204bb4d5 add more translations and resolve issues 2020-12-14 13:50:44 +01:00
Delucse e52e3943c1 add generalReducer to store settings 2020-12-14 13:06:55 +01:00
Mario 7d1d2409e4 add first translations 2020-12-14 08:51:31 +01:00
Delucse 42981a4f11 badge selection 2020-12-13 20:52:23 +01:00
dependabot[bot]andGitHub a6e800c91b Bump ini from 1.3.5 to 1.3.8
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-13 06:33:56 +00:00
Delucse 4f002d8694 definig success and error callbacks for every private axios request 2020-12-11 14:35:24 +01:00
Delucse 1821ac4e40 tutorial status is stored in user account if exists or in local storage 2020-12-11 13:06:38 +01:00
Mario PeschandGitHub 3d2a18c1db Merge pull request #46 from sensebox/slice-empty-sensor
slice first empty option from sensor array
2020-12-10 14:53:49 +01:00
Mario PeschandGitHub a929c3d8e6 Merge pull request #37 from sensebox/backend-connection
Backend connection
2020-12-10 14:42:11 +01:00
Delucse 5430e783cc show assigned badge 2020-12-10 10:31:43 +01:00
Delucse 101dfc7692 assigne badge after tutorial-success 2020-12-09 19:34:44 +01:00
Delucse f9caeb619e connect to MyBadges-account 2020-12-09 18:10:45 +01:00
Mario ac127dcca2 slice first empty option from sensor array 2020-12-09 16:10:37 +01:00
Delucse c47d98d2eb compile button 2020-12-09 09:34:33 +01:00
Delucse 3655063eaa Merge branch 'backend-connection' of https://github.com/sensebox/React-Ardublockly into backend-connection 2020-12-08 20:16:15 +01:00
Delucse a4cf0d32b0 adjustment of the project object property 'shared' 2020-12-08 20:15:54 +01:00
Mario PeschandGitHub c4c9ddc127 Merge pull request #40 from sensebox/compile-button-color
update compile button color
2020-12-08 20:14:40 +01:00
Mario f53baf2536 update compile button color 2020-12-08 20:06:51 +01:00
Delucse 3cf7f10d34 delete tutorial button at tutorial builder 2020-12-08 15:33:03 +01:00
Delucse e6813ba2d3 create modular structure of WorkspaceFunc component 2020-12-08 13:53:43 +01:00
Mario a1834875a0 Update store.js 2020-12-08 10:34:11 +01:00
Mario PeschandGitHub 2285f52a0c Merge pull request #38 from sensebox/add-access-token
add access-token
2020-12-08 09:43:30 +01:00
Delucse 646254017c display account information 2020-12-07 20:12:33 +01:00
Delucse 80fd3b83a9 Merge branch 'backend-connection' of https://github.com/sensebox/React-Ardublockly into backend-connection 2020-12-07 18:19:08 +01:00
Delucse 50e22fdf92 possiblilty to change title of project, get share link, delete project for every project via button 2020-12-07 18:18:08 +01:00
Mario 0e05cdca5c add access-token 2020-12-07 16:26:18 +01:00
Mario 49fb018703 fix build process 2020-12-07 15:44:56 +01:00
Delucse b2f6b1d012 display of the sharing link validity 2020-12-07 14:15:08 +01:00
Delucse dddb00bd79 osem boxes dropdown blockly menu 2020-12-07 12:33:47 +01:00
Delucse 6a8036e075 restrictions in the accessibility of URLs 2020-12-03 16:56:04 +01:00
Delucse 31dbda57df load user, if valid token exists 2020-12-03 15:38:47 +01:00
Delucse 80fd112658 private routes and redirecting 2020-12-03 12:09:01 +01:00
Delucse 5d9bfa97af login 2020-12-03 11:17:39 +01:00
Delucse 4f57e7fd32 note, if no data are available in database 2020-12-02 18:49:08 +01:00
Delucse e2915e8cd0 update gallery-project 2020-12-02 18:04:03 +01:00
Delucse 155675821a delete (gallery-)project 2020-12-02 17:16:40 +01:00
Delucse c5fd5c6239 update project 2020-12-02 15:21:28 +01:00
Delucse a30747c608 project redux store 2020-12-02 14:02:03 +01:00
Delucse a8e36a4f06 create and display projects 2020-12-02 12:42:45 +01:00
Delucse e600c19679 new script: npm run dev 2020-12-01 19:35:53 +01:00
Delucse 0d4072ab17 redirection to home if no share or gallery content is available 2020-12-01 19:05:14 +01:00
Delucse 2dfd146d18 display gallery content 2020-12-01 18:01:52 +01:00
Delucse 2e330d1215 Merge branch 'assessment' into backend-connection 2020-12-01 14:43:25 +01:00
Delucse 47f0ebb80d restriction of workspace functions in context tutorials 2020-12-01 14:37:32 +01:00
Delucse 6db8c094ea create and display content to share 2020-12-01 13:29:52 +01:00
Delucse d0dda4038e change existing tutorial with Tutorial-Builder 2020-11-30 17:19:32 +01:00
Delucse c8f01f8273 load pictures from the api server 2020-11-30 13:44:05 +01:00
Delucse a2c571c1e7 adjustments do mongoDB output 2020-11-27 17:21:42 +01:00
Delucse 2d29b8d7bd load tutorial only once 2020-11-27 13:31:03 +01:00
Delucse 28720edeea linear progress at navbar 2020-11-27 12:26:16 +01:00
Delucse cbe091db27 updated status reading 2020-11-27 12:06:13 +01:00
Delucse b8a2f87321 get all tutorials about the API 2020-11-27 09:30:42 +01:00
Delucse ea00d173c5 get a tutorial about the API 2020-11-27 08:41:34 +01:00
Mario PeschandGitHub 28d674b6cd Merge pull request #34 from sensebox/add-impressum
add impressum
2020-11-25 18:23:06 +01:00
Mario aae3771020 add impressum 2020-11-25 18:18:45 +01:00
Mario PeschandGitHub 18ac32893c Merge pull request #30 from sensebox/add-lora-tutorial
add lora tutorial
2020-11-18 12:06:04 +01:00
Mario 14260efa3b add lora tutorial 2020-11-17 16:49:49 +01:00
Mario PeschandGitHub 73aa1ef878 Merge pull request #29 from sensebox/add-markdown
Add markdown
2020-11-17 16:47:17 +01:00
Mario 38700bf57c remove lora tutorial 2020-11-17 16:38:39 +01:00
Mario 0829522743 fix build error 2020-11-17 16:36:23 +01:00
Mario 7ffe9ff18b add some styling 2020-11-16 15:51:44 +01:00
Mario PeschandGitHub 1b0743b0cf Merge pull request #28 from sensebox/small-fixes
Small fixes
2020-11-16 14:16:03 +01:00
Mario PeschandGitHub b4fb4f8501 Merge branch 'add-markdown' into small-fixes 2020-11-16 14:15:32 +01:00
Mario 02a64b9a8f add new tutorial and hardware 2020-11-16 14:14:43 +01:00
Mario PeschandGitHub 4255d14873 Merge pull request #27 from sensebox/small-fixes
small code fixes
2020-11-16 09:35:13 +01:00
Mario c17fc8a50f small code fixes 2020-11-16 09:27:26 +01:00
Mario fd21bd76f9 update tutorials 2020-11-16 09:05:47 +01:00
Mario b60ec9136a allow markdown in tutorial text 2020-11-13 15:33:21 +01:00
Mario PeschandGitHub 13d2d3d301 Merge pull request #26 from sensebox/fix-logic-block
fix logic block
2020-11-12 11:47:06 +01:00
Mario b68fb77663 fix logic block 2020-11-12 11:40:38 +01:00
Mario PeschandGitHub e81627b8ec Merge pull request #25 from sensebox/blocks/webserver
Blocks/webserver
2020-11-12 09:05:44 +01:00
Mario 4e34c63f08 fix color in mutator 2020-11-11 15:48:41 +01:00
Mario dad91d0a93 resolve warnings 2020-11-11 15:29:56 +01:00
Mario 0183679041 add webserver blocks 2020-11-11 15:24:33 +01:00
Mario d649c3d395 small spelling changes 2020-11-11 14:46:29 +01:00
Mario PeschandGitHub bbc3022644 Merge pull request #23 from sensebox/add-procedures
[WIP] - Add procedures
2020-11-11 14:10:41 +01:00
Mario PeschandGitHub aa8b1067dc Merge pull request #24 from sensebox/blocks/mqtt
Blocks/mqtt
2020-11-11 14:08:44 +01:00
Mario 9318d3ef12 add services 2020-11-11 12:37:51 +01:00
Mario fe328f9da3 add first draft for mqtt blocks 2020-11-11 11:09:19 +01:00
Mario PeschandGitHub 3df66cd425 Merge pull request #22 from sensebox/gps-ttn-mapper
[WIP] initial gps ttn mapper code
2020-11-06 11:56:19 +01:00
Mario 3dfcffc2ad add translations 2020-11-06 11:02:28 +01:00
Mario 0cba423749 switch order 2020-11-06 10:27:58 +01:00
Mario b1b80f8af0 Update Toolbox.js 2020-11-06 10:23:44 +01:00
Mario 2e4df70ddd add gps blocks to toolbox 2020-11-06 10:16:41 +01:00
felixerdy 5621fdc620 add some delay and fix type limit 2020-11-05 20:57:17 +01:00
Mario b4a59d3875 put initLora always to the end of the setup 2020-11-05 18:48:19 +01:00
Mario 70c8a1db60 add feature to hide Workspace stats 2020-11-05 18:30:27 +01:00
Mario 5da3006e75 small fixes 2020-11-05 14:38:38 +01:00
Mario 8e2deed1d5 init implementation of procedures 2020-11-05 11:05:14 +01:00
felixerdy 7b89897e54 initial gps ttn mapper code 2020-10-30 12:25:03 +01:00
Mario PeschandGitHub 4601439ae3 Merge pull request #21 from sensebox/add-cookie-consent
add cookie consent
2020-10-29 11:23:19 +01:00
Mario fd1d8c35e5 add cookie consent
fix #15
2020-10-29 11:09:50 +01:00
Mario PeschandGitHub b07d753e6c Merge pull request #19 from sensebox/feat/blockly-gallery
add blockly project gallery
2020-10-29 10:58:40 +01:00
Mario f1ea8ca2e8 Merge branch 'feat/blockly-gallery' of https://github.com/sensebox/React-Ardublockly into feat/blockly-gallery 2020-10-29 10:51:17 +01:00
Mario cc54c18b47 update osem block 2020-10-29 10:50:48 +01:00
Mario PeschandGitHub bc819f224b Merge branch 'master' into feat/blockly-gallery 2020-10-29 08:50:41 +01:00
Mario 14947267d1 add language selection 2020-10-29 08:48:35 +01:00
Mario PeschandGitHub 0a459938a8 Merge branch 'master' into feat/blockly-gallery 2020-10-20 10:49:31 +02:00
Mario PeschandGitHub 61ca2e8799 Merge pull request #20 from sensebox/dynamic-osem-dropdown
Dynamic osem dropdown
2020-10-17 14:18:54 +02:00
Mario 71a73ddd1d cleanup code 2020-10-17 14:18:05 +02:00
Mario 9dedc9ccd1 generate dynamic dropdowns 2020-10-17 14:17:37 +02:00
Mario 145c14c0cc Update WorkspaceFunc.js 2020-10-17 09:42:54 +02:00
Mario d7b725d1fd add margin 2020-10-16 23:58:00 +02:00
Mario 09c5ef5aae update api endpoint 2020-10-16 22:52:13 +02:00
Mario dbebb25b17 fix variable Name 2020-10-16 22:36:43 +02:00
Mario e647d6e58e add block sharing 2020-10-16 22:33:02 +02:00
Mario 0cb7bba521 add blockly project gallery 2020-10-16 14:32:52 +02:00
210 changed files with 61504 additions and 17572 deletions
+7
View File
@@ -1,2 +1,9 @@
REACT_APP_COMPILER_URL=https://compiler.sensebox.de
REACT_APP_BOARD=sensebox-mcu
REACT_APP_BLOCKLY_API=https://api.blockly.sensebox.de
REACT_APP_MYBADGES=https://mybadges.org
REACT_APP_MYBADGES_API=https://mybadges.org/api/v1
# in days
REACT_APP_SHARE_LINK_EXPIRES=30
+93
View File
@@ -0,0 +1,93 @@
# 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_880bb55f28e0dbb0bb9c2160d8e50594.png)
## 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_0d505fc2472178182995732af226e736.png)
### 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_bd9544b118a1dbe83d149c00678eb39d.png)
### 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_a9df4b0b9b1e6f39f09cf3b1743caad2.png)
### 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_b59691f2ebcf04d8b67a5f4e7fbe70b6.png)
## 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_c3965edc99021339a30b8d6704471e50.png)
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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_57284cea57bfa5df3d55fe456f9d7cfa.png)
### Speichern von Projekten
Nach dem Login über den openSenseMap Account lassen sich Projekte online speichern und wieder abrufen
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_148146b1206fde184afff6edce26b515.png)
### Tutorials
Es gibt jetzt Tutorials! Eine reihe von verschiedenen Tutorials zeigt dir die ersten Schritte in der Programmierung mit Blockly. (Inhalte werden noch ausgebaut)
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_db0e64df48d4c34a9540ffb089e95769.png)
### 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_c61e1fa98f9d840507a8a53b00605484.png)
### 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.
![](https://radosgw.public.os.wwu.de/pad/uploads/upload_a8dba6720fe2fb39cadf129d9bb04a62.png)
## Fehler
Falls ihr Fehler findet legt bitte ein Issue in folgendem Repository an: https://github.com/sensebox/React-Ardublockly/issues
+4 -4
View File
@@ -2,18 +2,18 @@
# React Ardublockly
This repository contains the source code and documentation of [sensebox-ardublockly](https://sensebox-ardublockly.netlify.app/) :rocket:.
This repository contains the source code and documentation of [sensebox-ardublockly](https://sensebox-ardublockly.netlify.app/).
This project was created with [Create React App](https://github.com/facebook/create-react-app) and represents the continuation or improvement of [blockly.sensebox.de](https://blockly.sensebox.de/ardublockly/?lang=de&board=sensebox-mcu).
## Getting Started
1. [Download](https://github.com/sensebox/React-Ardublockly/archive/bachelor.zip) or clone the GitHub Repository ``git clone https://github.com/sensebox/React-Ardublockly`` and checkout to branch ``bachelor``.
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``.
2. install [Node.js v10.xx](https://nodejs.org/en/) on your local machine
3. open shell and navigate inside folder ``React-Ardublockly`` or rather ``Quellcode``
3. open shell and navigate inside folder ``React-Ardublockly``
* run ``npm install``
* run ``npm start``
4. open [localhost:3000](http://localhost:3000)
@@ -22,7 +22,7 @@ This project was created with [Create React App](https://github.com/facebook/cre
Ensure that line 14 in [store.js](https://github.com/sensebox/React-Ardublockly/blob/master/src/store.js#L14) is commented out or otherwise you have installed [Redux DevTools Extension](http://extension.remotedev.io/).
## Demo
A demo of the current status of the bachelor branch can be accessed via [sensebox-ardublockly.netlify.app](https://sensebox-ardublockly.netlify.app/) :rocket:.
A demo of the current status of the master 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)
+34810 -4217
View File
File diff suppressed because it is too large Load Diff
+15 -5
View File
@@ -5,28 +5,38 @@
"dependencies": {
"@blockly/block-plus-minus": "^2.0.10",
"@blockly/field-slider": "^2.1.1",
"@blockly/plugin-typed-variable-modal": "^3.1.1",
"@blockly/plugin-typed-variable-modal": "^3.1.15",
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/react-fontawesome": "^0.1.11",
"@material-ui/core": "^4.11.0",
"@sentry/react": "^6.0.0",
"@sentry/tracing": "^6.0.0",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"blockly": "^3.20200924.0",
"axios": "^0.21.0",
"blockly": "^5.20210325.1",
"file-saver": "^2.0.2",
"mnemonic-id": "^3.2.7",
"moment": "^2.28.0",
"prismjs": "^1.20.0",
"prismjs": "^1.23.0",
"react": "^16.13.1",
"react-cookie-consent": "^5.2.0",
"react-dom": "^16.13.1",
"react-markdown": "^5.0.2",
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"react-scripts": "^4.0.3",
"reactour": "^1.18.0",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
"redux-thunk": "^2.3.0",
"styled-components": "^4.4.1",
"uuid": "^8.3.1"
},
"scripts": {
"start": "react-scripts start",
"dev": "set \"REACT_APP_BLOCKLY_API=http://localhost:8080\" && set \"REACT_APP_MYBADGES_API=http://localhost:3001/api/v1\"&& npm start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

+44
View File
@@ -5,3 +5,47 @@
position: relative;
padding-bottom: 60px; /* height of your footer + 30px*/
}
.tutorial img{
display: flex;
align-items: center;
max-height: 40vH;
max-width: 100%;
margin: auto;
}
.news img{
display: flex;
align-items: center;
max-height: 40vH;
max-width: 100%;
margin: auto;
}
.tutorial blockquote{
background: #f9f9f9;
border-left: 10px solid#4EAF47;
margin: 1.5em 10px;
padding: 0.5em 10px;
quotes: "\201C""\201D""\2018""\2019";
}
blockquote:before {
color:#4EAF47;
content: open-quote;
font-size: 4em;
line-height: 0.1em;
margin-right: 0.25em;
vertical-align: -0.4em;
}
blockquote p {
display: inline;
}
.overlay {
display: flex;
flex-direction: column;
align-items: center;
}
+15 -12
View File
@@ -1,18 +1,17 @@
import React from 'react';
import React, { Component } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { createBrowserHistory } from "history";
import { Provider } from 'react-redux';
import store from './store';
import { loadUser } from './actions/authActions';
import './App.css';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import Routes from './components/Routes';
import Content from './components/Content';
const theme = createMuiTheme({
palette: {
@@ -22,27 +21,31 @@ const theme = createMuiTheme({
},
secondary: {
main: '#DDDDDD'
},
button: {
compile: '#e27136'
}
}
});
class App extends Component {
componentDidMount() {
store.dispatch(loadUser());
}
render() {
const customHistory = createBrowserHistory();
function App() {
return (
<ThemeProvider theme={theme}>
<Provider store={store}>
<Router history={customHistory}>
<div className="wrapper">
<Navbar />
<Routes />
<Footer />
</div>
<Content />
</Router>
</Provider>
</ThemeProvider>
);
}
}
export default App;
+294
View File
@@ -0,0 +1,294 @@
import { MYBADGES_CONNECT, MYBADGES_DISCONNECT, 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);
});
};
var logoutTimerId;
const timeToLogout = 14.9*60*1000; // nearly 15 minutes corresponding to the API
// 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 => {
// Logout automatically if refreshToken "expired"
const logoutTimer = () => setTimeout(
() => dispatch(logout()),
timeToLogout
);
logoutTimerId = logoutTimer();
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
});
});
};
// Connect to MyBadges-Account
export const connectMyBadges = ({ username, password }) => (dispatch, getState) => {
const config = {
success: res => {
var user = getState().auth.user;
user.badge = res.data.account;
user.badges = res.data.badges;
dispatch({
type: MYBADGES_CONNECT,
payload: user
});
dispatch(returnSuccess(res.data.message, res.status, 'MYBADGES_CONNECT_SUCCESS'));
},
error: err => {
dispatch(returnErrors(err.response.data.message, err.response.status, 'MYBADGES_CONNECT_FAIL'));
}
};
// Request Body
const body = JSON.stringify({ username, password });
axios.post(`${process.env.REACT_APP_BLOCKLY_API}/user/badge`, body, config)
.then(res => {
res.config.success(res);
})
.catch(err => {
if(err.response && err.response.status !== 401){
err.config.error(err);
}
});
};
// Disconnect MyBadges-Account
export const disconnectMyBadges = () => (dispatch, getState) => {
const config = {
success: res => {
var user = getState().auth.user;
user.badge = null;
user.badges = null;
dispatch({
type: MYBADGES_DISCONNECT,
payload: user
});
dispatch(returnSuccess(res.data.message, res.status, 'MYBADGES_DISCONNECT_SUCCESS'));
},
error: err => {
dispatch(returnErrors(err.response.data.message, err.response.status, 'MYBADGES_DISCONNECT_FAIL'));
}
};
axios.put(`${process.env.REACT_APP_BLOCKLY_API}/user/badge`, {}, config)
.then(res => {
res.config.success(res);
})
.catch(err => {
if(err.response && err.response.status !== 401){
err.config.error(err);
}
});
};
// 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'));
clearTimeout(logoutTimerId);
},
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
});
clearTimeout(logoutTimerId);
}
};
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) {
clearTimeout(logoutTimerId);
const logoutTimer = () => setTimeout(
() => dispatch(logout()),
timeToLogout
);
logoutTimerId = logoutTimer();
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);
}
);
};
+25 -1
View File
@@ -1,4 +1,4 @@
import { VISIT } from './types';
import { VISIT, LANGUAGE, RENDERER, STATISTICS } from './types';
export const visitPage = () => (dispatch) => {
@@ -6,3 +6,27 @@ export const visitPage = () => (dispatch) => {
type: VISIT
});
};
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 setStatistics = (showStatistics) => (dispatch) => {
dispatch({
type: STATISTICS,
payload: showStatistics
});
};
+32
View File
@@ -0,0 +1,32 @@
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
};
};
+204
View File
@@ -0,0 +1,204 @@
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(''));
};
+206 -19
View File
@@ -1,6 +1,152 @@
import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types';
import { MYBADGES_DISCONNECT, TUTORIAL_PROGRESS, GET_TUTORIAL, GET_TUTORIALS, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_STEP } from './types';
import tutorials from '../data/tutorials';
import axios from 'axios';
import { returnErrors, returnSuccess } from './messageActions';
export const tutorialProgress = () => (dispatch) => {
dispatch({type: TUTORIAL_PROGRESS});
};
export const getTutorial = (id) => (dispatch, getState) => {
axios.get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/${id}`)
.then(res => {
var tutorial = res.data.tutorial;
existingTutorial(tutorial, getState().tutorial.status).then(status => {
dispatch({
type: TUTORIAL_SUCCESS,
payload: status
});
dispatch(updateStatus(status));
dispatch({
type: GET_TUTORIAL,
payload: tutorial
});
dispatch({type: TUTORIAL_PROGRESS});
dispatch(returnSuccess(res.data.message, res.status));
});
})
.catch(err => {
if (err.response) {
dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_TUTORIAL_FAIL'));
}
dispatch({ type: TUTORIAL_PROGRESS });
});
};
export const getTutorials = () => (dispatch, getState) => {
axios.get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial`)
.then(res => {
var tutorials = res.data.tutorials;
console.log(tutorials);
existingTutorials(tutorials, getState().tutorial.status).then(status => {
dispatch({
type: TUTORIAL_SUCCESS,
payload: status
});
console.log('zwei');
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 assigneBadge = (id) => (dispatch, getState) => {
const config = {
success: res => {
var badge = res.data.badge;
var user = getState().auth.user;
user.badges.push(badge._id);
dispatch({
type: MYBADGES_DISCONNECT,
payload: user
});
dispatch(returnSuccess(badge, res.status, 'ASSIGNE_BADGE_SUCCESS'));
},
error: err => {
dispatch(returnErrors(err.response.data.message, err.response.status, 'ASSIGNE_BADGE_FAIL'));
}
};
axios.put(`${process.env.REACT_APP_BLOCKLY_API}/user/badge/${id}`, {}, config)
.then(res => {
res.config.success(res);
})
.catch(err => {
if(err.response && err.response.status !== 401){
err.config.error(err);
}
});
};
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 => {
// dispatch(returnSuccess(badge, res.status, 'UPDATE_STATUS_SUCCESS'));
})
.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) => {
dispatch({
@@ -10,9 +156,9 @@ export const tutorialChange = () => (dispatch) => {
export const tutorialCheck = (status, step) => (dispatch, getState) => {
var tutorialsStatus = getState().tutorial.status;
var id = getState().tutorial.currentId;
var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id);
var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === step.id);
var id = getState().tutorial.tutorials[0]._id;
var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus._id === id);
var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task._id === step._id);
tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = {
...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex],
type: status
@@ -21,18 +167,22 @@ export const tutorialCheck = (status, step) => (dispatch, getState) => {
type: status === 'success' ? TUTORIAL_SUCCESS : TUTORIAL_ERROR,
payload: tutorialsStatus
});
console.log('drei');
dispatch(updateStatus(tutorialsStatus));
dispatch(tutorialChange());
dispatch(returnSuccess('', '', 'TUTORIAL_CHECK_SUCCESS'));
};
export const storeTutorialXml = (code) => (dispatch, getState) => {
var id = getState().tutorial.currentId;
if (id !== null) {
var tutorial = getState().tutorial.tutorials[0];
if (tutorial) {
var id = tutorial._id;
var activeStep = getState().tutorial.activeStep;
var steps = tutorials.filter(tutorial => tutorial.id === id)[0].steps;
if (steps[activeStep].type === 'task') {
var steps = tutorial.steps;
if (steps && steps[activeStep].type === 'task') {
var tutorialsStatus = getState().tutorial.status;
var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id);
var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === steps[activeStep].id);
var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus._id === id);
var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task._id === steps[activeStep]._id);
tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = {
...tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex],
xml: code
@@ -41,21 +191,58 @@ export const storeTutorialXml = (code) => (dispatch, getState) => {
type: TUTORIAL_XML,
payload: tutorialsStatus
});
dispatch(updateStatus(tutorialsStatus));
}
}
};
export const tutorialId = (id) => (dispatch) => {
dispatch({
type: TUTORIAL_ID,
payload: id
});
};
export const tutorialStep = (step) => (dispatch) => {
dispatch({
type: TUTORIAL_STEP,
payload: step
});
};
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);
});
+18 -8
View File
@@ -1,4 +1,4 @@
import { PROGRESS, JSON_STRING, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP, BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from './types';
import { PROGRESS, JSON_STRING, BUILDER_CHANGE, BUILDER_ERROR, BUILDER_TITLE, BUILDER_ID, BUILDER_BADGE, BUILDER_ADD_STEP, BUILDER_DELETE_STEP, BUILDER_CHANGE_STEP, BUILDER_CHANGE_ORDER, BUILDER_DELETE_PROPERTY } from './types';
import data from '../data/hardware.json';
@@ -39,6 +39,14 @@ export const tutorialId = (id) => (dispatch) => {
dispatch(changeTutorialBuilder());
};
export const tutorialBadge = (badge) => (dispatch) => {
dispatch({
type: BUILDER_BADGE,
payload: badge
});
dispatch(changeTutorialBuilder());
};
export const addStep = (index) => (dispatch, getState) => {
var steps = getState().builder.steps;
var step = {
@@ -180,16 +188,19 @@ export const setSubmitError = () => (dispatch, getState) => {
// if(builder.id === undefined || builder.id === ''){
// dispatch(setError(undefined, 'id'));
// }
if (builder.id === undefined || builder.title === '') {
if (builder.title === '') {
dispatch(setError(undefined, 'title'));
}
if (builder.title === null) {
dispatch(setError(undefined, 'badge'));
}
var type = builder.steps.map((step, i) => {
// media and xml are directly checked for errors in their components and
// therefore do not have to be checked again
step.id = i + 1;
if (i === 0) {
if (step.requirements && step.requirements.length > 0) {
var requirements = step.requirements.filter(requirement => typeof (requirement) === 'number');
var requirements = step.requirements.filter(requirement => /^[0-9a-fA-F]{24}$/.test(requirement));
if (requirements.length < step.requirements.length) {
dispatch(changeContent(requirements, i, 'requirements'));
}
@@ -222,7 +233,7 @@ export const setSubmitError = () => (dispatch, getState) => {
export const checkError = () => (dispatch, getState) => {
dispatch(setSubmitError());
var error = getState().builder.error;
if (error.id || error.title || error.type) {
if (error.id || error.title || error.badge ||error.type) {
return true;
}
for (var i = 0; i < error.steps.length; i++) {
@@ -243,10 +254,9 @@ export const progress = (inProgress) => (dispatch) => {
export const resetTutorial = () => (dispatch, getState) => {
dispatch(jsonString(''));
dispatch(tutorialTitle(''));
dispatch(tutorialId(''));
dispatch(tutorialBadge(undefined));
var steps = [
{
id: 1,
type: 'instruction',
headline: '',
text: '',
@@ -274,7 +284,7 @@ export const readJSON = (json) => (dispatch, getState) => {
// accept only valid attributes
var steps = json.steps.map((step, i) => {
var object = {
id: step.id,
_id: step._id,
type: step.type,
headline: step.headline,
text: step.text
@@ -298,7 +308,7 @@ export const readJSON = (json) => (dispatch, getState) => {
return object;
});
dispatch(tutorialTitle(json.title));
dispatch(tutorialId(json.id));
dispatch(tutorialBadge(json.badge));
dispatch(tutorialSteps(steps));
dispatch(setSubmitError());
dispatch(progress(false));
+34 -1
View File
@@ -1,3 +1,16 @@
// authentication
export const USER_LOADING = 'USER_LOADING';
export const USER_LOADED = 'USER_LOADED';
export const AUTH_ERROR = 'AUTH_ERROR';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LOGIN_FAIL = 'LOGIN_FAIL';
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
export const LOGOUT_FAIL = 'LOGOUT_FAIL';
export const REFRESH_TOKEN_FAIL = 'REFRESH_TOKEN_FAIL';
export const REFRESH_TOKEN_SUCCESS = 'REFRESH_TOKEN_SUCCESS';
export const MYBADGES_CONNECT = 'MYBADGES_CONNECT';
export const MYBADGES_DISCONNECT = 'MYBADGES_DISCONNECT';
export const NEW_CODE = 'NEW_CODE';
export const CHANGE_WORKSPACE = 'CHANGE_WORKSPACE';
export const CREATE_BLOCK = 'CREATE_BLOCK';
@@ -7,7 +20,10 @@ export const DELETE_BLOCK = 'DELETE_BLOCK';
export const CLEAR_STATS = 'CLEAR_STATS';
export const NAME = 'NAME';
export const TUTORIAL_PROGRESS = 'TUTORIAL_PROGRESS';
export const GET_TUTORIAL = 'GET_TUTORIAL';
export const GET_TUTORIALS = 'GET_TUTORIALS';
export const GET_STATUS = 'GET_STATUS';
export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS';
export const TUTORIAL_ERROR = 'TUTORIAL_ERROR';
export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE';
@@ -19,6 +35,7 @@ export const JSON_STRING = 'JSON_STRING';
export const BUILDER_CHANGE = 'BUILDER_CHANGE';
export const BUILDER_TITLE = 'BUILDER_TITLE';
export const BUILDER_BADGE = 'BUILDER_BADGE';
export const BUILDER_ID = 'BUILDER_ID';
export const BUILDER_ADD_STEP = 'BUILDER_ADD_STEP';
export const BUILDER_DELETE_STEP = 'BUILDER_DELETE_STEP';
@@ -30,3 +47,19 @@ export const PROGRESS = 'PROGRESS';
export const VISIT = 'VISIT';
export const LANGUAGE = 'LANGUAGE';
export const RENDERER = 'RENDERER';
export const STATISTICS = 'STATISTICS';
// messages
export const GET_ERRORS = 'GET_ERRORS';
export const GET_SUCCESS = 'GET_SUCCESS';
export const CLEAR_MESSAGES = 'CLEAR_MESSAGES';
// projects: share, gallery, project
export const PROJECT_PROGRESS = 'PROJECT_PROGRESS';
export const GET_PROJECT = 'GET_PROJECT';
export const GET_PROJECTS = 'GET_PROJECTS';
export const PROJECT_TYPE = 'PROJECT_TYPE';
export const PROJECT_DESCRIPTION = 'PROJECT_DESCRIPTION';
+11
View File
@@ -16,6 +16,17 @@ export const onChangeCode = () => (dispatch, getState) => {
code.arduino = Blockly.Arduino.workspaceToCode(workspace);
var xmlDom = Blockly.Xml.workspaceToDom(workspace);
code.xml = Blockly.Xml.domToPrettyText(xmlDom);
var selectedBlock = Blockly.selected
console.log(selectedBlock)
if (selectedBlock !== null) {
code.helpurl = selectedBlock.helpUrl
code.tooltip = selectedBlock.tooltip
} else if (selectedBlock === null) {
code.tooltip = Blockly.Msg.tooltip_hint
code.helpurl = ''
}
dispatch({
type: NEW_CODE,
payload: code
+34
View File
@@ -0,0 +1,34 @@
import React, { Component } from 'react';
import { withStyles } from '@material-ui/core/styles';
import { fade } from '@material-ui/core/styles/colorManipulator';
import Typography from '@material-ui/core/Typography';
const styles = (theme) => ({
alert: {
marginBottom: '20px',
border: `1px solid ${theme.palette.primary.main}`,
padding: '10px 20px',
borderRadius: '4px',
background: fade(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);
@@ -24,14 +24,12 @@
import React from 'react';
import Blockly from 'blockly/core';
import locale from 'blockly/msg/en';
import 'blockly/blocks';
import Toolbox from './toolbox/Toolbox';
import { Card } from '@material-ui/core';
Blockly.setLocale(locale);
class BlocklyComponent extends React.Component {
+1 -2
View File
@@ -53,7 +53,6 @@ class BlocklySvg extends Component {
var css = '<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' + cssContent + ']]></style></defs>';
var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox();
var content = new XMLSerializer().serializeToString(canvas);
var xml = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="${bbox.width}" height="${bbox.height}" viewBox="${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}">
${css}">${content}</svg>`;
@@ -65,7 +64,7 @@ class BlocklySvg extends Component {
render() {
return (
<div
style={{display: 'flex', justifyContent: 'center', transform: 'scale(0.8) translate(0, calc(100% * -0.2 / 2))'}}
style={{display: 'inline-flex', justifyContent: 'center', transform: 'scale(0.8) translate(0, calc(100% * -0.2 / 2))'}}
dangerouslySetInnerHTML={{ __html: this.state.svg }}
/>
);
+22 -7
View File
@@ -2,15 +2,15 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { onChangeWorkspace, clearStats } from '../../actions/workspaceActions';
// import * as De from 'blockly/msg/de';
import {De} from './msg/de';
import BlocklyComponent from './BlocklyComponent';
import BlocklySvg from './BlocklySvg';
import * as Blockly from 'blockly/core';
import './blocks/index';
import './generator/index';
import { initialXml } from './initialXml.js';
import { initialXml } from './initialXml.js';
class BlocklyWindow extends Component {
@@ -18,7 +18,6 @@ class BlocklyWindow extends Component {
constructor(props) {
super(props);
this.simpleWorkspace = React.createRef();
Blockly.setLocale(De);
}
componentDidMount() {
@@ -46,7 +45,17 @@ class BlocklyWindow extends Component {
if (!xml) xml = initialXml;
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
}
if (props.language !== this.props.language) {
// change language
if (!xml) xml = initialXml;
var xmlDom = Blockly.Xml.textToDom(xml);
Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace);
// var toolbox = workspace.getToolbox();
// console.log(toolbox);
// workspace.updateToolbox(toolbox.toolboxDef_);
}
Blockly.svgResize(workspace);
}
render() {
@@ -56,7 +65,7 @@ class BlocklyWindow extends Component {
style={this.props.svg ? { height: 0 } : this.props.blocklyCSS}
readOnly={this.props.readOnly !== undefined ? this.props.readOnly : false}
trashcan={this.props.trashcan !== undefined ? this.props.trashcan : true}
renderer='geras'
renderer={this.props.renderer}
zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom
controls: this.props.zoomControls !== undefined ? this.props.zoomControls : true,
wheel: false,
@@ -90,8 +99,14 @@ class BlocklyWindow extends Component {
BlocklyWindow.propTypes = {
onChangeWorkspace: PropTypes.func.isRequired,
clearStats: PropTypes.func.isRequired
clearStats: PropTypes.func.isRequired,
renderer: PropTypes.string.isRequired,
language: PropTypes.string.isRequired
};
const mapStateToProps = state => ({
renderer: state.general.renderer,
language: state.general.language
});
export default connect(null, { onChangeWorkspace, clearStats })(BlocklyWindow);
export default connect(mapStateToProps, { onChangeWorkspace, clearStats })(BlocklyWindow);
+3
View File
@@ -9,6 +9,7 @@ import './sensebox-display';
import './sensebox-lora';
import './sensebox-led';
import './sensebox-sd';
import './mqtt';
import './text';
import './io';
import './audio';
@@ -17,5 +18,7 @@ import './map';
import './procedures';
import './time';
import './variables';
import './lists';
import './webserver';
import '../helpers/types'
+59
View File
@@ -0,0 +1,59 @@
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.typeId);
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.typeId);
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);
},
};
+475 -277
View File
@@ -1,276 +1,462 @@
import Blockly from 'blockly/core';
import { getColour } from '../helpers/colour';
import * as Types from '../helpers/types';
import { getCompatibleTypes } from '../helpers/types';
import Blockly from "blockly/core";
import { getColour } from "../helpers/colour";
import * as Types from "../helpers/types";
import { getCompatibleTypes } from "../helpers/types";
Blockly.Blocks["controls_if"] = {
/**
* Block for if/elseif/else condition.
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl(Blockly.Msg.CONTROLS_IF_HELPURL);
this.setColour(getColour().logic);
this.appendValueInput("IF0")
.setCheck(Types.getCompatibleTypes("boolean"))
.appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
this.appendStatementInput("DO0").appendField(
Blockly.Msg.CONTROLS_IF_MSG_THEN
);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setMutator(
new Blockly.Mutator(["controls_if_elseif", "controls_if_else"])
);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
if (!thisBlock.elseifCount_ && !thisBlock.elseCount_) {
return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
} else if (!thisBlock.elseifCount_ && thisBlock.elseCount_) {
return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;
} else if (thisBlock.elseifCount_ && !thisBlock.elseCount_) {
return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
} else if (thisBlock.elseifCount_ && thisBlock.elseCount_) {
return Blockly.Msg.CONTROLS_IF_TOOLTIP_4;
}
return "";
});
this.elseifCount_ = 0;
this.elseCount_ = 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.elseifCount_ && !this.elseCount_) {
return null;
}
var container = document.createElement("mutation");
if (this.elseifCount_) {
container.setAttribute("elseif", this.elseifCount_);
}
if (this.elseCount_) {
container.setAttribute("else", 1);
}
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.elseifCount_ = parseInt(xmlElement.getAttribute("elseif"), 10) || 0;
this.elseCount_ = parseInt(xmlElement.getAttribute("else"), 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("controls_if_if");
containerBlock.initSvg();
var connection = containerBlock.nextConnection;
for (var i = 1; i <= this.elseifCount_; i++) {
var elseifBlock = workspace.newBlock("controls_if_elseif");
elseifBlock.initSvg();
connection.connect(elseifBlock.previousConnection);
connection = elseifBlock.nextConnection;
}
if (this.elseCount_) {
var elseBlock = workspace.newBlock("controls_if_else");
elseBlock.initSvg();
connection.connect(elseBlock.previousConnection);
}
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.elseifCount_ = 0;
this.elseCount_ = 0;
var valueConnections = [null];
var statementConnections = [null];
var elseStatementConnection = null;
while (clauseBlock) {
switch (clauseBlock.type) {
case "controls_if_elseif":
this.elseifCount_++;
valueConnections.push(clauseBlock.valueConnection_);
statementConnections.push(clauseBlock.statementConnection_);
break;
case "controls_if_else":
this.elseCount_++;
elseStatementConnection = 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.elseifCount_; i++) {
Blockly.Mutator.reconnect(valueConnections[i], this, "IF" + i);
Blockly.Mutator.reconnect(statementConnections[i], this, "DO" + i);
}
Blockly.Mutator.reconnect(elseStatementConnection, this, "ELSE");
},
/**
* 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;
var inputDo;
while (clauseBlock) {
switch (clauseBlock.type) {
case "controls_if_elseif":
var inputIf = this.getInput("IF" + i);
inputDo = this.getInput("DO" + i);
clauseBlock.valueConnection_ =
inputIf && inputIf.connection.targetConnection;
clauseBlock.statementConnection_ =
inputDo && inputDo.connection.targetConnection;
i++;
break;
case "controls_if_else":
inputDo = this.getInput("ELSE");
clauseBlock.statementConnection_ =
inputDo && inputDo.connection.targetConnection;
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.
if (this.getInput("ELSE")) {
this.removeInput("ELSE");
}
var j = 1;
while (this.getInput("IF" + j)) {
this.removeInput("IF" + j);
this.removeInput("DO" + j);
j++;
}
// Rebuild block.
for (var i = 1; i <= this.elseifCount_; i++) {
this.appendValueInput("IF" + i)
.setCheck(Types.getCompatibleTypes("boolean"))
.appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF);
this.appendStatementInput("DO" + i).appendField(
Blockly.Msg.CONTROLS_IF_MSG_THEN
);
}
if (this.elseCount_) {
this.appendStatementInput("ELSE").appendField(
Blockly.Msg.CONTROLS_IF_MSG_ELSE
);
}
},
};
Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
Blockly.Blocks["controls_if_if"] = {
/**
* Mutator block for if container.
* @this Blockly.Block
*/
init: function () {
this.setColour(getColour().logic);
this.appendDummyInput().appendField(Blockly.Msg.CONTROLS_IF_IF_TITLE_IF);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.CONTROLS_IF_IF_TOOLTIP);
this.contextMenu = false;
},
};
Blockly.Blocks["controls_if_elseif"] = {
/**
* Mutator bolck for else-if condition.
* @this Blockly.Block
*/
init: function () {
this.setColour(getColour().logic);
this.appendDummyInput().appendField(
Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF
);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP);
this.contextMenu = false;
},
};
Blockly.Blocks["controls_if_else"] = {
/**
* Mutator block for else condition.
* @this Blockly.Block
*/
init: function () {
this.setColour(getColour().logic);
this.appendDummyInput().appendField(
Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE
);
this.setPreviousStatement(true);
this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP);
this.contextMenu = false;
},
};
Blockly.defineBlocksWithJsonArray([
// BEGIN JSON EXTRACT
// Block for boolean data type: true and false.
{
"type": "logic_boolean",
"message0": "%1",
"args0": [
type: "logic_boolean",
message0: "%1",
args0: [
{
"type": "field_dropdown",
"name": "BOOL",
"options": [
type: "field_dropdown",
name: "BOOL",
options: [
["%{BKY_LOGIC_BOOLEAN_TRUE}", "TRUE"],
["%{BKY_LOGIC_BOOLEAN_FALSE}", "FALSE"]
]
}
["%{BKY_LOGIC_BOOLEAN_FALSE}", "FALSE"],
],
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"tooltip": "%{BKY_LOGIC_BOOLEAN_TOOLTIP}",
"helpUrl": "%{BKY_LOGIC_BOOLEAN_HELPURL}"
},
// Block for if/elseif/else condition.
{
"type": "controls_if",
"message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
"args0": [
{
"type": "input_value",
"name": "IF0",
"check": Types.getCompatibleTypes('boolean')
}
],
"message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
"args1": [
{
"type": "input_statement",
"name": "DO0"
}
],
"previousStatement": null,
"nextStatement": null,
"style": "logic_blocks",
"helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
"mutator": "controls_if_mutator",
"extensions": ["controls_if_tooltip"]
output: Types.BOOLEAN.typeName,
style: "logic_blocks",
tooltip: "%{BKY_LOGIC_BOOLEAN_TOOLTIP}",
helpUrl: "%{BKY_LOGIC_BOOLEAN_HELPURL}",
},
// If/else block that does not use a mutator.
{
"type": "controls_ifelse",
"message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
"args0": [
type: "controls_ifelse",
message0: "%{BKY_CONTROLS_IF_MSG_IF} %1",
args0: [
{
"type": "input_value",
"name": "IF0",
"check": Types.getCompatibleTypes('boolean')
}
type: "input_value",
name: "IF0",
check: Types.getCompatibleTypes("boolean"),
},
],
"message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
"args1": [
message1: "%{BKY_CONTROLS_IF_MSG_THEN} %1",
args1: [
{
"type": "input_statement",
"name": "DO0"
}
type: "input_statement",
name: "DO0",
},
],
"message2": "%{BKY_CONTROLS_IF_MSG_ELSE} %1",
"args2": [
message2: "%{BKY_CONTROLS_IF_MSG_ELSE} %1",
args2: [
{
"type": "input_statement",
"name": "ELSE"
}
type: "input_statement",
name: "ELSE",
},
],
"previousStatement": null,
"nextStatement": null,
"style": "logic_blocks",
"tooltip": "%{BKYCONTROLS_IF_TOOLTIP_2}",
"helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
"extensions": ["controls_if_tooltip"]
previousStatement: null,
nextStatement: null,
style: "logic_blocks",
tooltip: "%{BKYCONTROLS_IF_TOOLTIP_2}",
helpUrl: "%{BKY_CONTROLS_IF_HELPURL}",
extensions: ["controls_if_tooltip"],
},
// Block for comparison operator.
{
"type": "logic_compare",
"message0": "%1 %2 %3",
"args0": [
type: "logic_compare",
message0: "%1 %2 %3",
args0: [
{
"type": "input_value",
"name": "A"
type: "input_value",
name: "A",
},
{
"type": "field_dropdown",
"name": "OP",
"options": [
type: "field_dropdown",
name: "OP",
options: [
["=", "EQ"],
["\u2260", "NEQ"],
["\u200F<", "LT"],
["\u200F\u2264", "LTE"],
["\u200F>", "GT"],
["\u200F\u2265", "GTE"]
]
["\u200F\u2265", "GTE"],
],
},
{
"type": "input_value",
"name": "B"
}
type: "input_value",
name: "B",
},
],
"inputsInline": true,
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"helpUrl": "%{BKY_LOGIC_COMPARE_HELPURL}",
"extensions": ["logic_compare", "logic_op_tooltip"]
inputsInline: true,
output: Types.BOOLEAN.typeName,
style: "logic_blocks",
helpUrl: "%{BKY_LOGIC_COMPARE_HELPURL}",
extensions: ["logic_compare", "logic_op_tooltip"],
},
// Block for logical operations: 'and', 'or'.
{
"type": "logic_operation",
"message0": "%1 %2 %3",
"args0": [
type: "logic_operation",
message0: "%1 %2 %3",
args0: [
{
"type": "input_value",
"name": "A",
"check": Types.getCompatibleTypes('boolean')
type: "input_value",
name: "A",
check: Types.getCompatibleTypes("boolean"),
},
{
"type": "field_dropdown",
"name": "OP",
"options": [
type: "field_dropdown",
name: "OP",
options: [
["%{BKY_LOGIC_OPERATION_AND}", "AND"],
["%{BKY_LOGIC_OPERATION_OR}", "OR"]
]
["%{BKY_LOGIC_OPERATION_OR}", "OR"],
],
},
{
"type": "input_value",
"name": "B",
"check": Types.getCompatibleTypes('boolean')
}
type: "input_value",
name: "B",
check: Types.getCompatibleTypes("boolean"),
},
],
"inputsInline": true,
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"helpUrl": "%{BKY_LOGIC_OPERATION_HELPURL}",
"extensions": ["logic_op_tooltip"]
inputsInline: true,
output: Types.BOOLEAN.typeName,
style: "logic_blocks",
helpUrl: "%{BKY_LOGIC_OPERATION_HELPURL}",
extensions: ["logic_op_tooltip"],
},
// Block for negation.
{
"type": "logic_negate",
"message0": "%{BKY_LOGIC_NEGATE_TITLE}",
"args0": [
type: "logic_negate",
message0: "%{BKY_LOGIC_NEGATE_TITLE}",
args0: [
{
"type": "input_value",
"name": "BOOL",
"check": Types.getCompatibleTypes('boolean'),
}
type: "input_value",
name: "BOOL",
check: Types.getCompatibleTypes("boolean"),
},
],
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"tooltip": "%{BKY_LOGIC_NEGATE_TOOLTIP}",
"helpUrl": "%{BKY_LOGIC_NEGATE_HELPURL}"
output: Types.BOOLEAN.typeName,
style: "logic_blocks",
tooltip: "%{BKY_LOGIC_NEGATE_TOOLTIP}",
helpUrl: "%{BKY_LOGIC_NEGATE_HELPURL}",
},
// Block for null data type.
{
"type": "logic_null",
"message0": "%{BKY_LOGIC_NULL}",
"output": null,
"style": "logic_blocks",
"tooltip": "%{BKY_LOGIC_NULL_TOOLTIP}",
"helpUrl": "%{BKY_LOGIC_NULL_HELPURL}"
type: "logic_null",
message0: "%{BKY_LOGIC_NULL}",
output: null,
style: "logic_blocks",
tooltip: "%{BKY_LOGIC_NULL_TOOLTIP}",
helpUrl: "%{BKY_LOGIC_NULL_HELPURL}",
},
// Block for ternary operator.
{
"type": "logic_ternary",
"message0": "%{BKY_LOGIC_TERNARY_CONDITION} %1",
"args0": [
type: "logic_ternary",
message0: "%{BKY_LOGIC_TERNARY_CONDITION} %1",
args0: [
{
"type": "input_value",
"name": "IF",
"check": Types.getCompatibleTypes('boolean'),
}
type: "input_value",
name: "IF",
check: Types.getCompatibleTypes("boolean"),
},
],
"message1": "%{BKY_LOGIC_TERNARY_IF_TRUE} %1",
"args1": [
message1: "%{BKY_LOGIC_TERNARY_IF_TRUE} %1",
args1: [
{
"type": "input_value",
"name": "THEN"
}
type: "input_value",
name: "THEN",
check: Types.getCompatibleTypes("boolean"),
},
],
"message2": "%{BKY_LOGIC_TERNARY_IF_FALSE} %1",
"args2": [
message2: "%{BKY_LOGIC_TERNARY_IF_FALSE} %1",
args2: [
{
"type": "input_value",
"name": "ELSE"
}
type: "input_value",
name: "ELSE",
check: Types.getCompatibleTypes("boolean"),
},
],
"output": null,
"style": "logic_blocks",
"tooltip": "%{BKY_LOGIC_TERNARY_TOOLTIP}",
"helpUrl": "%{BKY_LOGIC_TERNARY_HELPURL}",
"extensions": ["logic_ternary"]
}
output: null,
style: "logic_blocks",
tooltip: "%{BKY_LOGIC_TERNARY_TOOLTIP}",
helpUrl: "%{BKY_LOGIC_TERNARY_HELPURL}",
extensions: ["logic_ternary"],
},
]); // END JSON EXTRACT (Do not delete this comment.)
Blockly.defineBlocksWithJsonArray([ // Mutator blocks. Do not extract.
// Block representing the if statement in the controls_if mutator.
{
"type": "controls_if_if",
"message0": "%{BKY_CONTROLS_IF_IF_TITLE_IF}",
"nextStatement": null,
"enableContextMenu": false,
"style": "logic_blocks",
"tooltip": "%{BKY_CONTROLS_IF_IF_TOOLTIP}"
},
// Block representing the else-if statement in the controls_if mutator.
{
"type": "controls_if_elseif",
"message0": "%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",
"previousStatement": null,
"nextStatement": null,
"enableContextMenu": false,
"style": "logic_blocks",
"tooltip": "%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"
},
// Block representing the else statement in the controls_if mutator.
{
"type": "controls_if_else",
"message0": "%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",
"previousStatement": null,
"enableContextMenu": false,
"style": "logic_blocks",
"tooltip": "%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"
}
]);
Blockly.Blocks['logic_compare'] = {
Blockly.Blocks["logic_compare"] = {
/**
* Block for comparison operator.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = this.RTL ? [
['=', 'EQ'],
['\u2260', 'NEQ'],
['>', 'LT'],
['\u2265', 'LTE'],
['<', 'GT'],
['\u2264', 'GTE']
] : [
['=', 'EQ'],
['\u2260', 'NEQ'],
['<', 'LT'],
['\u2264', 'LTE'],
['>', 'GT'],
['\u2265', 'GTE']
var OPERATORS = this.RTL
? [
["=", "EQ"],
["\u2260", "NEQ"],
[">", "LT"],
["\u2265", "LTE"],
["<", "GT"],
["\u2264", "GTE"],
]
: [
["=", "EQ"],
["\u2260", "NEQ"],
["<", "LT"],
["\u2264", "LTE"],
[">", "GT"],
["\u2265", "GTE"],
];
this.setHelpUrl(Blockly.Msg.LOGIC_COMPARE_HELPURL);
this.setColour(getColour().logic);
this.setOutput(true, Types.BOOLEAN.typeName);
this.appendValueInput('A');
this.appendValueInput('B')
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.appendValueInput("A");
this.appendValueInput("B").appendField(
new Blockly.FieldDropdown(OPERATORS),
"OP"
);
this.setInputsInline(true);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var op = thisBlock.getFieldValue('OP');
var op = thisBlock.getFieldValue("OP");
var TOOLTIPS = {
'EQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ,
'NEQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ,
'LT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT,
'LTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE,
'GT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT,
'GTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE
EQ: Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ,
NEQ: Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ,
LT: Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT,
LTE: Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE,
GT: Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT,
GTE: Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE,
};
return TOOLTIPS[op];
});
@@ -282,37 +468,44 @@ Blockly.Blocks['logic_compare'] = {
* @this Blockly.Block
*/
onchange: function (e) {
var blockA = this.getInputTargetBlock('A');
var blockB = this.getInputTargetBlock('B');
var blockA = this.getInputTargetBlock("A");
console.log(blockA);
var blockB = this.getInputTargetBlock("B");
if (blockA === null && blockB === null) {
this.getInput('A').setCheck(null);
this.getInput('B').setCheck(null);
this.getInput("A").setCheck(null);
this.getInput("B").setCheck(null);
}
if (blockA !== null && blockB === null) {
this.getInput('A').setCheck(getCompatibleTypes(blockA.outputConnection.check_[0]));
this.getInput('B').setCheck(getCompatibleTypes(blockA.outputConnection.check_[0]));
this.getInput("A").setCheck(
getCompatibleTypes(blockA.outputConnection.check_[0])
);
this.getInput("B").setCheck(
getCompatibleTypes(blockA.outputConnection.check_[0])
);
}
if (blockB !== null && blockA === null) {
this.getInput('B').setCheck(getCompatibleTypes(blockB.outputConnection.check_[0]));
this.getInput('A').setCheck(getCompatibleTypes(blockB.outputConnection.check_[0]));
}
this.getInput("B").setCheck(
getCompatibleTypes(blockB.outputConnection.check_[0])
);
this.getInput("A").setCheck(
getCompatibleTypes(blockB.outputConnection.check_[0])
);
}
},
};
Blockly.Blocks['switch_case'] = {
Blockly.Blocks["switch_case"] = {
init: function () {
this.setColour(getColour().logic);
this.setPreviousStatement(true);
this.setTooltip(Blockly.Msg.cases_tooltip);
this.setNextStatement(true);
this.appendValueInput('CONDITION')
.appendField(Blockly.Msg.cases_switch);
this.appendValueInput('CASECONDITION0')
.appendField(Blockly.Msg.cases_condition);
this.appendStatementInput('CASE0')
.appendField(Blockly.Msg.cases_do);
this.setMutator(new Blockly.Mutator(['case_incaseof', 'case_default']));
this.setTooltip('Does something if the condition is true. If there isn\'t a matching case the default function will be executed.');
this.appendValueInput("CONDITION").appendField(Blockly.Msg.cases_switch);
this.appendValueInput("CASECONDITION0").appendField(
Blockly.Msg.cases_condition
);
this.appendStatementInput("CASE0").appendField(Blockly.Msg.cases_do);
this.setMutator(new Blockly.Mutator(["case_incaseof", "case_default"]));
this.caseCount_ = 0;
this.defaultCount_ = 0;
},
@@ -321,43 +514,42 @@ Blockly.Blocks['switch_case'] = {
if (!this.caseCount_ && !this.defaultCount_) {
return null;
}
var container = document.createElement('mutation');
var container = document.createElement("mutation");
if (this.caseCount_) {
container.setAttribute('case', this.caseCount_);
container.setAttribute("case", this.caseCount_);
}
if (this.defaultCount_) {
container.setAttribute('default', 1);
container.setAttribute("default", 1);
}
return container;
},
domToMutation: function (xmlElement) {
this.caseCount_ = parseInt(xmlElement.getAttribute('case'), 10);
this.defaultCount_ = parseInt(xmlElement.getAttribute('default'), 10);
this.caseCount_ = parseInt(xmlElement.getAttribute("case"), 10);
this.defaultCount_ = parseInt(xmlElement.getAttribute("default"), 10);
for (var x = 0; x <= this.caseCount_; x++) {
this.appendValueInput('CASECONDITION' + x)
.appendField(Blockly.Msg.cases_condition);
this.appendStatementInput('CASE' + x)
.appendField(Blockly.Msg.cases_do);
this.appendValueInput("CASECONDITION" + x).appendField(
Blockly.Msg.cases_condition
);
this.appendStatementInput("CASE" + x).appendField(Blockly.Msg.cases_do);
}
if (this.defaultCount_) {
this.appendStatementInput('ONDEFAULT')
.appendField('default');
this.appendStatementInput("ONDEFAULT").appendField("default");
}
},
decompose: function (workspace) {
var containerBlock = workspace.newBlock('control_case');
var containerBlock = workspace.newBlock("control_case");
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
var connection = containerBlock.getInput("STACK").connection;
for (var x = 1; x <= this.caseCount_; x++) {
var caseBlock = workspace.newBlock('case_incaseof');
var caseBlock = workspace.newBlock("case_incaseof");
caseBlock.initSvg();
connection.connect(caseBlock.previousConnection);
connection = caseBlock.nextConnection;
}
if (this.defaultCount_) {
var defaultBlock = Blockly.Block.obtain(workspace, 'case_default');
var defaultBlock = Blockly.Block.obtain(workspace, "case_default");
defaultBlock.initSvg();
connection.connect(defaultBlock.previousConnection);
}
@@ -367,23 +559,25 @@ Blockly.Blocks['switch_case'] = {
compose: function (containerBlock) {
//Disconnect all input blocks and remove all inputs.
if (this.defaultCount_) {
this.removeInput('ONDEFAULT');
this.removeInput("ONDEFAULT");
}
this.defaultCount_ = 0;
for (var x = this.caseCount_; x > 0; x--) {
this.removeInput('CASECONDITION' + x);
this.removeInput('CASE' + x);
this.removeInput("CASECONDITION" + x);
this.removeInput("CASE" + x);
}
this.caseCount_ = 0;
var caseBlock = containerBlock.getInputTargetBlock('STACK');
var caseBlock = containerBlock.getInputTargetBlock("STACK");
while (caseBlock) {
switch (caseBlock.type) {
case 'case_incaseof':
case "case_incaseof":
this.caseCount_++;
var caseconditionInput = this.appendValueInput('CASECONDITION' + this.caseCount_)
.appendField(Blockly.Msg.cases_condition);
var caseInput = this.appendStatementInput('CASE' + this.caseCount_)
.appendField(Blockly.Msg.cases_do);
var caseconditionInput = this.appendValueInput(
"CASECONDITION" + this.caseCount_
).appendField(Blockly.Msg.cases_condition);
var caseInput = this.appendStatementInput(
"CASE" + this.caseCount_
).appendField(Blockly.Msg.cases_do);
if (caseBlock.valueConnection_) {
caseconditionInput.connection.connect(caseBlock.valueConnection_);
}
@@ -391,78 +585,82 @@ Blockly.Blocks['switch_case'] = {
caseInput.connection.connect(caseBlock.statementConnection_);
}
break;
case 'case_default':
case "case_default":
this.defaultCount_++;
var defaultInput = this.appendStatementInput('ONDEFAULT')
.appendField('default');
var defaultInput = this.appendStatementInput("ONDEFAULT").appendField(
"default"
);
if (caseBlock.statementConnection_) {
defaultInput.connection.connect(caseBlock.statementConnection_);
}
break;
default:
throw new Error('Unknown block type.');
throw new Error("Unknown block type.");
}
caseBlock = caseBlock.nextConnection &&
caseBlock.nextConnection.targetBlock();
caseBlock =
caseBlock.nextConnection && caseBlock.nextConnection.targetBlock();
}
},
saveConnections: function (containerBlock) {
var caseBlock = containerBlock.getInputTargetBlock('STACK');
var caseBlock = containerBlock.getInputTargetBlock("STACK");
var x = 1;
while (caseBlock) {
switch (caseBlock.type) {
case 'case_incaseof':
var caseconditionInput = this.getInput('CASECONDITION' + x);
var caseInput = this.getInput('CASE' + x);
caseBlock.valueConnection_ = caseconditionInput && caseconditionInput.connection.targetConnection;
caseBlock.statementConnection_ = caseInput && caseInput.connection.targetConnection;
case "case_incaseof":
var caseconditionInput = this.getInput("CASECONDITION" + x);
var caseInput = this.getInput("CASE" + x);
caseBlock.valueConnection_ =
caseconditionInput &&
caseconditionInput.connection.targetConnection;
caseBlock.statementConnection_ =
caseInput && caseInput.connection.targetConnection;
x++;
break;
case 'case_default':
var defaultInput = this.getInput('ONDEFAULT');
caseBlock.satementConnection_ = defaultInput && defaultInput.connection.targetConnection;
case "case_default":
var defaultInput = this.getInput("ONDEFAULT");
caseBlock.satementConnection_ =
defaultInput && defaultInput.connection.targetConnection;
break;
default:
throw new Error('Unknown block type');
}
caseBlock = caseBlock.nextConnection &&
caseBlock.nextConnection.targetBlock();
throw new Error("Unknown block type");
}
caseBlock =
caseBlock.nextConnection && caseBlock.nextConnection.targetBlock();
}
},
};
Blockly.Blocks['control_case'] = {
Blockly.Blocks["control_case"] = {
init: function () {
this.setColour(getColour().logic);
this.appendDummyInput()
.appendField(Blockly.Msg.cases_switch);
this.appendStatementInput('STACK');
this.setTooltip('--Placeholder--');
this.appendDummyInput().appendField(Blockly.Msg.cases_switch);
this.appendStatementInput("STACK");
this.setTooltip("--Placeholder--");
this.contextMenu = false;
}
},
};
Blockly.Blocks['case_incaseof'] = {
Blockly.Blocks["case_incaseof"] = {
init: function () {
this.setColour(getColour().logic);
this.appendDummyInput()
.appendField(Blockly.Msg.cases_add);
this.appendDummyInput().appendField(Blockly.Msg.cases_add);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip('--Placeholder--');
this.setTooltip("--Placeholder--");
this.contextMenu = false;
}
},
};
Blockly.Blocks['case_default'] = {
Blockly.Blocks["case_default"] = {
init: function () {
this.setColour(getColour().logic);
this.appendValueInput('default')
.appendField('default');
this.appendValueInput("default").appendField("default");
this.setPreviousStatement(true);
this.setNextStatement(false);
this.setTooltip('This function will run if there aren\'t any matching cases.');
this.setTooltip(
"This function will run if there aren't any matching cases."
);
this.contextMenu = false;
}
},
};
+3 -1
View File
@@ -2,7 +2,7 @@
import Blockly from 'blockly';
import { getColour } from '../helpers/colour';
import { getCompatibleTypes } from '../helpers/types'
import * as Types from '../helpers/types';
Blockly.Blocks['controls_whileUntil'] = {
/**
@@ -47,6 +47,7 @@ Blockly.Blocks['controls_for'] = {
{
"type": "field_variable",
"name": "VAR",
"defaultType": Types.NUMBER.typeName,
"variable": null
},
{
@@ -97,6 +98,7 @@ Blockly.Blocks['controls_forEach'] = {
{
"type": "field_variable",
"name": "VAR",
"defaultType": Types.NUMBER.typeName,
"variable": null
},
{
+2 -1
View File
@@ -287,7 +287,8 @@ Blockly.Blocks['math_change'] = {
{
"type": "field_variable",
"name": "VAR",
"variable": Blockly.Msg.MATH_CHANGE_TITLE_ITEM
"defaultType": Types.NUMBER.typeName,
"variable": null
},
{
"type": "input_value",
+86
View File
@@ -0,0 +1,86 @@
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);
}
};
File diff suppressed because it is too large Load Diff
@@ -11,8 +11,8 @@ Blockly.Blocks['sensebox_display_beginDisplay'] = {
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tip);
this.setHelpUrl('https://sensebox.de/books');
this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl);
}
};
@@ -23,8 +23,8 @@ Blockly.Blocks['sensebox_display_clearDisplay'] = {
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tip);
this.setHelpUrl('https://sensebox.de/books');
this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl);
}
};
@@ -50,10 +50,56 @@ Blockly.Blocks['sensebox_display_printDisplay'] = {
.setCheck(null);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
let variableName = this.getField('COLOR');
console.log(variableName.getValue());
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip);
this.setHelpUrl('https://sensebox.de/books');
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_fastPrint'] = {
init: function (block) {
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_display_fastPrint_show);
this.appendValueInput("Title1", 'Title1')
.appendField(Blockly.Msg.senseBox_display_fastPrint_title);
this.appendValueInput("Value1", 'Value1')
.appendField(Blockly.Msg.senseBox_display_fastPrint_value);
this.appendValueInput("Dimension1", 'Dimension1')
.appendField(Blockly.Msg.senseBox_display_fastPrint_dimension);
this.appendValueInput("Title2", 'Title2')
.appendField(Blockly.Msg.senseBox_display_fastPrint_title);
this.appendValueInput("Value2", 'Value2')
.appendField(Blockly.Msg.senseBox_display_fastPrint_value);
this.appendValueInput("Dimension2", 'Dimension2')
.appendField(Blockly.Msg.senseBox_display_fastPrint_dimension);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.sensebox_display_fastPrint_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl);
},
/**
* Called whenever anything on the workspace changes.
@@ -113,8 +159,8 @@ Blockly.Blocks['sensebox_display_plotDisplay'] = {
.setCheck(null);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip);
this.setHelpUrl('https://sensebox.de/books');
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_display_helpurl);
},
/**
* Called whenever anything on the workspace changes.
@@ -174,6 +220,8 @@ Blockly.Blocks['sensebox_display_fillCircle'] = {
.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);
},
@@ -224,6 +272,8 @@ Blockly.Blocks['sensebox_display_drawRectangle'] = {
.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);
},
+149 -13
View File
@@ -1,8 +1,7 @@
import * as Blockly from 'blockly';
import { FieldSlider } from '@blockly/field-slider';
import { getColour } from '../helpers/colour'
import { selectedBoard } from '../helpers/board'
import * as Types from '../helpers/types'
Blockly.Blocks['sensebox_led'] = {
@@ -16,7 +15,7 @@ Blockly.Blocks['sensebox_led'] = {
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_on, "HIGH"], [Blockly.Msg.senseBox_off, "LOW"]]), "STAT");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.senseBox_led_tip);
this.setTooltip(Blockly.Msg.senseBox_led_tooltip);
}
};
@@ -27,18 +26,155 @@ Blockly.Blocks['sensebox_rgb_led'] = {
.appendField(Blockly.Msg.senseBox_rgb_led)
.appendField("Pin:")
.appendField(new Blockly.FieldDropdown(selectedBoard().digitalPins), "PIN");
this.appendDummyInput()
.appendField(Blockly.Msg.COLOUR_RGB_RED)//Blockly.Msg.senseBox_basic_red
.appendField(new FieldSlider(255, 0, 255), "RED");
this.appendDummyInput()
.appendField(Blockly.Msg.COLOUR_RGB_GREEN)//Blockly.Msg.senseBox_basic_green
.appendField(new FieldSlider(255, 0, 255), "GREEN");
this.appendDummyInput()
.appendField(Blockly.Msg.COLOUR_RGB_BLUE)//Blockly.Msg.senseBox_basic_green
.appendField(new FieldSlider(255, 0, 255), "BLUE");
this.appendValueInput("COLOR", 'Number')
.appendField(Blockly.Msg.senseBox_ws2818_rgb_led_color)
.setCheck("Colour");
// this.appendValueInput("RED", 'Number')
// .appendField(Blockly.Msg.COLOUR_RGB_RED);//Blockly.Msg.senseBox_basic_red
// this.appendValueInput("GREEN", 'Number')
// .appendField(Blockly.Msg.COLOUR_RGB_GREEN);//Blockly.Msg.senseBox_basic_green
// this.appendValueInput("BLUE", 'Number')
// .appendField(Blockly.Msg.COLOUR_RGB_BLUE);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.senseBox_rgb_led_tip);
this.setHelpUrl('https://sensebox.de/books');
}
};
Blockly.Blocks['sensebox_ws2818_led_init'] = {
init: function () {
var dropdownOptions = [[Blockly.Msg.senseBox_ultrasonic_port_A, '1'],
[Blockly.Msg.senseBox_ultrasonic_port_B, '3'], [Blockly.Msg.senseBox_ultrasonic_port_C, '5']];
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_ws2818_rgb_led_init)
.appendField("Port:")
.appendField(new Blockly.FieldDropdown(dropdownOptions), "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 () {
var dropdownOptions = [[Blockly.Msg.senseBox_ultrasonic_port_A, '1'],
[Blockly.Msg.senseBox_ultrasonic_port_B, '3'], [Blockly.Msg.senseBox_ultrasonic_port_C, '5']];
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_ws2818_rgb_led)
.appendField("Port:")
.appendField(new Blockly.FieldDropdown(dropdownOptions), "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.)
+37 -6
View File
@@ -8,12 +8,11 @@ import { getColour } from '../helpers/colour';
Blockly.Blocks['sensebox_lora_initialize_otaa'] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tip);
this.setHelpUrl('');
this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_LoRa_init_helpurl);
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField("Initialize LoRa (OTAA)");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_LEFT)
.appendField(Blockly.Msg.senseBox_LoRa_device_id)
@@ -37,8 +36,8 @@ Blockly.Blocks['sensebox_lora_initialize_otaa'] = {
Blockly.Blocks['sensebox_lora_initialize_abp'] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tip);
this.setHelpUrl('');
this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_LoRa_init_helpurl);
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField("Initialize LoRa (ABP)");
@@ -68,7 +67,7 @@ Blockly.Blocks['sensebox_lora_initialize_abp'] = {
Blockly.Blocks['sensebox_lora_message_send'] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tip);
this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tooltip);
this.setHelpUrl('');
this.setColour(getColour().sensebox);
this.appendStatementInput('DO')
@@ -119,6 +118,38 @@ Blockly.Blocks['sensebox_send_lora_sensor_value'] = {
LOOP_TYPES: ['sensebox_lora_message_send'],
};
Blockly.Blocks['sensebox_lora_ttn_mapper'] = {
init: function (block) {
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField("TTN Mapper");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("Fix Type Limit")
.appendField(new Blockly.FieldDropdown([["0", "0"], ["1", "1"], ["2", "2"], ["3", "3"]].reverse()), "dropdown");
// reverse() because i want 3 be be at first and i'm to lazy to write the array again
this.appendValueInput('Latitude')
.appendField(Blockly.Msg.senseBox_gps_lat)
.setCheck(null);
this.appendValueInput('Longitude')
.appendField(Blockly.Msg.senseBox_gps_lng)
.setCheck(null);
this.appendValueInput('Altitude')
.appendField(Blockly.Msg.senseBox_gps_alt)
.setCheck(null);
this.appendValueInput('pDOP')
.appendField('pDOP')
.setCheck(null);
this.appendValueInput('Fix Type')
.appendField('Fix Type')
.setCheck(null);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip);
}
};
Blockly.Blocks['sensebox_lora_cayenne_send'] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_tip);
+98 -6
View File
@@ -1,6 +1,14 @@
import * as Blockly from 'blockly/core';
import { getColour } from '../helpers/colour';
import store from '../../../store';
var boxes = store.getState().auth.user ? store.getState().auth.user.boxes : null;
store.subscribe(() => {
boxes = store.getState().auth.user ? store.getState().auth.user.boxes : null;
});
var selectedBox = '';
Blockly.Blocks['sensebox_osem_connection'] = {
init: function () {
@@ -16,10 +24,25 @@ Blockly.Blocks['sensebox_osem_connection'] = {
.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);
@@ -28,9 +51,40 @@ Blockly.Blocks['sensebox_osem_connection'] = {
},
onchange: function (e) {
//Blockly.Blocks.sensebox.getDescendants = blocks;
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');
*/
selectedBox = this.getFieldValue('BoxID');
console.log(selectedBox)
if (selectedBox !== '' && boxes) {
var accessToken = boxes.find(element => element._id === selectedBox).access_token
if (accessToken !== undefined) {
this.getField('access_token').setValue(accessToken)
} else {
this.getField('access_token').setValue('access_token')
}
}
},
mutationToDom: function () {
var container = document.createElement('mutation');
var input = this.getFieldValue('type');
@@ -70,6 +124,7 @@ Blockly.Blocks['sensebox_osem_connection'] = {
this.removeInput('timeStamp');
}
},
LOOP_TYPES: ['sensebox_interval_timer']
};
Blockly.Blocks['sensebox_send_to_osem'] = {
init: function () {
@@ -78,20 +133,52 @@ Blockly.Blocks['sensebox_send_to_osem'] = {
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_send_to_osem);
if (boxes) {
this.appendValueInput('Value')
.setCheck(null)
.appendField('Sensor ID')
.appendField(new Blockly.FieldTextInput('Sensor ID'), 'SensorID');
.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])
}
console.log(dropdown)
}
if (dropdown.length > 1) {
var options = dropdown.slice(1)
return options
} else {
return dropdown
}
}
return dropdown
},
/**
* Called whenever anything on the workspace changes.
* Add warning if block is not nested inside a the correct loop.
* @param {!Blockly.Events.Abstract} e Change event.
* @this Blockly.Block
*/
onchange: function (e) {
onchange: function () {
var legal = false;
// Is the block nested in a loop?
var block = this;
@@ -108,5 +195,10 @@ Blockly.Blocks['sensebox_send_to_osem'] = {
this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
}
},
LOOP_TYPES: ['sensebox_osem_connection'],
/**
* 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']
};
+48 -25
View File
@@ -1,57 +1,80 @@
import * as Blockly from 'blockly/core';
import { getColour } from '../helpers/colour';
import * as Blockly from "blockly/core";
import { getColour } from "../helpers/colour";
var checkFileName = function (filename) {
var length = filename.length;
if (length > 8) {
alert("dateiname sollte kleiner als 8 Zeichen sein");
return filename.slice(0, 8);
}
return filename;
};
Blockly.Blocks['sensebox_sd_open_file'] = {
Blockly.Blocks["sensebox_sd_open_file"] = {
init: function () {
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_sd_open_file)
.setAlign(Blockly.ALIGN_LEFT)
.appendField(
new Blockly.FieldTextInput('Data.txt'),
'Filename');
this.appendStatementInput('SD')
.setCheck(null);
new Blockly.FieldTextInput("Data", checkFileName),
"Filename"
)
.appendField(".")
.appendField(
new Blockly.FieldDropdown([
["txt", "txt"],
["csv", "csv"],
]),
"extension"
);
this.appendStatementInput("SD").setCheck(null);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip);
this.setHelpUrl('https://sensebox.de/books');
}
this.setTooltip(Blockly.Msg.senseBox_sd_open_file_tooltip);
this.setHelpUrl("https://docs.sensebox.de/hardware/bee-sd/");
},
};
Blockly.Blocks['sensebox_sd_create_file'] = {
Blockly.Blocks["sensebox_sd_create_file"] = {
init: function () {
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_sd_create_file)
.setAlign(Blockly.ALIGN_LEFT)
.appendField(Blockly.Msg.senseBox_output_filename)
.appendField(
new Blockly.FieldTextInput('Data.txt'),
'Filename');
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_output_safetosd_tip);
this.setHelpUrl('https://sensebox.de/books');
}
this.setTooltip(Blockly.Msg.senseBox_sd_create_file_tooltip);
this.setHelpUrl("https://docs.sensebox.de/hardware/bee-sd/");
},
};
Blockly.Blocks['sensebox_sd_write_file'] = {
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')
this.appendValueInput("DATA").setCheck(null);
this.appendDummyInput("CheckboxText")
.appendField(Blockly.Msg.senseBox_output_linebreak)
.appendField(new Blockly.FieldCheckbox('TRUE'), 'linebreak');
.appendField(new Blockly.FieldCheckbox("TRUE"), "linebreak");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_output_safetosd_tip);
this.setHelpUrl('https://sensebox.de/books');
this.setTooltip(Blockly.Msg.senseBox_sd_write_file_tooltip);
this.setHelpUrl("https://docs.sensebox.de/hardware/bee-sd/");
},
/**
* Called whenever anything on the workspace changes.
@@ -76,5 +99,5 @@ Blockly.Blocks['sensebox_sd_write_file'] = {
this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
}
},
LOOP_TYPES: ['sensebox_sd_open_file'],
LOOP_TYPES: ["sensebox_sd_open_file"],
};
+131 -19
View File
@@ -18,8 +18,8 @@ Blockly.Blocks['sensebox_sensor_temp_hum'] = {
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_hum, "Humidity"]]), "NAME");
this.setOutput(true, Types.DECIMAL.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_temp_hum_tip);
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
this.setTooltip(Blockly.Msg.senseBox_temp_hum_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_temp_hum_helpurl);
}
};
@@ -29,6 +29,7 @@ Blockly.Blocks['sensebox_sensor_temp_hum'] = {
*/
Blockly.Blocks['sensebox_sensor_uv_light'] = {
init: function () {
this.appendDummyInput()
@@ -39,8 +40,8 @@ Blockly.Blocks['sensebox_sensor_uv_light'] = {
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_light, "Illuminance"], [Blockly.Msg.senseBox_uv, "UvIntensity"]]), "NAME");
this.setOutput(true, Types.DECIMAL.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_uv_light_tip);
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
this.setTooltip(Blockly.Msg.senseBox_uv_light_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_uv_light_helpurl);
}
};
@@ -62,8 +63,8 @@ Blockly.Blocks['sensebox_sensor_bmx055_accelerometer'] = {
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_range_2g, "0x3"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_4g, "0x5"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_8g, "0x8"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_16g, "0x0C"]]), "RANGE");
this.setOutput(true, Types.DECIMAL.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip);
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_bmx055_helpurl);
}
};
@@ -84,8 +85,8 @@ Blockly.Blocks['sensebox_sensor_sds011'] = {
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_serial1, "Serial1"], [Blockly.Msg.senseBox_sds011_serial2, "Serial2"]]), "SERIAL");
this.setOutput(true, Types.DECIMAL.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_sds011_tip);
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html');
this.setTooltip(Blockly.Msg.senseBox_sds011_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_sds011_helpurl);
}
};
@@ -110,8 +111,8 @@ Blockly.Blocks['sensebox_sensor_pressure'] = {
.appendField(dropdown, "NAME");
this.setColour(getColour().sensebox);
this.setOutput(true, Types.DECIMAL.typeName);
this.setTooltip(Blockly.Msg.senseBox_pressure_tip);
this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/luftdruck.html');
this.setTooltip(Blockly.Msg.senseBox_pressure_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_pressure_helpurl);
},
/**
* Parse XML to restore the number of pins available.
@@ -175,7 +176,8 @@ Blockly.Blocks['sensebox_sensor_bme680_bsec'] = {
.appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown")
this.setOutput(true, Types.DECIMAL.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_bme_tip);
this.setTooltip(Blockly.Msg.senseBox_bme_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_bme680_helpurl)
}
};
@@ -209,8 +211,8 @@ Blockly.Blocks['sensebox_sensor_ultrasonic_ranger'] = {
.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');
this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_ultrasonic_helpurl);
},
/**
* Parse XML to restore the number of pins available.
@@ -274,8 +276,8 @@ Blockly.Blocks['sensebox_sensor_sound'] = {
.appendField("Pin:")
.appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN")
this.setOutput(true, Types.NUMBER.typeName);
this.setHelpUrl(Blockly.Msg.senseBox_sound_tip);
this.setTooltip('Dieser Sensor mist den Geräuschpegel.');
this.setHelpUrl(Blockly.Msg.senseBox_sound_helpurl);
this.setTooltip(Blockly.Msg.senseBox_sound_tooltip);
}
};
@@ -295,8 +297,7 @@ Blockly.Blocks['sensebox_button'] = {
.appendField(new Blockly.FieldDropdown(selectedBoard().digitalPinsButton), "PIN");
this.setOutput(true, Types.BOOLEAN.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_button_tip);
this.setHelpUrl('https://sensebox.de/books');
this.setTooltip(Blockly.Msg.senseBox_button_tooltip);
}
};
@@ -309,7 +310,7 @@ Blockly.Blocks['sensebox_button'] = {
Blockly.Blocks['sensebox_scd30'] = {
init: function () {
var dropdownOptions = [[Blockly.Msg.senseBox_temp, "temperature"], [Blockly.Msg.senseBox_hum, "humidity"], [Blockly.Msg.senseBox_bme_co2, "CO2"]];
var dropdownOptions = [[Blockly.Msg.senseBox_scd_co2, "CO2"], [Blockly.Msg.senseBox_temp, "temperature"], [Blockly.Msg.senseBox_hum, "humidity"]];
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_scd30);
this.appendDummyInput()
@@ -318,6 +319,117 @@ Blockly.Blocks['sensebox_scd30'] = {
.appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown")
this.setOutput(true, Types.NUMBER.typeName);
this.setColour(getColour().sensebox);
this.setTooltip(Blockly.Msg.senseBox_bme_tip);
this.setTooltip(Blockly.Msg.senseBox_scd_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_scd_helpurl);
},
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"], ["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 () {
var dropdownOptions = [[Blockly.Msg.senseBox_ultrasonic_port_A, 'A'],
[Blockly.Msg.senseBox_ultrasonic_port_B, 'B'], [Blockly.Msg.senseBox_ultrasonic_port_C, 'C']];
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_smt50);
this.appendDummyInput()
.appendField("Port:")
.appendField(new Blockly.FieldDropdown(dropdownOptions), "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);
}
};
/**
* DS18B20 Watertemperature
*
*/
Blockly.Blocks['sensebox_sensor_watertemperature'] = {
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']];
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_watertemperature)
.appendField("Port:")
.appendField(new Blockly.FieldDropdown(dropdownOptions), "Port")
this.setOutput(true, Types.NUMBER.typeName);
this.setTooltip(Blockly.Msg.senseBox_watertemperature_tip);
}
};
/**
* 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 () {
var dropdownOptions = [[Blockly.Msg.senseBox_ultrasonic_port_A, 'A'],
[Blockly.Msg.senseBox_ultrasonic_port_B, 'B'], [Blockly.Msg.senseBox_ultrasonic_port_C, 'C']];
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_soundsensor_dfrobot)
.appendField("Port:")
.appendField(new Blockly.FieldDropdown(dropdownOptions), "Port")
this.setOutput(true, Types.DECIMAL.typeName);
this.setTooltip(Blockly.Msg.senseBox_soundsensor_dfrobot_tooltip);
this.setHelpUrl(Blockly.Msg.senseBox_soundsensor_dfrobot_helpurl)
}
};
@@ -12,6 +12,7 @@ Blockly.Blocks["sensebox_telegram"] = {
.appendField("telegram")
.appendField(new Blockly.FieldTextInput("token"), "telegram_token");
this.setPreviousStatement(true, null);
this.setTooltip(Blockly.Msg.senseBox_telegram_init_tooltip);
this.setNextStatement(true, null);
}
};
@@ -24,6 +25,7 @@ Blockly.Blocks["sensebox_telegram_do"] = {
this.appendStatementInput("telegram_do");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.senseBox_telegram_do_tooltip)
}
};
@@ -36,6 +38,7 @@ Blockly.Blocks["sensebox_telegram_do_on_message"] = {
.appendField(Blockly.Msg.senseBox_telegram_message)
.appendField(new Blockly.FieldTextInput("/message"), 'telegram_message');
this.appendStatementInput("telegram_do_on_message").setCheck(null);
this.setTooltip(Blockly.Msg.senseBox_telegram_message_tooltip)
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
}
@@ -46,8 +49,10 @@ Blockly.Blocks["sensebox_telegram_send"] = {
this.setColour(getColour().sensebox);
this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_send);
this.appendValueInput("telegram_text_to_send").setCheck(null);
this.setTooltip(Blockly.Msg.senseBox_telegram_send_tooltip)
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
},
LOOP_TYPES: ["sensebox_telegram_do_on_message"]
};
@@ -3,7 +3,7 @@ import { getColour } from '../helpers/colour'
Blockly.Blocks['sensebox_wifi'] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_wifi_tip);
this.setTooltip(Blockly.Msg.senseBox_wifi_tooltip);
this.setHelpUrl('');
this.setColour(getColour().sensebox);
this.appendDummyInput()
@@ -16,6 +16,7 @@ Blockly.Blocks['sensebox_wifi'] = {
.setAlign(Blockly.ALIGN_LEFT)
.appendField(Blockly.Msg.senseBox_output_password)
.appendField(new Blockly.FieldTextInput("Password"), "Password");
this.setHelpUrl(Blockly.Msg.senseBox_wifi_helpurl)
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
},
@@ -43,7 +44,7 @@ Blockly.Blocks['sensebox_wifi'] = {
Blockly.Blocks['sensebox_startap'] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_wifi_tip);
this.setTooltip(Blockly.Msg.senseBox_wifi_startap_tooltip);
this.setHelpUrl('');
this.setColour(getColour().sensebox);
this.appendDummyInput()
@@ -52,6 +53,7 @@ Blockly.Blocks['sensebox_startap'] = {
.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);
}
+32 -37
View File
@@ -8,80 +8,75 @@
* The arduino built in functions syntax can be found in
* http://arduino.cc/en/Reference/HomePage
*/
import Blockly from 'blockly';
import { getColour } from '../helpers/colour'
import * as Types from '../helpers/types'
import Blockly from "blockly";
import { getColour } from "../helpers/colour";
import * as Types from "../helpers/types";
Blockly.Blocks['time_delay'] = {
Blockly.Blocks["time_delay"] = {
/**
* Delay block definition
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl('http://arduino.cc/en/Reference/Delay');
this.setHelpUrl("http://arduino.cc/en/Reference/Delay");
this.setColour(getColour().time);
this.appendValueInput('DELAY_TIME_MILI')
this.appendValueInput("DELAY_TIME_MILI")
.setCheck(Types.NUMBER.checkList)
.appendField(Blockly.Msg.ARD_TIME_DELAY);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_TIME_MS);
this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MS);
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_TIP);
}
},
};
Blockly.Blocks['time_delaymicros'] = {
Blockly.Blocks["time_delaymicros"] = {
/**
* delayMicroseconds block definition
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl('http://arduino.cc/en/Reference/DelayMicroseconds');
this.setHelpUrl("http://arduino.cc/en/Reference/DelayMicroseconds");
this.setColour(getColour().time);
this.appendValueInput('DELAY_TIME_MICRO')
this.appendValueInput("DELAY_TIME_MICRO")
.setCheck(Types.NUMBER.checkList)
.appendField(Blockly.Msg.ARD_TIME_DELAY);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS);
this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS);
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP);
}
},
};
Blockly.Blocks['time_millis'] = {
Blockly.Blocks["time_millis"] = {
/**
* Elapsed time in milliseconds block definition
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl('http://arduino.cc/en/Reference/Millis');
this.setHelpUrl("http://arduino.cc/en/Reference/Millis");
this.setColour(getColour().time);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_TIME_MILLIS);
this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MILLIS);
this.setOutput(true, Types.LARGE_NUMBER.typeId);
this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP);
},
/** @return {string} The type of return value for the block, an integer. */
getBlockType: function () {
return Blockly.Types.LARGE_NUMBER;
}
},
};
Blockly.Blocks['time_micros'] = {
Blockly.Blocks["time_micros"] = {
/**
* Elapsed time in microseconds block definition
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl('http://arduino.cc/en/Reference/Micros');
this.setHelpUrl("http://arduino.cc/en/Reference/Micros");
this.setColour(getColour().time);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_TIME_MICROS);
this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_MICROS);
this.setOutput(true, Types.LARGE_NUMBER.typeId);
this.setTooltip(Blockly.Msg.ARD_TIME_MICROS_TIP);
},
@@ -91,40 +86,40 @@ Blockly.Blocks['time_micros'] = {
*/
getBlockType: function () {
return Types.LARGE_NUMBER;
}
},
};
Blockly.Blocks['infinite_loop'] = {
Blockly.Blocks["infinite_loop"] = {
/**
* Waits forever, end of program.
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl('');
this.setHelpUrl("");
this.setColour(getColour().time);
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_TIME_INF);
this.appendDummyInput().appendField(Blockly.Msg.ARD_TIME_INF);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setTooltip(Blockly.Msg.ARD_TIME_INF_TIP);
}
},
};
Blockly.Blocks['sensebox_interval_timer'] = {
Blockly.Blocks["sensebox_interval_timer"] = {
init: function () {
this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip);
this.setInputsInline(true);
this.setHelpUrl('');
this.setHelpUrl("");
this.setColour(getColour().time);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_interval_timer);
.appendField(Blockly.Msg.senseBox_interval_timer)
.appendField(new Blockly.FieldTextInput("name"), "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.appendStatementInput("DO").setCheck(null);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
}
},
};
+28 -28
View File
@@ -1,43 +1,43 @@
import Blockly from 'blockly/core';
import { getColour } from '../helpers/colour';
import { getCompatibleTypes } from '../helpers/types'
import Blockly from "blockly/core";
import { getColour } from "../helpers/colour";
import { getCompatibleTypes } from "../helpers/types";
Blockly.Blocks['variables_set_dynamic'] = {
Blockly.Blocks["variables_set_dynamic"] = {
init: function () {
// const type = myVar.type;
this.setColour(getColour().variables);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.appendValueInput('VALUE')
.appendField('set', 'set')
.appendField('', 'type')
.appendField(new Blockly.FieldVariable('VAR'), 'VAR')
.appendField('to');
this.appendValueInput("VALUE")
.appendField("set", "set")
.appendField("", "type")
.appendField(new Blockly.FieldVariable("VAR"), "VAR")
.appendField("to");
},
onchange: function (e) {
let variableID = this.getFieldValue('VAR');
let variable = Blockly.getMainWorkspace().getVariableMap().getVariableById(variableID)
this.getField('type').setValue(variable.type);
this.getInput('VALUE').setCheck(getCompatibleTypes(variable.type));
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'] = {
Blockly.Blocks["variables_get_dynamic"] = {
init: function () {
this.setColour(getColour().variables);
this.appendDummyInput()
.appendField('', 'type')
.appendField(new Blockly.FieldVariable('VAR'), 'VAR');
.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);
}
}
let variableID = this.getFieldValue("VAR");
let variable = Blockly.getMainWorkspace()
.getVariableMap()
.getVariableById(variableID);
this.getField("type").setValue(variable.type);
this.setOutput(true, variable.type);
},
};
+334
View File
@@ -0,0 +1,334 @@
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');
}
};
+12 -2
View File
@@ -44,7 +44,7 @@ Blockly['Arduino'].addReservedWords(
'setup,loop,if,else,for,switch,case,while,' +
'do,break,continue,return,goto,define,include,' +
'HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false,' +
'interger, constants,floating,point,void,bookean,char,' +
'interger, constants,floating,point,void,boolean,char,' +
'unsigned,byte,int,word,long,float,double,string,String,array,' +
'static, volatile,const,sizeof,pinMode,digitalWrite,digitalRead,' +
'analogReference,analogRead,analogWrite,tone,noTone,shiftOut,shitIn,' +
@@ -106,6 +106,9 @@ Blockly['Arduino'].init = function (workspace) {
// creates a list of code to be setup before the setup block
Blockly['Arduino'].setupCode_ = Object.create(null);
// creates a list of code to be setup before the setup block
Blockly['Arduino'].loraSetupCode_ = Object.create(null);
// creates a list of code for the loop to be runned once
Blockly['Arduino'].loopCodeOnce_ = Object.create(null)
@@ -202,6 +205,7 @@ Blockly['Arduino'].finish = function (code) {
let loopCodeOnce = '';
let setupCode = '';
let preSetupCode = '';
let loraSetupCode = '';
let devVariables = '\n';
for (const key in Blockly['Arduino'].libraries_) {
@@ -233,7 +237,13 @@ Blockly['Arduino'].finish = function (code) {
for (const key in Blockly['Arduino'].setupCode_) {
preSetupCode += Blockly['Arduino'].setupCode_[key] || '';
}
setupCode = '\nvoid setup() { \n' + preSetupCode + '\n}\n';
for (const key in Blockly['Arduino'].loraSetupCode_) {
loraSetupCode += Blockly['Arduino'].loraSetupCode_[key] || '';
}
setupCode = '\nvoid setup() { \n' + preSetupCode + '\n' + loraSetupCode + '\n}\n';
let loopCode = '\nvoid loop() { \n' + loopCodeOnce + code + '\n}\n';
@@ -8,6 +8,7 @@ import './sensebox-display';
import './sensebox-lora';
import './sensebox-led';
import './sensebox-sd';
import './mqtt';
import './logic';
import './text';
import './math';
@@ -17,5 +18,7 @@ import './audio';
import './procedures';
import './time';
import './variables';
import './lists';
import './webserver';
+19
View File
@@ -0,0 +1,19 @@
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];
}
+4 -7
View File
@@ -74,14 +74,14 @@ Blockly.Arduino['controls_if'] = function (Block) {
conditionCode +
') {\n' +
branchCode +
'}';
'}\n';
++n;
} while (Block.getInput('IF' + n));
if (Block.getInput('ELSE')) {
branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE');
code += ' else {\n' + branchCode + '}';
code += ' else {\n' + branchCode + '}\n';
}
return code + '\n';
};
@@ -106,14 +106,14 @@ Blockly.Arduino['controls_ifelse'] = function (Block) {
conditionCode +
') {\n' +
branchCode +
'}';
'}\n';
++n;
} while (Block.getInput('IF' + n));
if (Block.getInput('ELSE')) {
branchCode = Blockly.Arduino.statementToCode(Block, 'ELSE');
code += ' else {\n' + branchCode + '}';
code += ' else {\n' + branchCode + '}\n';
}
return code + '\n';
}
@@ -127,9 +127,6 @@ Blockly.Arduino['logic_negate'] = function (Block) {
};
Blockly.Arduino['switch_case'] = function (block) {
var n = 0;
var argument = Blockly.Arduino.valueToCode(this, 'CONDITION',
+81
View File
@@ -0,0 +1,81 @@
import * as Blockly from 'blockly/core';
/**
* MQTT Blocks
*/
let service;
Blockly.Arduino.sensebox_mqtt_setup = function () {
var server = this.getFieldValue('server');
var port = this.getFieldValue('port');
var username = this.getFieldValue('username');
var pass = this.getFieldValue('password');
service = this.getFieldValue('service');
Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"';
Blockly.Arduino.libraries_['library_adafruitmqtt'] = '#include "Adafruit_MQTT.h"';
Blockly.Arduino.libraries_['library_adafruitmqttclient'] = '#include "Adafruit_MQTT_Client.h"';
Blockly.Arduino.definitions_['mqtt_server'] = '#define SERVER "' + server + '"';
Blockly.Arduino.definitions_['mqtt_port'] = '#define SERVERPORT ' + port + '';
Blockly.Arduino.definitions_['mqtt_username'] = '#define USERNAME "' + username + '"';
Blockly.Arduino.definitions_['mqtt_pass'] = '#define PASS "' + pass + '"';
Blockly.Arduino.definitions_['wifi_client'] = 'WiFiClient client;';
Blockly.Arduino.definitions_['mqtt_client'] = 'Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, USERNAME, PASS);'
var code = '';
return code;
};
Blockly.Arduino.sensebox_mqtt_publish = function (block) {
var feedname = this.getFieldValue('publishfeed');
var res = feedname.split("/");
var feed_client = res[res.length - 1];
var value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC) || '"No Block connected"';
switch (service) {
case 'adafruitio':
Blockly.Arduino.definitions_['mqtt_' + feed_client + ''] = 'Adafruit_MQTT_Publish ' + feed_client + ' = Adafruit_MQTT_Publish(&mqtt, USERNAME "/feeds/' + feedname + '");'
break;
case 'dioty':
Blockly.Arduino.definitions_['mqtt_' + feed_client + ''] = 'Adafruit_MQTT_Publish ' + feed_client + ' = Adafruit_MQTT_Publish(&mqtt, "/"USERNAME"/' + feedname + '");'
break;
case 'custom':
Blockly.Arduino.definitions_['mqtt_' + feed_client + ''] = 'Adafruit_MQTT_Publish ' + feed_client + ' = Adafruit_MQTT_Publish(&mqtt, "' + feedname + '");'
break;
default:
break;
}
//Blockly.Arduino.definitions_['mqtt_' + feed_client + ''] = 'Adafruit_MQTT_Publish ' + feed_client + ' = Adafruit_MQTT_Publish(&mqtt, USERNAME "/feeds/' + feedname + '");'
Blockly.Arduino.codeFunctions_['mqtt_connect_function'] = `// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
mqtt.disconnect();
delay(5000); // wait 5 seconds
}
}`;
Blockly.Arduino.loopCodeOnce_['mqtt_connect'] = 'MQTT_connect();';
var code = '' + feed_client + '.publish(' + value + ');';
return code
};
Blockly.Arduino.sensebox_mqtt_subscribe = function (block) {
var feedname = this.getFieldValue('subscribefeed');
var x = 5, feed_client;
feed_client = feedname.substr(feedname.length - x, x);
Blockly.Arduino.definitions_['mqtt_' + feed_client + ''] = 'Adafruit_MQTT_Subscribe ' + feed_client + '= Adafruit_MQTT_Subscribe(&mqtt,' + feedname + ');';
Blockly.Arduino.codeFunctions_['mqtt_' + feed_client + 'callbackFunction'] = `void ` + feed_client + `Callback (double x){
Serial.println(x);
}`;
Blockly.Arduino.setupCode_['mqtt_' + feed_client + '_callback'] = '' + feed_client + '.setCallback(' + feed_client + 'Callback);';
Blockly.Arduino.setupCode_['mqtt_' + feed_client + '_subscribe'] = 'mqtt.subscribe(&' + feed_client + ');';
Blockly.Arduino.loopCodeOnce_['mqtt_processPackages'] = 'mqtt.processPackets(10);';
var code = '';
return code;
};
@@ -28,3 +28,101 @@ Blockly.Arduino['arduino_functions'] = function (block) {
//var loopcode = Blockly.Arduino.scrub_(block, loopBranch); No comment block
return loopBranch;
};
Blockly.Arduino['procedures_defreturn'] = function (block) {
// Define a procedure with a return value.
const funcName = Blockly.Arduino.variableDB_.getName(
block.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE
);
const branch = Blockly.Arduino.statementToCode(block, 'STACK');
const returnType = block.getFieldValue('RETURN TYPE') || 'void';
let returnValue =
Blockly.Arduino.valueToCode(block, 'RETURN', Blockly.Arduino.ORDER_NONE) ||
'';
if (returnValue) {
returnValue = Blockly.Arduino.INDENT + 'return ' + returnValue + ';\n';
}
const args = [];
for (let i = 0; i < block.argumentVarModels_.length; i++) {
args[i] =
translateType(block.argumentVarModels_[i].type) +
' ' +
block.argumentVarModels_[i].name;
}
let code =
translateType(returnType) +
' ' +
funcName +
'(' +
args.join(', ') +
') {\n' +
branch +
returnValue +
'}';
code = Blockly.Arduino.scrub_(block, code);
// Add % so as not to collide with helper functions in definitions list.
Blockly.Arduino.functionNames_['%' + funcName] = code;
return null;
};
function translateType(type) {
console.log(type);
switch (type) {
case 'int':
return 'int';
case 'String':
return 'String';
case 'void':
return 'void';
case 'boolean':
return 'boolean';
case 'float':
return 'float'
default:
throw new Error('Invalid Parameter Type');
}
}
Blockly.Arduino['procedures_defnoreturn'] =
Blockly.Arduino['procedures_defreturn'];
Blockly.Arduino['procedures_callreturn'] = function (block) {
// Call a procedure with a return value.
const funcName = Blockly.Arduino.variableDB_.getName(
block.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE
);
const args = [];
for (let i = 0; i < block.arguments_.length; i++) {
args[i] =
Blockly.Arduino.valueToCode(
block,
'ARG' + i,
Blockly.Arduino.ORDER_COMMA
) || 'null';
}
const code = funcName + '(' + args.join(', ') + ')';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino['procedures_callnoreturn'] = function (block) {
// Call a procedure with no return value.
const funcName = Blockly.Arduino.variableDB_.getName(
block.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE
);
const args = [];
for (let i = 0; i < block.arguments_.length; i++) {
args[i] =
Blockly.Arduino.valueToCode(
block,
'ARG' + i,
Blockly.Arduino.ORDER_COMMA
) || 'null';
}
return funcName + '(' + args.join(', ') + ');\n';
};
@@ -19,10 +19,10 @@ Blockly.Arduino.sensebox_display_clearDisplay = function () {
};
Blockly.Arduino.sensebox_display_printDisplay = function () {
var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0'
var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0'
var x = this.getFieldValue('X');
var y = this.getFieldValue('Y');
var printDisplay = Blockly.Arduino.valueToCode(this, 'printDisplay', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"';
var size = Blockly.Arduino.valueToCode(this, 'SIZE', Blockly.Arduino.ORDER_ATOMIC) || '1'
var size = this.getFieldValue('SIZE');
var color = this.getFieldValue('COLOR');
var code = 'display.setCursor(' + x + ',' + y + ');\n';
code += 'display.setTextSize(' + size + ');\n';
@@ -31,6 +31,42 @@ Blockly.Arduino.sensebox_display_printDisplay = function () {
return code;
};
Blockly.Arduino.sensebox_display_fastPrint = function () {
var title1 = Blockly.Arduino.valueToCode(this, 'Title1', Blockly.Arduino.ORDER_ATOMIC) || '0'
var value1 = Blockly.Arduino.valueToCode(this, 'Value1', Blockly.Arduino.ORDER_ATOMIC);
var dimension1 = Blockly.Arduino.valueToCode(this, 'Dimension1', Blockly.Arduino.ORDER_ATOMIC) || '0'
var title2 = Blockly.Arduino.valueToCode(this, 'Title2', Blockly.Arduino.ORDER_ATOMIC) || '0'
var value2 = Blockly.Arduino.valueToCode(this, 'Value2', Blockly.Arduino.ORDER_ATOMIC);
var dimension2 = Blockly.Arduino.valueToCode(this, 'Dimension2', Blockly.Arduino.ORDER_ATOMIC) || '0'
Blockly.Arduino.codeFunctions_['sensebox_fastPrint'] = `
void printOnDisplay(String title1, String measurement1, String unit1, String title2, String measurement2, String unit2) {
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.println(title1);
display.setCursor(0, 10);
display.setTextSize(2);
display.print(measurement1);
display.print(" ");
display.setTextSize(1);
display.println(unit1);
display.setCursor(0, 30);
display.setTextSize(1);
display.println(title2);
display.setCursor(0, 40);
display.setTextSize(2);
display.print(measurement2);
display.print(" ");
display.setTextSize(1);
display.println(unit2);
}
`
var code = ` printOnDisplay(${title1}, String(${value1}), ${dimension1}, ${title2}, String(${value2}), ${dimension2});\n`;
return code;
};
Blockly.Arduino.sensebox_display_show = function (block) {
var show = Blockly.Arduino.statementToCode(block, 'SHOW');
var code = '';
@@ -10,13 +10,58 @@ Blockly.Arduino.sensebox_led = function () {
Blockly.Arduino.sensebox_rgb_led = function () {
var dropdown_pin = this.getFieldValue('PIN');
var red = this.getFieldValue('RED') || '0'
var green = this.getFieldValue('GREEN') || '0'
var blue = this.getFieldValue('BLUE') || '0'
var color = Blockly.Arduino.valueToCode(this, 'COLOR', Blockly.Arduino.ORDER_ATOMIC) || '0'
Blockly.Arduino.libraries_['define_rgb_led' + dropdown_pin] = '#include <Adafruit_NeoPixel.h>\n Adafruit_NeoPixel rgb_led_' + dropdown_pin + ' = Adafruit_NeoPixel(1,' + dropdown_pin + ',NEO_RGB + NEO_KHZ800);\n';
Blockly.Arduino.setupCode_['setup_rgb_led' + dropdown_pin] = 'rgb_led_' + dropdown_pin + '.begin();';
var code = 'rgb_led_' + dropdown_pin + '.setPixelColor(0,rgb_led_' + dropdown_pin + '.Color(' + red + ',' + green + ',' + blue + '));\n';
var code = 'rgb_led_' + dropdown_pin + '.setPixelColor(0,rgb_led_' + dropdown_pin + '.Color(' + color + '));\n';
code += 'rgb_led_' + dropdown_pin + '.show();';
return code;
};
Blockly.Arduino.sensebox_ws2818_led_init = function () {
var dropdown_pin = this.getFieldValue('Port');
var numPixel = Blockly.Arduino.valueToCode(this, 'NUMBER', Blockly.Arduino.ORDER_ATOMIC) || '1';
var brightness = Blockly.Arduino.valueToCode(this, 'BRIGHTNESS', Blockly.Arduino.ORDER_ATOMIC) || '50'
Blockly.Arduino.definitions_['define_rgb_led' + dropdown_pin] = `#include <Adafruit_NeoPixel.h>\n Adafruit_NeoPixel rgb_led_${dropdown_pin}= Adafruit_NeoPixel(${numPixel}, ${dropdown_pin},NEO_GRB + NEO_KHZ800);\n`;
Blockly.Arduino.setupCode_['setup_rgb_led' + dropdown_pin] = 'rgb_led_' + dropdown_pin + '.begin();\n';
Blockly.Arduino.setupCode_['setup_rgb_led_brightness' + dropdown_pin] = `rgb_led_${dropdown_pin}.setBrightness(${brightness});\n`;
return '';
};
Blockly.Arduino.sensebox_ws2818_led = function () {
var dropdown_pin = this.getFieldValue('Port');
var position = Blockly.Arduino.valueToCode(this, 'POSITION', Blockly.Arduino.ORDER_ATOMIC) || '0';
var color = Blockly.Arduino.valueToCode(this, 'COLOR', Blockly.Arduino.ORDER_ATOMIC) || '0'
console.log(color)
var code = `rgb_led_${dropdown_pin}.setPixelColor(${position},rgb_led_${dropdown_pin}.Color(${color}));\nrgb_led_${dropdown_pin}.show();\n`;
return code;
};
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
Blockly.Arduino['colour_picker'] = function (block) {
const rgb = hexToRgb(block.getFieldValue('COLOUR'));
return [rgb.r + ', ' + rgb.g + ', ' + rgb.b, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino['colour_random'] = function (block) {
return ['random(0, 255), random(0, 255), random(0, 255)', Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino['colour_rgb'] = function (block) {
const red = Blockly.Arduino.valueToCode(block, 'RED', Blockly.Arduino.ORDER_ATOMIC);
const green = Blockly.Arduino.valueToCode(block, 'GREEN', Blockly.Arduino.ORDER_ATOMIC);
const blue = Blockly.Arduino.valueToCode(block, 'BLUE', Blockly.Arduino.ORDER_ATOMIC);
return [red + ', ' + green + ', ' + blue, Blockly.Arduino.ORDER_ATOMIC];
};
@@ -120,9 +120,9 @@ Blockly.Arduino.sensebox_lora_initialize_otaa = function (block) {
break;
}
}`;
Blockly.Arduino.setupCode_['initLora'] = 'initLora();';
Blockly.Arduino.setupCode_['serial.begin'] = 'Serial.begin(9600);';
var code = ''
Blockly.Arduino.loraSetupCode_['initLora'] = 'initLora();\n';
Blockly.Arduino.setupCode_['serial.begin'] = 'Serial.begin(9600);\ndelay(1000);\n';
var code = '';
return code;
};
@@ -195,6 +195,60 @@ Blockly.Arduino.sensebox_lora_cayenne_send = function (block) {
return '';
}
Blockly.Arduino.sensebox_lora_ttn_mapper = function (block) {
var latitude = Blockly.Arduino.valueToCode(this, 'Latitude', Blockly.Arduino.ORDER_ATOMIC)
var longitude = Blockly.Arduino.valueToCode(this, 'Longitude', Blockly.Arduino.ORDER_ATOMIC)
var altitude = Blockly.Arduino.valueToCode(this, 'Altitude', Blockly.Arduino.ORDER_ATOMIC)
var pDOP = Blockly.Arduino.valueToCode(this, 'pDOP', Blockly.Arduino.ORDER_ATOMIC)
var fixType = Blockly.Arduino.valueToCode(this, 'Fix Type', Blockly.Arduino.ORDER_ATOMIC)
var fixTypeLimit = this.getFieldValue('dropdown');
Blockly.Arduino.functionNames_['functions_do_send'] = `
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
int fixType = ${fixType};
if (fixType >= ${fixTypeLimit}) { // we have a 3D fix
int32_t latitude = ${latitude}; // in degrees * 10^-7
int32_t longitude = ${longitude}; // in degrees * 10^-7
int32_t altitude = ${altitude} / 100; // in dm above mean sea level
uint16_t pDOP = ${pDOP}; // positional dillution of precision
uint8_t data[12];
data[0] = latitude;
data[1] = latitude >> 8;
data[2] = latitude >> 16;
data[3] = latitude >> 24;
data[4] = longitude;
data[5] = longitude >> 8;
data[6] = longitude >> 16;
data[7] = longitude >> 24;
data[8] = altitude;
data[9] = altitude >> 8;
data[10] = pDOP;
data[11] = pDOP >> 8;
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, data, sizeof(data), 0);
Serial.println(F("Packet queued"));
} else {
// wait for better fix type
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
}
}
// Next TX is scheduled after TX_COMPLETE event.
}`;
Blockly.Arduino.loopCodeOnce_['os_runloop'] = 'os_runloop_once();'
return '';
}
Blockly.Arduino.sensebox_lora_initialize_abp = function (block) {
var nwskey = this.getFieldValue('NWSKEY');
var appskey = this.getFieldValue('APPSKEY');
@@ -372,8 +426,8 @@ Blockly.Arduino.sensebox_lora_initialize_abp = function (block) {
break;
}
}`;
Blockly.Arduino.setupCode_['initLora'] = 'initLora();';
Blockly.Arduino.setupCode_['serial.begin'] = 'Serial.begin(9600);';
Blockly.Arduino.loraSetupCode_['initLora'] = 'initLora();\n';
Blockly.Arduino.setupCode_['serial.begin'] = 'Serial.begin(9600);\ndelay(1000);\n';
return '';
}
@@ -18,17 +18,20 @@ Blockly.Arduino.sensebox_osem_connection = function (Block) {
var box_id = this.getFieldValue('BoxID');
var host = this.getFieldValue('host');
var branch = Blockly.Arduino.statementToCode(Block, 'DO');
//var blocks = Blockly.Block.getDescendants;
var access_token = this.getFieldValue('access_token');
var blocks = this.getDescendants();
var type = this.getFieldValue('type');
var ssl = this.getFieldValue('SSL');
var port = 0;
var count = 0;
// for (var i = 0; i < blocks.length; i++) {
// if (blocks[i].type === 'sensebox_send_to_osem') {
// count++;
if (blocks !== undefined) {
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].type === 'sensebox_send_to_osem') {
count++;
// }
// }
}
}
}
var num_sensors = count;
Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"';
Blockly.Arduino.definitions_['num_sensors'] = 'static const uint8_t NUM_SENSORS = ' + num_sensors + ';'
@@ -84,7 +87,7 @@ Blockly.Arduino.sensebox_osem_connection = function (Block) {
if (connected == true) {
// construct the HTTP POST request:
sprintf_P(buffer,
PSTR("POST /boxes/%s/data HTTP/1.1\\nHost: %s\\nContent-Type: "
PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_token}\\nHost: %s\\nContent-Type: "
"text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"),
SENSEBOX_ID, server, num_measurements * lengthMultiplikator);
// send the HTTP POST request:
@@ -144,7 +147,7 @@ Blockly.Arduino.sensebox_osem_connection = function (Block) {
if (connected == true) {
// construct the HTTP POST request:
sprintf_P(buffer,
PSTR("POST /boxes/%s/data HTTP/1.1\\nHost: %s\\nContent-Type: "
PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_token}\\nHost: %s\\nContent-Type: "
"text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"),
SENSEBOX_ID, server, num_measurements * lengthMultiplikator);
// send the HTTP POST request:
+28 -25
View File
@@ -1,5 +1,4 @@
import Blockly from 'blockly';
import Blockly from "blockly";
/* SD-Card Blocks using the Standard SD Library*/
/**
@@ -10,45 +9,49 @@ import Blockly from 'blockly';
*/
Blockly.Arduino.sensebox_sd_create_file = function (block) {
var filename = this.getFieldValue('Filename');
var res = filename.slice(0, 4);
Blockly.Arduino.libraries_['library_spi'] = '#include <SPI.h>';
Blockly.Arduino.libraries_['library_sd'] = '#include <SD.h>';
Blockly.Arduino.definitions_['define_' + res] = 'File dataFile' + res + ';';
Blockly.Arduino.setupCode_['sensebox_sd'] = 'SD.begin(28);';
Blockly.Arduino.setupCode_['sensebox_sd' + filename] = 'dataFile' + res + ' = SD.open("' + filename + '", FILE_WRITE);\ndataFile' + res + '.close();\n';
var code = '';
var filename = this.getFieldValue("Filename");
var extension = this.getFieldValue("extension");
var newFileName = filename.concat(".", extension);
Blockly.Arduino.libraries_["library_spi"] = "#include <SPI.h>";
Blockly.Arduino.libraries_["library_sd"] = "#include <SD.h>";
Blockly.Arduino.definitions_["define_" + filename] = `File ${filename};`;
Blockly.Arduino.setupCode_["sensebox_sd"] = "SD.begin(28);\n";
Blockly.Arduino.setupCode_[
"sensebox_sd" + filename
] = `${filename} = SD.open("${newFileName}", FILE_WRITE);\n${filename}.close();\n`;
var code = "";
return code;
};
Blockly.Arduino.sensebox_sd_open_file = function (block) {
var filename = this.getFieldValue('Filename');
var res = filename.slice(0, 4);
var branch = Blockly.Arduino.statementToCode(block, 'SD');
var code = 'dataFile' + res + ' = SD.open("' + filename + '", FILE_WRITE);\n'
var filename = this.getFieldValue("Filename");
var extension = this.getFieldValue("extension");
var newFileName = filename.concat(".", extension);
var branch = Blockly.Arduino.statementToCode(block, "SD");
var code = `${filename} = SD.open("${newFileName}", FILE_WRITE);\n`;
code += branch;
code += 'dataFile' + res + '.close();\n'
code += `${filename}.close();\n`;
return code;
};
Blockly.Arduino.sensebox_sd_write_file = function (block) {
if (this.parentBlock_ != null) {
var filename = this.getSurroundParent().getFieldValue('Filename');
var filename = this.getSurroundParent().getFieldValue("Filename");
}
var res = filename.slice(0, 4);
var text = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"';
var linebreak = this.getFieldValue('linebreak');
var branch =
Blockly.Arduino.valueToCode(this, "DATA", Blockly.Arduino.ORDER_ATOMIC) ||
'"Keine Eingabe"';
var linebreak = this.getFieldValue("linebreak");
if (linebreak === "TRUE") {
linebreak = "ln";
} else {
linebreak = "";
}
var code = '';
if (text === "gps.getLongitude()" || text === "gps.getLatitude()") {
code = 'dataFile' + res + '.print' + linebreak + '(' + text + ',5);\n'
}
else {
code = 'dataFile' + res + '.print' + linebreak + '(' + text + ');\n'
var code = "";
if (branch === "gps.getLongitude()" || branch === "gps.getLatitude()") {
code = `${filename}.print${linebreak}(${branch},5);\n`;
} else {
code = `${filename}.print${linebreak}(${branch});\n`;
}
return code;
};
@@ -28,15 +28,23 @@ Blockly.Arduino.sensebox_sensor_uv_light = function () {
Blockly.Arduino.setupCode_['sensebox_sensor_uv_light'] = 'veml.begin();'
code = 'veml.get' + dropdown_name + '()';
}
// if (dropdown_name === 'Illuminance') {
// Blockly.Arduino.definitions_['define_tsl'] = 'TSL45315 tsl;'
// Blockly.Arduino.setupCode_['sensebox_sensor_illuminance'] = 'tsl.begin();'
// code = 'tsl.get' + dropdown_name + '()';
// }
if (dropdown_name === 'Illuminance') {
Blockly.Arduino.definitions_['define_tsl'] = 'TSL45315 tsl;'
Blockly.Arduino.setupCode_['sensebox_sensor_illuminance'] = 'tsl.begin();'
code = 'tsl.get' + dropdown_name + '()';
Blockly.Arduino.definitions_['define_lightsensor'] = 'Lightsensor lightsensor;'
Blockly.Arduino.setupCode_['sensebox_sensor_illuminance'] = 'lightsensor.begin();'
code = 'lightsensor.get' + dropdown_name + '()';
}
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
/**
* BMX055 Accelerometer
*
@@ -263,32 +271,22 @@ Blockly.Arduino.sensebox_scd30 = function () {
Blockly.Arduino.libraries_['scd30_library'] = '#include "SparkFun_SCD30_Arduino_Library.h"'
Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"';
Blockly.Arduino.definitions_['SCD30'] = 'SCD30 airSensor;';
Blockly.Arduino.variables_['scd30_temp'] = 'float scd30_temp;';
Blockly.Arduino.variables_['scd30_humi'] = 'float scd30_humi;';
Blockly.Arduino.variables_['scd30_co2'] = 'float scd30_co2;';
Blockly.Arduino.setupCode_['init_scd30'] = ` Wire.begin();
if (airSensor.begin() == false)
{
Serial.println("Air sensor not detected. Please check wiring. Freezing...");
while (1)
;
}`;
Blockly.Arduino.loopCodeOnce_['scd30_getData'] = `if (airSensor.dataAvailable())
{
scd30_co2 = airSensor.getCO2();
scd30_temp = airSensor.getTemperature();
scd30_humi = airSensor.getHumidity();
}`
var code = '';
switch (dropdown) {
case 'temperature':
code = 'scd30_temp';
code = 'airSensor.getTemperature()';
break;
case 'humidity':
code = 'scd30_humi';
code = 'airSensor.getHumiditiy()';
break;
case 'CO2':
code = 'scd30_co2';
code = 'airSensor.getCO2()';
break;
default:
code = ''
@@ -296,3 +294,177 @@ Blockly.Arduino.sensebox_scd30 = function () {
return [code, Blockly.Arduino.ORDER_ATOMIC];
}
/**
* GPS Module
*
*/
Blockly.Arduino.sensebox_gps = function () {
var dropdown = this.getFieldValue('dropdown');
Blockly.Arduino.libraries_['gps_library'] = '#include <SparkFun_u-blox_GNSS_Arduino_Library.h>'
Blockly.Arduino.libraries_['library_wire'] = '#include <Wire.h>';
Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"';
Blockly.Arduino.definitions_['GPS'] = 'SFE_UBLOX_GNSS myGNSS;';
Blockly.Arduino.setupCode_['init_gps'] = ` Wire.begin();
if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
{
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
while (1);
}
myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
myGNSS.saveConfiguration(); //Save the current settings to flash and BBR`;
var code = '';
switch (dropdown) {
case 'latitude':
code = 'myGNSS.getLatitude()';
break;
case 'longitude':
code = 'myGNSS.getLongitude()';
break;
case 'altitude':
code = 'myGNSS.getAltitudeMSL()';
break;
case 'pDOP':
code = 'myGNSS.getPDOP()';
break;
case 'fixType':
code = 'myGNSS.getFixType()';
break;
default:
code = ''
}
return [code, Blockly.Arduino.ORDER_ATOMIC];
}
/**
* Block for Truebner STM50
*/
Blockly.Arduino.sensebox_sensor_truebner_smt50 = function () {
var dropdown_port = this.getFieldValue('Port')
var dropdown_value = this.getFieldValue('value');
var dropdown_pin = 1;
var code = '';
if (dropdown_value === 'temp') {
if (dropdown_port === 'A') {
dropdown_pin = 1;
}
if (dropdown_port === 'B') {
dropdown_pin = 3;
}
if (dropdown_port === 'C') {
dropdown_pin = 5;
}
Blockly.Arduino.codeFunctions_['sensebox_smt50_temp'] = 'float getSMT50Temperature(int analogPin){\n int sensorValue = analogRead(analogPin);\n float voltage = sensorValue * (3.3 / 1024.0);\n return (voltage - 0.5) * 100;\n}';
code = 'getSMT50Temperature(' + dropdown_pin + ')';
return [code, Blockly.Arduino.ORDER_ATOMIC];
}
else if (dropdown_value === 'soil') {
if (dropdown_port === 'A') {
dropdown_pin = 2;
}
if (dropdown_port === 'B') {
dropdown_pin = 4;
}
if (dropdown_port === 'C') {
dropdown_pin = 6;
}
Blockly.Arduino.codeFunctions_['sensebox_smt50_soil'] = 'float getSMT50Moisture(int analogPin){\n int sensorValue = analogRead(analogPin);\n float voltage = sensorValue * (3.3 / 1024.0);\n return (voltage * 50) / 3;\n}';
code = 'getSMT50Moisture(' + dropdown_pin + ')';
return [code, Blockly.Arduino.ORDER_ATOMIC];
}
};
/**
* DS18B20 Watertemperature
*
*/
Blockly.Arduino.sensebox_sensor_watertemperature = function () {
var dropdown_port = this.getFieldValue('Port');
var dropdown_pin = 1;
if (dropdown_port === 'A') {
dropdown_pin = 1;
}
if (dropdown_port === 'B') {
dropdown_pin = 3;
}
if (dropdown_port === 'C') {
dropdown_pin = 5;
}
Blockly.Arduino.libraries_['library_oneWire'] = '#include "OneWire.h"';
Blockly.Arduino.libraries_['library_oneDallasTemperature'] = '#include "DallasTemperature.h"';
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];
};
/**
* Windspeed
* remove for now
Blockly.Arduino.sensebox_windspeed = function () {
var dropdown_pin = this.getFieldValue('PIN');
Blockly.Arduino.codeFunctions_['windspeed'] = `
float getWindspeed(){
float voltageWind = analogRead(`+ dropdown_pin + `) * (3.3 / 1024.0);
float windspeed = 0.0;
if (voltageWind >= 0.018){
float poly1 = pow(voltageWind, 3);
poly1 = 17.0359801998299 * poly1;
float poly2 = pow(voltageWind, 2);
poly2 = 47.9908168343362 * poly2;
float poly3 = 122.899677524413 * voltageWind;
float poly4 = 0.657504127272728;
windspeed = poly1 - poly2 + poly3 - poly4;
windspeed = windspeed * 0.2777777777777778; //conversion in m/s
}
return windspeed;
}`
var code = 'getWindspeed()';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
*/
/**
* DF Robot Soundsensor
*/
/**
*
*
*/
Blockly.Arduino.sensebox_soundsensor_dfrobot = function () {
var dropdown_port = this.getFieldValue('Port');
var dropdown_pin = 1;
if (dropdown_port === 'A') {
dropdown_pin = 1;
}
if (dropdown_port === 'B') {
dropdown_pin = 3;
}
if (dropdown_port === 'C') {
dropdown_pin = 5;
}
Blockly.Arduino.codeFunctions_['soundsensor'] = `
float getSoundValue(){
float v = analogRead(`+ dropdown_pin + `) * (3.3 / 1024.0);
float decibel = v * 50;
return decibel;
}`
var code = 'getSoundValue()';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
+34 -21
View File
@@ -1,4 +1,4 @@
import Blockly from 'blockly';
import Blockly from "blockly";
/**
* @license Licensed under the Apache License, Version 2.0 (the "License"):
@@ -16,10 +16,14 @@ import Blockly from 'blockly';
* @param {!Blockly.Block} block Block to generate the code from.
* @return {string} Completed code.
*/
Blockly.Arduino['time_delay'] = function (block) {
var delayTime = Blockly.Arduino.valueToCode(
block, 'DELAY_TIME_MILI', Blockly.Arduino.ORDER_ATOMIC) || '0';
var code = 'delay(' + delayTime + ');\n';
Blockly.Arduino["time_delay"] = function (block) {
var delayTime =
Blockly.Arduino.valueToCode(
block,
"DELAY_TIME_MILI",
Blockly.Arduino.ORDER_ATOMIC
) || "0";
var code = "delay(" + delayTime + ");\n";
return code;
};
@@ -29,10 +33,14 @@ Blockly.Arduino['time_delay'] = function (block) {
* @param {!Blockly.Block} block Block to generate the code from.
* @return {string} Completed code.
*/
Blockly.Arduino['time_delaymicros'] = function (block) {
var delayTimeMs = Blockly.Arduino.valueToCode(
block, 'DELAY_TIME_MICRO', Blockly.Arduino.ORDER_ATOMIC) || '0';
var code = 'delayMicroseconds(' + delayTimeMs + ');\n';
Blockly.Arduino["time_delaymicros"] = function (block) {
var delayTimeMs =
Blockly.Arduino.valueToCode(
block,
"DELAY_TIME_MICRO",
Blockly.Arduino.ORDER_ATOMIC
) || "0";
var code = "delayMicroseconds(" + delayTimeMs + ");\n";
return code;
};
@@ -42,8 +50,8 @@ Blockly.Arduino['time_delaymicros'] = function (block) {
* @param {!Blockly.Block} block Block to generate the code from.
* @return {array} Completed code with order of operation.
*/
Blockly.Arduino['time_millis'] = function (block) {
var code = 'millis()';
Blockly.Arduino["time_millis"] = function (block) {
var code = "millis()";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
@@ -53,8 +61,8 @@ Blockly.Arduino['time_millis'] = function (block) {
* @param {!Blockly.Block} block Block to generate the code from.
* @return {array} Completed code with order of operation.
*/
Blockly.Arduino['time_micros'] = function (block) {
var code = 'micros()';
Blockly.Arduino["time_micros"] = function (block) {
var code = "micros()";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
@@ -64,17 +72,22 @@ Blockly.Arduino['time_micros'] = function (block) {
* @param {!Blockly.Block} block Block to generate the code from.
* @return {string} Completed code.
*/
Blockly.Arduino['infinite_loop'] = function (block) {
return 'while(true);\n';
Blockly.Arduino["infinite_loop"] = function (block) {
return "while(true);\n";
};
Blockly.Arduino.sensebox_interval_timer = function (block) {
var interval = this.getFieldValue('interval');
Blockly.Arduino.variables_['define_interval_variables'] = 'const long interval = ' + interval + ';\nlong time_start = 0;\nlong time_actual = 0;';
var branch = Blockly.Arduino.statementToCode(block, 'DO');
var code = 'time_start = millis();\n';
code += 'if (time_start > time_actual + interval) {\n time_actual = millis();\n'
var intervalTime = this.getFieldValue("interval");
var intervalName = this.getFieldValue("name");
Blockly.Arduino.variables_[`define_interval_variables${intervalName}`] = `
const long interval${intervalName} = ${intervalTime};
long time_start${intervalName} = 0;
long time_actual${intervalName} = 0;`;
var branch = Blockly.Arduino.statementToCode(block, "DO");
var code = `time_start${intervalName} = millis();\n`;
code += `
if (time_start${intervalName} > time_actual${intervalName} + interval${intervalName}) {\n time_actual${intervalName} = millis();\n`;
code += branch;
code += '}\n'
code += "}\n";
return code;
};
+22 -3
View File
@@ -14,9 +14,28 @@ const setVariableFunction = function (defaultValue) {
const allVars = Blockly.getMainWorkspace().getVariableMap().getAllVariables();
const myVar = allVars.filter(v => v.name === variableName)[0]
var code = ''
switch (myVar.type) {
default:
Blockly.Arduino.variables_[myVar + myVar.type] = myVar.type + " " + myVar.name + ';\n';
return variableName + ' = ' + (variableValue || defaultValue) + ';\n';
code = variableName + ' = ' + (variableValue || defaultValue) + ';\n';
break;
case 'Array':
var arrayType;
var number;
if (this.getChildren().length > 0) {
if (this.getChildren()[0].type === 'lists_create_empty') {
arrayType = this.getChildren()[0].getFieldValue('type');
number = Blockly.Arduino.valueToCode(this.getChildren()[0], 'NUMBER', Blockly['Arduino'].ORDER_ATOMIC);
Blockly.Arduino.variables_[myVar + myVar.type] = `${arrayType} ${myVar.name} [${number}];\n`;
}
}
break;
}
return code;
};
};
@@ -25,8 +44,8 @@ const getVariableFunction = function (block) {
block.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE
);
return [variableName, Blockly['Arduino'].ORDER_ATOMIC];
var code = variableName;
return [code, Blockly['Arduino'].ORDER_ATOMIC];
};
Blockly['Arduino']['variables_set_dynamic'] = setVariableFunction()
@@ -0,0 +1,127 @@
import Blockly from "blockly";
/**
* Webserver Blocks by Lucas Steinmann
*
*/
Blockly.Arduino.sensebox_initialize_http_server = function (block) {
var box_id = this.getFieldValue("Port");
Blockly.Arduino.libraries_["library_senseBoxMCU"] =
'#include "SenseBoxMCU.h"';
Blockly.Arduino.codeFunctions_["define_wifi_server"] =
"WiFiServer server(" + box_id + ");";
Blockly.Arduino.setupCode_["sensebox_wifi_server_beging"] = "server.begin();";
return "";
};
Blockly.Arduino.sensebox_http_on_client_connect = function (block) {
var onConnect = Blockly.Arduino.statementToCode(block, "ON_CONNECT");
var code = "";
code += "WiFiClient client = server.available();\n";
code += "if (client && client.available()) {\n";
code += " String request_string = listenClient(client);\n";
code += " Request request;\n";
code += " if (parseRequestSafe(request_string, request)) {\n";
code += onConnect;
code += " }\n";
code += " delay(1);\n";
code += " client.stop();\n";
code += " delay(1);\n";
code += "}\n";
return code;
};
Blockly.Arduino.sensebox_http_method = function (block) {
var code = "request.method";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_http_uri = function (block) {
var code = "request.uri";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_http_protocol_version = function (block) {
var code = "request.protocol_version";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_http_user_agent = function (block) {
var code = "request.user_agent";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_generate_html_doc = function (block) {
var header =
Blockly.Arduino.valueToCode(block, "HEADER", Blockly.Arduino.ORDER_NONE) ||
'""';
var body =
Blockly.Arduino.valueToCode(block, "BODY", Blockly.Arduino.ORDER_NONE) ||
'""';
var code = "buildHTML(" + header + ", " + body + ")";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_generate_http_succesful_response = function (block) {
var content =
Blockly.Arduino.valueToCode(block, "CONTENT", Blockly.Arduino.ORDER_NONE) ||
'""';
var code =
"client.println(buildSuccessfulResponse(request, " + content + "));\n";
return code;
};
Blockly.Arduino.sensebox_generate_http_not_found_response = function (block) {
var code = "client.println(buildNotFoundResponse(request));\n";
return code;
};
Blockly.Arduino.sensebox_ip_address = function (block) {
var code = "b->getIpAddress()";
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_general_html_tag = function (block) {
var tag = this.getFieldValue("TAG");
var code = 'buildTag("' + tag + '",';
var n = 0;
var branch = Blockly.Arduino.valueToCode(
block,
"DO" + n,
Blockly.Arduino.ORDER_NONE
);
if (branch.length > 0) {
code += "\n " + branch;
} else {
code += '""';
}
for (n = 1; n <= block.additionalChildCount_; n++) {
branch = Blockly.Arduino.valueToCode(
block,
"DO" + n,
Blockly.Arduino.ORDER_NONE
);
code += " +" + branch;
}
return [code + ")", Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.sensebox_web_readHTML = function (block) {
var filename = this.getFieldValue("FILENAME");
Blockly.Arduino.libraries_["library_spi"] = "#include <SPI.h>";
Blockly.Arduino.libraries_["library_sd"] = "#include <SD.h>";
Blockly.Arduino.codeFunctions_["define_sd" + filename] = "File webFile;";
Blockly.Arduino.setupCode_["sensebox_sd"] = "SD.begin(28);";
Blockly.Arduino.codeFunctions_["generateHTML"] = `
String generateHTML(){
webFile = SD.open("${filename}", FILE_READ);
String finalString ="";
while (webFile.available())
{
finalString+=(char)webFile.read();
}
return finalString;
}`;
var code = `generateHTML()`;
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
+3
View File
@@ -10,6 +10,9 @@ const colours = {
text: 160,
variables: 330,
audio: 250,
arrays: 33,
mqtt: 90,
webserver: 40
}
+66 -61
View File
@@ -8,101 +8,110 @@
* types.
*/
/** Single character. */
export const CHARACTER = {
typeId: 'Character',
typeName: 'char',
typeMsgName: 'ARD_TYPE_CHAR',
}
typeId: "Character",
typeName: "char",
typeMsgName: "ARD_TYPE_CHAR",
};
export const BOOLEAN = {
typeId: 'Boolean',
typeName: 'boolean',
typeMsgName: 'ARD_TYPE_BOOL',
}
typeId: "Boolean",
typeName: "boolean",
typeMsgName: "ARD_TYPE_BOOL",
};
/** Text string. */
export const TEXT = {
typeId: 'Text',
typeName: 'String',
typeMsgName: 'ARD_TYPE_TEXT',
}
typeId: "Text",
typeName: "String",
typeMsgName: "ARD_TYPE_TEXT",
};
/** Short integer number. */
export const SHORT_NUMBER = {
typeId: 'Short_Number',
typeName: 'int',
typeMsgName: 'ARD_TYPE_SHORT',
}
typeId: "Short_Number",
typeName: "int",
typeMsgName: "ARD_TYPE_SHORT",
};
/** Integer number. */
export const NUMBER = {
typeId: 'Number',
typeName: 'int',
typeMsgName: 'ARD_TYPE_NUMBER',
}
typeId: "Number",
typeName: "int",
typeMsgName: "ARD_TYPE_NUMBER",
};
/** Large integer number. */
export const LARGE_NUMBER = {
typeId: 'Large Number',
typeName: 'long',
typeMsgName: 'ARD_TYPE_LONG',
}
typeId: "Large Number",
typeName: "long",
typeMsgName: "ARD_TYPE_LONG",
};
/** Decimal/floating point number. */
export const DECIMAL = {
typeId: 'Decimal',
typeName: 'float',
typeMsgName: 'ARD_TYPE_DECIMAL',
}
typeId: "Decimal",
typeName: "float",
typeMsgName: "ARD_TYPE_DECIMAL",
};
/** Array/List of items. */
export const ARRAY = {
typeId: 'Array',
typeName: 'array',
typeMsgName: 'ARD_TYPE_ARRAY',
compatibleTypes: []
}
typeId: "Array",
typeName: "Array",
typeMsgName: "ARD_TYPE_ARRAY",
compatibleTypes: [],
};
/** Null indicate there is no type. */
export const NULL = {
typeId: 'Null',
typeName: 'void',
typeMsgName: 'ARD_TYPE_NULL',
}
typeId: "Null",
typeName: "void",
typeMsgName: "ARD_TYPE_NULL",
};
/** Type not defined, or not yet defined. */
export const UNDEF = {
typeId: 'Undefined',
typeName: 'undef',
typeMsgName: 'ARD_TYPE_UNDEF',
}
typeId: "Undefined",
typeName: "undef",
typeMsgName: "ARD_TYPE_UNDEF",
};
/** Set when no child block (meant to define the variable type) is connected. */
export const CHILD_BLOCK_MISSING = {
typeId: 'ChildBlockMissing',
typeMsgName: 'ARD_TYPE_CHILDBLOCKMISSING',
compatibleTypes: []
}
typeId: "ChildBlockMissing",
typeMsgName: "ARD_TYPE_CHILDBLOCKMISSING",
compatibleTypes: [],
};
const compatibleTypes = {
boolean: ['boolean'],
int: ['int'],
char: ['char'],
String: ['String'],
void: ['void'],
long: ['int', 'long'],
double: ['int', 'long', 'double'],
float: ['int', 'long', 'double', 'float']
}
Array: ["Array"],
boolean: ["boolean"],
int: ["int", "long", "double", "float"],
char: ["char"],
String: ["String"],
void: ["void"],
long: ["int", "long"],
double: ["int", "long", "double"],
float: ["int", "long", "double", "float"],
null: ["null"],
};
export const getCompatibleTypes = (type) => {
return compatibleTypes[type];
};
export const VARIABLE_TYPES = [['SHORT_NUMBER', 'char'], ['NUMBER', 'int'], ['DECIMAL', 'long'], ['TEXT', 'String'], ['CHARACTER', 'char'], ['BOOLEAN', 'boolean'], ['NULL', 'void'], ['UNDEF', 'undefined']];
export const VARIABLE_TYPES = [
["SHORT_NUMBER", "char"],
["NUMBER", "int"],
["DECIMAL", "long"],
["TEXT", "String"],
["CHARACTER", "char"],
["BOOLEAN", "boolean"],
["NULL", "void"],
["UNDEF", "undefined"],
];
// /**
// * Some Types have circular dependencies on their compatibilities, so add them
@@ -231,7 +240,3 @@ export const VARIABLE_TYPES = [['SHORT_NUMBER', 'char'], ['NUMBER', 'int'], ['DE
// }
// return Blockly.Types.NULL;
// };
+46 -775
View File
@@ -1,777 +1,48 @@
// import * as Blockly from 'blockly/core';
// https://developers.google.com/blockly/guides/configure/web/translations
import { AUDIO } from './de/audio';
import { FAQ } from './de/faq';
import { IO } from './de/io';
import { LOGIC } from './de/logic';
import { LOOPS } from './de/loops';
import { MATH } from './de/math';
import { MQTT } from './de/mqtt';
import { DISPLAY } from './de/sensebox-display';
import { LED } from './de/sensebox-led';
import { LORA } from './de/sensebox-lora';
import { OSEM } from './de/sensebox-osem';
import { SD } from './de/sensebox-sd';
import { SENSORS } from './de/sensebox-sensors';
import { TELEGRAM } from './de/sensebox-telegram';
import { WEB } from './de/sensebox-web';
import { TEXT } from './de/text';
import { TIME } from './de/time';
import { TOURS } from './de/tours';
import { TRANSLATIONS } from './de/translations';
import { UI } from './de/ui';
import { VARIABLES } from './de/variables';
import { WEBSERVER } from './de/webserver';
const Blockly = {};
Blockly.Msg = {};
Blockly.Msg.ADD_COMMENT = "Kommentar hinzufügen";
Blockly.Msg.AUTH = "Bitte autorisiere diese App zum Aktivieren der Speicherung deiner Arbeit und zum Teilen.";
Blockly.Msg.CHANGE_VALUE_TITLE = "Wert ändern:";
Blockly.Msg.CHAT = "Chatte mit unserem Mitarbeiter durch Eingeben von Text in diesen Kasten!";
Blockly.Msg.CLEAN_UP = "Blöcke aufräumen";
Blockly.Msg.COLLAPSE_ALL = "Alle Blöcke zusammenfalten";
Blockly.Msg.COLLAPSE_BLOCK = "Block zusammenfalten";
Blockly.Msg.COLOUR_BLEND_COLOUR1 = "Farbe 1";
Blockly.Msg.COLOUR_BLEND_COLOUR2 = "mit Farbe 2";
Blockly.Msg.COLOUR_BLEND_HELPURL = "http://meyerweb.com/eric/tools/color-blend/";
Blockly.Msg.COLOUR_BLEND_RATIO = "im Verhältnis";
Blockly.Msg.COLOUR_BLEND_TITLE = "mische";
Blockly.Msg.COLOUR_BLEND_TOOLTIP = "Vermische 2 Farben mit konfigurierbaren Farbverhältnis (0.0 - 1.0).";
Blockly.Msg.COLOUR_PICKER_HELPURL = "https://de.wikipedia.org/wiki/Farbe";
Blockly.Msg.COLOUR_PICKER_TOOLTIP = "Wähle eine Farbe aus der Palette.";
Blockly.Msg.COLOUR_RANDOM_HELPURL = "http://randomcolour.com"; // untranslated
Blockly.Msg.COLOUR_RANDOM_TITLE = "zufällige Farbe";
Blockly.Msg.COLOUR_RANDOM_TOOLTIP = "Wähle eine Farbe nach dem Zufallsprinzip.";
Blockly.Msg.COLOUR_RGB_BLUE = "blau";
Blockly.Msg.COLOUR_RGB_GREEN = "grün";
Blockly.Msg.COLOUR_RGB_HELPURL = "https://de.wikipedia.org/wiki/RGB-Farbraum";
Blockly.Msg.COLOUR_RGB_RED = "rot";
Blockly.Msg.COLOUR_RGB_TITLE = "Farbe mit";
Blockly.Msg.COLOUR_RGB_TOOLTIP = "Erstelle eine Farbe mit selbst definierten Rot-, Grün- und Blauwerten. Alle Werte müssen zwischen 0 und 100 liegen.";
Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL = "https://de.wikipedia.org/wiki/Kontrollstruktur";
Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK = "Die Schleife abbrechen";
Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE = "mit der nächsten Iteration der Schleife fortfahren";
Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK = "Die umgebende Schleife beenden.";
Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE = "Diese Anweisung abbrechen und mit dem nächsten Schleifendurchlauf fortfahren.";
Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING = "Warnung: Dieser Block sollte nur in einer Schleife verwendet werden.";
Blockly.Msg.CONTROLS_FOREACH_HELPURL = "https://de.wikipedia.org/wiki/For-Schleife";
Blockly.Msg.CONTROLS_FOREACH_TITLE = "Für Wert %1 aus der Liste %2";
Blockly.Msg.CONTROLS_FOREACH_TOOLTIP = "Führe eine Anweisung für jeden Wert in der Liste aus und setzte dabei die Variable \"%1\" auf den aktuellen Listenwert.";
Blockly.Msg.CONTROLS_FOR_HELPURL = "https://de.wikipedia.org/wiki/For-Schleife";
Blockly.Msg.CONTROLS_FOR_TITLE = "Zähle %1 von %2 bis %3 mit %4";
Blockly.Msg.CONTROLS_FOR_TOOLTIP = "Zähle die Variable \"%1\" von einem Startwert bis zu einem Zielwert und führe für jeden Wert eine Anweisung aus.";
Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = "Eine weitere Bedingung hinzufügen.";
Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = "Eine sonst-Bedingung hinzufügen, führt eine Anweisung aus, falls keine Bedingung zutrifft.";
Blockly.Msg.CONTROLS_IF_HELPURL = "https://github.com/google/blockly/wiki/IfElse"; // untranslated
Blockly.Msg.CONTROLS_IF_IF_TOOLTIP = "Hinzufügen, entfernen oder sortieren von Sektionen";
Blockly.Msg.CONTROLS_IF_MSG_ELSE = "sonst";
Blockly.Msg.CONTROLS_IF_MSG_ELSEIF = "sonst wenn";
Blockly.Msg.CONTROLS_IF_MSG_IF = "wenn";
Blockly.Msg.CONTROLS_IF_TOOLTIP_1 = "Wenn eine Bedingung wahr (true) ist, dann führe eine Anweisung aus.";
Blockly.Msg.CONTROLS_IF_TOOLTIP_2 = "Wenn eine Bedingung wahr (true) ist, dann führe die erste Anweisung aus. Ansonsten führe die zweite Anweisung aus.";
Blockly.Msg.CONTROLS_IF_TOOLTIP_3 = "Wenn die erste Bedingung wahr (true) ist, dann führe die erste Anweisung aus. Oder wenn die zweite Bedingung wahr (true) ist, dann führe die zweite Anweisung aus.";
Blockly.Msg.CONTROLS_IF_TOOLTIP_4 = "Wenn die erste Bedingung wahr (true) ist, dann führe die erste Anweisung aus. Oder wenn die zweite Bedingung wahr (true) ist, dann führe die zweite Anweisung aus. Falls keine der beiden Bedingungen wahr (true) ist, dann führe die dritte Anweisung aus.";
Blockly.Msg.CONTROLS_REPEAT_HELPURL = "https://de.wikipedia.org/wiki/For-Schleife";
Blockly.Msg.CONTROLS_REPEAT_INPUT_DO = "mache";
Blockly.Msg.CONTROLS_REPEAT_TITLE = "Wiederhole %1 mal";
Blockly.Msg.CONTROLS_REPEAT_TOOLTIP = "Eine Anweisung mehrfach ausführen.";
Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL = "https://de.wikipedia.org/wiki/Schleife_%28Programmierung%29";
Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL = "Wiederhole bis";
Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE = "Wiederhole solange";
Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL = "Führe die Anweisung solange aus wie die Bedingung falsch (false) ist.";
Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE = "Führe die Anweisung solange aus wie die Bedingung wahr (true) ist.";
Blockly.Msg.DELETE_ALL_BLOCKS = "Alle %1 Bausteine löschen?";
Blockly.Msg.DELETE_BLOCK = "Block löschen";
Blockly.Msg.DELETE_X_BLOCKS = "Block %1 löschen";
Blockly.Msg.DISABLE_BLOCK = "Block deaktivieren";
Blockly.Msg.DUPLICATE_BLOCK = "Kopieren";
Blockly.Msg.ENABLE_BLOCK = "Block aktivieren";
Blockly.Msg.EXPAND_ALL = "Alle Blöcke entfalten";
Blockly.Msg.EXPAND_BLOCK = "Block entfalten";
Blockly.Msg.EXTERNAL_INPUTS = "externe Eingänge";
Blockly.Msg.HELP = "Hilfe";
Blockly.Msg.INLINE_INPUTS = "interne Eingänge";
Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
Blockly.Msg.LISTS_CREATE_EMPTY_TITLE = "Erzeuge eine leere Liste";
Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP = "Erzeugt eine leere Liste ohne Inhalt.";
Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD = "Liste";
Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP = "Hinzufügen, entfernen und sortieren von Elementen.";
Blockly.Msg.LISTS_CREATE_WITH_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-list-with";
Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH = "Erzeuge Liste mit";
Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP = "Ein Element zur Liste hinzufügen.";
Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP = "Erzeugt eine List mit konfigurierten Elementen.";
Blockly.Msg.LISTS_GET_INDEX_FIRST = "erstes";
Blockly.Msg.LISTS_GET_INDEX_FROM_END = "#tes von hinten";
Blockly.Msg.LISTS_GET_INDEX_FROM_START = "#tes";
Blockly.Msg.LISTS_GET_INDEX_GET = "nimm";
Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE = "nimm und entferne";
Blockly.Msg.LISTS_GET_INDEX_LAST = "letztes";
Blockly.Msg.LISTS_GET_INDEX_RANDOM = "zufälliges";
Blockly.Msg.LISTS_GET_INDEX_REMOVE = "entferne";
Blockly.Msg.LISTS_GET_INDEX_TAIL = "";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST = "Extrahiere das erste Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM_END = "Extrahiere das #1te Element aus Ende der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM_START = "Extrahiere das #1te Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST = "Extrahiere das letzte Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM = "Extrahiere ein zufälliges Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST = "Extrahiere und entfernt das erste Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM_END = "Extrahiere und entfernt das #1te Element aus Ende der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM_START = "Extrahiere und entfernt das #1te Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST = "Extrahiere und entfernt das letzte Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM = "Extrahiere und entfernt ein zufälliges Element aus der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST = "Entfernt das erste Element von der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM_END = "Entfernt das #1te Element von Ende der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM_START = "Entfernt das #1te Element von der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST = "Entfernt das letzte Element von der Liste.";
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM = "Entfernt ein zufälliges Element von der Liste.";
Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END = "bis zu # von hinten";
Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START = "bis zu #";
Blockly.Msg.LISTS_GET_SUBLIST_END_LAST = "bis zum Ende";
Blockly.Msg.LISTS_GET_SUBLIST_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST = "erhalte Unterliste vom Anfang";
Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END = "erhalte Unterliste von # von hinten";
Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START = "erhalte Unterliste von #";
Blockly.Msg.LISTS_GET_SUBLIST_TAIL = "";
Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP = "Erstellt eine Kopie mit dem angegebenen Abschnitt der Liste.";
Blockly.Msg.LISTS_INDEX_OF_FIRST = "suche erstes Auftreten von";
Blockly.Msg.LISTS_INDEX_OF_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.LISTS_INDEX_OF_LAST = "suche letztes Auftreten von";
Blockly.Msg.LISTS_INDEX_OF_TOOLTIP = "Sucht die Position (index) eines Elementes in der Liste. Gibt 0 zurück, falls kein Element gefunden wurde.";
Blockly.Msg.LISTS_INLIST = "von der Liste";
Blockly.Msg.LISTS_ISEMPTY_HELPURL = "https://github.com/google/blockly/wiki/Lists#is-empty"; // untranslated
Blockly.Msg.LISTS_ISEMPTY_TITLE = "%1 ist leer?";
Blockly.Msg.LISTS_ISEMPTY_TOOLTIP = "Ist wahr (true), wenn die Liste leer ist.";
Blockly.Msg.LISTS_LENGTH_HELPURL = "https://github.com/google/blockly/wiki/Lists#length-of"; // untranslated
Blockly.Msg.LISTS_LENGTH_TITLE = "Länge von %1";
Blockly.Msg.LISTS_LENGTH_TOOLTIP = "Die Anzahl von Elementen in der Liste.";
Blockly.Msg.LISTS_REPEAT_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.LISTS_REPEAT_TITLE = "Erzeuge Liste mit Element %1 wiederhole es %2 mal";
Blockly.Msg.LISTS_REPEAT_TOOLTIP = "Erzeugt eine Liste mit einer variablen Anzahl von Elementen";
Blockly.Msg.LISTS_SET_INDEX_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.LISTS_SET_INDEX_INPUT_TO = "ein";
Blockly.Msg.LISTS_SET_INDEX_INSERT = "füge";
Blockly.Msg.LISTS_SET_INDEX_SET = "setze";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST = "Fügt das Element an den Anfang der Liste an.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_END = "Fügt das Element an der angegebenen Position in der Liste ein. #1 ist das letzte Element.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_START = "Fügt das Element an der angegebenen Position in der Liste ein. #1 ist die erste Element.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST = "Fügt das Element ans Ende der Liste an.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM = "Fügt das Element zufällig in die Liste ein.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST = "Setzt das erste Element in der Liste.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM_END = "Setzt das Element an der angegebenen Position in der Liste. #1 ist das letzte Element.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM_START = "Setzte das Element an der angegebenen Position in der Liste. #1 ist das erste Element.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST = "Setzt das letzte Element in der Liste.";
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM = "Setzt ein zufälliges Element in der Liste.";
Blockly.Msg.LISTS_SORT_HELPURL = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
Blockly.Msg.LISTS_SORT_ORDER_ASCENDING = "aufsteigend";
Blockly.Msg.LISTS_SORT_ORDER_DESCENDING = "absteigend";
Blockly.Msg.LISTS_SORT_TITLE = "%1 %2 %3 sortieren";
Blockly.Msg.LISTS_SORT_TOOLTIP = "Eine Kopie einer Liste sortieren.";
Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE = "alphabetisch, Schreibung ignorieren";
Blockly.Msg.LISTS_SORT_TYPE_NUMERIC = "numerisch";
Blockly.Msg.LISTS_SORT_TYPE_TEXT = "alphabetisch";
Blockly.Msg.LISTS_SPLIT_HELPURL = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = "Liste aus Text erstellen";
Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = "Text aus Liste erstellen";
Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN = "Liste mit Texten in einen Text vereinen, getrennt durch ein Trennzeichen.";
Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT = "Text in eine Liste mit Texten aufteilen, unterbrochen bei jedem Trennzeichen.";
Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = "mit Trennzeichen";
Blockly.Msg.LOGIC_BOOLEAN_FALSE = "falsch";
Blockly.Msg.LOGIC_BOOLEAN_HELPURL = "https://github.com/google/blockly/wiki/Logic#values"; // untranslated
Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = "Ist entweder wahr (true) oder falsch (false)";
Blockly.Msg.LOGIC_BOOLEAN_TRUE = "wahr";
Blockly.Msg.LOGIC_COMPARE_HELPURL = "https://de.wikipedia.org/wiki/Vergleich_%28Zahlen%29";
Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ = "Ist wahr (true), wenn beide Werte gleich sind.";
Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT = "Ist wahr (true), wenn der erste Wert größer als der zweite Wert ist.";
Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = "Ist wahr (true), wenn der erste Wert größer als oder gleich groß wie der zweite Wert ist.";
Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT = "Ist wahr (true), wenn der erste Wert kleiner als der zweite Wert ist.";
Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE = "Ist wahr (true), wenn der erste Wert kleiner als oder gleich groß wie der zweite Wert ist.";
Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ = "Ist wahr (true), wenn beide Werte unterschiedlich sind.";
Blockly.Msg.LOGIC_NEGATE_HELPURL = "https://github.com/google/blockly/wiki/Logic#not"; // untranslated
Blockly.Msg.LOGIC_NEGATE_TITLE = "nicht %1";
Blockly.Msg.LOGIC_NEGATE_TOOLTIP = "Ist wahr (true), wenn der Eingabewert falsch (false) ist. Ist falsch (false), wenn der Eingabewert wahr (true) ist.";
Blockly.Msg.LOGIC_NULL = "null";
Blockly.Msg.LOGIC_NULL_HELPURL = "https://de.wikipedia.org/wiki/Nullwert";
Blockly.Msg.LOGIC_NULL_TOOLTIP = "Ist NULL.";
Blockly.Msg.LOGIC_OPERATION_AND = "und";
Blockly.Msg.LOGIC_OPERATION_HELPURL = "https://github.com/google/blockly/wiki/Logic#logical-operations"; // untranslated
Blockly.Msg.LOGIC_OPERATION_OR = "oder";
Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = "Ist wahr (true), wenn beide Werte wahr (true) sind.";
Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = "Ist wahr (true), wenn einer der beiden Werte wahr (true) ist.";
Blockly.Msg.LOGIC_TERNARY_CONDITION = "teste";
Blockly.Msg.LOGIC_TERNARY_HELPURL = "https://de.wikipedia.org/wiki/%3F:#Auswahloperator";
Blockly.Msg.LOGIC_TERNARY_IF_FALSE = "wenn falsch";
Blockly.Msg.LOGIC_TERNARY_IF_TRUE = "wenn wahr";
Blockly.Msg.LOGIC_TERNARY_TOOLTIP = "Überprüft eine Bedingung \"teste\". Wenn die Bedingung wahr ist, wird der \"wenn wahr\" Wert zurückgegeben, andernfalls der \"wenn falsch\" Wert";
Blockly.Msg.MATH_ADDITION_SYMBOL = "+"; // untranslated
Blockly.Msg.MATH_ARITHMETIC_HELPURL = "https://de.wikipedia.org/wiki/Grundrechenart";
Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD = "Ist die Summe zweier Werte.";
Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE = "Ist der Quotient zweier Werte.";
Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS = "Ist die Differenz zweier Werte.";
Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY = "Ist das Produkt zweier Werte.";
Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER = "Ist der erste Wert potenziert mit dem zweiten Wert.";
Blockly.Msg.MATH_CHANGE_HELPURL = "https://de.wikipedia.org/wiki/Inkrement_und_Dekrement";
Blockly.Msg.MATH_CHANGE_TITLE = "erhöhe %1 um %2";
Blockly.Msg.MATH_CHANGE_TOOLTIP = "Addiert einen Wert zur Variable \"%1\" hinzu.";
Blockly.Msg.MATH_CONSTANT_HELPURL = "https://de.wikipedia.org/wiki/Mathematische_Konstante";
Blockly.Msg.MATH_CONSTANT_TOOLTIP = "Mathematische Konstanten wie: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) oder ∞ (unendlich).";
Blockly.Msg.MATH_CONSTRAIN_HELPURL = "https://en.wikipedia.org/wiki/Clamping_%28graphics%29"; // untranslated
Blockly.Msg.MATH_CONSTRAIN_TITLE = "begrenze %1 von %2 bis %3";
Blockly.Msg.MATH_CONSTRAIN_TOOLTIP = "Begrenzt den Wertebereich auf den \"von\"-Wert bis einschließlich zum \"bis\"-Wert. (inklusiv)";
Blockly.Msg.MATH_DIVISION_SYMBOL = "÷"; // untranslated
Blockly.Msg.MATH_IS_DIVISIBLE_BY = "ist teilbar durch";
Blockly.Msg.MATH_IS_EVEN = "ist gerade";
Blockly.Msg.MATH_IS_NEGATIVE = "ist negativ";
Blockly.Msg.MATH_IS_ODD = "ist ungerade";
Blockly.Msg.MATH_IS_POSITIVE = "ist positiv";
Blockly.Msg.MATH_IS_PRIME = "ist eine Primzahl";
Blockly.Msg.MATH_IS_TOOLTIP = "Überprüft ob eine Zahl gerade, ungerade, eine Primzahl, ganzzahlig, positiv, negativ oder durch eine zweite Zahl teilbar ist. Gibt wahr (true) oder falsch (false) zurück.";
Blockly.Msg.MATH_IS_WHOLE = "ist eine ganze Zahl";
Blockly.Msg.MATH_MODULO_HELPURL = "https://de.wikipedia.org/wiki/Modulo";
Blockly.Msg.MATH_MODULO_TITLE = "Rest von %1 ÷ %2";
Blockly.Msg.MATH_MODULO_TOOLTIP = "Der Rest nach einer Division.";
Blockly.Msg.MATH_MULTIPLICATION_SYMBOL = "×";
Blockly.Msg.MATH_NUMBER_HELPURL = "https://de.wikipedia.org/wiki/Zahl";
Blockly.Msg.MATH_NUMBER_TOOLTIP = "Eine Zahl.";
Blockly.Msg.MATH_ONLIST_HELPURL = "http://www.sysplus.ch/einstieg.php?links=menu&seite=4125&grad=Crash&prog=Excel";
Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE = "Mittelwert einer Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_MAX = "Maximalwert einer Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN = "Median einer Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_MIN = "Minimalwert einer Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_MODE = "am häufigsten in Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM = "Zufallswert einer Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV = "Standardabweichung einer Liste";
Blockly.Msg.MATH_ONLIST_OPERATOR_SUM = "Summe einer Liste";
Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE = "Ist der Durchschnittswert aller Werte in einer Liste.";
Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX = "Ist der größte Wert in einer Liste.";
Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN = "Ist der Median aller Werte in einer Liste.";
Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN = "Ist der kleinste Wert in einer Liste.";
Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE = "Findet den am häufigsten vorkommenden Wert in einer Liste. Falls kein Wert öfter vorkommt als alle anderen, wird die originale Liste zurückgeben";
Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM = "Gebe einen zufälligen Wert aus der Liste zurück.";
Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV = "Ist die standardisierte Standardabweichung aller Werte in der Liste";
Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM = "Ist die Summe aller Werte in einer Liste.";
Blockly.Msg.MATH_POWER_SYMBOL = "^";
Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL = "https://de.wikipedia.org/wiki/Zufallszahlen";
Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM = "Zufallszahl (0.0 -1.0)";
Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP = "Erzeuge eine Zufallszahl zwischen 0.0 (inklusiv) und 1.0 (exklusiv).";
Blockly.Msg.MATH_RANDOM_INT_HELPURL = "https://de.wikipedia.org/wiki/Zufallszahlen";
Blockly.Msg.MATH_RANDOM_INT_TITLE = "ganzzahliger Zufallswert zwischen %1 bis %2";
Blockly.Msg.MATH_RANDOM_INT_TOOLTIP = "Erzeuge einen ganzzahligen Zufallswert zwischen zwei Werten (inklusiv).";
Blockly.Msg.MATH_ROUND_HELPURL = "https://de.wikipedia.org/wiki/Runden";
Blockly.Msg.MATH_ROUND_OPERATOR_ROUND = "runden";
Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN = "abrunden";
Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP = "aufrunden";
Blockly.Msg.MATH_ROUND_TOOLTIP = "Eine Zahl auf- oder abrunden.";
Blockly.Msg.MATH_SINGLE_HELPURL = "https://de.wikipedia.org/wiki/Quadratwurzel";
Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE = "Absolutwert";
Blockly.Msg.MATH_SINGLE_OP_ROOT = "Quadratwurzel";
Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS = "Ist der Absolutwert eines Wertes.";
Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP = "Ist Wert der Exponentialfunktion eines Wertes.";
Blockly.Msg.MATH_SINGLE_TOOLTIP_LN = "Ist der natürliche Logarithmus eines Wertes.";
Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10 = "Ist der dekadische Logarithmus eines Wertes.";
Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG = "Negiert einen Wert.";
Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10 = "Rechnet 10 hoch Eingabewert.";
Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT = "Ist die Quadratwurzel eines Wertes.";
Blockly.Msg.MATH_SUBTRACTION_SYMBOL = "-";
Blockly.Msg.MATH_TRIG_ACOS = "acos";
Blockly.Msg.MATH_TRIG_ASIN = "asin";
Blockly.Msg.MATH_TRIG_ATAN = "atan";
Blockly.Msg.MATH_TRIG_COS = "cos";
Blockly.Msg.MATH_TRIG_HELPURL = "https://de.wikipedia.org/wiki/Trigonometrie";
Blockly.Msg.MATH_TRIG_SIN = "sin";
Blockly.Msg.MATH_TRIG_TAN = "tan";
Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS = "Ist der Arkuskosinus des Eingabewertes.";
Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN = "Ist der Arkussinus des Eingabewertes.";
Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN = "Ist der Arkustangens des Eingabewertes.";
Blockly.Msg.MATH_TRIG_TOOLTIP_COS = "Ist der Kosinus des Winkels.";
Blockly.Msg.MATH_TRIG_TOOLTIP_SIN = "Ist der Sinus des Winkels.";
Blockly.Msg.MATH_TRIG_TOOLTIP_TAN = "Ist der Tangens des Winkels.";
Blockly.Msg.ME = "Ich";
Blockly.Msg.NEW_VARIABLE = "Neue Variable...";
Blockly.Msg.NEW_VARIABLE_TITLE = "Name der neuen Variable:";
Blockly.Msg.ORDINAL_NUMBER_SUFFIX = "";
Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = "Aussagen erlauben";
Blockly.Msg.PROCEDURES_BEFORE_PARAMS = "mit:";
Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL = "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP = "Rufe einen Funktionsblock ohne Rückgabewert auf.";
Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL = "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP = "Rufe einen Funktionsblock mit Rückgabewert auf.";
Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = "mit:";
Blockly.Msg.PROCEDURES_CREATE_DO = "Erzeuge \"Aufruf %1\"";
Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = "Beschreibe diese Funktion …";
Blockly.Msg.PROCEDURES_DEFNORETURN_DO = "";
Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = "Funktionsblock";
Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE = "zu";
Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP = "Ein Funktionsblock ohne Rückgabewert.";
Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL = "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
Blockly.Msg.PROCEDURES_DEFRETURN_RETURN = "gebe zurück";
Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP = "Ein Funktionsblock mit Rückgabewert.";
Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING = "Warnung: dieser Funktionsblock hat zwei gleich benannte Parameter.";
Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF = "Markiere Funktionsblock";
Blockly.Msg.PROCEDURES_IFRETURN_HELPURL = "http://c2.com/cgi/wiki?GuardClause";
Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP = "Wenn der erste Wert wahr (true) ist, Gebe den zweiten Wert zurück.";
Blockly.Msg.PROCEDURES_IFRETURN_WARNING = "Warnung: Dieser Block darf nur innerhalb eines Funktionsblock genutzt werden.";
Blockly.Msg.PROCEDURES_MUTATORARG_TITLE = "Variable:";
Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP = "Eine Eingabe zur Funktion hinzufügen.";
Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE = "Parameter";
Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP = "Die Eingaben zu dieser Funktion hinzufügen, entfernen oder neu anordnen.";
Blockly.Msg.REDO = "Wiederholen";
Blockly.Msg.REMOVE_COMMENT = "Kommentar entfernen";
Blockly.Msg.RENAME_VARIABLE = "Variable umbenennen...";
Blockly.Msg.RENAME_VARIABLE_TITLE = "Alle \"%1\" Variablen umbenennen in:";
Blockly.Msg.TEXT_APPEND_APPENDTEXT = "Text anhängen";
Blockly.Msg.TEXT_APPEND_HELPURL = "https://github.com/google/blockly/wiki/Text#text-modification"; // untranslated
Blockly.Msg.TEXT_APPEND_TO = "An";
Blockly.Msg.TEXT_APPEND_TOOLTIP = "Text an die Variable \"%1\" anhängen.";
Blockly.Msg.TEXT_CHANGECASE_HELPURL = "https://github.com/google/blockly/wiki/Text#adjusting-text-case"; // untranslated
Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE = "umwandeln in kleinbuchstaben";
Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE = "umwandeln in Substantive";
Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE = "umwandeln in GROSSBUCHSTABEN";
Blockly.Msg.TEXT_CHANGECASE_TOOLTIP = "Wandelt Schreibweise von Texten um, in Großbuchstaben, Kleinbuchstaben oder den ersten Buchstaben jedes Wortes groß und die anderen klein.";
Blockly.Msg.TEXT_CHARAT_FIRST = "Nehme ersten Buchstaben";
Blockly.Msg.TEXT_CHARAT_FROM_END = "Nehme #ten Buchstaben von hinten";
Blockly.Msg.TEXT_CHARAT_FROM_START = "Nehme #ten Buchstaben";
Blockly.Msg.TEXT_CHARAT_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.TEXT_CHARAT_INPUT_INTEXT = "vom Text";
Blockly.Msg.TEXT_CHARAT_LAST = "Nehme letzten Buchstaben";
Blockly.Msg.TEXT_CHARAT_RANDOM = "Nehme zufälligen Buchstaben";
Blockly.Msg.TEXT_CHARAT_TAIL = "";
Blockly.Msg.TEXT_CHARAT_TOOLTIP = "Extrahiere einen Buchstaben von einer spezifizierten Position.";
Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP = "Ein Element zum Text hinzufügen.";
Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN = "verbinden";
Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP = "Hinzufügen, entfernen und sortieren von Elementen.";
Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END = "bis zum #ten Buchstaben von hinten";
Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START = "bis zum #ten Buchstaben";
Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST = "bis zum letzten Buchstaben";
Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT = "in Text";
Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST = "vom ersten Buchstaben";
Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END = "vom #ten Buchstaben von hinten";
Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START = "vom #ten Buchstaben";
Blockly.Msg.TEXT_GET_SUBSTRING_TAIL = "";
Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP = "Gibt den angegebenen Textabschnitt zurück.";
Blockly.Msg.TEXT_INDEXOF_HELPURL = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
Blockly.Msg.TEXT_INDEXOF_INPUT_INTEXT = "im Text";
Blockly.Msg.TEXT_INDEXOF_OPERATOR_FIRST = "Suche erstes Auftreten des Begriffs";
Blockly.Msg.TEXT_INDEXOF_OPERATOR_LAST = "Suche letztes Auftreten des Begriffs";
Blockly.Msg.TEXT_INDEXOF_TAIL = "";
Blockly.Msg.TEXT_INDEXOF_TOOLTIP = "Findet das erste / letzte Auftreten eines Suchbegriffs in einem Text. Gibt die Position des Begriffs oder 0 zurück.";
Blockly.Msg.TEXT_ISEMPTY_HELPURL = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text"; // untranslated
Blockly.Msg.TEXT_ISEMPTY_TITLE = "%1 ist leer?";
Blockly.Msg.TEXT_ISEMPTY_TOOLTIP = "Ist wahr (true), wenn der Text keine Zeichen enthält ist.";
Blockly.Msg.TEXT_JOIN_HELPURL = "";
Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH = "Erstelle Text aus";
Blockly.Msg.TEXT_JOIN_TOOLTIP = "Erstellt einen Text durch das Verbinden von mehreren Textelementen.";
Blockly.Msg.TEXT_LENGTH_HELPURL = "https://github.com/google/blockly/wiki/Text#text-modification"; // untranslated
Blockly.Msg.TEXT_LENGTH_TITLE = "Länge %1";
Blockly.Msg.TEXT_LENGTH_TOOLTIP = "Die Anzahl von Zeichen in einem Text. (inkl. Leerzeichen)";
Blockly.Msg.TEXT_PRINT_HELPURL = "https://github.com/google/blockly/wiki/Text#printing-text"; // untranslated
Blockly.Msg.TEXT_PRINT_TITLE = "Ausgabe %1";
Blockly.Msg.TEXT_PRINT_TOOLTIP = "Gib den Inhalt einer Variable aus.";
Blockly.Msg.TEXT_PROMPT_HELPURL = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user"; // untranslated
Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER = "Fragt den Benutzer nach einer Zahl.";
Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT = "Fragt den Benutzer nach einem Text.";
Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER = "Fragt nach Zahl mit Hinweis";
Blockly.Msg.TEXT_PROMPT_TYPE_TEXT = "Fragt nach Text mit Hinweis";
Blockly.Msg.TEXT_TEXT_HELPURL = "https://de.wikipedia.org/wiki/Zeichenkette";
Blockly.Msg.TEXT_TEXT_TOOLTIP = "Ein Buchstabe, Text oder Satz.";
Blockly.Msg.TEXT_TRIM_HELPURL = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces"; // untranslated
Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH = "entferne Leerzeichen vom Anfang und vom Ende (links und rechts)";
Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT = "entferne Leerzeichen vom Anfang (links)";
Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT = "entferne Leerzeichen vom Ende (rechts)";
Blockly.Msg.TEXT_TRIM_TOOLTIP = "Entfernt Leerzeichen vom Anfang und / oder Ende eines Textes.";
Blockly.Msg.TODAY = "Heute";
Blockly.Msg.UNDO = "Rückgängig";
Blockly.Msg.VARIABLES_DEFAULT_NAME = "Element";
Blockly.Msg.VARIABLES_GET_CREATE_SET = "Erzeuge \"Schreibe %1\"";
Blockly.Msg.VARIABLES_GET_HELPURL = "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29";
Blockly.Msg.VARIABLES_GET_TOOLTIP = "Gibt den Wert der Variable zurück.";
Blockly.Msg.VARIABLES_SET = "Schreibe %1 %2";
Blockly.Msg.VARIABLES_SET_CREATE_GET = "Erzeuge \"Lese %1\"";
Blockly.Msg.VARIABLES_SET_HELPURL = "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29";
Blockly.Msg.VARIABLES_SET_TOOLTIP = "Setzt den Wert einer Variable.";
Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
// Ardublockly strings
Blockly.Msg.ARD_ANALOGREAD = "lese analogen Pin#";
Blockly.Msg.ARD_ANALOGREAD_TIP = "Gibt einen Wert zwischen 0 und 1024 zurüch";
Blockly.Msg.ARD_ANALOGWRITE = "setzte analogen Pin#";
Blockly.Msg.ARD_ANALOGWRITE_TIP = "Schreibe analogen Wert zwischen 0 und 255 an einen spezifischen PWM Port";
Blockly.Msg.ARD_BUILTIN_LED = "eingebaute LED";
Blockly.Msg.ARD_BUILTIN_LED_TIP = "Schaltet die interne LED An oder Aus";
Blockly.Msg.ARD_COMPONENT_WARN1 = "A %1 configuration block with the same %2 name must be added to use this block!";
Blockly.Msg.ARD_DEFINE = "Definiere";
Blockly.Msg.ARD_DIGITALREAD = "lesen digitalen Pin#";
Blockly.Msg.ARD_DIGITALREAD_TIP = "Lese Wert an digitalen Pin: HIGH(1) oder LOW(0)";
Blockly.Msg.ARD_DIGITALWRITE = "setzte digitalen Pin#";
Blockly.Msg.ARD_DIGITALWRITE_TIP = "Schreibe digitalen Wert HIGH (1) oder LOW(0) an spezifischen Port";
Blockly.Msg.ARD_FUN_RUN_LOOP = "Endlosschleife()";
Blockly.Msg.ARD_FUN_RUN_SETUP = "Setup()";
Blockly.Msg.ARD_FUN_RUN_TIP = "Definiert die setup() und loop() Funktionen";
Blockly.Msg.ARD_HIGH = "HIGH";
Blockly.Msg.ARD_HIGHLOW_TIP = "Setzt einen Status auf HIGH oder LOWSet a pin state logic High or Low.";
Blockly.Msg.ARD_LOW = "LOW";
Blockly.Msg.ARD_MAP = "Verteile Wert";
Blockly.Msg.ARD_MAP_FROMMIN = "von Minimum";
Blockly.Msg.ARD_MAP_FROMMAX = "bis maximum";
Blockly.Msg.ARD_MAP_TOMIN = "auf Minimum";
Blockly.Msg.ARD_MAP_TOMAX = "bis Maximum";
Blockly.Msg.ARD_MAP_TIP = "Verteilt Werte zwischen [0-1024] zu andere.";
Blockly.Msg.ARD_MAP_VAL = "Wert zu [0-";
Blockly.Msg.ARD_NOTONE = "Schalte Ton aus an Pin";
Blockly.Msg.ARD_NOTONE_PIN = "keinen Ton an Pin";
Blockly.Msg.ARD_NOTONE_PIN_TIP = "Stoppe die Tonerzeugung an Pin";
Blockly.Msg.ARD_NOTONE_TIP = "Schaltet den Ton am ausgewählten Pin aus";
Blockly.Msg.ARD_PIN_WARN1 = "Pin %1 wird benötigt für %2 als Pin %3. Bereitsgenutzt als %4.";
Blockly.Msg.ARD_PULSETIMEOUT_TIP = "Misst die Laufzeit eines Impulses am ausgewählten Pin, wenn die Zeit ist in Microsekunden.";
Blockly.Msg.ARD_PULSE_READ = "Misst %1 Impuls an Pin #%2";
Blockly.Msg.ARD_PULSE_READ_TIMEOUT = "Misst %1 Impuls an Pin #%2 (Unterbrechung nach %3 μs)";
Blockly.Msg.ARD_PULSE_TIP = "Misst die Zeit eines Impulses an dem ausgewählten Pin.";
Blockly.Msg.ARD_SERIAL_BPS = "bps";
Blockly.Msg.ARD_SERIAL_PRINT = "schreibe";
Blockly.Msg.ARD_SERIAL_PRINT_NEWLINE = "neue Zeile hinzufügen";
Blockly.Msg.ARD_SERIAL_PRINT_TIP = "Prints data to the console/serial port as human-readable ASCII text."; // untranslated
Blockly.Msg.ARD_SERIAL_PRINT_WARN = "A setup block for %1 must be added to the workspace to use this block!"; // untranslated
Blockly.Msg.ARD_SERIAL_SETUP = "Setup";
Blockly.Msg.ARD_SERIAL_SETUP_TIP = "Selects the speed for a specific Serial peripheral"; // untranslated
Blockly.Msg.ARD_SERIAL_SPEED = ": Übertragungsgeschwindigkeit zu";
Blockly.Msg.ARD_SERVO_READ = "liest SERVO an PIN#";
Blockly.Msg.ARD_SERVO_READ_TIP = "Liest den Winkel des Servomotors aus";
Blockly.Msg.ARD_SERVO_WRITE = "setzt SERVO an Pin";
Blockly.Msg.ARD_SERVO_WRITE_DEG_180 = "Winkel (0~180)";
Blockly.Msg.ARD_SERVO_WRITE_TIP = "Set a Servo to an specified angle"; // untranslated
Blockly.Msg.ARD_SERVO_WRITE_TO = ""; // untranslated
Blockly.Msg.ARD_SETTONE = "Spiele Ton an Pin"; // untranslated
Blockly.Msg.ARD_SPI_SETUP = "Setup";
Blockly.Msg.ARD_SPI_SETUP_CONF = "Konfiguration:";
Blockly.Msg.ARD_SPI_SETUP_DIVIDE = "clock divide"; // untranslated
Blockly.Msg.ARD_SPI_SETUP_LSBFIRST = "LSBFIRST"; // untranslated
Blockly.Msg.ARD_SPI_SETUP_MODE = "SPI mode (idle - edge)"; // untranslated
Blockly.Msg.ARD_SPI_SETUP_MODE0 = "0 (LOW - Fallend)";
Blockly.Msg.ARD_SPI_SETUP_MODE1 = "1 (LOW - Steigend)";
Blockly.Msg.ARD_SPI_SETUP_MODE2 = "2 (HIGH - Fallend)";
Blockly.Msg.ARD_SPI_SETUP_MODE3 = "3 (HIGH - Steigend)";
Blockly.Msg.ARD_SPI_SETUP_MSBFIRST = "MSBFIRST"; // untranslated
Blockly.Msg.ARD_SPI_SETUP_SHIFT = "data shift"; // untranslated
Blockly.Msg.ARD_SPI_SETUP_TIP = "Configures the SPI peripheral."; // untranslated
Blockly.Msg.ARD_SPI_TRANSRETURN_TIP = "Send a SPI message to an specified slave device and get data back."; // untranslated
Blockly.Msg.ARD_SPI_TRANS_NONE = "none"; // untranslated
Blockly.Msg.ARD_SPI_TRANS_SLAVE = "to slave pin"; // untranslated
Blockly.Msg.ARD_SPI_TRANS_TIP = "Send a SPI message to an specified slave device."; // untranslated
Blockly.Msg.ARD_SPI_TRANS_VAL = "transfer"; // untranslated
Blockly.Msg.ARD_SPI_TRANS_WARN1 = "A setup block for %1 must be added to the workspace to use this block!"; // untranslated
Blockly.Msg.ARD_SPI_TRANS_WARN2 = "Old pin value %1 is no longer available."; // untranslated
Blockly.Msg.ARD_STEPPER_COMPONENT = "stepper"; // untranslated
Blockly.Msg.ARD_STEPPER_DEFAULT_NAME = "MyStepper"; // untranslated
Blockly.Msg.ARD_STEPPER_FOUR_PINS = "4"; // untranslated
Blockly.Msg.ARD_STEPPER_MOTOR = "stepper motor:"; // untranslated
Blockly.Msg.ARD_STEPPER_NUMBER_OF_PINS = "Number of pins"; // untranslated
Blockly.Msg.ARD_STEPPER_PIN1 = "pin1#"; // untranslated
Blockly.Msg.ARD_STEPPER_PIN2 = "pin2#"; // untranslated
Blockly.Msg.ARD_STEPPER_PIN3 = "pin3#"; // untranslated
Blockly.Msg.ARD_STEPPER_PIN4 = "pin4#"; // untranslated
Blockly.Msg.ARD_STEPPER_REVOLVS = "how many steps per revolution"; // untranslated
Blockly.Msg.ARD_STEPPER_SETUP = "Setup stepper motor"; // untranslated
Blockly.Msg.ARD_STEPPER_SETUP_TIP = "Configures a stepper motor pinout and other settings."; // untranslated
Blockly.Msg.ARD_STEPPER_SPEED = "set speed (rpm) to"; // untranslated
Blockly.Msg.ARD_STEPPER_STEP = "move stepper"; // untranslated
Blockly.Msg.ARD_STEPPER_STEPS = "steps"; // untranslated
Blockly.Msg.ARD_STEPPER_STEP_TIP = "Turns the stepper motor a specific number of steps."; // untranslated
Blockly.Msg.ARD_STEPPER_TWO_PINS = "2"; // untranslated
Blockly.Msg.ARD_TIME_DELAY = "Warte";
Blockly.Msg.ARD_TIME_DELAY_MICROS = "Mikrosekunden";
Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP = "Warte eine spezifischen Zeit in Microsekunden";
Blockly.Msg.ARD_TIME_DELAY_TIP = "Warte spezifische Zeit in Millisekunden";
Blockly.Msg.ARD_TIME_INF = "Warte für immer (Beende Programm)";
Blockly.Msg.ARD_TIME_INF_TIP = "Stoppt das Programm.";
Blockly.Msg.ARD_TIME_MICROS = "Bereits vergangen Zeit (Mikrosekunden)";
Blockly.Msg.ARD_TIME_MICROS_TIP = "Gibt eine Zahl in Microsekunden zurück, die der Zeitdauer des Aktuellen Programms entspricht. Muss als positiven Integer gespeichert werden"; // untranslated
Blockly.Msg.ARD_TIME_MILLIS = "Bereits vergangen Zeit (Millisekunden)";
Blockly.Msg.ARD_TIME_MILLIS_TIP = "Gibt eine Zahl in Millisekunden zurück, die der Zeitdauer des Aktuellen Programms entspricht. Muss als positiven Integer gespeichert werden"; // untranslated
Blockly.Msg.ARD_TIME_MS = "Millisekunden";
Blockly.Msg.ARD_TONEFREQ = "mit Frequenz";
Blockly.Msg.ARD_TONE_FREQ = "Frequenz";
Blockly.Msg.ARD_TONE_PIN = "Ton PIN#";
Blockly.Msg.ARD_TONE_PIN_TIP = "Erzeugt einen Ton an Pin";
Blockly.Msg.ARD_TONE_TIP = "Erzeugt einen Ton an Pin mit einer spezifischen Frequenz zwischen 31 - 65535";
Blockly.Msg.ARD_TONE_WARNING = "Frequenz muss zwischen 31 - 65535 liegen";
Blockly.Msg.ARD_TYPE_ARRAY = "Array";
Blockly.Msg.ARD_TYPE_BOOL = "Boolean";
Blockly.Msg.ARD_TYPE_CHAR = "Zeichen";
Blockly.Msg.ARD_TYPE_CHILDBLOCKMISSING = "ChildBlockMissing"; // untranslated
Blockly.Msg.ARD_TYPE_DECIMAL = "Dezimalzahl";
Blockly.Msg.ARD_TYPE_LONG = "große Zahl";
Blockly.Msg.ARD_TYPE_NULL = "Null";
Blockly.Msg.ARD_TYPE_NUMBER = "Zahl";
Blockly.Msg.ARD_TYPE_SHORT = "kurze Zahl";
Blockly.Msg.ARD_TYPE_TEXT = "Text";
Blockly.Msg.ARD_TYPE_UNDEF = "Undefiniert";
Blockly.Msg.ARD_VAR_AS = "als";
Blockly.Msg.ARD_VAR_AS_TIP = "Wert einem spezififischen Datentyp zuordnen";
Blockly.Msg.ARD_WRITE_TO = "zu";
Blockly.Msg.NEW_INSTANCE = "Neue Instanz...";
Blockly.Msg.NEW_INSTANCE_TITLE = "Neue Instanz mit Name:";
Blockly.Msg.RENAME_INSTANCE = "Instanz umbenennen...";
Blockly.Msg.RENAME_INSTANCE_TITLE = "Benenne alle '%1' Instanzen zu:";
/*senseBox Blockly Translations*/
Blockly.Msg.senseBox_basic_blue = "Blau";
Blockly.Msg.senseBox_basic_green = "Grün";
Blockly.Msg.senseBox_basic_red = "Rot";
Blockly.Msg.senseBox_basic_state = "Status";
Blockly.Msg.senseBox_off = "Aus";
Blockly.Msg.senseBox_on = "Ein";
Blockly.Msg.senseBox_sensor = "Sensoren"
Blockly.Msg.senseBox_output_filename = "Daten";
Blockly.Msg.senseBox_output_format = "Format:";
Blockly.Msg.senseBox_sd_create_file = "Erstelle Datei auf SD-Karte";
Blockly.Msg.senseBox_sd_write_file = " Schreibe Daten auf SD-Karte";
Blockly.Msg.senseBox_sd_open_file = "Öffne eine Datei auf der SD-Karte";
Blockly.Msg.sensebox_sd_filename = "Daten";
Blockly.Msg.senseBox_SD_COMPONENT = "SD-Block";
Blockly.Msg.senseBox_sd_decimals = "Dezimalen";
Blockly.Msg.senseBox_output_linebreak = "Zeilenumbruch";
Blockly.Msg.senseBox_output_networkid = "NetzwerkID";
Blockly.Msg.senseBox_output_password = "Passwort";
Blockly.Msg.senseBox_output_safetosd = "Auf SD Karte speichern";
Blockly.Msg.senseBox_output_safetosd_tip = "Speichert Messwerte auf SD Karte"
Blockly.Msg.senseBox_output_serialprint = "Auf Kommandozeile ausgeben";
Blockly.Msg.senseBox_serial_tip = "Gibt Messwerte oder Daten auf dem Seriellen Monitor der Arduino IDE aus. Praktisch um ohne Display zu arbeiten";
Blockly.Msg.senseBox_output_timestamp = "Zeitstempel";
Blockly.Msg.senseBox_button = "Button";
Blockly.Msg.senseBox_button_tip = "Liest den Zustand des Buttons";
Blockly.Msg.senseBox_led = "LED an digitalen";
Blockly.Msg.senseBox_led_tip = "Einfache LED. Beim Anschluss sollte immer ein Vorwiderstand verwendet werden";
Blockly.Msg.senseBox_piezo = "Piezo an digital";
Blockly.Msg.senseBox_piezo_tip = "Piezo an digital PIN. Beim Anschluss sollte immer ein Vorwiderstand verwendet werden";
Blockly.Msg.senseBox_foto = "Fotowiderstand";
Blockly.Msg.senseBox_foto_tip = "Fotowiderstand";
Blockly.Msg.senseBox_hum = "Luftfeuchtigkeit in %";
Blockly.Msg.senseBox_hum_tip = "Luftfeuchtigkeit";
Blockly.Msg.senseBox_ir = "Infrarot Abstandssensor";
Blockly.Msg.senseBox_ir_tip = "Infrarot Abstandssensor";
Blockly.Msg.senseBox_lux = "Helligkeitssensor";
Blockly.Msg.senseBox_lux_tip = "Helligkeitssensor";
Blockly.Msg.senseBox_poti = "Potenziometer";
Blockly.Msg.senseBox_poti_tip = "Potenziometer";
Blockly.Msg.senseBox_pressure_sensor = "Luftdruck-/Temperatursensor (BMP280)";
Blockly.Msg.senseBox_pressure = "Luftdruck in Pa";
Blockly.Msg.senseBox_pressure_dimension = "Luftdruck in Pa";
Blockly.Msg.senseBox_pressure_tip = "Luftdrucksensor";
Blockly.Msg.senseBox_pressure_referencePressure = "Luftdruck auf NN";
Blockly.Msg.senseBox_pressure_referencePressure_dim = "hPa";
Blockly.Msg.senseBox_sound = "Mikrofon";
Blockly.Msg.senseBox_sound_tip = "Gibt den Messwert des Mikrofons in Volt zurück";
Blockly.Msg.senseBox_rgb_led = "RGB-LED"
Blockly.Msg.senseBox_rgb_led_tip = "RGB-LED benötigt einen digitalen Pin und eine Stromkreis ";
Blockly.Msg.senseBox_temp = "Temperatur in °C";
Blockly.Msg.senseBox_temp_hum = "Temperatur-/Luftfeuchtigkeitssensor (HDC1080)";
Blockly.Msg.senseBox_temp_hum_tip = "Sensor misst Temperatur und Luftfeuchtigkeit";
Blockly.Msg.senseBox_ultrasonic = "Ultraschall-Abstandssensor an Port";
Blockly.Msg.senseBox_ultrasonic_port_A = "A";
Blockly.Msg.senseBox_ultrasonic_port_B = "B";
Blockly.Msg.senseBox_ultrasonic_port_C = "C";
Blockly.Msg.senseBox_ultrasonic_tip = "Misst die Distanz mithilfe von Ultraschall in cm";
Blockly.Msg.senseBox_value = "Messwert:";
Blockly.Msg.senseBox_uv_light = "Helligkeit-/UV-Sensor";
Blockly.Msg.senseBox_uv_light_tip = "Sensor misst UV-Licht oder die Helligkeit";
Blockly.Msg.senseBox_uv = "UV-Intensität in µW/cm²";
Blockly.Msg.senseBox_light = "Beleuchtungsstärke in Lux";
Blockly.Msg.senseBox_bmx055_compass = "Lage Sensor";
Blockly.Msg.senseBox_bmx055_accelerometer = "Beschleunigungssensor";
Blockly.Msg.senseBox_bmx055_accelerometer_range = "Messbereich";
Blockly.Msg.senseBox_bmx055_accelerometer_range_2g = "2g";
Blockly.Msg.senseBox_bmx055_accelerometer_range_4g = "4g";
Blockly.Msg.senseBox_bmx055_accelerometer_range_8g = "8g";
Blockly.Msg.senseBox_bmx055_accelerometer_range_16g = "16g";
Blockly.Msg.senseBox_bmx055_accelerometer_direction = "Richtung";
Blockly.Msg.senseBox_bmx055_accelerometer_direction_x = "X-Achse";
Blockly.Msg.senseBox_bmx055_accelerometer_direction_y = "Y-Achse";
Blockly.Msg.senseBox_bmx055_accelerometer_direction_z = "Z-Achse";
Blockly.Msg.senseBox_bmx055_accelerometer_direction_total = "Gesamt";
Blockly.Msg.senseBox_bmx055_gyroscope = "Lage Sensor";
Blockly.Msg.senseBox_bmx055_accelerometer_tip = "Lage Sensor";
Blockly.Msg.senseBox_bmx055_compass_tip = "Lage Sensor";
Blockly.Msg.senseBox_bmx055_gyroscope_tip = "Lage Sensor";
Blockly.Msg.senseBox_bmx055_x = "X-Richtung";
Blockly.Msg.senseBox_bmx055_y = "Y-Richtung";
Blockly.Msg.senseBox_wifi_connect = "Verbinde mit WLAN";
Blockly.Msg.senseBox_wifi_ssid = "Netzwerkname";
Blockly.Msg.senseBox_wifi_tip = "stellt eine WLAN verbindung her";
Blockly.Msg.senseBox_wifi_startap = "Initialisiere WLAN Access Point";
Blockly.Msg.senseBox_osem_connection_tip = "stellt eine WLAN verbindung her";
Blockly.Msg.senseBox_send_to_osem_tip = "sende Messwert an";
Blockly.Msg.senseBox_send_to_osem = "Sende Messwert an die openSenseMap";
Blockly.Msg.senseBox_osem_connection = "Verbinde mit openSenseMap:";
Blockly.Msg.senseBox_osem_host = "opensensemap.org";
Blockly.Msg.senseBox_osem_host_workshop = "workshop.opensensemap.org";
Blockly.Msg.senseBox_osem_connection = "Verbinde mit openSenseMap";
Blockly.Msg.senseBox_osem_exposure = "Typ";
Blockly.Msg.senseBox_osem_stationary = "Stationär";
Blockly.Msg.senseBox_osem_mobile = "Mobil";
Blockly.Msg.senseBox_sds011 = "Feinstaubsensor";
Blockly.Msg.senseBox_sds011_dimension = "in µg/m³ an";
Blockly.Msg.senseBox_sds011_pm25 = "PM2.5";
Blockly.Msg.senseBox_sds011_pm10 = "PM10";
Blockly.Msg.senseBox_sds011_tip = "Misst die Feinstaubbelastung";
Blockly.Msg.senseBox_sds011_serial1 = "Serial1";
Blockly.Msg.senseBox_sds011_serial2 = "Serial2";
/*Display*/
Blockly.Msg.senseBox_display_beginDisplay = "Display initialisieren";
Blockly.Msg.senseBox_display_clearDisplay_tip = "Starten die Ausgabe auf dem Display";
Blockly.Msg.senseBox_display_clearDisplay = "Display löschen";
Blockly.Msg.senseBox_display_clearDisplay_tip = "Löscht den Inhalt des Displays";
Blockly.Msg.senseBox_display_printDisplay = "Schreibe Text/Zahl";
Blockly.Msg.senseBox_display_printDisplay_tip = "zeigt Wert auf dem Display an.";
Blockly.Msg.senseBox_display_printDisplay_x = "x-Koordinate";
Blockly.Msg.senseBox_display_printDisplay_y = "y-Koordinate";
Blockly.Msg.senseBox_display_printDisplay_value = "Wert";
Blockly.Msg.senseBox_display_setSize = "Schriftgröße";
Blockly.Msg.senseBox_display_setSize_tip = "Ändere die Schriftgröße auf einen Wert zwischen 1 und 10.";
Blockly.Msg.senseBox_display_color = "Schriftfarbe";
Blockly.Msg.senseBox_display_white = "Weiß";
Blockly.Msg.senseBox_display_black = "Schwarz";
Blockly.Msg.sensebox_display_show = "Zeige auf dem Display";
Blockly.Msg.sensebox_display_show_tip = "Zeigt den Nachfolgenden Inhalt auf dem Bildschirm";
Blockly.Msg.senseBox_dipslay_plotTitle = "Titel";
Blockly.Msg.senseBox_display_plotDisplay = "Zeichne Diagramm";
Blockly.Msg.senseBox_display_plotXLabel = "X-Achsen Beschriftung";
Blockly.Msg.senseBox_display_plotYLabel = "Y-Achsen Beschriftung";
Blockly.Msg.senseBox_display_plotXRange1 = "X-Wertebereich Anfang";
Blockly.Msg.senseBox_display_plotXRange2 = "X-Wertebereich Ende";
Blockly.Msg.senseBox_display_plotYRange1 = "Y-Wertebereich Anfang";
Blockly.Msg.senseBox_display_plotYRange2 = "Y-Wertebereich Ende";
Blockly.Msg.senseBox_display_plotXTick = "X-Linienabstand";
Blockly.Msg.senseBox_display_plotYTick = "Y-Linienabstand";
Blockly.Msg.senseBox_display_plotTimeFrame = "Zeitabschnitt";
Blockly.Msg.sensebox_display_fillCircle = "Zeichne Punkt";
Blockly.Msg.sensebox_display_fillCircle_radius = "Radius";
Blockly.Msg.sensebox_display_drawRectangle = "Zeichne Rechteck";
Blockly.Msg.sensebox_display_drawRectangle_width = "Breite";
Blockly.Msg.sensebox_display_drawRectangle_height = "Höhe";
Blockly.Msg.senseBox_display_filled = "Ausgefüllt"
// GPS
Blockly.Msg.senseBox_gps_getValues = "GPS Modul";
Blockly.Msg.senseBox_gps_getValues_tip = "ruft das GPS Signal ab";
Blockly.Msg.senseBox_gps_lat = "Breitengrad";
Blockly.Msg.senseBox_gps_lng = "Längengrad";
Blockly.Msg.senseBox_gps_alt = "Höhe über NN in m";
Blockly.Msg.senseBox_gps_speed = "Geschwindigkeit in km/h";
Blockly.Msg.senseBox_gps_date = "Datum";
Blockly.Msg.senseBox_gps_time = "Uhrzeit";
Blockly.Msg.senseBox_gps_timeStamp = "Zeitstempel (RFC 3339)";
// openSenseMap
Blockly.Msg.senseBox_send_mobile_to_osem = "Sende Messwert und Standort an die openSenseMap";
Blockly.Msg.senseBox_send_mobile_to_osem_tip = "Sende Messwert und Standort an die openSenseMap";
Blockly.Msg.senseBox_interval_timer = "Messintervall";
Blockly.Msg.senseBox_interval = "ms"
Blockly.Msg.senseBox_interval_timer_tip = "Intervall";
Blockly.Msg.senseBox_soil = "Bodenfeuchte";
Blockly.Msg.senseBox_watertemperature = "Wassertemperatur"
// Cases
Blockly.Msg.cases_do = "Führe aus";
Blockly.Msg.cases_condition = "Fall (Variable) = ";
Blockly.Msg.cases_switch = "Variable";
Blockly.Msg.cases_add = "Fall";
//Button
Blockly.Msg.senseBox_button_isPressed = "ist gedrückt";
Blockly.Msg.senseBox_button_switch = "als Schalter";
Blockly.Msg.senseBox_button_wasPressed = "wurde gedrückt";
//Webserver
Blockly.Msg.senseBox_ip_address = "IP-Adresse";
Blockly.Msg.senseBox_ip_address_tip = "Gibt die IP-Adresse als Zeichenkette zurück.";
Blockly.Msg.senseBox_init_http_server_tip = "Initialisiert einen http-Server auf dem angegebenen Port";
Blockly.Msg.senseBox_init_http_server = "HTTP-Server initialisieren";
Blockly.Msg.senseBox_http_on_client_connect = "Wenn Client verbunden ist:";
Blockly.Msg.senseBox_http_on_client_connect_tip = "Überprüft, ob ein Client verbunden ist und führt in diesem Fall die angegebene Anweisung aus";
Blockly.Msg.senseBox_http_method = "Methode";
Blockly.Msg.senseBox_http_method_tip = "Methode des aktuellen HTTP-Requests";
Blockly.Msg.senseBox_http_uri = "URI";
Blockly.Msg.senseBox_http_uri_tip = "URI der angeforderten Ressource der aktuellen HTTP-Anfrage";
Blockly.Msg.senseBox_http_user_agent = "User-Agent";
Blockly.Msg.senseBox_http_user_agent_tip = "Der Benutzer-Agent sendet zusammen mit der aktuellen HTTP-Anfrage";
Blockly.Msg.senseBox_http_protocol_version = "HTTP Version";
Blockly.Msg.senseBox_http_protocol_version_tip = "The HTTP Version of the current HTTP request";
Blockly.Msg.senseBox_http_success_tip = "Senden einer erfolgreichen HTTP-Antwort mit Inhalt";
Blockly.Msg.senseBox_http_not_found_tip = "Senden einer vordefinierten 404 HTTP-Antwort.";
Blockly.Msg.senseBox_http_success = "Erfolgreiche";
Blockly.Msg.senseBox_http_success_l2 = "HTTP-Antwort";
Blockly.Msg.senseBox_http_success_buildhtml = "HTML:"
Blockly.Msg.senseBox_http_not_found = "404 Fehler";
Blockly.Msg.senseBox_html_document = "HTML";
Blockly.Msg.senseBox_html_header = "<head>";
Blockly.Msg.senseBox_html_header_end = "</head>";
Blockly.Msg.senseBox_html_body = "<body>";
Blockly.Msg.senseBox_html_body_end = "</body>";
Blockly.Msg.senseBox_html_general_tag_tip = "Ein allgemeiner HTML-Tag-Baustein.";
Blockly.Msg.senseBox_html_document_tip = "Ein Block zum Erzeugen eines HTML-Dokuments...";
Blockly.Msg.senseBox_tag_first_mutator_tip = "Mögliche Erweiterungen zu diesem Block...";
Blockly.Msg.senseBox_tag_optional_mutator_tip = "Mehr Tags zum Block hinzufügen";
Blockly.Msg.senseBox_sd_web_readHTML = "Lese HTML von SD Karte";
Blockly.Msg.sensebox_web_readHTML_filename = "Datei:";
Blockly.Msg.senseBox_bme680 = "Umweltsensor (BME680)";
Blockly.Msg.senseBox_bme680_tip = "Gibt Messwerte des BME680 zurück";
Blockly.Msg.senseBox_bme680_warning = "Achtung. Gas (VOC) kann nicht gleichzeitig mit anderen Parametern gemessen werden"
Blockly.Msg.senseBox_gas = "Gas (VOC)";
Blockly.Msg.sensebox_soil_smt50 = "Bodenfeuchte/-temperatur (SMT50)";
// LoRa
Blockly.Msg.senseBox_LoRa_connect = "Zu TTN senden";
Blockly.Msg.senseBox_LoRa_device_id = "Device EUI (lsb)";
Blockly.Msg.senseBox_LoRa_app_id = "Application EUI (lsb)";
Blockly.Msg.senseBox_LoRa_app_key = "App Key (msb)";
Blockly.Msg.senseBox_LoRa_nwskey_id = "Network Session Key (msb)";
Blockly.Msg.senseBox_LoRa_appskey_id = "App Session Key (msb)";
Blockly.Msg.senseBox_LoRa_devaddr_id = "Device Adress";
Blockly.Msg.senseBox_LoRa_interval = "Intervall in Minuten"
Blockly.Msg.senseBox_measurement = "Messung";
Blockly.Msg.senseBox_measurements = "Messungen";
Blockly.Msg.senseBox_LoRa_send_message = "Sende als Lora Nachricht";
Blockly.Msg.senseBox_LoRa_send_cayenne = "Sende als Cayenne Nachricht";
Blockly.Msg.senseBox_LoRa_cayenne_temperature = "Temperatur";
Blockly.Msg.senseBox_LoRa_cayenne_channel = "Kanal";
Blockly.Msg.senseBox_LoRa_cayenne_humidity = "Luftfeuchtigkeit"
Blockly.Msg.senseBox_LoRa_cayenne_pressure = "Luftdruck";
Blockly.Msg.senseBox_LoRa_cayenne_luminosity = "Helligkeit";
Blockly.Msg.senseBox_LoRa_cayenne_analog = "Analoger Wert";
Blockly.Msg.senseBox_LoRa_cayenne_x = "X Wert";
Blockly.Msg.senseBox_LoRa_cayenne_y = "Y Wert";
Blockly.Msg.senseBox_LoRa_cayenne_z = "Z Wert";
Blockly.Msg.senseBox_LoRa_cayenne_lat = "Breitengrad";
Blockly.Msg.senseBox_LoRa_cayenne_lng = "Längengrad";
Blockly.Msg.senseBox_LoRa_cayenne_alt = "Höhe";
Blockly.Msg.senseBox_LoRa_cayenne_tip = "Sende Daten als Cayenne Payload Format"
Blockly.Msg.senseBox_LoRa_cayenne_gps_tip = "Sende GPS";
Blockly.Msg.senseBox_LoRa_cayenne_temperature_tip = "Sendet Temperaturwert mit einer Nachkommastelle";
Blockly.Msg.senseBox_LoRa_cayenne_pressure_tip = "Sendet Luftdruck mit einer Nachkommastelle";
Blockly.Msg.senseBox_LoRa_cayenne_luminosity_tip = "Sendet Helligkeitswert";
Blockly.Msg.senseBox_LoRa_cayenne_analog_tip = "Sendet einen Dezimalwert mit einer Nachkommastelle";
Blockly.Msg.senseBox_LoRa_message_tip = "Sende eine Nachricht über LoRa";
Blockly.Msg.senseBox_LoRa_sensor_tip = "Sende eine Sensorwert mit einer bestimmten Anzahl an Bytes";
Blockly.Msg.senseBox_LoRa_init_abp_tip = "Initialisiere die LoRa übertragung. Kopiere die ID's im lsb Format";
Blockly.Msg.senseBox_LoRa_init_otaa_tip = "Initialisiere die LoRa übertragung. Kopiere die ID's im lsb Format";
//BME680
Blockly.Msg.senseBox_bme680 = "Umweltsensor (BME680)";
Blockly.Msg.senseBox_bme_iaq = "Innenraumluftqualität (IAQ)";
Blockly.Msg.senseBox_bme_iaq_accuracy = "Kalibrierungswert";
Blockly.Msg.senseBox_bme_co2 = "CO2 Äquivalent";
Blockly.Msg.senseBox_bme_breatheVocEquivalent = "Atemluft VOC Äquivalent";
Blockly.Msg.senseBox_bme_tip = "Gibt Messwerte des BME680 zurück";
Blockly.Msg.senseBox_gas = "Gas (VOC)";
Blockly.Msg.sensebox_soil_stm50 = "Bodenfeuchte/-temperatur (SMT50)";
//Telegram
Blockly.Msg.senseBox_telegram_init = "Telegram Bot initialisieren"
Blockly.Msg.senseBox_telegram_token = "Token"
Blockly.Msg.senseBox_telegram_do = "Telegram mache"
Blockly.Msg.senseBox_telegram_do_on_message = "bei Nachricht"
Blockly.Msg.senseBox_telegram_message = "Nachricht"
Blockly.Msg.senseBox_telegram_send = "Sende Nachricht"
Blockly.Msg.senseBox_scd30 = "CO2 Sensor (Sensirion SCD30)";
export const De = Blockly.Msg;
export const De = {
...AUDIO,
...FAQ,
...IO,
...LOGIC,
...LOOPS,
...MATH,
...MQTT,
...DISPLAY,
...LED,
...LORA,
...OSEM,
...SD,
...SENSORS,
...TELEGRAM,
...WEB,
...TEXT,
...TIME,
...TOURS,
...TRANSLATIONS,
...UI,
...VARIABLES,
...WEBSERVER
}
+10
View File
@@ -0,0 +1,10 @@
export const AUDIO = {
ARD_TONEFREQ: "mit Frequenz",
ARD_TONE_FREQ: "Frequenz",
ARD_TONE_PIN: "Ton PIN#",
ARD_TONE_PIN_TIP: "Erzeugt einen Ton an Pin",
ARD_TONE_TIP: "Erzeugt einen Ton an Pin mit einer spezifischen Frequenz zwischen 31 - 65535 Hz",
ARD_TONE_WARNING: "Frequenz muss zwischen 31 - 65535 liegen",
}
+27
View File
@@ -0,0 +1,27 @@
export const FAQ = {
/**
* FAQ
*/
faq_q1_question: `Wie kann ich mein Programm auf die senseBox kopieren?`,
faq_q1_answer: `Um Programme auf die senseBox zu kopieren wird diese mit dem Micro USB Kabel an den Computer angeschlossen. Mache anschließend auf der senseBox MCU einen Doppelklick auf den roten Reset Button. Die senseBox wird nun als Wechseldatenträger an deinem Computer erkannt und die zuvor erstellen Programm können per Drag & Drop kopiert werden. Nach jeder Änderung des Programmcodes muss das Programm neu kompiliert und übertragen werden
#### Lernmodus der MCU aktivieren
<iframe width="560" height="315" src="https://www.youtube.com/embed/jzlOJ7Zuqqw" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
#### Kopieren von Programmen unter MacOS
Das Kopieren der Programme unter MacOS funktioniert nicht über den Finder, es gibt es aber dennoch zwei verschiedene Möglichkeiten die Programme zu kopieren:
- [senseBox Kopiertool](https://sensebox.de/docs/senseBox_Sketch_Uploader_DE.zip)
- [muCommander](https://www.mucommander.com/)
`,
faq_q2_question: `Mit welcher senseBox ist die Programmierumgebung kompatibel?`,
faq_q2_answer: `
Grundsätzlich kann die Programmierumgebung mit jeder senseBox mit senseBox MCU verwendet werden.
`,
faq_q3_question: `Ich habe einen Fehler gefunden oder etwas funktioniert nicht. Wo kann ich diesen melden?`,
faq_q3_answer: `
Am besten legst du dazu ein Issue auf [Github](https://github.com/sensebox/React-Ardublockly/issues) an. Alternativ kannst du uns auch eine Email an info(at)sensebox.de senden
`,
}
+108
View File
@@ -0,0 +1,108 @@
export const IO = {
ARD_ANALOGREAD: "lese analogen Pin#",
ARD_ANALOGREAD_TIP: "Gibt einen Wert zwischen 0 und 1024 zurüch",
ARD_ANALOGWRITE: "setzte analogen Pin#",
ARD_ANALOGWRITE_TIP: "Schreibe analogen Wert zwischen 0 und 255 an einen spezifischen PWM Port",
ARD_BUILTIN_LED: "eingebaute LED",
ARD_BUILTIN_LED_TIP: "Schaltet die interne LED An oder Aus",
ARD_COMPONENT_WARN1: "A %1 configuration block with the same %2 name must be added to use this block!",
ARD_DEFINE: "Definiere",
ARD_DIGITALREAD: "lesen digitalen Pin#",
ARD_DIGITALREAD_TIP: "Lese Wert an digitalen Pin: HIGH(1) oder LOW(0)",
ARD_DIGITALWRITE: "setzte digitalen Pin#",
ARD_DIGITALWRITE_TIP: "Schreibe digitalen Wert HIGH (1) oder LOW(0) an spezifischen Port",
ARD_FUN_RUN_LOOP: "Endlosschleife()",
ARD_FUN_RUN_SETUP: "Setup()",
ARD_FUN_RUN_TIP: "Definiert die setup() und loop() Funktionen. Die setup()-Funktion wird beim starten **einmal** ausgeführt. Anschließend wir die loop()-Funktion in einer **Endlosschleife** ausgeführt. Füge in die Setup()-Funktion Blöcke ein, um z.B. das Display zu initalisieren, eine Verbindung zum WiFi-Netzwerk herzustellen oder um die LoRa Verbindung zu initialsieren.",
ARD_HIGH: "HIGH",
ARD_HIGHLOW_TIP: "Setzt einen Status auf HIGH oder LOWSet a pin state logic High or Low.",
ARD_LOW: "LOW",
ARD_MAP: "Verteile Wert",
ARD_MAP_FROMMIN: "von Minimum",
ARD_MAP_FROMMAX: "bis maximum",
ARD_MAP_TOMIN: "auf Minimum",
ARD_MAP_TOMAX: "bis Maximum",
ARD_MAP_TIP: "Verteilt Werte zwischen [0-1024] zu andere.",
ARD_MAP_VAL: "Wert zu [0-",
ARD_NOTONE: "Schalte Ton aus an Pin",
ARD_NOTONE_PIN: "keinen Ton an Pin",
ARD_NOTONE_PIN_TIP: "Stoppe die Tonerzeugung an Pin",
ARD_NOTONE_TIP: "Schaltet den Ton am ausgewählten Pin aus",
ARD_PIN_WARN1: "Pin %1 wird benötigt für %2 als Pin %3. Bereitsgenutzt als %4.",
ARD_PULSETIMEOUT_TIP: "Misst die Laufzeit eines Impulses am ausgewählten Pin, wenn die Zeit ist in Microsekunden.",
ARD_PULSE_READ: "Misst %1 Impuls an Pin #%2",
ARD_PULSE_READ_TIMEOUT: "Misst %1 Impuls an Pin #%2 (Unterbrechung nach %3 μs)",
ARD_PULSE_TIP: "Misst die Zeit eines Impulses an dem ausgewählten Pin.",
ARD_SERIAL_BPS: "bps",
ARD_SERIAL_PRINT: "schreibe",
ARD_SERIAL_PRINT_NEWLINE: "neue Zeile hinzufügen",
ARD_SERIAL_PRINT_TIP: "Prints data to the console/serial port as human-readable ASCII text.", // untranslated
ARD_SERIAL_PRINT_WARN: "A setup block for %1 must be added to the workspace to use this block!", // untranslated
ARD_SERIAL_SETUP: "Setup",
ARD_SERIAL_SETUP_TIP: "Selects the speed for a specific Serial peripheral", // untranslated
ARD_SERIAL_SPEED: ": Übertragungsgeschwindigkeit zu",
ARD_SERVO_READ: "liest SERVO an PIN#",
ARD_SERVO_READ_TIP: "Liest den Winkel des Servomotors aus",
ARD_SERVO_WRITE: "setzt SERVO an Pin",
ARD_SERVO_WRITE_DEG_180: "Winkel (0~180)",
ARD_SERVO_WRITE_TIP: "Set a Servo to an specified angle", // untranslated
ARD_SERVO_WRITE_TO: "", // untranslated
ARD_SETTONE: "Spiele Ton an Pin", // untranslated
ARD_SPI_SETUP: "Setup",
ARD_SPI_SETUP_CONF: "Konfiguration:",
ARD_SPI_SETUP_DIVIDE: "clock divide", // untranslated
ARD_SPI_SETUP_LSBFIRST: "LSBFIRST", // untranslated
ARD_SPI_SETUP_MODE: "SPI mode (idle - edge)", // untranslated
ARD_SPI_SETUP_MODE0: "0 (LOW - Fallend)",
ARD_SPI_SETUP_MODE1: "1 (LOW - Steigend)",
ARD_SPI_SETUP_MODE2: "2 (HIGH - Fallend)",
ARD_SPI_SETUP_MODE3: "3 (HIGH - Steigend)",
ARD_SPI_SETUP_MSBFIRST: "MSBFIRST", // untranslated
ARD_SPI_SETUP_SHIFT: "data shift", // untranslated
ARD_SPI_SETUP_TIP: "Configures the SPI peripheral.", // untranslated
ARD_SPI_TRANSRETURN_TIP: "Send a SPI message to an specified slave device and get data back.", // untranslated
ARD_SPI_TRANS_NONE: "none", // untranslated
ARD_SPI_TRANS_SLAVE: "to slave pin", // untranslated
ARD_SPI_TRANS_TIP: "Send a SPI message to an specified slave device.", // untranslated
ARD_SPI_TRANS_VAL: "transfer", // untranslated
ARD_SPI_TRANS_WARN1: "A setup block for %1 must be added to the workspace to use this block!", // untranslated
ARD_SPI_TRANS_WARN2: "Old pin value %1 is no longer available.", // untranslated
ARD_STEPPER_COMPONENT: "stepper", // untranslated
ARD_STEPPER_DEFAULT_NAME: "MyStepper", // untranslated
ARD_STEPPER_FOUR_PINS: "4", // untranslated
ARD_STEPPER_MOTOR: "stepper motor:", // untranslated
ARD_STEPPER_NUMBER_OF_PINS: "Number of pins", // untranslated
ARD_STEPPER_PIN1: "pin1#", // untranslated
ARD_STEPPER_PIN2: "pin2#", // untranslated
ARD_STEPPER_PIN3: "pin3#", // untranslated
ARD_STEPPER_PIN4: "pin4#", // untranslated
ARD_STEPPER_REVOLVS: "how many steps per revolution", // untranslated
ARD_STEPPER_SETUP: "Setup stepper motor", // untranslated
ARD_STEPPER_SETUP_TIP: "Configures a stepper motor pinout and other settings.", // untranslated
ARD_STEPPER_SPEED: "set speed (rpm) to", // untranslated
ARD_STEPPER_STEP: "move stepper", // untranslated
ARD_STEPPER_STEPS: "steps", // untranslated
ARD_STEPPER_STEP_TIP: "Turns the stepper motor a specific number of steps.", // untranslated
ARD_STEPPER_TWO_PINS: "2", // untranslated
ARD_TYPE_ARRAY: "Array",
ARD_TYPE_BOOL: "Boolean",
ARD_TYPE_CHAR: "Zeichen",
ARD_TYPE_CHILDBLOCKMISSING: "ChildBlockMissing", // untranslated
ARD_TYPE_DECIMAL: "Dezimalzahl",
ARD_TYPE_LONG: "große Zahl",
ARD_TYPE_NULL: "Null",
ARD_TYPE_NUMBER: "Zahl",
ARD_TYPE_SHORT: "kurze Zahl",
ARD_TYPE_TEXT: "Text",
ARD_TYPE_UNDEF: "Undefiniert",
ARD_VAR_AS: "als",
ARD_VAR_AS_TIP: "Wert einem spezififischen Datentyp zuordnen",
ARD_WRITE_TO: "zu",
NEW_INSTANCE: "Neue Instanz...",
NEW_INSTANCE_TITLE: "Neue Instanz mit Name:",
RENAME_INSTANCE: "Instanz umbenennen...",
RENAME_INSTANCE_TITLE: "Benenne alle '%1' Instanzen zu:",
}
+50
View File
@@ -0,0 +1,50 @@
export const LOGIC = {
CONTROLS_IF_ELSEIF_TOOLTIP: "Eine weitere Bedingung hinzufügen.",
CONTROLS_IF_ELSE_TOOLTIP: "Eine sonst-Bedingung hinzufügen, führt eine Anweisung aus, falls keine Bedingung zutrifft.",
CONTROLS_IF_HELPURL: "https://github.com/google/blockly/wiki/IfElse", // untranslated
CONTROLS_IF_IF_TOOLTIP: "Hinzufügen, entfernen oder sortieren von Sektionen",
CONTROLS_IF_MSG_ELSE: "sonst",
CONTROLS_IF_MSG_ELSEIF: "sonst wenn",
CONTROLS_IF_MSG_IF: "wenn",
CONTROLS_IF_TOOLTIP_1: "Wenn eine Bedingung wahr (true) ist, dann führe eine Anweisung aus.",
CONTROLS_IF_TOOLTIP_2: "Wenn eine Bedingung wahr (true) ist, dann führe die erste Anweisung aus. Ansonsten führe die zweite Anweisung aus.",
CONTROLS_IF_TOOLTIP_3: "Wenn die erste Bedingung wahr (true) ist, dann führe die erste Anweisung aus. Oder wenn die zweite Bedingung wahr (true) ist, dann führe die zweite Anweisung aus.",
CONTROLS_IF_TOOLTIP_4: "Wenn die erste Bedingung wahr (true) ist, dann führe die erste Anweisung aus. Oder wenn die zweite Bedingung wahr (true) ist, dann führe die zweite Anweisung aus. Falls keine der beiden Bedingungen wahr (true) ist, dann führe die dritte Anweisung aus.",
LOGIC_BOOLEAN_HELPURL: "https://github.com/google/blockly/wiki/Logic#values", // untranslated
LOGIC_BOOLEAN_TOOLTIP: "Ist entweder wahr (true) oder falsch (false)",
LOGIC_BOOLEAN_TRUE: "wahr",
LOGIC_COMPARE_HELPURL: "https://de.wikipedia.org/wiki/Vergleich_%28Zahlen%29",
LOGIC_COMPARE_TOOLTIP_EQ: "Ist wahr (true), wenn beide Werte gleich sind.",
LOGIC_COMPARE_TOOLTIP_GT: "Ist wahr (true), wenn der erste Wert größer als der zweite Wert ist.",
LOGIC_COMPARE_TOOLTIP_GTE: "Ist wahr (true), wenn der erste Wert größer als oder gleich groß wie der zweite Wert ist.",
LOGIC_COMPARE_TOOLTIP_LT: "Ist wahr (true), wenn der erste Wert kleiner als der zweite Wert ist.",
LOGIC_COMPARE_TOOLTIP_LTE: "Ist wahr (true), wenn der erste Wert kleiner als oder gleich groß wie der zweite Wert ist.",
LOGIC_COMPARE_TOOLTIP_NEQ: "Ist wahr (true), wenn beide Werte unterschiedlich sind.",
LOGIC_NEGATE_HELPURL: "https://github.com/google/blockly/wiki/Logic#not", // untranslated
LOGIC_NEGATE_TITLE: "nicht %1",
LOGIC_NEGATE_TOOLTIP: "Ist wahr (true), wenn der Eingabewert falsch (false) ist. Ist falsch (false), wenn der Eingabewert wahr (true) ist.",
LOGIC_NULL: "null",
LOGIC_NULL_HELPURL: "https://de.wikipedia.org/wiki/Nullwert",
LOGIC_NULL_TOOLTIP: "Ist NULL.",
LOGIC_OPERATION_AND: "und",
LOGIC_OPERATION_HELPURL: "https://github.com/google/blockly/wiki/Logic#logical-operations", // untranslated
LOGIC_OPERATION_OR: "oder",
LOGIC_OPERATION_TOOLTIP_AND: "Ist wahr (true), wenn beide Werte wahr (true) sind.",
LOGIC_OPERATION_TOOLTIP_OR: "Ist wahr (true), wenn einer der beiden Werte wahr (true) ist.",
LOGIC_TERNARY_CONDITION: "teste",
LOGIC_TERNARY_HELPURL: "https://de.wikipedia.org/wiki/%3F:#Auswahloperator",
LOGIC_TERNARY_IF_FALSE: "wenn falsch",
LOGIC_TERNARY_IF_TRUE: "wenn wahr",
LOGIC_TERNARY_TOOLTIP: "Überprüft eine Bedingung \"teste\". Wenn die Bedingung wahr ist, wird der \"wenn wahr\" Wert zurückgegeben, andernfalls der \"wenn falsch\" Wert",
/**
* Cases
*/
cases_do: "Führe aus",
cases_condition: "Fall (Variable): ",
cases_switch: "Variable",
cases_add: "Fall",
cases_tooltip: "Führt den entsprechenden Fall aus, wenn die Überprüfung der Variable TRUE ergibt. Über das Zahnrad kannst du weitere Fälle hinzufügen. Über den 'Default' fall kannst du bestimmen, was passieren soll wenn keiner der vorher definierten Fälle eingetreten ist.",
}
+25
View File
@@ -0,0 +1,25 @@
export const LOOPS = {
CONTROLS_FLOW_STATEMENTS_HELPURL: "https://de.wikipedia.org/wiki/Kontrollstruktur",
CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK: "Die Schleife abbrechen",
CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE: "mit der nächsten Iteration der Schleife fortfahren",
CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK: "Die umgebende Schleife beenden.",
CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE: "Diese Anweisung abbrechen und mit dem nächsten Schleifendurchlauf fortfahren.",
CONTROLS_FLOW_STATEMENTS_WARNING: "Warnung: Dieser Block sollte nur in einer Schleife verwendet werden.",
CONTROLS_FOREACH_HELPURL: "https://de.wikipedia.org/wiki/For-Schleife",
CONTROLS_FOREACH_TITLE: "Für Wert %1 aus der Liste %2",
CONTROLS_FOREACH_TOOLTIP: "Führe eine Anweisung für jeden Wert in der Liste aus und setzte dabei die Variable \"%1\" auf den aktuellen Listenwert.",
CONTROLS_FOR_HELPURL: "https://de.wikipedia.org/wiki/For-Schleife",
CONTROLS_FOR_TITLE: "Zähle %1 von %2 bis %3 mit %4",
CONTROLS_FOR_TOOLTIP: "Zähle die Variable \"%1\" von einem Startwert bis zu einem Zielwert und führe für jeden Wert eine Anweisung aus.",
CONTROLS_REPEAT_HELPURL: "https://de.wikipedia.org/wiki/For-Schleife",
CONTROLS_REPEAT_INPUT_DO: "mache",
CONTROLS_REPEAT_TITLE: "Wiederhole %1 mal",
CONTROLS_REPEAT_TOOLTIP: "Eine Anweisung mehrfach ausführen.",
CONTROLS_WHILEUNTIL_HELPURL: "https://de.wikipedia.org/wiki/Schleife_%28Programmierung%29",
CONTROLS_WHILEUNTIL_OPERATOR_UNTIL: "Wiederhole bis",
CONTROLS_WHILEUNTIL_OPERATOR_WHILE: "Wiederhole solange",
CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL: "Führe die Anweisung solange aus wie die Bedingung falsch (false) ist.",
CONTROLS_WHILEUNTIL_TOOLTIP_WHILE: "Führe die Anweisung solange aus wie die Bedingung wahr (true) ist.",
}
+86
View File
@@ -0,0 +1,86 @@
export const MATH = {
MATH_ADDITION_SYMBOL: "+", // untranslated
MATH_ARITHMETIC_HELPURL: "https://de.wikipedia.org/wiki/Grundrechenart",
MATH_ARITHMETIC_TOOLTIP_ADD: "Ist die Summe zweier Werte.",
MATH_ARITHMETIC_TOOLTIP_DIVIDE: "Ist der Quotient zweier Werte.",
MATH_ARITHMETIC_TOOLTIP_MINUS: "Ist die Differenz zweier Werte.",
MATH_ARITHMETIC_TOOLTIP_MULTIPLY: "Ist das Produkt zweier Werte.",
MATH_ARITHMETIC_TOOLTIP_POWER: "Ist der erste Wert potenziert mit dem zweiten Wert.",
MATH_CHANGE_HELPURL: "https://de.wikipedia.org/wiki/Inkrement_und_Dekrement",
MATH_CHANGE_TITLE: "erhöhe %1 um %2",
MATH_CHANGE_TOOLTIP: "Addiert einen Wert zur Variable \"%1\" hinzu.",
MATH_CONSTANT_HELPURL: "https://de.wikipedia.org/wiki/Mathematische_Konstante",
MATH_CONSTANT_TOOLTIP: "Mathematische Konstanten wie: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) oder ∞ (unendlich).",
MATH_CONSTRAIN_HELPURL: "https://en.wikipedia.org/wiki/Clamping_%28graphics%29", // untranslated
MATH_CONSTRAIN_TITLE: "begrenze %1 von %2 bis %3",
MATH_CONSTRAIN_TOOLTIP: "Begrenzt den Wertebereich auf den \"von\"-Wert bis einschließlich zum \"bis\"-Wert. (inklusiv)",
MATH_DIVISION_SYMBOL: "÷", // untranslated
MATH_IS_DIVISIBLE_BY: "ist teilbar durch",
MATH_IS_EVEN: "ist gerade",
MATH_IS_NEGATIVE: "ist negativ",
MATH_IS_ODD: "ist ungerade",
MATH_IS_POSITIVE: "ist positiv",
MATH_IS_PRIME: "ist eine Primzahl",
MATH_IS_TOOLTIP: "Überprüft ob eine Zahl gerade, ungerade, eine Primzahl, ganzzahlig, positiv, negativ oder durch eine zweite Zahl teilbar ist. Gibt wahr (true) oder falsch (false) zurück.",
MATH_IS_WHOLE: "ist eine ganze Zahl",
MATH_MODULO_HELPURL: "https://de.wikipedia.org/wiki/Modulo",
MATH_MODULO_TITLE: "Rest von %1 ÷ %2",
MATH_MODULO_TOOLTIP: "Der Rest nach einer Division.",
MATH_MULTIPLICATION_SYMBOL: "×",
MATH_NUMBER_HELPURL: "https://de.wikipedia.org/wiki/Zahl",
MATH_NUMBER_TOOLTIP: "Eine Zahl.",
MATH_ONLIST_HELPURL: "http://www.sysplus.ch/einstieg.php?links:menu&seite:4125&grad:Crash&prog:Excel",
MATH_ONLIST_OPERATOR_AVERAGE: "Mittelwert einer Liste",
MATH_ONLIST_OPERATOR_MAX: "Maximalwert einer Liste",
MATH_ONLIST_OPERATOR_MEDIAN: "Median einer Liste",
MATH_ONLIST_OPERATOR_MIN: "Minimalwert einer Liste",
MATH_ONLIST_OPERATOR_MODE: "am häufigsten in Liste",
MATH_ONLIST_OPERATOR_RANDOM: "Zufallswert einer Liste",
MATH_ONLIST_OPERATOR_STD_DEV: "Standardabweichung einer Liste",
MATH_ONLIST_OPERATOR_SUM: "Summe einer Liste",
MATH_ONLIST_TOOLTIP_AVERAGE: "Ist der Durchschnittswert aller Werte in einer Liste.",
MATH_ONLIST_TOOLTIP_MAX: "Ist der größte Wert in einer Liste.",
MATH_ONLIST_TOOLTIP_MEDIAN: "Ist der Median aller Werte in einer Liste.",
MATH_ONLIST_TOOLTIP_MIN: "Ist der kleinste Wert in einer Liste.",
MATH_ONLIST_TOOLTIP_MODE: "Findet den am häufigsten vorkommenden Wert in einer Liste. Falls kein Wert öfter vorkommt als alle anderen, wird die originale Liste zurückgeben",
MATH_ONLIST_TOOLTIP_RANDOM: "Gebe einen zufälligen Wert aus der Liste zurück.",
MATH_ONLIST_TOOLTIP_STD_DEV: "Ist die standardisierte Standardabweichung aller Werte in der Liste",
MATH_ONLIST_TOOLTIP_SUM: "Ist die Summe aller Werte in einer Liste.",
MATH_POWER_SYMBOL: "^",
MATH_RANDOM_FLOAT_HELPURL: "https://de.wikipedia.org/wiki/Zufallszahlen",
MATH_RANDOM_FLOAT_TITLE_RANDOM: "Zufallszahl (0.0 -1.0)",
MATH_RANDOM_FLOAT_TOOLTIP: "Erzeuge eine Zufallszahl zwischen 0.0 (inklusiv) und 1.0 (exklusiv).",
MATH_RANDOM_INT_HELPURL: "https://de.wikipedia.org/wiki/Zufallszahlen",
MATH_RANDOM_INT_TITLE: "ganzzahliger Zufallswert zwischen %1 bis %2",
MATH_RANDOM_INT_TOOLTIP: "Erzeuge einen ganzzahligen Zufallswert zwischen zwei Werten (inklusiv).",
MATH_ROUND_HELPURL: "https://de.wikipedia.org/wiki/Runden",
MATH_ROUND_OPERATOR_ROUND: "runden",
MATH_ROUND_OPERATOR_ROUNDDOWN: "abrunden",
MATH_ROUND_OPERATOR_ROUNDUP: "aufrunden",
MATH_ROUND_TOOLTIP: "Eine Zahl auf- oder abrunden.",
MATH_SINGLE_HELPURL: "https://de.wikipedia.org/wiki/Quadratwurzel",
MATH_SINGLE_OP_ABSOLUTE: "Absolutwert",
MATH_SINGLE_OP_ROOT: "Quadratwurzel",
MATH_SINGLE_TOOLTIP_ABS: "Ist der Absolutwert eines Wertes.",
MATH_SINGLE_TOOLTIP_EXP: "Ist Wert der Exponentialfunktion eines Wertes.",
MATH_SINGLE_TOOLTIP_LN: "Ist der natürliche Logarithmus eines Wertes.",
MATH_SINGLE_TOOLTIP_LOG10: "Ist der dekadische Logarithmus eines Wertes.",
MATH_SINGLE_TOOLTIP_NEG: "Negiert einen Wert.",
MATH_SINGLE_TOOLTIP_POW10: "Rechnet 10 hoch Eingabewert.",
MATH_SINGLE_TOOLTIP_ROOT: "Ist die Quadratwurzel eines Wertes.",
MATH_SUBTRACTION_SYMBOL: "-",
MATH_TRIG_ACOS: "acos",
MATH_TRIG_ASIN: "asin",
MATH_TRIG_ATAN: "atan",
MATH_TRIG_COS: "cos",
MATH_TRIG_HELPURL: "https://de.wikipedia.org/wiki/Trigonometrie",
MATH_TRIG_SIN: "sin",
MATH_TRIG_TAN: "tan",
MATH_TRIG_TOOLTIP_ACOS: "Ist der Arkuskosinus des Eingabewertes.",
MATH_TRIG_TOOLTIP_ASIN: "Ist der Arkussinus des Eingabewertes.",
MATH_TRIG_TOOLTIP_ATAN: "Ist der Arkustangens des Eingabewertes.",
MATH_TRIG_TOOLTIP_COS: "Ist der Kosinus des Winkels.",
MATH_TRIG_TOOLTIP_SIN: "Ist der Sinus des Winkels.",
MATH_TRIG_TOOLTIP_TAN: "Ist der Tangens des Winkels.",
}
+15
View File
@@ -0,0 +1,15 @@
export const MQTT = {
/**
* MQTT
*/
senseBox_mqtt_init: "Verbinde mit MQTT Broker",
senseBox_mqtt_server: "Server",
senseBox_mqtt_port: "Port",
senseBox_mqtt_username: "Benutzername",
senseBox_mqtt_password: "Passwort",
sensebox_mqtt_subscribe: "Subscribe to Feed",
senseBox_mqtt_publish: "Sende an Feed/Topic",
senseBox_mqtt_init_tooltip: "Initialisiere die Verbindung zu dem MQTT Broker. Verwende diesen Block innerhalb der setup()-Funktion und stelle zuerst eine Verbindung mit dem Wlan Netzwerk her.",
senseBox_mqtt_publish_tooltip: "Sende etwas an ein 'Topic' deines MQTT Brokers.",
}
@@ -0,0 +1,51 @@
export const DISPLAY = {
/**
* Display
*/
senseBox_display_beginDisplay: "Display initialisieren",
senseBox_display_beginDisplay_tooltip: `Initialisiert das Display. Dieser Block muss im Setup() verwendet werden.
**Anschluss:** I2C
`,
senseBox_display_clearDisplay_tooltip: "Löscht die Anzeige auf dem Display. Sollte immer zu Begin oder am Ende der Endlosschleife aufgerufen werden.",
senseBox_display_clearDisplay: "Display löschen",
senseBox_display_printDisplay: "Schreibe Text/Zahl",
senseBox_display_printDisplay_tooltip: "Zeigt eine Zahl/Text auf dem Display an. Über die X- und Y-Koordinaten kann die Position auf dem Display bestimmt werden. Die Schriftgröße lässt sich in ganzzahligen Werten zwischen 1 und 4 einstellen. Das Display hat eine Auflösung von 128x64 Pixeln (X- und Y-Achse)",
senseBox_display_printDisplay_x: "x-Koordinate",
senseBox_display_printDisplay_y: "y-Koordinate",
senseBox_display_printDisplay_value: "Wert",
senseBox_display_setSize: "Schriftgröße",
senseBox_display_setSize_tip: "Ändere die Schriftgröße auf einen Wert zwischen 1 und 10.",
senseBox_display_color: "Schriftfarbe",
senseBox_display_white: "Weiß",
senseBox_display_black: "Schwarz",
sensebox_display_show: "Zeige auf dem Display",
sensebox_display_show_tip: "Zeigt den Nachfolgenden Inhalt auf dem Bildschirm",
senseBox_dipslay_plotTitle: "Titel",
senseBox_display_plotDisplay: "Zeichne Diagramm",
senseBox_display_plotXLabel: "X-Achsen Beschriftung",
senseBox_display_plotYLabel: "Y-Achsen Beschriftung",
senseBox_display_plotXRange1: "X-Wertebereich Anfang",
senseBox_display_plotXRange2: "X-Wertebereich Ende",
senseBox_display_plotYRange1: "Y-Wertebereich Anfang",
senseBox_display_plotYRange2: "Y-Wertebereich Ende",
senseBox_display_plotXTick: "X-Linienabstand",
senseBox_display_plotYTick: "Y-Linienabstand",
senseBox_display_plotTimeFrame: "Zeitabschnitt",
sensebox_display_fillCircle: "Zeichne Punkt",
sensebox_display_fillCircle_radius: "Radius",
senseBox_display_fillCircle_tooltip: "Mit diesem Block kann ein Punkt auf dem Display angezeigt werden. Über die Koordinaten kannst du den Punkt auf dem Display platzieren und mithilfe des Radius die Größe bestimmen.",
sensebox_display_drawRectangle: "Zeichne Rechteck",
sensebox_display_drawRectangle_width: "Breite",
sensebox_display_drawRectangle_height: "Höhe",
senseBox_display_drawRectangle_tooltip: "Dieser Block zeichnet ein Rechteck auf das Display. Mit den X- und Y-Koordinaten wird die Position der oberen linken Ecke des Rechtecks auf dem Display bestimmt. Die Höhe und Breite wird in Pixeln angegeben und mit der Checkbox 'Ausgefüllt' kann ausgewählt werden ob das Rechteck ausgefüllt oder nur als Rahmen angezeigt wird.",
senseBox_display_filled: "Ausgefüllt",
senseBox_display_fastPrint_show: "Zeige Messwerte",
senseBox_display_fastPrint_title: "Titel",
senseBox_display_fastPrint_value: "Messwert",
senseBox_display_fastPrint_dimension: "Einheit",
sensebox_display_fastPrint_tooltip: "Zeigt zwei Messwerte auf dem Display an. Wähle eine Überschrift für jeden Messwert und gib die Einheit an.",
senseBox_display_helpurl: "https://docs.sensebox.de/blockly/blockly-display/"
}
@@ -0,0 +1,36 @@
export const LED = {
/**
* WS2818 RGB LED
*/
senseBox_ws2818_rgb_led: "Setze RGB-LED an",
senseBox_ws2818_rgb_led_init: "RGB LED (WS2818) initialisieren",
senseBox_ws2818_rgb_led_position: "Position",
senseBox_ws2818_rgb_led_brightness: "Helligkeit",
senseBox_ws2818_rgb_led_tooltip: "Verändere mit diesem Block die Farbe deiner RGB-LED. Verbinde einen Block für die Farbe. Wenn mehrere RGB-LEDs miteinander verkettet werden kannst du über die Position bestimmen welche LED angesteuert wird. ",
senseBox_ws2818_rgb_led_init_tooltip: "Schließe die RGB-LED an einen der drei **digital/analog Ports** an. Wenn mehrere RGB-LEDs miteinander verkettet werden kannst du über die Position bestimmen welche LED angesteuert wird. ",
senseBox_ws2818_rgb_led_color: "Farbe",
senseBox_ws2818_rgb_led_number: "Anzahl",
/**
* Color
*/
COLOUR_BLEND_COLOUR1: "Farbe 1",
COLOUR_BLEND_COLOUR2: "mit Farbe 2",
COLOUR_BLEND_HELPURL: "http://meyerweb.com/eric/tools/color-blend/",
COLOUR_BLEND_RATIO: "im Verhältnis",
COLOUR_BLEND_TITLE: "mische",
COLOUR_BLEND_TOOLTIP: "Vermische 2 Farben mit konfigurierbaren Farbverhältnis (0.0 - 1.0).",
COLOUR_PICKER_HELPURL: "https://de.wikipedia.org/wiki/Farbe",
COLOUR_PICKER_TOOLTIP: "Wähle eine Farbe aus der Palette. Die Farbe wird automatisch in RGB-Werte konvertiert.",
COLOUR_RANDOM_HELPURL: "http://randomcolour.com", // untranslated
COLOUR_RANDOM_TITLE: "zufällige Farbe",
COLOUR_RANDOM_TOOLTIP: "Erstelle eine Farbe nach dem Zufallsprinzip.",
COLOUR_RGB_BLUE: "blau",
COLOUR_RGB_GREEN: "grün",
COLOUR_RGB_HELPURL: "https://de.wikipedia.org/wiki/RGB-Farbraum",
COLOUR_RGB_RED: "rot",
COLOUR_RGB_TITLE: "Farbe mit",
COLOUR_RGB_TOOLTIP: "Erstelle eine Farbe mit selbst definierten Rot-, Grün- und Blauwerten. Alle Werte müssen zwischen 0 und 255 liegen. 0 ist hierbei die geringte Intensität der Farbe 255 die höchste.",
}
@@ -0,0 +1,44 @@
export const LORA = {
/*
* LoRa Blöcke
*/
senseBox_LoRa_connect: "Zu TTN senden",
senseBox_LoRa_device_id: "Device EUI (lsb)",
senseBox_LoRa_app_id: "Application EUI (lsb)",
senseBox_LoRa_app_key: "App Key (msb)",
senseBox_LoRa_nwskey_id: "Network Session Key (msb)",
senseBox_LoRa_appskey_id: "App Session Key (msb)",
senseBox_LoRa_devaddr_id: "Device Adress",
senseBox_LoRa_interval: "Intervall in Minuten",
senseBox_measurement: "Messung",
senseBox_measurements: "Messungen",
senseBox_LoRa_send_message: "Sende als Lora Nachricht",
senseBox_LoRa_send_cayenne: "Sende als Cayenne Nachricht",
senseBox_LoRa_cayenne_temperature: "Temperatur",
senseBox_LoRa_cayenne_channel: "Kanal",
senseBox_LoRa_cayenne_humidity: "Luftfeuchtigkeit",
senseBox_LoRa_cayenne_pressure: "Luftdruck",
senseBox_LoRa_cayenne_luminosity: "Helligkeit",
senseBox_LoRa_cayenne_analog: "Analoger Wert",
senseBox_LoRa_cayenne_x: "X Wert",
senseBox_LoRa_cayenne_y: "Y Wert",
senseBox_LoRa_cayenne_z: "Z Wert",
senseBox_LoRa_cayenne_lat: "Breitengrad",
senseBox_LoRa_cayenne_lng: "Längengrad",
senseBox_LoRa_cayenne_alt: "Höhe",
senseBox_LoRa_cayenne_tip: "Sende Daten als Cayenne Payload Format",
senseBox_LoRa_cayenne_gps_tip: "Sende GPS",
senseBox_LoRa_cayenne_temperature_tip: "Sendet Temperaturwert mit einer Nachkommastelle",
senseBox_LoRa_cayenne_pressure_tip: "Sendet Luftdruck mit einer Nachkommastelle",
senseBox_LoRa_cayenne_luminosity_tip: "Sendet Helligkeitswert",
senseBox_LoRa_cayenne_analog_tip: "Sendet einen Dezimalwert mit einer Nachkommastelle",
senseBox_LoRa_message_tooltip: "Sende eine Nachricht über LoRa",
senseBox_LoRa_sensor_tip: "Sende einen Sensorwert mit einer bestimmten Anzahl an Bytes",
senseBox_LoRa_init_abp_tooltip: "Initialisiere die LoRa übertragung. Die Aktivierung erfolgt über ABP. Registriere eine Application auf [thethingsnetwork](https://thethingsnetwork.com) und kopiere den **Network Session Key** und den **App Session Key** im **msb Format** und die **Device ID** im **hex Format**.",
senseBox_LoRa_init_helpurl: "https://docs.sensebox.de/blockly/blockly-web-lora/",
senseBox_LoRa_init_otaa_tooltip: "Initialisiere die LoRa übertragung. Die Aktivierung erfolgt über OTAA. Registriere eine Application auf [thethingsnetwork](https://thethingsnetwork.com) und kopiere die **DEVICE EUI** und die **Application EUI** im **lsb Format** den **App Key** im **msb Format**.",
}
@@ -0,0 +1,17 @@
export const OSEM = {
/**
* openSenseMap
*/
senseBox_osem_connection_tip: "stellt eine WLAN verbindung her",
senseBox_send_to_osem_tip: "sende Messwert an",
senseBox_send_to_osem: "Sende Messwert an die openSenseMap",
senseBox_osem_connection: "Verbinde mit openSenseMap:",
senseBox_osem_host: "opensensemap.org",
senseBox_osem_host_workshop: "workshop.opensensemap.org",
senseBox_osem_exposure: "Typ",
senseBox_osem_stationary: "Stationär",
senseBox_osem_mobile: "Mobil",
senseBox_osem_access_token: "API Schlüssel",
senseBox_send_mobile_to_osem: "Sende Messwert und Standort an die openSenseMap",
senseBox_send_mobile_to_osem_tip: "Sende Messwert und Standort an die openSenseMap",
}
@@ -0,0 +1,16 @@
export const SD = {
/**
* SD-Block
*/
senseBox_sd_create_file: "Erstelle Datei auf SD-Karte",
senseBox_sd_write_file: "Schreibe Daten auf SD-Karte",
senseBox_sd_open_file: "Öffne Datei auf der SD-Karte",
senseBox_sd_create_file_tooltip:
"Erstellt eine Datei auf der Karte. Stecke das SD-Bee auf den Steckplatz **XBEE2**. Die **maximale** Länge des Dateinamen sind **8 Zeichen**. Die Datei sollte zuerst im *Setup()* erstellt werden",
senseBox_sd_write_file_tooptip:
"Schreibe Daten auf die SD-Karte. Beachte, dass die Datei zuerst geöffnet werden muss.",
senseBox_sd_open_file_tooltip:
"Öffne die Datei auf der SD-Karte, um Dateien zu speichern. Am Ende der Schleife wird die Datei automatisch wieder geschlossen.",
sensebox_sd_filename: "Daten",
senseBox_sd_decimals: "Dezimalen",
};
@@ -0,0 +1,180 @@
export const SENSORS = {
/**
* Sensors
* ---------------------------------------------------
*
*/
/**
* BMP280
*/
senseBox_pressure_sensor: "Luftdruck-/Temperatursensor (BMP280)",
senseBox_pressure: "Luftdruck in Pa",
senseBox_pressure_dimension: "Luftdruck in Pa",
senseBox_pressure_tip: "Schließe den Sensor an einen der 5 **I2C-Anschlüsse** an. Der Sensor gibt dir den Messwert für den Luftdruck in Pa. Um die korrekte Höhe über NN zu berechnen benötigt der Sensor einen aktuellen Referenzwert.",
senseBox_pressure_referencePressure: "Luftdruck auf NN",
senseBox_pressure_referencePressure_dim: "hPa",
senseBox_pressure_helpurl: "",
/**
* Mikro
*/
senseBox_sound: "Mikrofon",
senseBox_sound_tip: "Schließe den Sensor über das Breadbord an einen der 3 **analog/digital** Ports an. Gibt den Messwert des Mikrofons in Volt zurück",
senseBox_sound_helpurl: "https://docs.sensebox.de/hardware/sensoren-mikro/",
/**
* Temperature and Humidity Sensor (HDC1080)
*/
senseBox_temp: "Temperatur in °C",
senseBox_temp_hum: "Temperatur-/Luftfeuchtigkeitssensor (HDC1080)",
senseBox_temp_hum_tooltip: "Dieser Block gibt dir die Messwerte des Temperatur- und Luftfeuchtigkeitssensor zurück. Schließe den Sensor an einen der 5 I2C Anschlüsse an. Messwert wird mit 2 Nachkommastellen ausgegeben.",
senseBox_temp_hum_helpurl: "https://docs.sensebox.de/hardware/sensoren-temperatur-luftfeuchte/",
/**
* Ultraschalldistanzsensor
*/
senseBox_ultrasonic: "Ultraschall-Abstandssensor an Port",
senseBox_ultrasonic_trigger: "Trigger",
senseBox_ultrasonic_echo: "Echo",
senseBox_ultrasonic_port_A: "A",
senseBox_ultrasonic_port_B: "B",
senseBox_ultrasonic_port_C: "C",
senseBox_ultrasonic_tooltip: `Misst die Distanz mithilfe von Ultraschall in cm. Schließe den Sensor an einen der drei Digital/Analog Ports an:
- Trigger: Grünes Kabel
- Echo: gelbes Kabel`,
senseBox_ultrasonic_helpurl: "https://docs.sensebox.de/hardware/sensoren-distanz/",
/**
* UV and Lightsensor
*/
senseBox_value: "Messwert:",
senseBox_uv_light: "Helligkeit-/UV-Sensor",
senseBox_uv_light_tooltip: "Sensor misst UV-Licht oder die Helligkeit. Die Helligkeit wird als **Ganzezahl** in Lux ausgegeben. Die UV-Intensität als **Kommazahl** in µW/cm².",
senseBox_uv: "UV-Intensität in µW/cm²",
senseBox_light: "Beleuchtungsstärke in Lux",
senseBox_uv_light_helpurl: "https://docs.sensebox.de/hardware/sensoren-helligkeit-uv/",
/**
* BMX055
*/
senseBox_bmx055_compass: "Lage Sensor",
senseBox_bmx055_accelerometer: "Beschleunigungssensor",
senseBox_bmx055_accelerometer_range: "Messbereich",
senseBox_bmx055_accelerometer_range_2g: "2g",
senseBox_bmx055_accelerometer_range_4g: "4g",
senseBox_bmx055_accelerometer_range_8g: "8g",
senseBox_bmx055_accelerometer_range_16g: "16g",
senseBox_bmx055_accelerometer_direction: "Richtung",
senseBox_bmx055_accelerometer_direction_x: "X-Achse",
senseBox_bmx055_accelerometer_direction_y: "Y-Achse",
senseBox_bmx055_accelerometer_direction_z: "Z-Achse",
senseBox_bmx055_accelerometer_direction_total: "Gesamt",
senseBox_bmx055_gyroscope: "Lage Sensor",
senseBox_bmx055_accelerometer_tip: "Lage Sensor",
senseBox_bmx055_compass_tip: "Lage Sensor",
senseBox_bmx055_gyroscope_tip: "Lage Sensor",
senseBox_bmx055_x: "X-Richtung",
senseBox_bmx055_y: "Y-Richtung",
senseBox_bmx055_accelerometer_tooltip: `Dieser Block gibt dir den Messwert des Beschleunigungssensors der direkt auf der senseBox MCU aufgelötet ist. Im Dropdown Menü kannst du die Richtung und den Messbereich auswählen.`,
senseBox_bmx055_helpurl: "",
/**
*
* GPS
*/
senseBox_gps_getValues: "GPS Modul",
senseBox_gps_lat: "Breitengrad",
senseBox_gps_lng: "Längengrad",
senseBox_gps_alt: "Höhe über NN in m",
senseBox_gps_speed: "Geschwindigkeit in km/h",
senseBox_gps_date: "Datum",
senseBox_gps_time: "Uhrzeit",
senseBox_gps_timeStamp: "Zeitstempel (RFC 3339)",
senseBox_gps_tooltip: `Liest das GPS Modul aus und gibt dir die Standortinformationen. Längen- und Breitengrad werden als Kommazahl mit 6 Nachkommastellen ausgegeben.
**Anschluss: I2C**
**Beachte:** Das GPS Modul benöigt beim ersten Verwenden relativ lange (ca. 5-10 Minuten) bis es deinen Standort gefunden hat!
`,
senseBox_gps_helpurl: "https://docs.sensebox.de/hardware/sensoren-gps/",
/**
* Windspeed
*/
senseBox_windspeed: "Windgeschwindigkeitssensor",
senseBox_windspeed_tooltip: "",
/*
* Soundsensor
*/
senseBox_soundsensor_dfrobot: "Soundsensor (DF Robot)",
senseBox_soundsensor_dfrobot_tooltip: "Schließe den Sensor an einen der 3 **digital/analog Ports** an. Der Sensor gibt dir den Messwert in dB mit einer Nachkommastelle",
senseBox_soundsensor_dfrobot_helpurl: "https://docs.sensebox.de/hardware/sensoren-lautstaerke/",
/*
* BME680
*/
senseBox_bme680: "Umweltsensor (BME680)",
senseBox_bme_iaq: "Innenraumluftqualität (IAQ)",
senseBox_bme_iaq_accuracy: "Kalibrierungswert",
senseBox_bme_co2: "CO2 Äquivalent",
senseBox_bme_breatheVocEquivalent: "Atemluft VOC Äquivalent",
senseBox_bme_tooltip: `Schließe den Umweltsensor an einen der 5 **I2C-Anschlüsse** an. **Beachte:** Der Sensor benöigt eine gewisse Zeit zum kalibrieren.
Den Status der Kalibrierung kann über den Kalibrierungswert abgelesen werden. Er ist entweder 0, 1, 2 oder 3 und sagt folgendes aus:
- IAQ Accuracy : 0 heißt Sensor wird stabilisiert (dauert ca. 25 Minuten) oder dass es eine Zeitüberschreitung gab,
- IAQ Accuracy : 1 heißt Wert ist ungenau,
- IAQ Accuracy : 2 heißt Sensor wird kalibriert,
- IAQ Accuracy : 3 heißt Sensor erfolgreich kalibriert.
Die Messwerte für Temperatur, Luftfeuchtigkeit und Luftdruck können direkt verwendet werden.`,
senseBox_bme680_helpurl: "https://docs.sensebox.de/hardware/sensoren-umweltsensor/",
/**
* Truebner SMT50
*/
senseBox_smt50: "Bodenfeuchte/-temperatur (SMT50)",
senseBox_smt50_helpurl: "https://docs.sensebox.de/hardware/sensoren-truebner/",
senseBox_smt50_tooltip: "Schließe den Bodenfeuchtigkeit- und Temperatursensor an einen der 3 digital/analog Ports an und wähle den Port im Block aus. Der Sensor gibt die Bodentemperatur in °C und die Bodenfeuchtigkeit in % aus.",
/**
* SCD30 CO2 Sensor
*/
senseBox_scd30: "CO2 Sensor (Sensirion SCD30)",
senseBox_scd_tooltip: "Schließe den Sensor an einen der 5 **I2C-Anschlüsse** an. Der Sensor gibt dir den Messwert für die CO2-Konzentration in ppm. Der Temperaturmesswert kann aufgrund der Messung direkt am Sensor um einige Grad vom realen Wert abweichen.",
senseBox_scd_co2: "CO2 in ppm",
senseBox_scd_helpurl: "https://docs.sensebox.de/hardware/sensoren-co2/",
/**
* Feinstaubsensor (SDS011)
*/
senseBox_sds011: "Feinstaubsensor",
senseBox_sds011_dimension: "in µg/m³ an",
senseBox_sds011_pm25: "PM2.5",
senseBox_sds011_pm10: "PM10",
senseBox_sds011_tooltip: "Dieser Block gibt dir den Messwert des Feinstaubsensor. Schließe den Feinstaubsensor an einen der 2 **Serial/UART** Anschlüssen an. Im Dropdown Menü zwischen PM2.5 und PM10 auswählen. Der Messwert wird dir als **Kommazahl** in µg/m3",
senseBox_sds011_serial1: "Serial1",
senseBox_sds011_serial2: "Serial2",
senseBox_sds011_helpurl: "https://docs.sensebox.de/hardware/sensoren-feinstaub/",
/**
* Button
*/
senseBox_button: "Button",
senseBox_button_isPressed: "ist gedrückt",
senseBox_button_switch: "als Schalter",
senseBox_button_wasPressed: "wurde gedrückt",
senseBox_button_tooltip: `Dieser Block gibt dir den Status des angeschlossenen Buttons. Im Dropdown Menü können verschiedene Modi für den Button ausgewählt werden. Angesteuert können entweder der on Board Button oder ein Button, der an einen der 6 digitalen Pins angeschlossen ist. verschiedene Modi:
- "ist gedrückt": Mit diesem Modus kannst du abfragen ob der Block gerade gedrückt wird. Du erhältst entweder den Wert TRUE oder FALSE.
- "wurde gedrückt": Mit diesem Modus kannst du abfragen ob der Block gedrückt wurde. Erst wenn der Knopf gedrückt und wieder losgelassen wurde erhältst du TRUE zurück
- "als Schalter": Wenn du diesen Block verwendest kannst du den Knopf wie ein Lichtschalter verwenden. Der Status wird gespeichert bis der Button erneut gedrückt wird`,
senseBox_button_helpurl: "",
}
@@ -0,0 +1,16 @@
export const TELEGRAM = {
/*
* Telegram
*/
senseBox_telegram_init: "Telegram Bot initialisieren",
senseBox_telegram_token: "Token",
senseBox_telegram_do: "Telegram mache",
senseBox_telegram_do_tooltip: "Füge in diese Schleife die Blöcke ein, die dein Telegram Bot ausführen soll. Beachte hierbei, dass du Aktionen bei einer bestimmten Nachricht ausführen lassen kannst oder auch selbst eine Nachricht versenden werden kann.",
senseBox_telegram_do_on_message: "bei Nachricht",
senseBox_telegram_message: "Nachricht",
senseBox_telegram_message_tooltip: "Führe eine Aktion aus, wenn der Telegram eine *Nachricht* empfangen hat.",
senseBox_telegram_send: "Sende Nachricht",
senseBox_telegram_send_tooltip: "Dein Telgram Bot sendet dir eine Nachricht auf dein Handy. Die Nachricht kann zum Beispiel ein Alarm oder auch ein Messwert sein",
senseBox_telegram_init_tooltip: "Initialisiere den Telegram Bot. Verwende diesen Block in der **Setup()-Schleife**. Den Token kannst du dir über den Telegram erstellen.",
senseBox_telegram_helpurl: "https://sensebox.de/projects/de/2019-12-15-telegram-blockly",
}
@@ -0,0 +1,11 @@
export const WEB = {
/**
* WiFi
*/
senseBox_wifi_connect: "Verbinde mit WLAN",
senseBox_wifi_ssid: "Netzwerkname",
senseBox_wifi_tooltip: "Stellt eine Verbindung mit einem WLAN-Netzwerk her. Möchtest du dich mit einem ungesicheren Netzwerk (z.B. Freifunk) verbinden lösche das Feld Passwort. Das WiFi-Bee muss auf den Steckplatz **XBEE1** aufgesteckt werden.",
senseBox_wifi_startap: "Initialisiere WLAN Access Point",
senseBox_wifi_startap_tooltip: "Erstellt einen WiFi-Accesspoint zu dem du dich verbinden kannst. Beachte, dass immer nur 1 Gerät gleichzeitig verbunden werden kann.",
senseBox_wifi_helpurl: "https://docs.sensebox.de/blockly/blockly-web-wifi/",
}
+65
View File
@@ -0,0 +1,65 @@
export const TEXT = {
TEXT_APPEND_APPENDTEXT: "Text anhängen",
TEXT_APPEND_HELPURL: "https://github.com/google/blockly/wiki/Text#text-modification", // untranslated
TEXT_APPEND_TO: "An",
TEXT_APPEND_TOOLTIP: "Text an die Variable \"%1\" anhängen.",
TEXT_CHANGECASE_HELPURL: "https://github.com/google/blockly/wiki/Text#adjusting-text-case", // untranslated
TEXT_CHANGECASE_OPERATOR_LOWERCASE: "umwandeln in kleinbuchstaben",
TEXT_CHANGECASE_OPERATOR_TITLECASE: "umwandeln in Substantive",
TEXT_CHANGECASE_OPERATOR_UPPERCASE: "umwandeln in GROSSBUCHSTABEN",
TEXT_CHANGECASE_TOOLTIP: "Wandelt Schreibweise von Texten um, in Großbuchstaben, Kleinbuchstaben oder den ersten Buchstaben jedes Wortes groß und die anderen klein.",
TEXT_CHARAT_FIRST: "Nehme ersten Buchstaben",
TEXT_CHARAT_FROM_END: "Nehme #ten Buchstaben von hinten",
TEXT_CHARAT_FROM_START: "Nehme #ten Buchstaben",
TEXT_CHARAT_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
TEXT_CHARAT_INPUT_INTEXT: "vom Text",
TEXT_CHARAT_LAST: "Nehme letzten Buchstaben",
TEXT_CHARAT_RANDOM: "Nehme zufälligen Buchstaben",
TEXT_CHARAT_TAIL: "",
TEXT_CHARAT_TOOLTIP: "Extrahiere einen Buchstaben von einer spezifizierten Position.",
TEXT_CREATE_JOIN_ITEM_TOOLTIP: "Ein Element zum Text hinzufügen.",
TEXT_CREATE_JOIN_TITLE_JOIN: "verbinden",
TEXT_CREATE_JOIN_TOOLTIP: "Hinzufügen, entfernen und sortieren von Elementen.",
TEXT_GET_SUBSTRING_END_FROM_END: "bis zum #ten Buchstaben von hinten",
TEXT_GET_SUBSTRING_END_FROM_START: "bis zum #ten Buchstaben",
TEXT_GET_SUBSTRING_END_LAST: "bis zum letzten Buchstaben",
TEXT_GET_SUBSTRING_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
TEXT_GET_SUBSTRING_INPUT_IN_TEXT: "in Text",
TEXT_GET_SUBSTRING_START_FIRST: "vom ersten Buchstaben",
TEXT_GET_SUBSTRING_START_FROM_END: "vom #ten Buchstaben von hinten",
TEXT_GET_SUBSTRING_START_FROM_START: "vom #ten Buchstaben",
TEXT_GET_SUBSTRING_TAIL: "",
TEXT_GET_SUBSTRING_TOOLTIP: "Gibt den angegebenen Textabschnitt zurück.",
TEXT_INDEXOF_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
TEXT_INDEXOF_INPUT_INTEXT: "im Text",
TEXT_INDEXOF_OPERATOR_FIRST: "Suche erstes Auftreten des Begriffs",
TEXT_INDEXOF_OPERATOR_LAST: "Suche letztes Auftreten des Begriffs",
TEXT_INDEXOF_TAIL: "",
TEXT_INDEXOF_TOOLTIP: "Findet das erste / letzte Auftreten eines Suchbegriffs in einem Text. Gibt die Position des Begriffs oder 0 zurück.",
TEXT_ISEMPTY_HELPURL: "https://github.com/google/blockly/wiki/Text#checking-for-empty-text", // untranslated
TEXT_ISEMPTY_TITLE: "%1 ist leer?",
TEXT_ISEMPTY_TOOLTIP: "Ist wahr (true), wenn der Text keine Zeichen enthält ist.",
TEXT_JOIN_HELPURL: "",
TEXT_JOIN_TITLE_CREATEWITH: "Erstelle Text aus",
TEXT_JOIN_TOOLTIP: "Erstellt einen Text durch das Verbinden von mehreren Textelementen.",
TEXT_LENGTH_HELPURL: "https://github.com/google/blockly/wiki/Text#text-modification", // untranslated
TEXT_LENGTH_TITLE: "Länge %1",
TEXT_LENGTH_TOOLTIP: "Die Anzahl von Zeichen in einem Text. (inkl. Leerzeichen)",
TEXT_PRINT_HELPURL: "https://github.com/google/blockly/wiki/Text#printing-text", // untranslated
TEXT_PRINT_TITLE: "Ausgabe %1",
TEXT_PRINT_TOOLTIP: "Gib den Inhalt einer Variable aus.",
TEXT_PROMPT_HELPURL: "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user", // untranslated
TEXT_PROMPT_TOOLTIP_NUMBER: "Fragt den Benutzer nach einer Zahl.",
TEXT_PROMPT_TOOLTIP_TEXT: "Fragt den Benutzer nach einem Text.",
TEXT_PROMPT_TYPE_NUMBER: "Fragt nach Zahl mit Hinweis",
TEXT_PROMPT_TYPE_TEXT: "Fragt nach Text mit Hinweis",
TEXT_TEXT_HELPURL: "https://de.wikipedia.org/wiki/Zeichenkette",
TEXT_TEXT_TOOLTIP: "Ein Buchstabe, Text oder Satz.",
TEXT_TRIM_HELPURL: "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces", // untranslated
TEXT_TRIM_OPERATOR_BOTH: "entferne Leerzeichen vom Anfang und vom Ende (links und rechts)",
TEXT_TRIM_OPERATOR_LEFT: "entferne Leerzeichen vom Anfang (links)",
TEXT_TRIM_OPERATOR_RIGHT: "entferne Leerzeichen vom Ende (rechts)",
TEXT_TRIM_TOOLTIP: "Entfernt Leerzeichen vom Anfang und / oder Ende eines Textes.",
}
+22
View File
@@ -0,0 +1,22 @@
export const TIME = {
/**
* Interval Block
*/
senseBox_interval_timer: "Intervall:",
senseBox_interval: "ms",
senseBox_interval_timer_tip: "Intervall",
senseBox_interval_time: "Zeit: ",
ARD_TIME_DELAY: "Warte",
ARD_TIME_DELAY_MICROS: "Mikrosekunden",
ARD_TIME_DELAY_MICRO_TIP: "Warte eine spezifischen Zeit in Microsekunden",
ARD_TIME_DELAY_TIP: "Warte spezifische Zeit in Millisekunden",
ARD_TIME_INF: "Warte für immer (Beende Programm)",
ARD_TIME_INF_TIP: "Stoppt das Programm.",
ARD_TIME_MICROS: "Bereits vergangen Zeit (Mikrosekunden)",
ARD_TIME_MICROS_TIP:
"Gibt eine Zahl in Microsekunden zurück, die der Zeitdauer des Aktuellen Programms entspricht. Muss als positiven Integer gespeichert werden", // untranslated
ARD_TIME_MILLIS: "Bereits vergangen Zeit (Millisekunden)",
ARD_TIME_MILLIS_TIP:
"Gibt eine Zahl in Millisekunden zurück, die der Zeitdauer des Aktuellen Programms entspricht. Muss als positiven Integer gespeichert werden", // untranslated
ARD_TIME_MS: "Millisekunden",
};

Some files were not shown because too many files have changed in this diff Show More