diff --git a/mixly/boards/default_src/arduino/arduino_generator.js b/mixly/boards/default_src/arduino/arduino_generator.js
new file mode 100644
index 00000000..a9b60371
--- /dev/null
+++ b/mixly/boards/default_src/arduino/arduino_generator.js
@@ -0,0 +1,165 @@
+import * as Blockly from 'blockly/core';
+import Names from './others/names';
+
+export class ArduinoGenerator extends Blockly.Generator {
+ constructor(name) {
+ super(name ?? 'Arduino')
+ this.ORDER_ATOMIC = 0 // 0 "" ...
+ this.ORDER_UNARY_POSTFIX = 1 // expr++ expr-- () [] .
+ this.ORDER_UNARY_PREFIX = 2 // -expr !expr ~expr ++expr --expr
+ this.ORDER_MULTIPLICATIVE = 3 // * / % ~/
+ this.ORDER_ADDITIVE = 4 // + -
+ this.ORDER_SHIFT = 5 // << >>
+ this.ORDER_RELATIONAL = 6 // is is! >= > <= <
+ this.ORDER_EQUALITY = 7 // == != === !==
+ this.ORDER_BITWISE_AND = 8 // &
+ this.ORDER_BITWISE_XOR = 9 // ^
+ this.ORDER_BITWISE_OR = 10 // |
+ this.ORDER_LOGICAL_AND = 11 // &&
+ this.ORDER_LOGICAL_OR = 12 // ||
+ this.ORDER_CONDITIONAL = 13 // expr ? expr : expr
+ this.ORDER_ASSIGNMENT = 14 // = *= /= ~/= %= += -= <<= >>= &= ^= |=
+ this.ORDER_NONE = 99 // (...)
+ this.INDENT = ' '
+ this.isInitialized = false
+ this.PASS = ''
+
+ this.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,unsigned,byte,int,short,word,long,float,double,string,String,array,static,volatile,const,sizeof'
+ )
+ }
+
+ init() {
+ super.init();
+ // Create a dictionary of definitions to be printed before setups.
+ this.definitions_ = Object.create(null)
+ // Create a dictionary of setups to be printed before the code.
+ this.setups_ = Object.create(null)
+ this.setups_begin_ = Object.create(null)
+ this.setups_end_ = Object.create(null)
+ this.libs_ = Object.create(null)
+ this.loops_begin_ = Object.create(null)
+ this.loops_end_ = Object.create(null)
+ //this.variableTypes_ = Object.create(null);//处理变量类型
+
+ if (!this.variableDB_) {
+ this.variableDB_ = new Names(
+ this.RESERVED_WORDS_
+ )
+ } else {
+ this.variableDB_.reset()
+ }
+ this.isInitialized = true;
+ }
+
+ finish(code) {
+ // Indent every line.
+ code = ' ' + code.replace(/\n/g, '\n ');
+ code = code.replace(/\n\s+$/, '\n');
+ // Convert the definitions dictionary into a list.
+ var imports = [];
+ var define = [];
+ var definitions_var = []; //变量定义
+ var definitions_fun = []; //函数定义
+ //var sorted_keys=Object.keys(this.definitions_).sort();
+ var sorted_keys = Object.keys(this.definitions_);
+ if (sorted_keys.length) {
+ for (var idx in sorted_keys) {
+ var name = sorted_keys[idx];
+ var def = this.definitions_[name];
+ if (name.match(/^define/)) {
+ define.push(def);
+ } else if (name.match(/^include/)) {
+ imports.push(def);
+ } else if (def.match(/^WiFiClient/)) {
+ imports.push(def);
+ } else if (name.match(/^var_declare/)) {
+ definitions_var.push(def);
+ } else {
+ definitions_fun.push(def);
+ }
+ }
+ }
+ // Convert the setups dictionary into a list.
+ var setups = [];
+ for (let name in this.setups_) {
+ setups.push(this.setups_[name]);
+ }
+ var setupsBegin = [], setupsEnd = [];
+ for (let name in this.setups_begin_) {
+ setupsBegin.push(this.setups_begin_[name]);
+ }
+ for (let name in this.setups_end_) {
+ setupsEnd.push(this.setups_end_[name]);
+ }
+
+ for (let name in this.libs_) {
+ imports.push(`#include "${name}.h"`);
+ }
+
+ var loopsBegin = [], loopsEnd = [];
+ for (let name in this.loops_begin_) {
+ loopsBegin.push(this.loops_begin_[name]);
+ }
+ for (let name in this.loops_end_) {
+ loopsEnd.push(this.loops_end_[name]);
+ }
+ code = 'void loop() {\n'
+ + (loopsBegin.length ? (' ' + loopsBegin.join('\n ')) : '')
+ + code
+ + (loopsEnd.length ? (' ' + loopsEnd.join('\n ')) : '')
+ + '\n}';
+ var allDefs = define.join('\n') + '\n' + imports.join('\n') + '\n\n'
+ + definitions_var.join('\n')
+ + '\n\n' + definitions_fun.join('\n')
+ + '\n\nvoid setup() {\n '
+ + setupsBegin.join('\n ') + ((setupsBegin.length && (setupsEnd.length || setups.length)) ? '\n ' : '')
+ + setups.join('\n ') + ((setupsEnd.length && setups.length) ? '\n ' : '')
+ + setupsEnd.join('\n ') + '\n}' + '\n\n';
+ return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n') + code;
+ }
+
+ scrubNakedValue(line) {
+ return line + ';\n'
+ }
+
+ quote_(string) {
+ // TODO: This is a quick hack. Replace with goog.string.quote
+ //return goog.string.quote(string);
+ return "\"" + string + "\"";
+ }
+
+ scrub_(block, code) {
+ if (code === null) {
+ // Block has handled code generation itself.
+ return '';
+ }
+ var commentCode = '';
+ // Only collect comments for blocks that aren't inline.
+ if (!block.outputConnection || !block.outputConnection.targetConnection) {
+ // Collect comment for this block.
+ let comment = block.getCommentText();
+ if (comment) {
+ commentCode += this.prefixLines(comment, '// ') + '\n';
+ }
+ // Collect comments for all value arguments.
+ // Don't collect comments for nested statements.
+ for (var x = 0; x < block.inputList.length; x++) {
+ if (block.inputList[x].type == Blockly.INPUT_VALUE) {
+ var childBlock = block.inputList[x].connection.targetBlock();
+ if (childBlock) {
+ let comment = this.allNestedComments(childBlock);
+ if (comment) {
+ commentCode += this.prefixLines(comment, '// ');
+ }
+ }
+ }
+ }
+ }
+ var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
+ var nextCode = this.blockToCode(nextBlock);
+ return commentCode + code + nextCode;
+ }
+}
+
+export const Arduino = new ArduinoGenerator();
diff --git a/mixly/boards/default_src/arduino/blocks/ethernet.js b/mixly/boards/default_src/arduino/blocks/ethernet.js
new file mode 100644
index 00000000..9d4d657a
--- /dev/null
+++ b/mixly/boards/default_src/arduino/blocks/ethernet.js
@@ -0,0 +1,223 @@
+import * as Blockly from 'blockly/core';
+import CITYS_DATA from '../templates/json/cities.json';
+
+const ETHERNET_HUE = 0;
+const WEATHER_HUE = '#27b6ac';
+
+
+/**
+ * @name 模块名 Http GET请求
+ * @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
+ */
+export const http_get = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_GET_REQUEST);
+ this.appendValueInput("api")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.appendStatementInput("success")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SUCCESS);
+ this.appendStatementInput("failure")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_FAILED);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setTooltip("");
+ }
+};
+
+/**
+ * @name 模块名 Http PATCH|POST|PUT请求
+ * @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
+ */
+export const http_post = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ ["POST", "POST"],
+ ["PATCH", "PATCH"],
+ ["PUT", "PUT"]
+ ]), "TYPE")
+ .appendField(Blockly.Msg.blockpy_REQUESTS);
+ this.appendValueInput("api")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.appendValueInput("data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.appendStatementInput("success")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SUCCESS);
+ this.appendStatementInput("failure")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_FAILED);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setTooltip("");
+ }
+};
+
+var PROVINCES = [], key;
+for (key in CITYS_DATA)
+ PROVINCES.push([key, key]);
+
+
+function getCitysByProvince(a) {
+ var b = [], c;
+ for (c in CITYS_DATA[a])
+ b.push([c, c]);
+ return b;
+}
+
+var citysByProvince = {};
+for (key of PROVINCES) {
+ citysByProvince[key[0]] = getCitysByProvince(key[0]);
+}
+
+export const china_city = {
+ init: function () {
+ const defaultOptions = [["-", "-"]];
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(PROVINCES), "province")
+ .appendField(new Blockly.FieldDependentDropdown("province", citysByProvince, defaultOptions), "city");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(WEATHER_HUE);
+ this.setHelpUrl("");
+ this.preProvince = null;
+ }
+};
+
+export const weather_private_key = {
+ init: function () {
+ this.setColour(WEATHER_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([['S9l2sb_ZK-UsWaynG', 'S9l2sb_ZK-UsWaynG'], ['SpRpSYb7QOMT0M8Tz', 'SpRpSYb7QOMT0M8Tz'], ['SboqGMxP4tYNXUN8f', 'SboqGMxP4tYNXUN8f'], ['SJiRrYGYFkGnfi081', 'SJiRrYGYFkGnfi081'], ['SMhSshUxuTL0GLVLS', 'SMhSshUxuTL0GLVLS']]), 'key');
+ this.setOutput(true, null);
+ }
+};
+
+export const weather_seniverse_city_weather = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MSG.catweather)
+ .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_LIVE_WEATHER, "weather/now"], [Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST, "weather/daily"], [Blockly.Msg.MIXLY_6_LIFE_INDEXES, "life/suggestion"]]), "api")
+ .appendField(Blockly.Msg.MIXLY_INFORMATION_CONFIGURATION);
+ this.appendValueInput("location")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_GEOGRAPHIC_LOCATION);
+ this.appendValueInput("private_key")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_API_PRIVATE_KEY);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_LANGUAGE)
+ .appendField(new Blockly.FieldDropdown([
+ ["简体中文", "zh-Hans"],
+ ["繁體中文", "zh-Hant"],
+ ["English", "en"]
+ ]), "language");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_TEMPERATURE_UNIT)
+ .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_CELSIUS + "(℃)", "c"], [Blockly.Msg.MIXLY_FAHRENHEIT + "(℉)", "f"]]), "unit");
+ this.setInputsInline(false);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(WEATHER_HUE);
+ this.setTooltip("这里的API私钥免费体验有次数限制\n访问频率限制20次/分钟");
+ this.setHelpUrl("");
+ }
+};
+
+
+export const weather_get_seniverse_weather_info = {
+ init: function () {
+ this.appendDummyInput("")
+ //.appendField("心知天气")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_LIVE_WEATHER, "weather/now"],
+ [Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST, "weather/daily"],
+ [Blockly.Msg.MIXLY_6_LIFE_INDEXES, "life/suggestion"]
+ ]), "api")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_AVAILABLE, "update"],
+ [Blockly.Msg.MIXLY_GET_DATA_UPDATE_TIME, "getLastUpdate"],
+ [Blockly.Msg.MIXLY_GET_SERVER_RESPONSE_STATUS_CODE, "getServerCode"]
+ ]), "type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(WEATHER_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+
+};
+
+export const weather_get_seniverse_weather_info1 = {
+ init: function () {
+ this.appendDummyInput("")
+ //.appendField("心知天气")
+ .appendField(Blockly.Msg.MIXLY_LIVE_WEATHER)
+ .appendField(Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_WEATHER_PHENOMENON, "getWeatherText"], [Blockly.Msg.MIXLY_WEATHER_PHENOMENON_CODE, "getWeatherCode"], [Blockly.Msg.MIXLY_TEMPERATURE, "getDegree"]]), "type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(WEATHER_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+
+};
+
+export const weather_get_seniverse_weather_info2 = {
+ init: function () {
+ this.appendDummyInput("")
+ //.appendField("心知天气")
+ .appendField(Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST)
+ .appendField(Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_TODAY, "0"], [Blockly.Msg.MIXLY_TOMORROW, "1"], [Blockly.Msg.MIXLY_DAY_AFTER_TOMORROW, "2"]]), "date")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.ForecastHigh, "getHigh"],
+ [Blockly.Msg.ForecastLow, "getLow"],
+ [Blockly.Msg.MIXLY_DAYTIME_WEATHER_PHENOMENON, "getDayText"],
+ [Blockly.Msg.MIXLY_DAYTIME_WEATHER_PHENOMENON_CODE, "getDayCode"],
+ [Blockly.Msg.MIXLY_EVENING_WEATHER_PHENOMENON, "getNightText"],
+ [Blockly.Msg.MIXLY_EVENING_WEATHER_PHENOMENON_CODE, "getNightCode"],
+ [Blockly.Msg.MIXLY_PROBABILITY_OF_PRECIPITATION, "getRain"],
+ [Blockly.Msg.ForecastFx, "getWindDirection"],
+ [Blockly.Msg.MIXLY_WIND_SPEED, "getWindSpeed"],
+ [Blockly.Msg.MIXLY_WIND_RATING, "getWindScale"],
+ [Blockly.Msg.MIXLY_Humidity, "getHumidity"]
+ ]), "type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(WEATHER_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const weather_get_seniverse_weather_info3 = {
+ init: function () {
+ this.appendDummyInput("")
+ //.appendField("心知天气")
+ .appendField(Blockly.Msg.MIXLY_6_LIFE_INDEXES)
+ .appendField(Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_CAR_WASH_INDEX, "getCarWash"],
+ [Blockly.Msg.MIXLY_DRESSING_INDEX, "getDressing"],
+ [Blockly.Msg.MIXLY_COLD_INDEX, "getFactorFlu"],
+ [Blockly.Msg.MIXLY_MOVEMENT_INDEX, "getExercise"],
+ [Blockly.Msg.MIXLY_TOURISM_INDEX, "getTravel"],
+ [Blockly.Msg.MIXLY_UV_INDEX, "getUV"]]
+ ), "type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(WEATHER_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/blocks/procedures.js b/mixly/boards/default_src/arduino/blocks/procedures.js
new file mode 100644
index 00000000..68efecff
--- /dev/null
+++ b/mixly/boards/default_src/arduino/blocks/procedures.js
@@ -0,0 +1,1314 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Procedure blocks for Blockly.
+ * @author fraser@google.com (Neil Fraser)
+ */
+
+import * as Blockly from 'blockly/core';
+import { Variables, Procedures } from 'blockly/core';
+
+/**
+ * Common HSV hue for all blocks in this category.
+ */
+const PROCEDURES_HUE = 290;
+
+export const procedures_defnoreturn = {
+ /**
+ * Block for defining a procedure with no return value.
+ * @this {Blockly.Block}
+ */
+ init: function () {
+ var initName = Procedures.findLegalName('', this);
+ var nameField = new Blockly.FieldTextInput(initName,
+ Procedures.rename);
+ nameField.setSpellcheck(false);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg['PROCEDURES_DEFNORETURN_TITLE'])
+ .appendField(nameField, 'NAME')
+ .appendField('', 'PARAMS');
+ this.setMutator(new Blockly.icons.MutatorIcon(['procedures_mutatorarg'], this));
+ if ((this.workspace.options.comments ||
+ (this.workspace.options.parentWorkspace &&
+ this.workspace.options.parentWorkspace.options.comments)) &&
+ Blockly.Msg['PROCEDURES_DEFNORETURN_COMMENT']) {
+ this.setCommentText(Blockly.Msg['PROCEDURES_DEFNORETURN_COMMENT']);
+ }
+ this.setStyle('procedure_blocks');
+ this.setTooltip(Blockly.Msg['PROCEDURES_DEFNORETURN_TOOLTIP']);
+ this.setHelpUrl(Blockly.Msg['PROCEDURES_DEFNORETURN_HELPURL']);
+ this.arguments_ = [];
+ this.argumentstype_ = [];//新增
+ this.argumentVarModels_ = [];
+ this.setStatements_(true);
+ this.statementConnection_ = null;
+ },
+ /**
+ * Add or remove the statement block from this function definition.
+ * @param {boolean} hasStatements True if a statement block is needed.
+ * @this {Blockly.Block}
+ */
+ setStatements_: function (hasStatements) {
+ if (this.hasStatements_ === hasStatements) {
+ return;
+ }
+ if (hasStatements) {
+ this.appendStatementInput('STACK')
+ .appendField(Blockly.Msg['PROCEDURES_DEFNORETURN_DO']);
+ if (this.getInput('RETURN')) {
+ this.moveInputBefore('STACK', 'RETURN');
+ }
+ } else {
+ this.removeInput('STACK', true);
+ }
+ this.hasStatements_ = hasStatements;
+ },
+ /**
+ * Update the display of parameters for this procedure definition block.
+ * @private
+ * @this {Blockly.Block}
+ */
+ updateParams_: function () {
+
+ // Merge the arguments into a human-readable list.
+ var paramString = '';
+ if (this.arguments_.length) {
+ paramString = Blockly.Msg['PROCEDURES_BEFORE_PARAMS'] +
+ ' ' + this.arguments_.join(', ');
+ }
+ // The params field is deterministic based on the mutation,
+ // no need to fire a change event.
+ Blockly.Events.disable();
+ try {
+ this.setFieldValue(paramString, 'PARAMS');
+ } finally {
+ Blockly.Events.enable();
+ }
+ },
+ /**
+ * Create XML to represent the argument inputs.
+ * @param {boolean=} opt_paramIds If true include the IDs of the parameter
+ * quarks. Used by Procedures.mutateCallers for reconnection.
+ * @return {!Element} XML storage element.
+ * @this {Blockly.Block}
+ */
+ mutationToDom: function (opt_paramIds) {
+ var container = Blockly.utils.xml.createElement('mutation');
+ if (opt_paramIds) {
+ container.setAttribute('name', this.getFieldValue('NAME'));
+ }
+ for (var i = 0; i < this.argumentVarModels_.length; i++) {
+ var parameter = Blockly.utils.xml.createElement('arg');
+ var argModel = this.argumentVarModels_[i];
+ parameter.setAttribute('name', argModel.name);
+ parameter.setAttribute('varid', argModel.getId());
+ parameter.setAttribute('vartype', this.argumentstype_[i]);
+ if (opt_paramIds && this.paramIds_) {
+ parameter.setAttribute('paramId', this.paramIds_[i]);
+ }
+ container.appendChild(parameter);
+ }
+
+ // Save whether the statement input is visible.
+ if (!this.hasStatements_) {
+ container.setAttribute('statements', 'false');
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the argument inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this {Blockly.Block}
+ */
+ domToMutation: function (xmlElement) {
+ this.arguments_ = [];
+ this.argumentstype_ = [];//新增
+ this.argumentVarModels_ = [];
+ for (var i = 0, childNode; (childNode = xmlElement.childNodes[i]); i++) {
+ if (childNode.nodeName.toLowerCase() == 'arg') {
+ var varName = childNode.getAttribute('name');
+ var varId = childNode.getAttribute('varid') || childNode.getAttribute('varId');
+ var varType = childNode.getAttribute('vartype') || childNode.getAttribute('varType'); //新增
+ this.arguments_.push(varName);
+ this.argumentstype_.push(varType); //新增
+ var variable = Variables.getOrCreateVariablePackage(
+ this.workspace, varId, varName, '');
+ if (variable != null) {
+ this.argumentVarModels_.push(variable);
+ } else {
+ console.log('Failed to create a variable with name ' + varName + ', ignoring.');
+ }
+ }
+ }
+ this.updateParams_();
+ Procedures.mutateCallers(this);
+
+ // Show or hide the statement input.
+ this.setStatements_(xmlElement.getAttribute('statements') !== 'false');
+ },
+ /**
+ * Returns the state of this block as a JSON serializable object.
+ *
+ * @returns The state of this block, eg the parameters and statements.
+ */
+ saveExtraState: function () {
+ if (!this.argumentVarModels_.length && this.hasStatements_) {
+ return null;
+ }
+ const state = Object.create(null);
+ if (this.argumentVarModels_.length) {
+ state['params'] = [];
+ for (let i = 0; i < this.argumentVarModels_.length; i++) {
+ state['params'].push({
+ // We don't need to serialize the name, but just in case we decide
+ // to separate params from variables.
+ 'name': this.argumentVarModels_[i].name,
+ 'id': this.argumentVarModels_[i].getId(),
+ 'type': this.argumentstype_[i],
+ });
+ }
+ }
+ if (!this.hasStatements_) {
+ state['hasStatements'] = false;
+ }
+ return state;
+ },
+ /**
+ * Applies the given state to this block.
+ *
+ * @param state The state to apply to this block, eg the parameters
+ * and statements.
+ */
+ loadExtraState: function (state) {
+ this.arguments_ = [];
+ this.argumentstype_ = [];
+ this.argumentVarModels_ = [];
+ if (state['params']) {
+ for (let i = 0; i < state['params'].length; i++) {
+ const param = state['params'][i];
+ const variable = Variables.getOrCreateVariablePackage(
+ this.workspace,
+ param['id'],
+ param['name'],
+ '',
+ );
+ this.arguments_.push(variable.name);
+ this.argumentstype_.push(param['type']);
+ this.argumentVarModels_.push(variable);
+ }
+ }
+ this.updateParams_();
+ Procedures.mutateCallers(this);
+ this.setStatements_(state['hasStatements'] !== false);
+ },
+ /**
+ * 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) {
+ /*
+ * Creates the following XML:
+ *
+ *
+ *
+ * arg1_name
+ * etc...
+ *
+ *
+ *
+ */
+
+ var containerBlockNode = Blockly.utils.xml.createElement('block');
+ containerBlockNode.setAttribute('type', 'procedures_mutatorcontainer');
+ var statementNode = Blockly.utils.xml.createElement('statement');
+ statementNode.setAttribute('name', 'STACK');
+ containerBlockNode.appendChild(statementNode);
+
+ var node = statementNode;
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var argBlockNode = Blockly.utils.xml.createElement('block');
+ argBlockNode.setAttribute('type', 'procedures_mutatorarg');
+ var fieldNode = Blockly.utils.xml.createElement('field');
+ fieldNode.setAttribute('name', 'NAME');
+ var argumentName = Blockly.utils.xml.createTextNode(this.arguments_[i]);
+ fieldNode.appendChild(argumentName);
+ argBlockNode.appendChild(fieldNode);
+
+ var fieldNode1 = Blockly.utils.xml.createElement('field');
+ fieldNode1.setAttribute('name', 'TYPEVAR');
+ var argumentName1 = Blockly.utils.xml.createTextNode(this.argumentstype_[i]);
+ fieldNode1.appendChild(argumentName1);
+ argBlockNode.appendChild(fieldNode1);
+
+ var nextNode = Blockly.utils.xml.createElement('next');
+ argBlockNode.appendChild(nextNode);
+
+ node.appendChild(argBlockNode);
+ node = nextNode;
+ }
+
+ var containerBlock = Blockly.Xml.domToBlock(containerBlockNode, workspace);
+
+ if (this.type == 'procedures_defreturn') {
+ containerBlock.setFieldValue(this.hasStatements_, 'STATEMENTS');
+ } else {
+ containerBlock.removeInput('STATEMENT_INPUT');
+ }
+
+ // Initialize procedure's callers with blank IDs.
+ Procedures.mutateCallers(this);
+ 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) {
+ // Parameter list.
+ this.arguments_ = [];
+ this.argumentstype_ = [];//新增
+ this.paramIds_ = [];
+ this.argumentVarModels_ = [];
+ var paramBlock = containerBlock.getInputTargetBlock('STACK');
+ while (paramBlock && !paramBlock.isInsertionMarker()) {
+ var varName = paramBlock.getFieldValue('NAME');
+ this.arguments_.push(varName);
+ var varType = paramBlock.getFieldValue('TYPEVAR');
+ this.argumentstype_.push(varType);
+ var variable = this.workspace.getVariable(varName, '');
+ this.argumentVarModels_.push(variable);
+
+ this.paramIds_.push(paramBlock.id);
+ paramBlock = paramBlock.nextConnection &&
+ paramBlock.nextConnection.targetBlock();
+ }
+ this.updateParams_();
+ Procedures.mutateCallers(this);
+
+ // Show/hide the statement input.
+ var hasStatements = containerBlock.getFieldValue('STATEMENTS');
+ if (hasStatements !== null) {
+ hasStatements = hasStatements == 'TRUE';
+ if (this.hasStatements_ != hasStatements) {
+ if (hasStatements) {
+ this.setStatements_(true);
+ // Restore the stack, if one was saved.
+ this.statementConnection_ && this.statementConnection_.reconnect(this, 'STACK');
+ this.statementConnection_ = null;
+ } else {
+ // Save the stack, then disconnect it.
+ var stackConnection = this.getInput('STACK').connection;
+ this.statementConnection_ = stackConnection.targetConnection;
+ if (this.statementConnection_) {
+ var stackBlock = stackConnection.targetBlock();
+ stackBlock.unplug();
+ stackBlock.bumpNeighbours();
+ }
+ this.setStatements_(false);
+ }
+ }
+ }
+ },
+ /**
+ * Return the signature of this procedure definition.
+ * @return {!Array} Tuple containing three elements:
+ * - the name of the defined procedure,
+ * - a list of all its arguments,
+ * - that it DOES NOT have a return value.
+ * @this {Blockly.Block}
+ */
+ getProcedureDef: function () {
+ return [this.getFieldValue('NAME'), this.arguments_, false];
+ },
+ /**
+ * Return all variables referenced by this block.
+ * @return {!Array} List of variable names.
+ * @this {Blockly.Block}
+ */
+ getVars: function () {
+ return this.arguments_;
+ },
+ /**
+ * Return all variables referenced by this block.
+ * @return {!Array} List of variable models.
+ * @this {Blockly.Block}
+ */
+ getVarModels: function () {
+ return this.argumentVarModels_;
+ },
+ /**
+ * Notification that a variable is renaming.
+ * If the ID matches one of this block's variables, rename it.
+ * @param {string} oldId ID of variable to rename.
+ * @param {string} newId ID of new variable. May be the same as oldId, but
+ * with an updated name. Guaranteed to be the same type as the old
+ * variable.
+ * @override
+ * @this {Blockly.Block}
+ */
+ renameVarById: function (oldId, newId) {
+ var oldVariable = this.workspace.getVariableById(oldId);
+ if (oldVariable.type != '') {
+ // Procedure arguments always have the empty type.
+ return;
+ }
+ var oldName = oldVariable.name;
+ var newVar = this.workspace.getVariableById(newId);
+
+ var change = false;
+ for (var i = 0; i < this.argumentVarModels_.length; i++) {
+ if (this.argumentVarModels_[i].getId() == oldId) {
+ this.arguments_[i] = newVar.name;
+ this.argumentVarModels_[i] = newVar;
+ change = true;
+ }
+ }
+ if (change) {
+ this.displayRenamedVar_(oldName, newVar.name);
+ Procedures.mutateCallers(this);
+ }
+ },
+ /**
+ * Notification that a variable is renaming but keeping the same ID. If the
+ * variable is in use on this block, rerender to show the new name.
+ * @param {!Blockly.VariableModel} variable The variable being renamed.
+ * @package
+ * @override
+ * @this {Blockly.Block}
+ */
+ updateVarName: function (variable) {
+ var newName = variable.name;
+ var change = false;
+ for (var i = 0; i < this.argumentVarModels_.length; i++) {
+ if (this.argumentVarModels_[i].getId() == variable.getId()) {
+ var oldName = this.arguments_[i];
+ this.arguments_[i] = newName;
+ change = true;
+ }
+ }
+ if (change) {
+ this.displayRenamedVar_(oldName, newName);
+ Procedures.mutateCallers(this);
+ }
+ },
+ /**
+ * Update the display to reflect a newly renamed argument.
+ * @param {string} oldName The old display name of the argument.
+ * @param {string} newName The new display name of the argument.
+ * @private
+ * @this {Blockly.Block}
+ */
+ displayRenamedVar_: function (oldName, newName) {
+ this.updateParams_();
+ const mutator = this.getIcon(Blockly.icons.MutatorIcon.TYPE);
+ // Update the mutator's variables if the mutator is open.
+ if (mutator && mutator.bubbleIsVisible()) {
+ var blocks = mutator.getWorkspace().getAllBlocks(false);
+ for (var i = 0, block; (block = blocks[i]); i++) {
+ if (block.type == 'procedures_mutatorarg' &&
+ Blockly.Names.equals(oldName, block.getFieldValue('NAME'))) {
+ block.setFieldValue(newName, 'NAME');
+ }
+ }
+ }
+ },
+ /**
+ * Add custom menu options to this block's context menu.
+ * @param {!Array} options List of menu options to add to.
+ * @this {Blockly.Block}
+ */
+ customContextMenu: function (options) {
+ if (this.isInFlyout) {
+ return;
+ }
+ // Add option to create caller.
+ var option = { enabled: true };
+ var name = this.getFieldValue('NAME');
+ option.text = Blockly.Msg['PROCEDURES_CREATE_DO'].replace('%1', name);
+ var xmlMutation = Blockly.utils.xml.createElement('mutation');
+ xmlMutation.setAttribute('name', name);
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var xmlArg = Blockly.utils.xml.createElement('arg');
+ xmlArg.setAttribute('name', this.arguments_[i]);
+ //xmlArg.setAttribute('vartype', this.argumentstype_[i]);
+ xmlMutation.appendChild(xmlArg);
+ }
+ var xmlBlock = Blockly.utils.xml.createElement('block');
+ xmlBlock.setAttribute('type', this.callType_);
+ xmlBlock.appendChild(xmlMutation);
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+
+ // Add options to create getters for each parameter.
+ if (!this.isCollapsed()) {
+ for (var i = 0; i < this.argumentVarModels_.length; i++) {
+ var argOption = { enabled: true };
+ var argVar = this.argumentVarModels_[i];
+ argOption.text = Blockly.Msg['VARIABLES_SET_CREATE_GET']
+ .replace('%1', argVar.name);
+
+ var argXmlField = Variables.generateVariableFieldDom(argVar);
+ var argXmlBlock = Blockly.utils.xml.createElement('block');
+ argXmlBlock.setAttribute('type', 'variables_get');
+ argXmlBlock.appendChild(argXmlField);
+ argOption.callback =
+ Blockly.ContextMenu.callbackFactory(this, argXmlBlock);
+ options.push(argOption);
+ }
+ }
+ },
+ callType_: 'procedures_callnoreturn'
+};
+
+export const procedures_defreturn = {
+ /**
+ * Block for defining a procedure with a return value.
+ * @this {Blockly.Block}
+ */
+ init: function () {
+ var initName = Procedures.findLegalName('', this);
+ var nameField = new Blockly.FieldTextInput(initName,
+ Procedures.rename);
+ nameField.setSpellcheck(false);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg['PROCEDURES_DEFRETURN_TITLE'])
+ .appendField(nameField, 'NAME')
+ .appendField('', 'PARAMS');
+ this.appendValueInput('RETURN')
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg['PROCEDURES_DEFRETURN_RETURN'])
+ .appendField(new Blockly.FieldDropdown(Procedures.DATA_TYPE, this.adjustReturnInput.bind(this)), "TYPE");
+ this.setMutator(new Blockly.icons.MutatorIcon(['procedures_mutatorarg'], this));
+ if ((this.workspace.options.comments ||
+ (this.workspace.options.parentWorkspace &&
+ this.workspace.options.parentWorkspace.options.comments)) &&
+ Blockly.Msg['PROCEDURES_DEFRETURN_COMMENT']) {
+ this.setCommentText(Blockly.Msg['PROCEDURES_DEFRETURN_COMMENT']);
+ }
+ this.setStyle('procedure_blocks');
+ this.setTooltip(Blockly.Msg['PROCEDURES_DEFRETURN_TOOLTIP']);
+ this.setHelpUrl(Blockly.Msg['PROCEDURES_DEFRETURN_HELPURL']);
+ this.arguments_ = [];
+ this.argumentVarModels_ = [];
+ this.setStatements_(true);
+ this.statementConnection_ = null;
+ this.returnType = 'void';
+ },
+ adjustReturnInput: function (value) {
+ const fieldName = 'RETRUN_TYPE';
+ if (value === 'CUSTOM') {
+ if (!this.getField(fieldName)) {
+ this.getInput('RETURN').appendField(
+ new Blockly.FieldTextInput(this.returnType ?? ''),
+ fieldName,
+ );
+ }
+ } else {
+ if (this.getField('RETRUN_TYPE')) {
+ this.returnType = this.getFieldValue('RETRUN_TYPE') || 'void';
+ }
+ this.getInput('RETURN').removeField(fieldName, true);
+ }
+ },
+ setStatements_: procedures_defnoreturn.setStatements_,
+ updateParams_: procedures_defnoreturn.updateParams_,
+ mutationToDom: procedures_defnoreturn.mutationToDom,
+ domToMutation: procedures_defnoreturn.domToMutation,
+ saveExtraState: function () {
+ const output = procedures_defnoreturn.saveExtraState.call(this) ?? {};
+ if (this.getField('RETRUN_TYPE')) {
+ output['returnType'] = this.getFieldValue('RETRUN_TYPE');
+ }
+ return output;
+ },
+ loadExtraState: function (state) {
+ this.returnType = state?.returnType;
+ if (!this.getField('RETRUN_TYPE')) {
+ this.getInput('RETURN').appendField(
+ new Blockly.FieldTextInput(this.returnType ?? ''),
+ 'RETRUN_TYPE',
+ );
+ }
+ procedures_defnoreturn.loadExtraState.call(this, state);
+ },
+ decompose: procedures_defnoreturn.decompose,
+ compose: procedures_defnoreturn.compose,
+ /**
+ * Return the signature of this procedure definition.
+ * @return {!Array} Tuple containing three elements:
+ * - the name of the defined procedure,
+ * - a list of all its arguments,
+ * - that it DOES have a return value.
+ * @this {Blockly.Block}
+ */
+ getProcedureDef: function () {
+ return [this.getFieldValue('NAME'), this.arguments_, true];
+ },
+ getVars: procedures_defnoreturn.getVars,
+ getVarModels: procedures_defnoreturn.getVarModels,
+ renameVarById: procedures_defnoreturn.renameVarById,
+ updateVarName: procedures_defnoreturn.updateVarName,
+ displayRenamedVar_: procedures_defnoreturn.displayRenamedVar_,
+ customContextMenu: procedures_defnoreturn.customContextMenu,
+ callType_: 'procedures_callreturn'
+};
+
+export const procedures_mutatorcontainer = {
+ /**
+ * Mutator block for procedure container.
+ * @this {Blockly.Block}
+ */
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg['PROCEDURES_MUTATORCONTAINER_TITLE']);
+ this.appendStatementInput('STACK');
+ this.appendDummyInput('STATEMENT_INPUT')
+ .appendField(Blockly.Msg['PROCEDURES_ALLOW_STATEMENTS'])
+ .appendField(new Blockly.FieldCheckbox('TRUE'), 'STATEMENTS');
+ this.setStyle('procedure_blocks');
+ this.setTooltip(Blockly.Msg['PROCEDURES_MUTATORCONTAINER_TOOLTIP']);
+ this.contextMenu = false;
+ },
+};
+
+export const procedures_mutatorarg = {
+ /**
+ * Mutator block for procedure argument.
+ * @this {Blockly.Block}
+ */
+ init: function () {
+ var field = new Blockly.FieldTextInput(
+ Procedures.DEFAULT_ARG, this.validator_);
+ // Hack: override showEditor to do just a little bit more work.
+ // We don't have a good place to hook into the start of a text edit.
+ field.oldShowEditorFn_ = field.showEditor_;
+ var newShowEditorFn = function () {
+ this.createdVariables_ = [];
+ this.oldShowEditorFn_();
+ };
+ field.showEditor_ = newShowEditorFn;
+
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.PROCEDURES_BEFORE_PARAMS)
+ .appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), "TYPEVAR")
+ .appendField(field, 'NAME');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setStyle('procedure_blocks');
+ this.setTooltip(Blockly.Msg['PROCEDURES_MUTATORARG_TOOLTIP']);
+ this.contextMenu = false;
+
+ // Create the default variable when we drag the block in from the flyout.
+ // Have to do this after installing the field on the block.
+ field.onFinishEditing_ = this.deleteIntermediateVars_;
+ // Create an empty list so onFinishEditing_ has something to look at, even
+ // though the editor was never opened.
+ field.createdVariables_ = [];
+ field.onFinishEditing_('x');
+ },
+ /**
+ * Obtain a valid name for the procedure argument. Create a variable if
+ * necessary.
+ * Merge runs of whitespace. Strip leading and trailing whitespace.
+ * Beyond this, all names are legal.
+ * @param {string} varName User-supplied name.
+ * @return {?string} Valid name, or null if a name was not specified.
+ * @private
+ * @this Blockly.FieldTextInput
+ */
+ validator_: function (varName) {
+ var sourceBlock = this.getSourceBlock();
+ var outerWs = sourceBlock.workspace.getRootWorkspace();
+ varName = varName.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
+ if (!varName) {
+ return null;
+ }
+
+ // Prevents duplicate parameter names in functions
+ var workspace = sourceBlock.workspace.targetWorkspace ||
+ sourceBlock.workspace;
+ var blocks = workspace.getAllBlocks(false);
+ var caselessName = varName.toLowerCase();
+ for (var i = 0; i < blocks.length; i++) {
+ if (blocks[i].id == this.getSourceBlock().id) {
+ continue;
+ }
+ // Other blocks values may not be set yet when this is loaded.
+ var otherVar = blocks[i].getFieldValue('NAME');
+ if (otherVar && otherVar.toLowerCase() == caselessName) {
+ return null;
+ }
+ }
+
+ // Don't create variables for arg blocks that
+ // only exist in the mutator's flyout.
+ if (sourceBlock.isInFlyout) {
+ return varName;
+ }
+
+ var model = outerWs.getVariable(varName, '');
+ if (model && model.name != varName) {
+ // Rename the variable (case change)
+ outerWs.renameVariableById(model.getId(), varName);
+ }
+ if (!model) {
+ model = outerWs.createVariable(varName, '');
+ if (model && this.createdVariables_) {
+ this.createdVariables_.push(model);
+ }
+ }
+ return varName;
+ },
+
+ /**
+ * Called when focusing away from the text field.
+ * Deletes all variables that were created as the user typed their intended
+ * variable name.
+ * @param {string} newText The new variable name.
+ * @private
+ * @this Blockly.FieldTextInput
+ */
+ deleteIntermediateVars_: function (newText) {
+ var outerWs = this.getSourceBlock().workspace.getRootWorkspace();
+ if (!outerWs) {
+ return;
+ }
+ for (var i = 0; i < this.createdVariables_.length; i++) {
+ var model = this.createdVariables_[i];
+ if (model.name != newText) {
+ outerWs.deleteVariableById(model.getId());
+ }
+ }
+ }
+};
+
+export const procedures_callnoreturn = {
+ /**
+ * Block for calling a procedure with no return value.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);
+ this.setColour(PROCEDURES_HUE);
+ this.appendDummyInput('TOPROW')
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO)
+ .appendField(this.id, 'NAME');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ // Tooltip is set in renameProcedure.
+ this.arguments_ = [];
+ this.quarkConnections_ = {};
+ this.quarkIds_ = null;
+ },
+ /**
+ * Returns the name of the procedure this block calls.
+ * @return {string} Procedure name.
+ * @this {Blockly.Block}
+ */
+ getProcedureCall: function () {
+ // The NAME field is guaranteed to exist, null will never be returned.
+ return /** @type {string} */ (this.getFieldValue('NAME'));
+ },
+ /**
+ * Notification that a procedure is renaming.
+ * If the name matches this block's procedure, rename it.
+ * @param {string} oldName Previous name of procedure.
+ * @param {string} newName Renamed procedure.
+ * @this {Blockly.Block}
+ */
+ renameProcedure: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getProcedureCall())) {
+ this.setFieldValue(newName, 'NAME');
+ var baseMsg = this.outputConnection ?
+ Blockly.Msg['PROCEDURES_CALLRETURN_TOOLTIP'] :
+ Blockly.Msg['PROCEDURES_CALLNORETURN_TOOLTIP'];
+ this.setTooltip(baseMsg.replace('%1', newName));
+ }
+ },
+ /**
+ * Notification that the procedure's parameters have changed.
+ * @param {!Array} paramNames New param names, e.g. ['x', 'y', 'z'].
+ * @param {!Array} paramIds IDs of params (consistent for each
+ * parameter through the life of a mutator, regardless of param renaming),
+ * e.g. ['piua', 'f8b_', 'oi.o'].
+ * @private
+ * @this {Blockly.Block}
+ */
+ setProcedureParameters_: function (paramNames, paramIds) {
+ // Data structures:
+ // this.arguments = ['x', 'y']
+ // Existing param names.
+ // this.quarkConnections_ {piua: null, f8b_: Connection}
+ // Look-up of paramIds to connections plugged into the call block.
+ // this.quarkIds_ = ['piua', 'f8b_']
+ // Existing param IDs.
+ // Note that quarkConnections_ may include IDs that no longer exist, but
+ // which might reappear if a param is reattached in the mutator.
+ const defBlock = Procedures.getDefinition(
+ this.getProcedureCall(),
+ this.workspace,
+ );
+ const mutatorIcon = defBlock && defBlock.getIcon(Blockly.icons.MutatorIcon.TYPE);
+ const mutatorOpen = mutatorIcon && mutatorIcon.bubbleIsVisible();
+ if (!mutatorOpen) {
+ this.quarkConnections_ = {};
+ this.quarkIds_ = null;
+ } else {
+ // fix #6091 - this call could cause an error when outside if-else
+ // expanding block while mutating prevents another error (ancient fix)
+ this.setCollapsed(false);
+ }
+ // Test arguments (arrays of strings) for changes. '\n' is not a valid
+ // argument name character, so it is a valid delimiter here.
+ if (paramNames.join('\n') === this.arguments_.join('\n')) {
+ // No change.
+ this.quarkIds_ = paramIds;
+ return;
+ }
+ if (paramIds.length !== paramNames.length) {
+ throw Error('paramNames and paramIds must be the same length.');
+ }
+ if (!this.quarkIds_) {
+ // Initialize tracking for this block.
+ this.quarkConnections_ = {};
+ this.quarkIds_ = [];
+ }
+ // Update the quarkConnections_ with existing connections.
+ for (let i = 0; i < this.arguments_.length; i++) {
+ const input = this.getInput('ARG' + i);
+ if (input) {
+ const connection = input?.connection?.targetConnection;
+ this.quarkConnections_[this.quarkIds_[i]] = connection;
+ if (
+ mutatorOpen &&
+ connection &&
+ !paramIds.includes(this.quarkIds_[i])
+ ) {
+ // This connection should no longer be attached to this block.
+ connection.disconnect();
+ connection.getSourceBlock().bumpNeighbours();
+ }
+ }
+ }
+ // Rebuild the block's arguments.
+ this.arguments_ = [].concat(paramNames);
+ // And rebuild the argument model list.
+ this.argumentVarModels_ = [];
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var variable = Blockly.Variables.getOrCreateVariablePackage(
+ this.workspace, null, this.arguments_[i], '');
+ this.argumentVarModels_.push(variable);
+ }
+
+ this.updateShape_();
+ this.quarkIds_ = paramIds;
+ // Reconnect any child blocks.
+ if (this.quarkIds_) {
+ for (let i = 0; i < this.arguments_.length; i++) {
+ const quarkId = this.quarkIds_[i]; // TODO(#6920)
+ if (quarkId in this.quarkConnections_) {
+ // TODO(#6920): investigate claimed circular initialisers.
+ const connection = this.quarkConnections_[quarkId];
+ if (!connection?.reconnect(this, 'ARG' + i)) {
+ // Block no longer exists or has been attached elsewhere.
+ delete this.quarkConnections_[quarkId];
+ }
+ }
+ }
+ }
+ },
+ /**
+ * Modify this block to have the correct number of arguments.
+ * @private
+ * @this {Blockly.Block}
+ */
+ updateShape_: function () {
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var field = this.getField('ARGNAME' + i);
+ if (field) {
+ // Ensure argument name is up to date.
+ // The argument name field is deterministic based on the mutation,
+ // no need to fire a change event.
+ Blockly.Events.disable();
+ try {
+ field.setValue(this.arguments_[i]);
+ } finally {
+ Blockly.Events.enable();
+ }
+ } else {
+ // Add new input.
+ field = new Blockly.FieldLabel(this.arguments_[i]);
+ var input = this.appendValueInput('ARG' + i)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(field, 'ARGNAME' + i);
+ input.init();
+ }
+ }
+ // Remove deleted inputs.
+ while (this.getInput('ARG' + i)) {
+ this.removeInput('ARG' + i);
+ i++;
+ }
+ // Add 'with:' if there are parameters, remove otherwise.
+ var topRow = this.getInput('TOPROW');
+ if (topRow) {
+ if (this.arguments_.length) {
+ if (!this.getField('WITH')) {
+ topRow.appendField(Blockly.Msg['PROCEDURES_CALL_BEFORE_PARAMS'], 'WITH');
+ topRow.init();
+ }
+ } else {
+ if (this.getField('WITH')) {
+ topRow.removeField('WITH');
+ }
+ }
+ }
+ },
+ /**
+ * Create XML to represent the (non-editable) name and arguments.
+ * @return {!Element} XML storage element.
+ * @this {Blockly.Block}
+ */
+ mutationToDom: function () {
+ var container = Blockly.utils.xml.createElement('mutation');
+ container.setAttribute('name', this.getProcedureCall());
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var parameter = Blockly.utils.xml.createElement('arg');
+ parameter.setAttribute('name', this.arguments_[i]);
+ container.appendChild(parameter);
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the (non-editable) name and parameters.
+ * @param {!Element} xmlElement XML storage element.
+ * @this {Blockly.Block}
+ */
+ domToMutation: function (xmlElement) {
+ var name = xmlElement.getAttribute('name');
+ this.renameProcedure(this.getProcedureCall(), name);
+ var args = [];
+ var paramIds = [];
+ for (var i = 0, childNode; (childNode = xmlElement.childNodes[i]); i++) {
+ if (childNode.nodeName.toLowerCase() == 'arg') {
+ args.push(childNode.getAttribute('name'));
+ paramIds.push(childNode.getAttribute('paramId'));
+ }
+ }
+ this.setProcedureParameters_(args, paramIds);
+ },
+ /**
+ * Returns the state of this block as a JSON serializable object.
+ *
+ * @returns The state of this block, ie the params and procedure name.
+ */
+ saveExtraState: function () {
+ const state = Object.create(null);
+ state['name'] = this.getProcedureCall();
+ if (this.arguments_.length) {
+ state['params'] = this.arguments_;
+ }
+ return state;
+ },
+ /**
+ * Applies the given state to this block.
+ *
+ * @param state The state to apply to this block, ie the params and
+ * procedure name.
+ */
+ loadExtraState: function (state) {
+ this.renameProcedure(this.getProcedureCall(), state['name']);
+ const params = state['params'];
+ if (params) {
+ const ids = [];
+ ids.length = params.length;
+ ids.fill(null); // TODO(#6920)
+ this.setProcedureParameters_(params, ids);
+ }
+ },
+ /**
+ * Return all variables referenced by this block.
+ * @return {!Array} List of variable names.
+ * @this {Blockly.Block}
+ */
+ getVars: function () {
+ return this.arguments_;
+ },
+ /**
+ * Return all variables referenced by this block.
+ * @return {!Array} List of variable models.
+ * @this {Blockly.Block}
+ */
+ getVarModels: function () {
+ return this.argumentVarModels_;
+ },
+ /**
+ * Procedure calls cannot exist without the corresponding procedure
+ * definition. Enforce this link whenever an event is fired.
+ * @param {!Blockly.Events.Abstract} event Change event.
+ * @this {Blockly.Block}
+ */
+ onchange: function (event) {
+ if (!this.workspace || this.workspace.isFlyout) {
+ // Block is deleted or is in a flyout.
+ return;
+ }
+ if (!event.recordUndo) {
+ // Events not generated by user. Skip handling.
+ return;
+ }
+ if (event.type == Blockly.Events.BLOCK_CREATE &&
+ event.ids.indexOf(this.id) != -1) {
+ // Look for the case where a procedure call was created (usually through
+ // paste) and there is no matching definition. In this case, create
+ // an empty definition block with the correct signature.
+ var name = this.getProcedureCall();
+ var def = Procedures.getDefinition(name, this.workspace);
+ if (def && (def.type != this.defType_)) {
+ // The signatures don't match.
+ def = null;
+ }
+ if (!def) {
+ Blockly.Events.setGroup(event.group);
+ /**
+ * Create matching definition block.
+ *
+ *
+ *
+ *
+ *
+ * test
+ *
+ *
+ */
+ var xml = Blockly.utils.xml.createElement('xml');
+ var block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', this.defType_);
+ var xy = this.getRelativeToSurfaceXY();
+ var x = xy.x + Blockly.SNAP_RADIUS * (this.RTL ? -1 : 1);
+ var y = xy.y + Blockly.SNAP_RADIUS * 2;
+ block.setAttribute('x', x);
+ block.setAttribute('y', y);
+ var mutation = this.mutationToDom();
+ block.appendChild(mutation);
+ var field = Blockly.utils.xml.createElement('field');
+ field.setAttribute('name', 'NAME');
+ var callName = this.getProcedureCall();
+ if (!callName) {
+ // Rename if name is empty string.
+ callName = Procedures.findLegalName('', this);
+ this.renameProcedure('', callName);
+ }
+ field.appendChild(Blockly.utils.xml.createTextNode(callName));
+ block.appendChild(field);
+ xml.appendChild(block);
+ Blockly.Xml.domToWorkspace(xml, this.workspace);
+ Blockly.Events.setGroup(false);
+ } else {
+ if (JSON.stringify(def.getVars()) != JSON.stringify(this.arguments_)) {
+ let paramNames = def.arguments_;
+ let paramIds = [];
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var input = this.getInput('ARG' + i);
+ if (!input) {
+ continue;
+ }
+ var connection = input.connection.targetConnection;
+ if (!connection) {
+ paramIds.push(null);
+ continue;
+ }
+ paramIds.push(connection.sourceBlock_.id);
+ }
+ this.setProcedureParameters_(paramNames, paramIds);
+ }
+ }
+ } else if (event.type == Blockly.Events.BLOCK_DELETE) {
+ // Look for the case where a procedure definition has been deleted,
+ // leaving this block (a procedure call) orphaned. In this case, delete
+ // the orphan.
+ var name = this.getProcedureCall();
+ var def = Procedures.getDefinition(name, this.workspace);
+ if (!def) {
+ Blockly.Events.setGroup(event.group);
+ this.dispose(true);
+ Blockly.Events.setGroup(false);
+ }
+ } else if (event.type == Blockly.Events.CHANGE && event.element == 'disabled') {
+ var name = this.getProcedureCall();
+ var def = Procedures.getDefinition(name, this.workspace);
+ if (def && def.id == event.blockId) {
+ // in most cases the old group should be ''
+ var oldGroup = Blockly.Events.getGroup();
+ if (oldGroup) {
+ // This should only be possible programmatically and may indicate a problem
+ // with event grouping. If you see this message please investigate. If the
+ // use ends up being valid we may need to reorder events in the undo stack.
+ console.log('Saw an existing group while responding to a definition change');
+ }
+ Blockly.Events.setGroup(event.group);
+ if (event.newValue) {
+ this.previousEnabledState_ = this.isEnabled();
+ this.setEnabled(false);
+ } else {
+ this.setEnabled(this.previousEnabledState_);
+ }
+ Blockly.Events.setGroup(oldGroup);
+ }
+ }
+ },
+ /**
+ * Add menu option to find the definition block for this call.
+ * @param {!Array} options List of menu options to add to.
+ * @this {Blockly.Block}
+ */
+ customContextMenu: function (options) {
+ if (!this.workspace.isMovable()) {
+ // If we center on the block and the workspace isn't movable we could
+ // loose blocks at the edges of the workspace.
+ return;
+ }
+
+ var option = { enabled: true };
+ option.text = Blockly.Msg['PROCEDURES_HIGHLIGHT_DEF'];
+ var name = this.getProcedureCall();
+ var workspace = this.workspace;
+ option.callback = function () {
+ var def = Procedures.getDefinition(name, workspace);
+ if (def) {
+ workspace.centerOnBlock(def.id);
+ def.select();
+ }
+ };
+ options.push(option);
+ },
+ defType_: 'procedures_defnoreturn'
+};
+
+export const procedures_callreturn = {
+ /**
+ * Block for calling a procedure with a return value.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);
+ this.setColour(PROCEDURES_HUE);
+ this.appendDummyInput('TOPROW')
+ .appendField(Blockly.Msg.PROCEDURES_CALLRETURN_CALL)
+ .appendField('', 'NAME');
+ this.setOutput(true);
+ // Tooltip is set in domToMutation.
+ this.arguments_ = [];
+ this.quarkConnections_ = {};
+ this.quarkIds_ = null;
+ },
+ getProcedureCall: procedures_callnoreturn.getProcedureCall,
+ renameProcedure: procedures_callnoreturn.renameProcedure,
+ setProcedureParameters_:
+ procedures_callnoreturn.setProcedureParameters_,
+ updateShape_: procedures_callnoreturn.updateShape_,
+ mutationToDom: procedures_callnoreturn.mutationToDom,
+ domToMutation: procedures_callnoreturn.domToMutation,
+ saveExtraState: procedures_callnoreturn.saveExtraState,
+ loadExtraState: procedures_callnoreturn.loadExtraState,
+ renameVar: procedures_callnoreturn.renameVar,
+ getVars: procedures_callnoreturn.getVars,
+ getVarModels: procedures_callnoreturn.getVarModels,
+ onchange: procedures_callnoreturn.onchange,
+ customContextMenu: procedures_callnoreturn.customContextMenu,
+ defType_: 'procedures_defreturn'
+};
+
+export const procedures_ifreturn = {
+ /**
+ * Block for conditionally returning a value from a procedure.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(PROCEDURES_HUE);
+ this.appendValueInput('CONDITION')
+ .setCheck(Boolean)
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
+ this.appendValueInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);
+ this.hasReturnValue_ = true;
+ },
+ /**
+ * Create XML to represent whether this block has a return value.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = document.createElement('mutation');
+ container.setAttribute('value', Number(this.hasReturnValue_));
+ return container;
+ },
+ /**
+ * Parse XML to restore whether this block has a return value.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ var value = xmlElement.getAttribute('value');
+ this.hasReturnValue_ = (value == 1);
+ if (!this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendDummyInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ }
+ },
+ /**
+ * Called whenever anything on the workspace changes.
+ * Add warning if this flow block is not nested inside a loop.
+ * @param {!Blockly.Events.Abstract} e Change event.
+ * @this Blockly.Block
+ */
+ onchange: function () {
+ var legal = false;
+ // Is the block nested in a procedure?
+ var block = this;
+ do {
+ if (this.FUNCTION_TYPES.indexOf(block.type) != -1) {
+ legal = true;
+ break;
+ }
+ block = block.getSurroundParent();
+ } while (block);
+ if (legal) {
+ // If needed, toggle whether this block has a return value.
+ if (block.type == 'procedures_defnoreturn' && this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendDummyInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.hasReturnValue_ = false;
+ } else if (block.type == 'procedures_defreturn' &&
+ !this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendValueInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.hasReturnValue_ = true;
+ }
+ this.setWarningText(null);
+ } else {
+ this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING);
+ }
+ },
+ /**
+ * List of block types that are functions and thus do not need warnings.
+ * To add a new function type add this to your code:
+ * procedures_ifreturn.FUNCTION_TYPES.push('custom_func');
+ */
+ FUNCTION_TYPES: ['procedures_defnoreturn', 'procedures_defreturn']
+};
+
+
+export const procedures_return = {
+ /**
+ * Block for conditionally returning a value from a procedure.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(PROCEDURES_HUE);
+ // this.appendValueInput('CONDITION')
+ // .setCheck(Boolean)
+ // .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
+ this.appendValueInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip();
+ this.hasReturnValue_ = true;
+ },
+ /**
+ * Create XML to represent whether this block has a return value.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = document.createElement('mutation');
+ container.setAttribute('value', Number(this.hasReturnValue_));
+ return container;
+ },
+ /**
+ * Parse XML to restore whether this block has a return value.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ var value = xmlElement.getAttribute('value');
+ this.hasReturnValue_ = (value == 1);
+ if (!this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendDummyInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ }
+ },
+ /**
+ * Called whenever anything on the workspace changes.
+ * Add warning if this flow block is not nested inside a loop.
+ * @param {!Blockly.Events.Abstract} e Change event.
+ * @this Blockly.Block
+ */
+ onchange: function () {
+ var legal = false;
+ // Is the block nested in a procedure?
+ var block = this;
+ do {
+ if (this.FUNCTION_TYPES.indexOf(block.type) != -1) {
+ legal = true;
+ break;
+ }
+ block = block.getSurroundParent();
+ } while (block);
+ if (legal) {
+ // If needed, toggle whether this block has a return value.
+ if (block.type == 'procedures_defnoreturn' && this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendDummyInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.hasReturnValue_ = false;
+ } else if (block.type == 'procedures_defreturn' &&
+ !this.hasReturnValue_) {
+ this.removeInput('VALUE');
+ this.appendValueInput('VALUE')
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.hasReturnValue_ = true;
+ }
+ this.setWarningText(null);
+ } else {
+ this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING);
+ }
+ },
+ /**
+ * List of block types that are functions and thus do not need warnings.
+ * To add a new function type add this to your code:
+ * procedures_ifreturn.FUNCTION_TYPES.push('custom_func');
+ */
+ FUNCTION_TYPES: ['procedures_defnoreturn', 'procedures_defreturn']
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/blocks/text.js b/mixly/boards/default_src/arduino/blocks/text.js
new file mode 100644
index 00000000..f16eea02
--- /dev/null
+++ b/mixly/boards/default_src/arduino/blocks/text.js
@@ -0,0 +1,24 @@
+import * as Blockly from 'blockly/core';
+
+const TEXTS_HUE = 160;
+
+
+export const text_base64_url_codec = {
+ init: function () {
+ this.appendValueInput('VALUE')
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.LEFT)
+ .appendField(new Blockly.FieldDropdown([
+ ['Base64', 'BASE64'],
+ ['URL', 'URL']
+ ]), 'TYPE')
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXPY_TEXT_ENCODE, 'ENCODE'],
+ [Blockly.Msg.MIXPY_TEXT_DECODE, 'DECODE']
+ ]), 'OPTION');
+ this.setOutput(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip('');
+ this.setHelpUrl('');
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/blocks/variables.js b/mixly/boards/default_src/arduino/blocks/variables.js
new file mode 100644
index 00000000..77c6ca63
--- /dev/null
+++ b/mixly/boards/default_src/arduino/blocks/variables.js
@@ -0,0 +1,85 @@
+import * as Blockly from 'blockly/core';
+import { Variables } from 'blockly/core';
+
+const VARIABLES_HUE = 330;
+
+
+export const variables_declare = {
+ init: function () {
+ this.setColour(VARIABLES_HUE);
+ this.appendValueInput('VALUE', null)
+ .appendField(Blockly.Msg.MIXLY_DECLARE)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GLOBAL_VARIABLE, 'global_variate'],
+ [Blockly.Msg.MIXLY_LOCAL_VARIABLE, 'local_variate']
+ ]), 'variables_type')
+ .appendField(new Blockly.FieldTextInput('item'), 'VAR')
+ .appendField(Blockly.Msg.MIXLY_AS)
+ .appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), 'TYPE')
+ .appendField(Blockly.Msg.MIXLY_VALUE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_VARIABLES_DECLARE);
+ },
+ getVars: function () {
+ return [this.getFieldValue('VAR')];
+ },
+ renameVar: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
+ this.setFieldValue(newName, 'VAR');
+ }
+ }
+};
+
+export const variables_get = {
+ init: function () {
+ this.setColour(VARIABLES_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldTextInput('item'), 'VAR')
+ this.setOutput(true);
+ this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP);
+ },
+ getVars: function () {
+ return [this.getFieldValue('VAR')];
+ },
+ renameVar: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
+ this.setFieldValue(newName, 'VAR');
+ }
+ }
+};
+
+export const variables_set = {
+ init: function () {
+ this.setColour(VARIABLES_HUE);
+ this.appendValueInput('VALUE')
+ .appendField(new Blockly.FieldTextInput('item'), 'VAR')
+ .appendField(Blockly.Msg.MIXLY_VALUE2);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP);
+ },
+ getVars: function () {
+ return [this.getFieldValue('VAR')];
+ },
+ renameVar: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
+ this.setFieldValue(newName, 'VAR');
+ }
+ }
+};
+
+/**
+ * Block for basic data type change.
+ * @this Blockly.Block
+ */
+export const variables_change = {
+ init: function () {
+ this.setColour(VARIABLES_HUE);
+ this.appendValueInput('MYVALUE')
+ .appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), 'OP');
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ this.setOutput(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_VARIABLES_CHANGE);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/export.js b/mixly/boards/default_src/arduino/export.js
new file mode 100644
index 00000000..4a8c935e
--- /dev/null
+++ b/mixly/boards/default_src/arduino/export.js
@@ -0,0 +1,28 @@
+import * as ArduinoEthernetBlocks from './blocks/ethernet';
+import * as ArduinoProceduresBlocks from './blocks/procedures';
+import * as ArduinoTextBlocks from './blocks/text';
+import * as ArduinoVariablesBlocks from './blocks/variables';
+import * as ArduinoProceduresGenerators from './generators/procedures';
+import * as ArduinoEthernetGenerators from './generators/ethernet';
+import * as ArduinoTextGenerators from './generators/text';
+import * as ArduinoVariablesGenerators from './generators/variables';
+import Names from './others/names';
+import Procedures from './others/procedures';
+import Variables from './others/variables';
+import { ArduinoGenerator, Arduino } from './arduino_generator';
+
+export {
+ ArduinoEthernetBlocks,
+ ArduinoProceduresBlocks,
+ ArduinoTextBlocks,
+ ArduinoVariablesBlocks,
+ ArduinoEthernetGenerators,
+ ArduinoProceduresGenerators,
+ ArduinoTextGenerators,
+ ArduinoVariablesGenerators,
+ Names,
+ Procedures,
+ Variables,
+ ArduinoGenerator,
+ Arduino
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/generators/ethernet.js b/mixly/boards/default_src/arduino/generators/ethernet.js
new file mode 100644
index 00000000..242b275f
--- /dev/null
+++ b/mixly/boards/default_src/arduino/generators/ethernet.js
@@ -0,0 +1,196 @@
+import * as Blockly from 'blockly/core';
+import * as Mixly from 'mixly';
+import CITYS_DATA from '../templates/json/cities.json';
+
+
+/**
+ * @name 模块名 Http GET请求
+ * @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
+ */
+export const http_get = function () {
+ const BOARD_TYPE = Mixly.Boards.getType();
+ const API = Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
+ let branch = Blockly.Arduino.statementToCode(this, 'success') || '';
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ let branch1 = Blockly.Arduino.statementToCode(this, 'failure') || '';
+ branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
+ let code = '';
+ if (BOARD_TYPE == 'arduino_esp8266') {
+ Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include ';
+ Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include ';
+ code
+ = 'if (WiFi.status() == WL_CONNECTED) {\n'
+ + ' WiFiClient client;\n'
+ + ' HTTPClient http;\n'
+ + ' http.begin(client, ' + API + ');\n'
+ + ' int httpCode = http.GET();\n'
+ + ' if (httpCode > 0) {\n'
+ + ' String Request_result = http.getString();\n'
+ + ' ' + branch + '\n'
+ + ' } else {\n'
+ + ' ' + branch1 + '\n'
+ + ' }\n'
+ + ' http.end();\n'
+ + '}\n';
+ } else {
+ Blockly.Arduino.definitions_['include_WiFi'] = '#include ';
+ Blockly.Arduino.definitions_['include_HTTPClient'] = '#include ';
+ code
+ = 'if (WiFi.status() == WL_CONNECTED) {\n'
+ + ' HTTPClient http;\n'
+ + ' http.begin(' + API + ');\n'
+ + ' int httpCode = http.GET();\n'
+ + ' if (httpCode > 0) {\n'
+ + ' String Request_result = http.getString();\n'
+ + ' ' + branch + '\n'
+ + ' }\n'
+ + ' else {\n'
+ + ' ' + branch1 + '\n'
+ + ' }\n'
+ + ' http.end();\n'
+ + '}\n';
+ }
+ return code;
+};
+
+/**
+ * @name 模块名 Http PATCH|POST|PUT请求
+ * @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
+ */
+export const http_post = function () {
+ const BOARD_TYPE = Mixly.Boards.getType();
+ const FIELD_TYPE = this.getFieldValue("TYPE");
+ const API = Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
+ const DATA = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
+ let branch = Blockly.Arduino.statementToCode(this, 'success') || '';
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ let branch1 = Blockly.Arduino.statementToCode(this, 'failure') || '';
+ branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
+ let code = '';
+ if (BOARD_TYPE == 'arduino_esp8266') {
+ Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include ';
+ Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include ';
+ code
+ = 'if (WiFi.status() == WL_CONNECTED) {\n'
+ + ' HTTPClient http;\n'
+ + ' WiFiClient client;\n'
+ + ' http.begin(client, ' + API + ');\n'
+ + ' http.addHeader("Content-Type", "application/json");\n'
+ + ' int httpCode = http.' + FIELD_TYPE + '(' + DATA + ');\n'
+ + ' if (httpCode > 0) {\n'
+ + ' String Request_result = http.getString();\n'
+ + ' ' + branch + '\n'
+ + ' } else {\n'
+ + ' ' + branch1 + '\n'
+ + ' }\n'
+ + ' http.end();\n'
+ + '}\n';
+ } else {
+ Blockly.Arduino.definitions_['include_WiFi'] = '#include ';
+ Blockly.Arduino.definitions_['include_HTTPClient'] = '#include ';
+ code
+ = 'if (WiFi.status() == WL_CONNECTED) {\n'
+ + ' HTTPClient http;\n'
+ + ' http.begin(' + API + ');\n'
+ + ' http.addHeader("Content-Type", "application/json");\n'
+ + ' int httpCode = http.' + FIELD_TYPE + '(' + DATA + ');\n'
+ + ' if (httpCode > 0) {\n'
+ + ' String Request_result = http.getString();\n'
+ + ' ' + branch + '\n'
+ + ' }\n'
+ + ' else {\n'
+ + ' ' + branch1 + '\n'
+ + ' }\n'
+ + ' http.end();\n'
+ + '}\n';
+ }
+ return code;
+};
+
+//网络天气
+export const china_city = function () {
+ var a = this.getFieldValue("province");
+ var b = this.getFieldValue("city");
+ var code = "";
+ try {
+ code = '"' + CITYS_DATA[a][b].pinyin + '"';
+ } catch (e) {
+ console.log(e);
+ }
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
+
+export const weather_private_key = function () {
+ var a = this.getFieldValue("key");
+ var code = '"' + a + '"';
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
+
+export const weather_seniverse_city_weather = function () {
+ var api = this.getFieldValue("api");
+ var location = Blockly.Arduino.valueToCode(this, "location", Blockly.Arduino.ORDER_ATOMIC);
+ var private_key = Blockly.Arduino.valueToCode(this, "private_key", Blockly.Arduino.ORDER_ATOMIC);
+ //private_key = private_key.replace(/\"/g, "")
+ var language = this.getFieldValue("language");
+ var unit = this.getFieldValue("unit");
+
+ Blockly.Arduino.definitions_['include_ESP8266_Seniverse'] = '#include ';
+
+ Blockly.Arduino.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+
+ switch (api) {
+ case 'weather/now':
+ Blockly.Arduino.definitions_['var_declare_weatherNow'] = 'WeatherNow weatherNow;';
+ Blockly.Arduino.setups_['setup_seniverse_weatherNow'] = 'weatherNow.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
+ break;
+ case 'weather/daily':
+ Blockly.Arduino.definitions_['var_declare_forecast'] = 'Forecast forecast;';
+ Blockly.Arduino.setups_['setup_seniverse_forecast'] = 'forecast.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
+ break;
+ case 'life/suggestion':
+ default:
+ Blockly.Arduino.definitions_['var_declare_lifeInfo'] = 'LifeInfo lifeInfo;';
+ Blockly.Arduino.setups_['setup_seniverse_lifeInfo'] = 'lifeInfo.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
+ }
+ var code = '';
+
+ return code;
+};
+
+export const weather_get_seniverse_weather_info = function () {
+ var api = this.getFieldValue("api");
+ var type = this.getFieldValue("type");
+ var code = '';
+ switch (api) {
+ case 'weather/now':
+ code = 'weatherNow.' + type + '()';
+ break;
+ case 'weather/daily':
+ code = 'forecast.' + type + '()';
+ break;
+ case 'life/suggestion':
+ default:
+ code = 'lifeInfo.' + type + '()';
+ }
+
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
+
+export const weather_get_seniverse_weather_info1 = function () {
+ var type = this.getFieldValue("type");
+ var code = 'weatherNow.' + type + '()';
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
+
+export const weather_get_seniverse_weather_info2 = function () {
+ var date = this.getFieldValue("date");
+ var type = this.getFieldValue("type");
+ var code = 'forecast.' + type + '(' + date + ')';
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
+
+export const weather_get_seniverse_weather_info3 = function () {
+ var type = this.getFieldValue("type");
+ var code = 'lifeInfo.' + type + '()';
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/generators/procedures.js b/mixly/boards/default_src/arduino/generators/procedures.js
new file mode 100644
index 00000000..ab180a60
--- /dev/null
+++ b/mixly/boards/default_src/arduino/generators/procedures.js
@@ -0,0 +1,114 @@
+import { Variables, Procedures } from 'blockly/core';
+
+export const procedures_defreturn = function (_, generator) {
+ // Define a procedure with a return value.
+ var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
+ Procedures.NAME_TYPE);
+ var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK'));
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
+ '\'' + this.id + '\'') + branch;
+ }
+ var returnValue = generator.valueToCode(this, 'RETURN',
+ generator.ORDER_NONE) || '';
+ var type = this.getFieldValue('TYPE');
+ if (type === 'CUSTOM') {
+ if (this.getField('RETRUN_TYPE')) {
+ type = this.getFieldValue('RETRUN_TYPE');
+ } else {
+ type = 'void';
+ }
+ }
+ if (returnValue) {
+ returnValue = ' return ' + returnValue + ';\n';
+ }
+ var returnType = type ? type : 'void';
+ var args = [];
+ for (var x = 0; x < this.arguments_.length; x++) {
+ args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x],
+ Variables.NAME_TYPE);
+ }
+ var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
+ branch + returnValue + '}\n';
+ code = generator.scrub_(this, code);
+ generator.definitions_[funcName] = code;
+ return null;
+}
+
+export const procedures_defnoreturn = function (_, generator) {
+ // Define a procedure with a return value.
+ var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
+ Procedures.NAME_TYPE);
+ var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK'));
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
+ '\'' + this.id + '\'') + branch;
+ }
+ var returnType = 'void';
+ var args = [];
+ for (var x = 0; x < this.arguments_.length; x++) {
+ args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x],
+ Variables.NAME_TYPE);
+ }
+ var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
+ branch + '}\n';
+ code = generator.scrub_(this, code);
+ generator.definitions_[funcName] = code;
+ return null;
+}
+
+export const procedures_callreturn = function (_, generator) {
+ // Call a procedure with a return value.
+ var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
+ Procedures.NAME_TYPE);
+ var args = [];
+ for (var x = 0; x < this.arguments_.length; x++) {
+ args[x] = generator.valueToCode(this, 'ARG' + x,
+ generator.ORDER_NONE) || 'null';
+ }
+ var code = funcName + '(' + args.join(', ') + ')';
+ return [code, generator.ORDER_UNARY_POSTFIX];
+}
+
+export const procedures_callnoreturn = function (_, generator) {
+ // Call a procedure with no return value.
+ var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
+ Procedures.NAME_TYPE);
+ var args = [];
+ for (var x = 0; x < this.arguments_.length; x++) {
+ args[x] = generator.valueToCode(this, 'ARG' + x,
+ generator.ORDER_NONE) || 'null';
+ }
+ var code = funcName + '(' + args.join(', ') + ');\n';
+ return code;
+}
+
+export const procedures_ifreturn = function (_, generator) {
+ // Conditionally return value from a procedure.
+ var condition = generator.valueToCode(this, 'CONDITION',
+ generator.ORDER_NONE) || 'false';
+ var code = 'if (' + condition + ') {\n';
+ if (this.hasReturnValue_) {
+ var value = generator.valueToCode(this, 'VALUE',
+ generator.ORDER_NONE) || '';
+ code += ' return ' + value + ';\n';
+ } else {
+ code += ' return;\n';
+ }
+ code += '}\n';
+ return code;
+}
+
+export const procedures_return = function (_, generator) {
+ // Conditionally return value from a procedure.
+ var code = ""
+ if (this.hasReturnValue_) {
+ var value = generator.valueToCode(this, 'VALUE',
+ generator.ORDER_NONE) || 'None';
+ code += 'return ' + value + ';\n';
+ } else {
+ code += 'return;\n';
+ }
+ code += '\n';
+ return code;
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/generators/text.js b/mixly/boards/default_src/arduino/generators/text.js
new file mode 100644
index 00000000..065f74e0
--- /dev/null
+++ b/mixly/boards/default_src/arduino/generators/text.js
@@ -0,0 +1,37 @@
+import * as Blockly from 'blockly/core';
+
+export const text_base64_url_codec = function () {
+ const FIELD_TYPE = this.getFieldValue("TYPE");
+ const FIELD_OPTION = this.getFieldValue("OPTION");
+ const VALUE_INPUT_VALUE = Blockly.Arduino.valueToCode(this, "VALUE", Blockly.Arduino.ORDER_ATOMIC);
+ let code = '';
+ if (FIELD_TYPE === 'BASE64') {
+ Blockly.Arduino.definitions_['include_rBase64'] = '#include ';
+ if (FIELD_OPTION === 'ENCODE') {
+ code = 'rbase64.encode(' + VALUE_INPUT_VALUE + ')';
+ } else {
+ code = 'rbase64.decode(' + VALUE_INPUT_VALUE + ')';
+ }
+ } else {
+ Blockly.Arduino.definitions_['include_URLCode'] = '#include ';
+ Blockly.Arduino.definitions_['var_declare_urlCode'] = 'URLCode urlCode;';
+ if (FIELD_OPTION === 'ENCODE') {
+ Blockly.Arduino.definitions_['function_urlEncode']
+ = 'String urlEncode(String urlStr) {\n'
+ + ' urlCode.strcode = urlStr;\n'
+ + ' urlCode.urlencode();\n'
+ + ' return urlCode.urlcode;\n'
+ + '}\n';
+ code = 'urlEncode(' + VALUE_INPUT_VALUE + ')';
+ } else {
+ Blockly.Arduino.definitions_['function_urlDecode']
+ = 'String urlDecode(String urlStr) {\n'
+ + ' urlCode.urlcode = urlStr;\n'
+ + ' urlCode.urldecode();\n'
+ + ' return urlCode.strcode;\n'
+ + '}\n';
+ code = 'urlDecode(' + VALUE_INPUT_VALUE + ')';
+ }
+ }
+ return [code, Blockly.Arduino.ORDER_ATOMIC];
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/generators/variables.js b/mixly/boards/default_src/arduino/generators/variables.js
new file mode 100644
index 00000000..cc3c6b52
--- /dev/null
+++ b/mixly/boards/default_src/arduino/generators/variables.js
@@ -0,0 +1,61 @@
+import { Variables } from 'blockly/core';
+
+export const variables_get = function (_, generator) {
+ // Variable getter.
+ var code = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const variables_declare = function (_, generator) {
+ var dropdown_type = this.getFieldValue('TYPE');
+ var dropdown_variables_type = this.getFieldValue('variables_type');
+ var argument0;
+ var code = '';
+ //TODO: settype to variable
+ if (dropdown_variables_type == 'global_variate') {
+ if (dropdown_type == 'String') {
+ argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '""';
+ } else {
+ argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
+ }
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ if (dropdown_type == 'String' || dropdown_type == 'char*')
+ generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + ';';
+ else
+ generator.definitions_['var_declare' + varName] = 'volatile ' + dropdown_type + ' ' + varName + ';';
+
+ generator.setups_['setup_var' + varName] = varName + ' = ' + argument0 + ';';
+ }
+ else {
+ if (dropdown_type == 'String') {
+ argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '""';
+ } else {
+ argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
+ }
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ code = dropdown_type + ' ' + varName + ' = ' + argument0 + ';\n';
+ }
+ //generator.variableTypes_[varName] = dropdown_type;//处理变量类型
+ return code;
+}
+
+export const variables_set = function (_, generator) {
+ // Variable setter.
+ var argument0 = generator.valueToCode(this, 'VALUE',
+ generator.ORDER_ASSIGNMENT) || '0';
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ return varName + ' = ' + argument0 + ';\n';
+}
+
+export const variables_change = function (_, generator) {
+ // Variable setter.
+ var operator = this.getFieldValue('OP');
+ var varName = generator.valueToCode(this, 'MYVALUE', generator.ORDER_ASSIGNMENT);
+ //修复强制类型转换不正确的bug
+ var code = '((' + operator + ')(' + varName + '))';
+ return [code, generator.ORDER_ATOMIC];
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/index.js b/mixly/boards/default_src/arduino/index.js
new file mode 100644
index 00000000..e69de29b
diff --git a/mixly/boards/default_src/arduino/others/names.js b/mixly/boards/default_src/arduino/others/names.js
new file mode 100644
index 00000000..2e69c902
--- /dev/null
+++ b/mixly/boards/default_src/arduino/others/names.js
@@ -0,0 +1,199 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Utility functions for handling variables and procedure names.
+ * @author fraser@google.com (Neil Fraser)
+ */
+
+import { Variables } from 'blockly/core';
+
+/**
+ * Class for a database of entity names (variables, functions, etc).
+ * @param {string} reservedWords A comma-separated string of words that are
+ * illegal for use as names in a language (e.g. 'new,if,this,...').
+ * @param {string=} opt_variablePrefix Some languages need a '$' or a namespace
+ * before all variable names.
+ * @constructor
+ */
+const Names = function (reservedWords, opt_variablePrefix) {
+ this.variablePrefix_ = opt_variablePrefix || '';
+ this.reservedDict_ = Object.create(null);
+ if (reservedWords) {
+ var splitWords = reservedWords.split(',');
+ for (var i = 0; i < splitWords.length; i++) {
+ this.reservedDict_[splitWords[i]] = true;
+ }
+ }
+ this.reset();
+};
+
+/**
+ * Constant to separate developer variable names from user-defined variable
+ * names when running generators.
+ * A developer variable will be declared as a global in the generated code, but
+ * will never be shown to the user in the workspace or stored in the variable
+ * map.
+ */
+Names.DEVELOPER_VARIABLE_TYPE = 'DEVELOPER_VARIABLE';
+
+/**
+ * When JavaScript (or most other languages) is generated, variable 'foo' and
+ * procedure 'foo' would collide. However, Blockly has no such problems since
+ * variable get 'foo' and procedure call 'foo' are unambiguous.
+ * Therefore, Blockly keeps a separate type name to disambiguate.
+ * getName('foo', 'variable') -> 'foo'
+ * getName('foo', 'procedure') -> 'foo2'
+ */
+
+/**
+ * Empty the database and start from scratch. The reserved words are kept.
+ */
+Names.prototype.reset = function () {
+ this.db_ = Object.create(null);
+ this.dbReverse_ = Object.create(null);
+ this.variableMap_ = null;
+};
+
+/**
+ * Set the variable map that maps from variable name to variable object.
+ * @param {!Blockly.VariableMap} map The map to track.
+ * @package
+ */
+Names.prototype.setVariableMap = function (map) {
+ this.variableMap_ = map;
+};
+
+/**
+ * Get the name for a user-defined variable, based on its ID.
+ * This should only be used for variables of type Variables.NAME_TYPE.
+ * @param {string} id The ID to look up in the variable map.
+ * @return {?string} The name of the referenced variable, or null if there was
+ * no variable map or the variable was not found in the map.
+ * @private
+ */
+Names.prototype.getNameForUserVariable_ = function (id) {
+ if (!this.variableMap_) {
+ /*
+ console.log('Deprecated call to Names.prototype.getName without ' +
+ 'defining a variable map. To fix, add the folowing code in your ' +
+ 'generator\'s init() function:\n' +
+ 'Blockly.YourGeneratorName.variableDB_.setVariableMap(' +
+ 'workspace.getVariableMap());');
+ */
+ return null;
+ }
+ var variable = this.variableMap_.getVariableById(id);
+ if (variable) {
+ return variable.name;
+ }
+ return null;
+};
+
+/**
+ * Convert a Blockly entity name to a legal exportable entity name.
+ * @param {string} name The Blockly entity name (no constraints).
+ * @param {string} type The type of entity in Blockly
+ * ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
+ * @return {string} An entity name that is legal in the exported language.
+ */
+Names.prototype.getName = function (name, type) {
+ if (type == Variables.NAME_TYPE) {
+ var varName = this.getNameForUserVariable_(name);
+ if (varName) {
+ name = varName;
+ }
+ }
+ var normalized = name + '_' + type;
+
+ var isVarType = type == Variables.NAME_TYPE ||
+ type == Names.DEVELOPER_VARIABLE_TYPE;
+
+ var prefix = isVarType ? this.variablePrefix_ : '';
+ if (normalized in this.db_) {
+ return prefix + this.db_[normalized];
+ }
+ var safeName = this.getDistinctName(name, type);
+ this.db_[normalized] = safeName.substr(prefix.length);
+ return safeName;
+};
+
+/**
+ * Convert a Blockly entity name to a legal exportable entity name.
+ * Ensure that this is a new name not overlapping any previously defined name.
+ * Also check against list of reserved words for the current language and
+ * ensure name doesn't collide.
+ * @param {string} name The Blockly entity name (no constraints).
+ * @param {string} type The type of entity in Blockly
+ * ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
+ * @return {string} An entity name that is legal in the exported language.
+ */
+Names.prototype.getDistinctName = function (name, type) {
+ var safeName = this.safeName_(name);
+ var i = '';
+ while (this.dbReverse_[safeName + i] ||
+ (safeName + i) in this.reservedDict_) {
+ // Collision with existing name. Create a unique name.
+ i = i ? i + 1 : 2;
+ }
+ safeName += i;
+ this.dbReverse_[safeName] = true;
+ var isVarType = type == Variables.NAME_TYPE ||
+ type == Names.DEVELOPER_VARIABLE_TYPE;
+ var prefix = isVarType ? this.variablePrefix_ : '';
+ return prefix + safeName;
+};
+
+/**
+ * Given a proposed entity name, generate a name that conforms to the
+ * [_A-Za-z][_A-Za-z0-9]* format that most languages consider legal for
+ * variables.
+ * @param {string} name Potentially illegal entity name.
+ * @return {string} Safe entity name.
+ * @private
+ */
+Names.prototype.safeName_ = function (name) {
+ if (!name) {
+ name = 'unnamed';
+ } else {
+ // Unfortunately names in non-latin characters will look like
+ // _E9_9F_B3_E4_B9_90 which is pretty meaningless.
+ // https://github.com/google/blockly/issues/1654
+ name = encodeURI(name.replace(/ /g, '_')).replace(/[^,\w]/g, '_');
+ // Most languages don't allow names with leading numbers.
+ if ('0123456789'.indexOf(name[0]) != -1) {
+ name = 'my_' + name;
+ }
+ }
+ return name;
+};
+
+/**
+ * Do the given two entity names refer to the same entity?
+ * Blockly names are case-insensitive.
+ * @param {string} name1 First name.
+ * @param {string} name2 Second name.
+ * @return {boolean} True if names are the same.
+ */
+Names.equals = function (name1, name2) {
+ return name1 == name2;
+};
+
+export default Names;
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/others/procedures.js b/mixly/boards/default_src/arduino/others/procedures.js
new file mode 100644
index 00000000..d3d6d253
--- /dev/null
+++ b/mixly/boards/default_src/arduino/others/procedures.js
@@ -0,0 +1,338 @@
+/**
+ * @license
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Utility functions for handling procedures.
+ * @author fraser@google.com (Neil Fraser)
+ */
+
+/**
+ * @name Blockly.Procedures
+ * @namespace
+ */
+import * as Blockly from 'blockly/core';
+import Variables from './variables';
+
+const Procedures = {};
+
+Procedures.DATA_TYPE = [
+ ...Variables.DATA_TYPE,
+ [Blockly.Msg.MIXLY_OTHER, 'CUSTOM']
+];
+
+/**
+ * Constant to separate procedure names from variables and generated functions
+ * when running generators.
+ * @deprecated Use Blockly.PROCEDURE_CATEGORY_NAME
+ */
+Procedures.NAME_TYPE = Blockly.PROCEDURE_CATEGORY_NAME;
+
+/**
+ * Find all user-created procedure definitions in a workspace.
+ * @param {!Blockly.Workspace} root Root workspace.
+ * @return {!Array.>} Pair of arrays, the
+ * first contains procedures without return variables, the second with.
+ * Each procedure is defined by a three-element list of name, parameter
+ * list, and return value boolean.
+ */
+Procedures.allProcedures = function (root) {
+ var blocks = root.getAllBlocks(false);
+ var proceduresReturn = [];
+ var proceduresNoReturn = [];
+ for (var i = 0; i < blocks.length; i++) {
+ if (blocks[i].getProcedureDef) {
+ var tuple = blocks[i].getProcedureDef();
+ if (tuple) {
+ if (tuple[2]) {
+ proceduresReturn.push(tuple);
+ } else {
+ proceduresNoReturn.push(tuple);
+ }
+ }
+ }
+ }
+ proceduresNoReturn.sort(Procedures.procTupleComparator_);
+ proceduresReturn.sort(Procedures.procTupleComparator_);
+ return [proceduresNoReturn, proceduresReturn];
+};
+
+/**
+ * Comparison function for case-insensitive sorting of the first element of
+ * a tuple.
+ * @param {!Array} ta First tuple.
+ * @param {!Array} tb Second tuple.
+ * @return {number} -1, 0, or 1 to signify greater than, equality, or less than.
+ * @private
+ */
+Procedures.procTupleComparator_ = function (ta, tb) {
+ return ta[0].toLowerCase().localeCompare(tb[0].toLowerCase());
+};
+
+/**
+ * Ensure two identically-named procedures don't exist.
+ * Take the proposed procedure name, and return a legal name i.e. one that
+ * is not empty and doesn't collide with other procedures.
+ * @param {string} name Proposed procedure name.
+ * @param {!Blockly.Block} block Block to disambiguate.
+ * @return {string} Non-colliding name.
+ */
+Procedures.findLegalName = function (name, block) {
+ if (block.isInFlyout) {
+ // Flyouts can have multiple procedures called 'do something'.
+ return name;
+ }
+ name = name || Blockly.Msg['UNNAMED_KEY'] || 'unnamed';
+ while (!Procedures.isLegalName_(name, block.workspace, block)) {
+ // Collision with another procedure.
+ var r = name.match(/^(.*?)(\d+)$/);
+ if (!r) {
+ name += '2';
+ } else {
+ name = r[1] + (parseInt(r[2], 10) + 1);
+ }
+ }
+ return name;
+};
+
+/**
+ * Does this procedure have a legal name? Illegal names include names of
+ * procedures already defined.
+ * @param {string} name The questionable name.
+ * @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
+ * @param {Blockly.Block=} opt_exclude Optional block to exclude from
+ * comparisons (one doesn't want to collide with oneself).
+ * @return {boolean} True if the name is legal.
+ * @private
+ */
+Procedures.isLegalName_ = function (name, workspace, opt_exclude) {
+ return !Procedures.isNameUsed(name, workspace, opt_exclude);
+};
+
+/**
+ * Return if the given name is already a procedure name.
+ * @param {string} name The questionable name.
+ * @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
+ * @param {Blockly.Block=} opt_exclude Optional block to exclude from
+ * comparisons (one doesn't want to collide with oneself).
+ * @return {boolean} True if the name is used, otherwise return false.
+ */
+Procedures.isNameUsed = function (name, workspace, opt_exclude) {
+ var blocks = workspace.getAllBlocks(false);
+ // Iterate through every block and check the name.
+ for (var i = 0; i < blocks.length; i++) {
+ if (blocks[i] == opt_exclude) {
+ continue;
+ }
+ if (blocks[i].getProcedureDef) {
+ var procName = blocks[i].getProcedureDef();
+ if (Blockly.Names.equals(procName[0], name)) {
+ return true;
+ }
+ }
+ }
+ return false;
+};
+
+/**
+ * Rename a procedure. Called by the editable field.
+ * @param {string} name The proposed new name.
+ * @return {string} The accepted name.
+ * @this {Blockly.Field}
+ */
+Procedures.rename = function (name) {
+ // Strip leading and trailing whitespace. Beyond this, all names are legal.
+ name = name.trim();
+
+ var legalName = Procedures.findLegalName(name, this.getSourceBlock());
+ var oldName = this.getValue();
+ if (oldName != name && oldName != legalName) {
+ // Rename any callers.
+ var blocks = this.getSourceBlock().workspace.getAllBlocks(false);
+ for (var i = 0; i < blocks.length; i++) {
+ if (blocks[i].renameProcedure) {
+ blocks[i].renameProcedure(oldName, legalName);
+ }
+ }
+ }
+ return legalName;
+};
+
+/**
+ * Construct the blocks required by the flyout for the procedure category.
+ * @param {!Blockly.Workspace} workspace The workspace containing procedures.
+ * @return {!Array.} Array of XML block elements.
+ */
+Procedures.flyoutCategory = function (workspace) {
+ var xmlList = [];
+ if (Blockly.Blocks['procedures_defnoreturn']) {
+ //
+ // do something
+ //
+ var block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'procedures_defnoreturn');
+ block.setAttribute('gap', 16);
+ var nameField = Blockly.utils.xml.createElement('field');
+ nameField.setAttribute('name', 'NAME');
+ nameField.appendChild(Blockly.utils.xml.createTextNode(
+ Blockly.Msg['PROCEDURES_DEFNORETURN_PROCEDURE']));
+ block.appendChild(nameField);
+ xmlList.push(block);
+ }
+ if (Blockly.Blocks['procedures_defreturn']) {
+ //
+ // do something
+ //
+ let block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'procedures_defreturn');
+ block.setAttribute('gap', 16);
+ let nameField = Blockly.utils.xml.createElement('field');
+ nameField.setAttribute('name', 'NAME');
+ nameField.appendChild(Blockly.utils.xml.createTextNode(
+ Blockly.Msg['PROCEDURES_DEFRETURN_PROCEDURE']));
+ block.appendChild(nameField);
+ xmlList.push(block);
+ }
+ if (Blockly.Blocks['procedures_return']) {
+ //
+ let block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'procedures_return');
+ block.setAttribute('gap', 16);
+ xmlList.push(block);
+ }
+ if (Blockly.Blocks['procedures_ifreturn']) {
+ //
+ let block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'procedures_ifreturn');
+ block.setAttribute('gap', 16);
+ xmlList.push(block);
+ }
+ if (xmlList.length) {
+ // Add slightly larger gap between system blocks and user calls.
+ xmlList[xmlList.length - 1].setAttribute('gap', 24);
+ }
+
+ function populateProcedures(procedureList, templateName) {
+ for (var i = 0; i < procedureList.length; i++) {
+ var name = procedureList[i][0];
+ var args = procedureList[i][1];
+ //
+ //
+ //
+ //
+ //
+ var block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', templateName);
+ block.setAttribute('gap', 16);
+ var mutation = Blockly.utils.xml.createElement('mutation');
+ mutation.setAttribute('name', name);
+ block.appendChild(mutation);
+ for (var j = 0; j < args.length; j++) {
+ var arg = Blockly.utils.xml.createElement('arg');
+ arg.setAttribute('name', args[j]);
+ mutation.appendChild(arg);
+ }
+ xmlList.push(block);
+ }
+ }
+
+ var tuple = Procedures.allProcedures(workspace);
+ populateProcedures(tuple[0], 'procedures_callnoreturn');
+ populateProcedures(tuple[1], 'procedures_callreturn');
+ return xmlList;
+};
+
+/**
+ * Find all the callers of a named procedure.
+ * @param {string} name Name of procedure.
+ * @param {!Blockly.Workspace} workspace The workspace to find callers in.
+ * @return {!Array.} Array of caller blocks.
+ */
+Procedures.getCallers = function (name, workspace) {
+ var callers = [];
+ var blocks = workspace.getAllBlocks(false);
+ // Iterate through every block and check the name.
+ for (var i = 0; i < blocks.length; i++) {
+ if (blocks[i].getProcedureCall) {
+ var procName = blocks[i].getProcedureCall();
+ // Procedure name may be null if the block is only half-built.
+ if (procName && Blockly.Names.equals(procName, name)) {
+ callers.push(blocks[i]);
+ }
+ }
+ }
+ return callers;
+};
+
+/**
+ * When a procedure definition changes its parameters, find and edit all its
+ * callers.
+ * @param {!Blockly.Block} defBlock Procedure definition block.
+ */
+Procedures.mutateCallers = function (defBlock) {
+ const oldRecordUndo = Blockly.Events.getRecordUndo();
+ const procedureBlock = defBlock;
+ const name = procedureBlock.getProcedureDef()[0];
+ const xmlElement = defBlock.mutationToDom(true);
+ const callers = Procedures.getCallers(name, defBlock.workspace);
+ for (let i = 0, caller; (caller = callers[i]); i++) {
+ const oldMutationDom = caller.mutationToDom();
+ const oldMutation = oldMutationDom && Blockly.utils.xml.domToText(oldMutationDom);
+ if (caller.domToMutation) {
+ caller.domToMutation(xmlElement);
+ }
+ const newMutationDom = caller.mutationToDom();
+ const newMutation = newMutationDom && Blockly.utils.xml.domToText(newMutationDom);
+ if (oldMutation !== newMutation) {
+ // Fire a mutation on every caller block. But don't record this as an
+ // undo action since it is deterministically tied to the procedure's
+ // definition mutation.
+ Blockly.Events.setRecordUndo(false);
+ Blockly.Events.fire(
+ new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
+ caller,
+ 'mutation',
+ null,
+ oldMutation,
+ newMutation,
+ ),
+ );
+ Blockly.Events.setRecordUndo(oldRecordUndo);
+ }
+ }
+};
+
+/**
+ * Find the definition block for the named procedure.
+ * @param {string} name Name of procedure.
+ * @param {!Blockly.Workspace} workspace The workspace to search.
+ * @return {Blockly.Block} The procedure definition block, or null not found.
+ */
+Procedures.getDefinition = function (name, workspace) {
+ // Assume that a procedure definition is a top block.
+ var blocks = workspace.getTopBlocks(false);
+ for (var i = 0; i < blocks.length; i++) {
+ if (blocks[i].getProcedureDef) {
+ var tuple = blocks[i].getProcedureDef();
+ if (tuple && Blockly.Names.equals(tuple[0], name)) {
+ return blocks[i];
+ }
+ }
+ }
+ return null;
+};
+
+export default Procedures;
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/others/variables.js b/mixly/boards/default_src/arduino/others/variables.js
new file mode 100644
index 00000000..c210e042
--- /dev/null
+++ b/mixly/boards/default_src/arduino/others/variables.js
@@ -0,0 +1,255 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2012 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Utility functions for handling variables.
+ * @author fraser@google.com (Neil Fraser)
+ */
+import * as Blockly from 'blockly/core';
+
+const Variables = {};
+
+/**
+ * Category to separate variable names from procedures and generated functions.
+ */
+Variables.NAME_TYPE = 'VARIABLE';
+
+Variables.DATA_TYPE = [
+ [Blockly.Msg.LANG_MATH_INT, 'int'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_INT, 'unsigned int'],
+ [Blockly.Msg.LANG_MATH_WORD, 'word'],
+ [Blockly.Msg.LANG_MATH_LONG, 'long'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_LONG, 'unsigned long'],
+ [Blockly.Msg.LANG_MATH_FLOAT, 'float'],
+ [Blockly.Msg.LANG_MATH_DOUBLE, 'double'],
+ [Blockly.Msg.LANG_MATH_BOOLEAN, 'bool'],
+ [Blockly.Msg.LANG_MATH_BYTE, 'byte'],
+ [Blockly.Msg.LANG_MATH_CHAR, 'char'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_CHAR, 'unsigned char'],
+ [Blockly.Msg.LANG_MATH_STRING, 'String'],
+ ['uint8_t', 'uint8_t'],
+ ['uint16_t', 'uint16_t'],
+ ['uint32_t', 'uint32_t'],
+ ['uint64_t', 'uint64_t'],
+ ['int*', 'int*'],
+ ['unsigned int*', 'unsigned int*'],
+ ['word*', 'word*'],
+ ['long*', 'long*'],
+ ['unsigned long*', 'unsigned long*'],
+ ['float*', 'float*'],
+ ['double*', 'double*'],
+ ['bool*', 'bool*'],
+ ['byte*', 'byte*'],
+ ['char*', 'char*'],
+ ['unsigned char*', 'unsigned char*'],
+ ['String*', 'String*'],
+ ['uint8_t*', 'uint8_t*'],
+ ['uint16_t*', 'uint16_t*'],
+ ['uint32_t*', 'uint32_t*'],
+ ['uint64_t*', 'uint64_t*']
+];
+
+/**
+ * Find all user-created variables.
+ * @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
+ * @return {!Array.} Array of variable names.
+ */
+Variables.allVariables = function (root) {
+ var blocks;
+ if (root.getDescendants) {
+ // Root is Block.
+ blocks = root.getDescendants();
+ } else if (root.getAllBlocks) {
+ // Root is Workspace.
+ blocks = root.getAllBlocks();
+ } else {
+ throw 'Not Block or Workspace: ' + root;
+ }
+ var variableHash = Object.create(null);
+ // Iterate through every block and add each variable to the hash.
+ for (var x = 0; x < blocks.length; x++) {
+ var blockVariables = blocks[x].getVars();
+ for (var y = 0; y < blockVariables.length; y++) {
+ var varName = blockVariables[y];
+ // Variable name may be null if the block is only half-built.
+ if (varName) {
+ variableHash[varName] = varName;
+ }
+ }
+ }
+ // Flatten the hash into a list.
+ var variableList = [];
+ for (var name in variableHash) {
+ variableList.push(variableHash[name]);
+ }
+ return variableList;
+};
+
+/**
+ * Find all instances of the specified variable and rename them.
+ * @param {string} oldName Variable to rename.
+ * @param {string} newName New variable name.
+ * @param {!Blockly.Workspace} workspace Workspace rename variables in.
+ */
+Variables.renameVariable = function (oldName, newName, workspace) {
+ Blockly.Events.setGroup(true);
+ var blocks = workspace.getAllBlocks();
+ // Iterate through every block.
+ for (var i = 0; i < blocks.length; i++) {
+ blocks[i].renameVar(oldName, newName);
+ }
+ Blockly.Events.setGroup(false);
+};
+
+/**
+ * Construct the blocks required by the flyout for the variable category.
+ * @param {!Blockly.Workspace} workspace The workspace contianing variables.
+ * @return {!Array.} Array of XML block elements.
+ */
+Variables.flyoutCategory = function (workspace) {
+ var variableList = Variables.allVariables(workspace);
+ //variableList.sort(goog.string.caseInsensitiveCompare);
+
+ // In addition to the user's variables, we also want to display the default
+ // variable name at the top. We also don't want this duplicated if the
+ // user has created a variable of the same name.
+
+ //在变量分类里添加默认变量取值与赋值模块时使用
+ //goog.array.remove(variableList, Blockly.Msg.VARIABLES_DEFAULT_NAME);
+ //variableList.unshift(Blockly.Msg.VARIABLES_DEFAULT_NAME);
+
+ var xmlList = [];
+
+
+ if (Blockly.Blocks['variables_declare']) {
+ //增加variables_declare模块
+ let block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'variables_declare');
+ xmlList.push(block);
+ }
+
+ //在变量分类里添加默认变量取值与赋值模块时使用
+ /*
+ if (Blockly.Blocks['variables_set']) {
+ //增加variables_declare模块
+ var block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'variables_set');
+ xmlList.push(block);
+ }
+ if (Blockly.Blocks['variables_get']) {
+ //增加variables_declare模块
+ var block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'variables_get');
+ xmlList.push(block);
+ }
+ */
+
+ //change tyep
+ if (Blockly.Blocks['variables_change']) {
+ //增加variables_declare模块
+ let block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'variables_change');
+ xmlList.push(block);
+ }
+ for (var i = 0; i < variableList.length; i++) {
+ //if(i==0&&!(Blockly.Arduino.definitions_['var_declare'+'item'])){
+ // continue;
+ //}
+
+ if (Blockly.Blocks['variables_set']) {
+ let block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'variables_set');
+ if (Blockly.Blocks['variables_get']) {
+ block.setAttribute('gap', 8);
+ }
+ let field = Blockly.utils.xml.createElement('field', null, variableList[i]);
+ field.setAttribute('name', 'VAR');
+ let name = Blockly.utils.xml.createTextNode(variableList[i]);
+ field.appendChild(name);
+ block.appendChild(field);
+ xmlList.push(block);
+ }
+ if (Blockly.Blocks['variables_get']) {
+ var block = Blockly.utils.xml.createElement('block');
+ block.setAttribute('type', 'variables_get');
+ if (Blockly.Blocks['variables_set']) {
+ block.setAttribute('gap', 24);
+ }
+ let field = Blockly.utils.xml.createElement('field', null, variableList[i]);
+ field.setAttribute('name', 'VAR');
+ let name = Blockly.utils.xml.createTextNode(variableList[i]);
+ field.appendChild(name);
+ block.appendChild(field);
+ xmlList.push(block);
+ }
+ }
+ return xmlList;
+};
+
+/**
+* Return a new variable name that is not yet being used. This will try to
+* generate single letter variable names in the range 'i' to 'z' to start with.
+* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
+* then 'i2' to 'z2' etc. Skip 'l'.
+ * @param {!Blockly.Workspace} workspace The workspace to be unique in.
+* @return {string} New variable name.
+*/
+Variables.generateUniqueName = function (workspace) {
+ var variableList = Variables.allVariables(workspace);
+ var newName = '';
+ if (variableList.length) {
+ var nameSuffix = 1;
+ var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
+ var letterIndex = 0;
+ var potName = letters.charAt(letterIndex);
+ while (!newName) {
+ var inUse = false;
+ for (var i = 0; i < variableList.length; i++) {
+ if (variableList[i] == potName) {
+ // This potential name is already used.
+ inUse = true;
+ break;
+ }
+ }
+ if (inUse) {
+ // Try the next potential name.
+ letterIndex++;
+ if (letterIndex == letters.length) {
+ // Reached the end of the character sequence so back to 'i'.
+ // a new suffix.
+ letterIndex = 0;
+ nameSuffix++;
+ }
+ potName = letters.charAt(letterIndex);
+ if (nameSuffix > 1) {
+ potName += nameSuffix;
+ }
+ } else {
+ // We can use the current potential name.
+ newName = potName;
+ }
+ }
+ } else {
+ newName = 'i';
+ }
+ return newName;
+};
+
+export default Variables;
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/package.json b/mixly/boards/default_src/arduino/package.json
new file mode 100644
index 00000000..88453e87
--- /dev/null
+++ b/mixly/boards/default_src/arduino/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "@mixly/arduino",
+ "version": "1.8.0",
+ "description": "适用于mixly的arduino模块",
+ "scripts": {
+ "build:dev": "webpack --config=webpack.dev.js",
+ "build:prod": "npm run build:examples & webpack --config=webpack.prod.js",
+ "build:examples": "node ../../../scripts/build-examples.js -t special",
+ "build:examples:ob": "node ../../../scripts/build-examples.js -t special --obfuscate",
+ "publish:board": "npm publish --registry https://registry.npmjs.org/"
+ },
+ "main": "./export.js",
+ "author": "Mixly Team",
+ "keywords": [
+ "mixly",
+ "mixly-plugin",
+ "arduino"
+ ],
+ "homepage": "https://gitee.com/bnu_mixly/mixly3/tree/master/boards/default_src/arduino",
+ "bugs": {
+ "url": "https://gitee.com/bnu_mixly/mixly3/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://gitee.com/bnu_mixly/mixly3.git",
+ "directory": "default_src/arduino"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "license": "Apache 2.0"
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/template.xml b/mixly/boards/default_src/arduino/template.xml
new file mode 100644
index 00000000..e69de29b
diff --git a/mixly/boards/default_src/arduino/templates/json/cities.json b/mixly/boards/default_src/arduino/templates/json/cities.json
new file mode 100644
index 00000000..5206fa72
--- /dev/null
+++ b/mixly/boards/default_src/arduino/templates/json/cities.json
@@ -0,0 +1,1185 @@
+{
+ "本地": {
+ "-": {
+ "pinyin": "ip"
+ }
+ },
+ "北京": {
+ "-": {
+ "pinyin": "beijing"
+ }
+ },
+ "天津": {
+ "-": {
+ "pinyin": "tianjin"
+ }
+ },
+ "河北": {
+ "石家庄": {
+ "pinyin": "shijiazhuang"
+ },
+ "邯郸": {
+ "pinyin": "handan"
+ },
+ "邢台": {
+ "pinyin": "xingtai"
+ },
+ "衡水": {
+ "pinyin": "hengshui"
+ },
+ "保定": {
+ "pinyin": "baoding"
+ },
+ "沧州": {
+ "pinyin": "cangzhou"
+ },
+ "张家口": {
+ "pinyin": "zhangjiakou"
+ },
+ "廊坊": {
+ "pinyin": "langfang"
+ },
+ "承德": {
+ "pinyin": "chengde"
+ },
+ "唐山": {
+ "pinyin": "tangshan"
+ },
+ "秦皇岛": {
+ "pinyin": "qinhuangdao"
+ }
+ },
+ "山西": {
+ "太原": {
+ "pinyin": "taiyuan"
+ },
+ "运城": {
+ "pinyin": "yuncheng"
+ },
+ "临汾": {
+ "pinyin": "linfen"
+ },
+ "吕梁": {
+ "pinyin": "lvliang"
+ },
+ "朔州": {
+ "pinyin": "shuozhou"
+ },
+ "晋城": {
+ "pinyin": "jincheng"
+ },
+ "长治": {
+ "pinyin": "changzhi"
+ },
+ "晋中": {
+ "pinyin": "jinzhong"
+ },
+ "阳泉": {
+ "pinyin": "yangquan"
+ },
+ "忻州": {
+ "pinyin": "xinzhou"
+ },
+ "大同": {
+ "pinyin": "datong"
+ }
+ },
+ "内蒙古": {
+ "呼和浩特": {
+ "pinyin": "huhehaote"
+ },
+ "阿左旗": {
+ "pinyin": "azuoqi"
+ },
+ "乌海": {
+ "pinyin": "wuhai"
+ },
+ "临河": {
+ "pinyin": "linhe"
+ },
+ "鄂尔多斯": {
+ "pinyin": "eerduosi"
+ },
+ "包头": {
+ "pinyin": "baotou"
+ },
+ "集宁": {
+ "pinyin": "jining"
+ },
+ "锡林浩特": {
+ "pinyin": "xilinhaote"
+ },
+ "赤峰": {
+ "pinyin": "chifeng"
+ },
+ "通辽": {
+ "pinyin": "tongliao"
+ },
+ "乌兰浩特": {
+ "pinyin": "wulanhaote"
+ },
+ "海拉尔": {
+ "pinyin": "hailaer"
+ }
+ },
+ "辽宁": {
+ "沈阳": {
+ "pinyin": "shenyang"
+ },
+ "大连": {
+ "pinyin": "dalian"
+ },
+ "葫芦岛": {
+ "pinyin": "huludao"
+ },
+ "朝阳": {
+ "pinyin": "chaoyang"
+ },
+ "营口": {
+ "pinyin": "yingkou"
+ },
+ "锦州": {
+ "pinyin": "jinzhou"
+ },
+ "盘锦": {
+ "pinyin": "panjin"
+ },
+ "阜新": {
+ "pinyin": "fuxin"
+ },
+ "鞍山": {
+ "pinyin": "anshan"
+ },
+ "辽阳": {
+ "pinyin": "liaoyang"
+ },
+ "丹东": {
+ "pinyin": "dandong"
+ },
+ "本溪": {
+ "pinyin": "benxi"
+ },
+ "抚顺": {
+ "pinyin": "fushun"
+ },
+ "铁岭": {
+ "pinyin": "tieling"
+ }
+ },
+ "吉林": {
+ "长春": {
+ "pinyin": "changchun"
+ },
+ "通化": {
+ "pinyin": "tonghua"
+ },
+ "白山": {
+ "pinyin": "baishan"
+ },
+ "辽源": {
+ "pinyin": "liaoyuan"
+ },
+ "四平": {
+ "pinyin": "siping"
+ },
+ "吉林": {
+ "pinyin": "jilin"
+ },
+ "延吉": {
+ "pinyin": "yanji"
+ },
+ "白城": {
+ "pinyin": "baicheng"
+ },
+ "松原": {
+ "pinyin": "songyuan"
+ }
+ },
+ "黑龙江": {
+ "哈尔滨": {
+ "pinyin": "haerbin"
+ },
+ "牡丹江": {
+ "pinyin": "mudanjiang"
+ },
+ "大庆": {
+ "pinyin": "daqing"
+ },
+ "齐齐哈尔": {
+ "pinyin": "qiqihaer"
+ },
+ "绥化": {
+ "pinyin": "suihua"
+ },
+ "伊春": {
+ "pinyin": "yichun"
+ },
+ "大兴安岭": {
+ "pinyin": "daxinganling"
+ },
+ "黑河": {
+ "pinyin": "heihe"
+ },
+ "鸡西": {
+ "pinyin": "jixi"
+ },
+ "七台河": {
+ "pinyin": "qitaihe"
+ },
+ "佳木斯": {
+ "pinyin": "jiamusi"
+ },
+ "鹤岗": {
+ "pinyin": "hegang"
+ },
+ "双鸭山": {
+ "pinyin": "shuangyashan"
+ }
+ },
+ "上海": {
+ "-": {
+ "pinyin": "shanghai"
+ }
+ },
+ "江苏": {
+ "南京": {
+ "pinyin": "nanjing"
+ },
+ "镇江": {
+ "pinyin": "zhenjiang"
+ },
+ "苏州": {
+ "pinyin": "suzhou"
+ },
+ "无锡": {
+ "pinyin": "wuxi"
+ },
+ "常州": {
+ "pinyin": "changzhou"
+ },
+ "南通": {
+ "pinyin": "nantong"
+ },
+ "扬州": {
+ "pinyin": "yangzhou"
+ },
+ "淮安": {
+ "pinyin": "huaian"
+ },
+ "泰州": {
+ "pinyin": "taizhou"
+ },
+ "盐城": {
+ "pinyin": "yancheng"
+ },
+ "徐州": {
+ "pinyin": "xuzhou"
+ },
+ "宿迁": {
+ "pinyin": "suqian"
+ },
+ "连云港": {
+ "pinyin": "lianyungang"
+ }
+ },
+ "浙江": {
+ "杭州": {
+ "pinyin": "hangzhou"
+ },
+ "温州": {
+ "pinyin": "wenzhou"
+ },
+ "衢州": {
+ "pinyin": "quzhou"
+ },
+ "丽水": {
+ "pinyin": "lishui"
+ },
+ "金华": {
+ "pinyin": "jinhua"
+ },
+ "绍兴": {
+ "pinyin": "shaoxing"
+ },
+ "湖州": {
+ "pinyin": "huzhou"
+ },
+ "嘉兴": {
+ "pinyin": "jiaxing"
+ },
+ "台州": {
+ "pinyin": "taizhou"
+ },
+ "宁波": {
+ "pinyin": "ningbo"
+ },
+ "舟山": {
+ "pinyin": "zhoushan"
+ }
+ },
+ "安徽": {
+ "合肥": {
+ "pinyin": "hefei"
+ },
+ "安庆": {
+ "pinyin": "anqing"
+ },
+ "池州": {
+ "pinyin": "chizhou"
+ },
+ "铜陵": {
+ "pinyin": "tongling"
+ },
+ "六安": {
+ "pinyin": "luan"
+ },
+ "阜阳": {
+ "pinyin": "fuyang"
+ },
+ "淮南": {
+ "pinyin": "huainan"
+ },
+ "蚌埠": {
+ "pinyin": "bengbu"
+ },
+ "宿州": {
+ "pinyin": "suzhou"
+ },
+ "黄山": {
+ "pinyin": "huangshan"
+ },
+ "宣城": {
+ "pinyin": "xuancheng"
+ },
+ "芜湖": {
+ "pinyin": "wuhu"
+ },
+ "马鞍山": {
+ "pinyin": "maanshan"
+ },
+ "滁州": {
+ "pinyin": "chuzhou"
+ },
+ "亳州": {
+ "pinyin": "bozhou"
+ },
+ "淮北": {
+ "pinyin": "huaibei"
+ }
+ },
+ "福建": {
+ "福州": {
+ "pinyin": "fuzhou"
+ },
+ "漳州": {
+ "pinyin": "zhangzhou"
+ },
+ "厦门": {
+ "pinyin": "xiamen"
+ },
+ "龙岩": {
+ "pinyin": "longyan"
+ },
+ "三明": {
+ "pinyin": "sanming"
+ },
+ "泉州": {
+ "pinyin": "quanzhou"
+ },
+ "莆田": {
+ "pinyin": "putian"
+ },
+ "南平": {
+ "pinyin": "nanping"
+ },
+ "宁德": {
+ "pinyin": "ningde"
+ }
+ },
+ "江西": {
+ "南昌": {
+ "pinyin": "nanchang"
+ },
+ "赣州": {
+ "pinyin": "ganzhou"
+ },
+ "萍乡": {
+ "pinyin": "pingxiang"
+ },
+ "吉安": {
+ "pinyin": "jian"
+ },
+ "宜春": {
+ "pinyin": "yichun"
+ },
+ "新余": {
+ "pinyin": "xinyu"
+ },
+ "抚州": {
+ "pinyin": "fuzhou"
+ },
+ "鹰潭": {
+ "pinyin": "yingtan"
+ },
+ "上饶": {
+ "pinyin": "shangrao"
+ },
+ "景德镇": {
+ "pinyin": "jingdezhen"
+ },
+ "九江": {
+ "pinyin": "jiujiang"
+ }
+ },
+ "山东": {
+ "济南": {
+ "pinyin": "jinan"
+ },
+ "枣庄": {
+ "pinyin": "zaozhuang"
+ },
+ "菏泽": {
+ "pinyin": "heze"
+ },
+ "济宁": {
+ "pinyin": "jining"
+ },
+ "聊城": {
+ "pinyin": "liaocheng"
+ },
+ "泰安": {
+ "pinyin": "taian"
+ },
+ "莱芜": {
+ "pinyin": "laiwu"
+ },
+ "德州": {
+ "pinyin": "dezhou"
+ },
+ "淄博": {
+ "pinyin": "zibo"
+ },
+ "滨州": {
+ "pinyin": "binzhou"
+ },
+ "临沂": {
+ "pinyin": "linyi"
+ },
+ "日照": {
+ "pinyin": "rizhao"
+ },
+ "青岛": {
+ "pinyin": "qingdao"
+ },
+ "潍坊": {
+ "pinyin": "weifang"
+ },
+ "东营": {
+ "pinyin": "dongying"
+ },
+ "烟台": {
+ "pinyin": "yantai"
+ },
+ "威海": {
+ "pinyin": "weihai"
+ }
+ },
+ "河南": {
+ "郑州": {
+ "pinyin": "zhengzhou"
+ },
+ "三门峡": {
+ "pinyin": "sanmenxia"
+ },
+ "洛阳": {
+ "pinyin": "luoyang"
+ },
+ "信阳": {
+ "pinyin": "xinyang"
+ },
+ "南阳": {
+ "pinyin": "nanyang"
+ },
+ "驻马店": {
+ "pinyin": "zhumadian"
+ },
+ "漯河": {
+ "pinyin": "luohe"
+ },
+ "周口": {
+ "pinyin": "zhoukou"
+ },
+ "平顶山": {
+ "pinyin": "pingdingshan"
+ },
+ "许昌": {
+ "pinyin": "xuchang"
+ },
+ "济源": {
+ "pinyin": "jiyuan"
+ },
+ "开封": {
+ "pinyin": "kaifeng"
+ },
+ "焦作": {
+ "pinyin": "jiaozuo"
+ },
+ "新乡": {
+ "pinyin": "xinxiang"
+ },
+ "鹤壁": {
+ "pinyin": "hebi"
+ },
+ "濮阳": {
+ "pinyin": "puyang"
+ },
+ "安阳": {
+ "pinyin": "anyang"
+ },
+ "商丘": {
+ "pinyin": "shangqiu"
+ }
+ },
+ "湖北": {
+ "武汉": {
+ "pinyin": "wuhan"
+ },
+ "恩施": {
+ "pinyin": "enshi"
+ },
+ "宜昌": {
+ "pinyin": "yichang"
+ },
+ "荆州": {
+ "pinyin": "jingzhou"
+ },
+ "神农架": {
+ "pinyin": "shennongjia"
+ },
+ "荆门": {
+ "pinyin": "jingmen"
+ },
+ "襄阳": {
+ "pinyin": "xiangyang"
+ },
+ "十堰": {
+ "pinyin": "shiyan"
+ },
+ "潜江": {
+ "pinyin": "qianjiang"
+ },
+ "天门": {
+ "pinyin": "tianmen"
+ },
+ "仙桃": {
+ "pinyin": "xiantao"
+ },
+ "咸宁": {
+ "pinyin": "xianning"
+ },
+ "黄石": {
+ "pinyin": "huangshi"
+ },
+ "孝感": {
+ "pinyin": "xiaogan"
+ },
+ "鄂州": {
+ "pinyin": "ezhou"
+ },
+ "黄冈": {
+ "pinyin": "huanggang"
+ },
+ "随州": {
+ "pinyin": "suizhou"
+ }
+ },
+ "湖南": {
+ "长沙": {
+ "pinyin": "changsha"
+ },
+ "永州": {
+ "pinyin": "yongzhou"
+ },
+ "怀化": {
+ "pinyin": "huaihua"
+ },
+ "邵阳": {
+ "pinyin": "shaoyang"
+ },
+ "娄底": {
+ "pinyin": "loudi"
+ },
+ "吉首": {
+ "pinyin": "jishou"
+ },
+ "张家界": {
+ "pinyin": "zhangjiajie"
+ },
+ "益阳": {
+ "pinyin": "yiyang"
+ },
+ "常德": {
+ "pinyin": "changde"
+ },
+ "郴州": {
+ "pinyin": "chenzhou"
+ },
+ "衡阳": {
+ "pinyin": "hengyang"
+ },
+ "湘潭": {
+ "pinyin": "xiangtan"
+ },
+ "株洲": {
+ "pinyin": "zhuzhou"
+ },
+ "岳阳": {
+ "pinyin": "yueyang"
+ }
+ },
+ "广东": {
+ "广州": {
+ "pinyin": "guangzhou"
+ },
+ "湛江": {
+ "pinyin": "zhanjiang"
+ },
+ "茂名": {
+ "pinyin": "maoming"
+ },
+ "阳江": {
+ "pinyin": "yangjiang"
+ },
+ "珠海": {
+ "pinyin": "zhuhai"
+ },
+ "云浮": {
+ "pinyin": "yunfu"
+ },
+ "肇庆": {
+ "pinyin": "zhaoqing"
+ },
+ "江门": {
+ "pinyin": "jiangmen"
+ },
+ "佛山": {
+ "pinyin": "foshan"
+ },
+ "中山": {
+ "pinyin": "zhongshan"
+ },
+ "东莞": {
+ "pinyin": "dongguan"
+ },
+ "清远": {
+ "pinyin": "qingyuan"
+ },
+ "深圳": {
+ "pinyin": "shenzhen"
+ },
+ "惠州": {
+ "pinyin": "huizhou"
+ },
+ "河源": {
+ "pinyin": "heyuan"
+ },
+ "韶关": {
+ "pinyin": "shaoguan"
+ },
+ "汕尾": {
+ "pinyin": "shanwei"
+ },
+ "汕头": {
+ "pinyin": "shantou"
+ },
+ "揭阳": {
+ "pinyin": "jieyang"
+ },
+ "潮州": {
+ "pinyin": "chaozhou"
+ },
+ "梅州": {
+ "pinyin": "meizhou"
+ }
+ },
+ "广西": {
+ "南宁": {
+ "pinyin": "nanning"
+ },
+ "崇左": {
+ "pinyin": "chongzuo"
+ },
+ "防城港": {
+ "pinyin": "fangchenggang"
+ },
+ "北海": {
+ "pinyin": "beihai"
+ },
+ "钦州": {
+ "pinyin": "qinzhou"
+ },
+ "百色": {
+ "pinyin": "baise"
+ },
+ "贵港": {
+ "pinyin": "guigang"
+ },
+ "来宾": {
+ "pinyin": "laibin"
+ },
+ "河池": {
+ "pinyin": "hechi"
+ },
+ "柳州": {
+ "pinyin": "liuzhou"
+ },
+ "玉林": {
+ "pinyin": "yulin"
+ },
+ "梧州": {
+ "pinyin": "wuzhou"
+ },
+ "桂林": {
+ "pinyin": "guilin"
+ },
+ "贺州": {
+ "pinyin": "hezhou"
+ }
+ },
+ "海南": {
+ "海口": {
+ "pinyin": "haikou"
+ },
+ "西沙": {
+ "pinyin": "xisha"
+ },
+ "三亚": {
+ "pinyin": "sanya"
+ },
+ "乐东": {
+ "pinyin": "ledong"
+ },
+ "五指山": {
+ "pinyin": "wuzhishan"
+ },
+ "东方": {
+ "pinyin": "dongfang"
+ },
+ "昌江": {
+ "pinyin": "changjiang"
+ },
+ "白沙": {
+ "pinyin": "baisha"
+ },
+ "儋州": {
+ "pinyin": "danzhou"
+ },
+ "保亭": {
+ "pinyin": "baoting"
+ },
+ "陵水": {
+ "pinyin": "lingshui"
+ },
+ "万宁": {
+ "pinyin": "wanning"
+ },
+ "琼中": {
+ "pinyin": "qiongzhong"
+ },
+ "屯昌": {
+ "pinyin": "tunchang"
+ },
+ "琼海": {
+ "pinyin": "qionghai"
+ },
+ "文昌": {
+ "pinyin": "wenchang"
+ },
+ "临高": {
+ "pinyin": "lingao"
+ },
+ "澄迈": {
+ "pinyin": "chengmai"
+ },
+ "定安": {
+ "pinyin": "dingan"
+ },
+ "南沙": {
+ "pinyin": "nansha"
+ },
+ "中沙": {
+ "pinyin": "wuzhishan"
+ }
+ },
+ "重庆": {
+ "-": {
+ "pinyin": "chongqing"
+ }
+ },
+ "四川": {
+ "成都": {
+ "pinyin": "chengdu"
+ },
+ "甘孜": {
+ "pinyin": "ganzi"
+ },
+ "攀枝花": {
+ "pinyin": "panzhihua"
+ },
+ "凉山": {
+ "pinyin": "liangshan"
+ },
+ "雅安": {
+ "pinyin": "yaan"
+ },
+ "乐山": {
+ "pinyin": "leshan"
+ },
+ "眉山": {
+ "pinyin": "meishan"
+ },
+ "宜宾": {
+ "pinyin": "yibin"
+ },
+ "泸州": {
+ "pinyin": "luzhou"
+ },
+ "自贡": {
+ "pinyin": "zigong"
+ },
+ "资阳": {
+ "pinyin": "ziyang"
+ },
+ "内江": {
+ "pinyin": "neijiang"
+ },
+ "遂宁": {
+ "pinyin": "suining"
+ },
+ "南充": {
+ "pinyin": "nanchong"
+ },
+ "广安": {
+ "pinyin": "guangan"
+ },
+ "阿坝": {
+ "pinyin": "aba"
+ },
+ "德阳": {
+ "pinyin": "deyang"
+ },
+ "绵阳": {
+ "pinyin": "mianyang"
+ },
+ "巴中": {
+ "pinyin": "bazhong"
+ },
+ "广元": {
+ "pinyin": "guangyuan"
+ },
+ "达州": {
+ "pinyin": "dazhou"
+ }
+ },
+ "贵州": {
+ "贵阳": {
+ "pinyin": "guiyang"
+ },
+ "兴义": {
+ "pinyin": "xingyi"
+ },
+ "水城": {
+ "pinyin": "shuicheng"
+ },
+ "安顺": {
+ "pinyin": "anshun"
+ },
+ "毕节": {
+ "pinyin": "bijie"
+ },
+ "都匀": {
+ "pinyin": "duyun"
+ },
+ "凯里": {
+ "pinyin": "kaili"
+ },
+ "遵义": {
+ "pinyin": "zunyi"
+ },
+ "铜仁": {
+ "pinyin": "tongren"
+ }
+ },
+ "云南": {
+ "昆明": {
+ "pinyin": "kunming"
+ },
+ "景洪": {
+ "pinyin": "jinghong"
+ },
+ "普洱": {
+ "pinyin": "puer"
+ },
+ "临沧": {
+ "pinyin": "lincang"
+ },
+ "德宏": {
+ "pinyin": "dehong"
+ },
+ "保山": {
+ "pinyin": "baoshan"
+ },
+ "怒江": {
+ "pinyin": "nujiang"
+ },
+ "大理": {
+ "pinyin": "dali"
+ },
+ "香格里拉": {
+ "pinyin": "xianggelila"
+ },
+ "丽江": {
+ "pinyin": "lijiang"
+ },
+ "红河": {
+ "pinyin": "honghe"
+ },
+ "玉溪": {
+ "pinyin": "yuxi"
+ },
+ "楚雄": {
+ "pinyin": "chuxiong"
+ },
+ "文山": {
+ "pinyin": "wenshan"
+ },
+ "曲靖": {
+ "pinyin": "qujing"
+ },
+ "昭通": {
+ "pinyin": "zhaotong"
+ }
+ },
+ "西藏": {
+ "拉萨": {
+ "pinyin": "lasa"
+ },
+ "阿里": {
+ "pinyin": "ali"
+ },
+ "日喀则": {
+ "pinyin": "rikaze"
+ },
+ "山南": {
+ "pinyin": "shannan"
+ },
+ "林芝": {
+ "pinyin": "linzhi"
+ },
+ "那曲": {
+ "pinyin": "naqu"
+ },
+ "昌都": {
+ "pinyin": "changdu"
+ }
+ },
+ "陕西": {
+ "西安": {
+ "pinyin": "xian"
+ },
+ "汉中": {
+ "pinyin": "hanzhong"
+ },
+ "安康": {
+ "pinyin": "ankang"
+ },
+ "宝鸡": {
+ "pinyin": "baoji"
+ },
+ "杨凌": {
+ "pinyin": "yangling"
+ },
+ "咸阳": {
+ "pinyin": "xianyang"
+ },
+ "铜川": {
+ "pinyin": "tongchuan"
+ },
+ "渭南": {
+ "pinyin": "weinan"
+ },
+ "商洛": {
+ "pinyin": "shangluo"
+ },
+ "延安": {
+ "pinyin": "yanan"
+ },
+ "榆林": {
+ "pinyin": "yulin"
+ }
+ },
+ "甘肃": {
+ "兰州": {
+ "pinyin": "lanzhou"
+ },
+ "武都": {
+ "pinyin": "wudu"
+ },
+ "张掖": {
+ "pinyin": "zhangye"
+ },
+ "嘉峪关": {
+ "pinyin": "jiayuguan"
+ },
+ "酒泉": {
+ "pinyin": "jiuquan"
+ },
+ "合作": {
+ "pinyin": "hezuo"
+ },
+ "临夏": {
+ "pinyin": "linxia"
+ },
+ "天水": {
+ "pinyin": "tianshui"
+ },
+ "定西": {
+ "pinyin": "dingxi"
+ },
+ "白银": {
+ "pinyin": "baiyin"
+ },
+ "平凉": {
+ "pinyin": "pingliang"
+ },
+ "武威": {
+ "pinyin": "wuwei"
+ },
+ "金昌": {
+ "pinyin": "jinchang"
+ },
+ "庆阳": {
+ "pinyin": "qingyang"
+ }
+ },
+ "青海": {
+ "西宁": {
+ "pinyin": "xining"
+ },
+ "玉树": {
+ "pinyin": "yushu"
+ },
+ "格尔木": {
+ "pinyin": "geermu"
+ },
+ "果洛": {
+ "pinyin": "guoluo"
+ },
+ "海南": {
+ "pinyin": "hainan"
+ },
+ "海西": {
+ "pinyin": "haixi"
+ },
+ "海北": {
+ "pinyin": "haibei"
+ },
+ "黄南": {
+ "pinyin": "huangnan"
+ },
+ "海东": {
+ "pinyin": "haidong"
+ }
+ },
+ "宁夏": {
+ "银川": {
+ "pinyin": "yinchuan"
+ },
+ "固原": {
+ "pinyin": "guyuan"
+ },
+ "中卫": {
+ "pinyin": "zhongwei"
+ },
+ "吴忠": {
+ "pinyin": "wuzhong"
+ },
+ "石嘴山": {
+ "pinyin": "shizuishan"
+ }
+ },
+ "新疆": {
+ "乌鲁木齐": {
+ "pinyin": "wulumuqi"
+ },
+ "喀什": {
+ "pinyin": "kashi"
+ },
+ "阿图什": {
+ "pinyin": "atushi"
+ },
+ "和田": {
+ "pinyin": "hetian"
+ },
+ "阿拉尔": {
+ "pinyin": "alaer"
+ },
+ "阿克苏": {
+ "pinyin": "akesu"
+ },
+ "伊宁": {
+ "pinyin": "yining"
+ },
+ "博乐": {
+ "pinyin": "bole"
+ },
+ "库尔勒": {
+ "pinyin": "kuerle"
+ },
+ "石河子": {
+ "pinyin": "shihezi"
+ },
+ "吐鲁番": {
+ "pinyin": "tulufan"
+ },
+ "昌吉": {
+ "pinyin": "changji"
+ },
+ "五家渠": {
+ "pinyin": "wujiaqu"
+ },
+ "塔城": {
+ "pinyin": "tacheng"
+ },
+ "克拉玛依": {
+ "pinyin": "kelamayi"
+ },
+ "阿勒泰": {
+ "pinyin": "aletai"
+ },
+ "哈密": {
+ "pinyin": "hami"
+ }
+ },
+ "香港": {
+ "-": {
+ "pinyin": "hong kong"
+ }
+ },
+ "澳门": {
+ "-": {
+ "pinyin": "macao"
+ }
+ },
+ "台湾": {
+ "台北": {
+ "pinyin": "taipei"
+ },
+ "高雄": {
+ "pinyin": "gaoxiong"
+ },
+ "台中": {
+ "pinyin": "taizhong"
+ }
+ }
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/webpack.common.js b/mixly/boards/default_src/arduino/webpack.common.js
new file mode 100644
index 00000000..5e590020
--- /dev/null
+++ b/mixly/boards/default_src/arduino/webpack.common.js
@@ -0,0 +1,13 @@
+const common = require('../../../webpack.common');
+const { merge } = require('webpack-merge');
+
+module.exports = merge(common, {
+ module: {
+ rules: [
+ {
+ test: /\.(txt|c|cpp|h|hpp)$/,
+ type: 'asset/source'
+ }
+ ]
+ }
+});
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/webpack.dev.js b/mixly/boards/default_src/arduino/webpack.dev.js
new file mode 100644
index 00000000..34785049
--- /dev/null
+++ b/mixly/boards/default_src/arduino/webpack.dev.js
@@ -0,0 +1,21 @@
+const path = require('path');
+const common = require('./webpack.common');
+const { merge } = require('webpack-merge');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ESLintPlugin = require('eslint-webpack-plugin');
+
+module.exports = merge(common, {
+ mode: 'development',
+ devtool: 'source-map',
+ plugins: [
+ new ESLintPlugin({
+ context: process.cwd(),
+ }),
+ new HtmlWebpackPlugin({
+ inject: false,
+ template: path.resolve(process.cwd(), 'template.xml'),
+ filename: 'index.xml',
+ minify: false
+ }),
+ ]
+});
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino/webpack.prod.js b/mixly/boards/default_src/arduino/webpack.prod.js
new file mode 100644
index 00000000..331b45f4
--- /dev/null
+++ b/mixly/boards/default_src/arduino/webpack.prod.js
@@ -0,0 +1,27 @@
+const path = require('path');
+const common = require('./webpack.common');
+const { merge } = require('webpack-merge');
+const TerserPlugin = require('terser-webpack-plugin');
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+
+module.exports = merge(common, {
+ mode: 'production',
+ optimization: {
+ minimize: true,
+ minimizer: [
+ new TerserPlugin({
+ extractComments: false,
+ }),
+ new HtmlWebpackPlugin({
+ inject: false,
+ template: path.resolve(process.cwd(), 'template.xml'),
+ filename: 'index.xml',
+ minify: {
+ removeAttributeQuotes: true,
+ collapseWhitespace: true,
+ removeComments: true,
+ }
+ })
+ ]
+ }
+});
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/.npmignore b/mixly/boards/default_src/arduino_avr/.npmignore
new file mode 100644
index 00000000..21ab2a3e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/.npmignore
@@ -0,0 +1,3 @@
+node_modules
+build
+origin
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/actuator.js b/mixly/boards/default_src/arduino_avr/blocks/actuator.js
new file mode 100644
index 00000000..f9f4b7c3
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/actuator.js
@@ -0,0 +1,1392 @@
+import * as Blockly from 'blockly/core';
+import { Profile } from 'mixly';
+
+const ACTUATOR_HUE = 100;
+
+export const servo_move = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SERVO)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendValueInput("DEGREE", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DEGREE_0_180);
+ this.appendValueInput("DELAY_TIME", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DELAY + '(' + Blockly.Msg.MIXLY_MILLIS + ')');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERVO_MOVE);
+ // this.setFieldValue("2", "PIN");
+ }
+};
+
+export const servo_writeMicroseconds = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SERVO)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendValueInput("DEGREE", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SERVO_WRITEMICROSECONDS);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SERVO_WRITEMICROSECONDS);
+ // this.setFieldValue("2", "PIN");
+ }
+};
+
+export const servo_read_degrees = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SERVO)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_READ_DEGREES)
+ this.setOutput(true, Number);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERVO_READ);
+ // this.setFieldValue("2", "PIN");
+ }
+};
+
+export const servo_move1 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput()
+ .appendField("模式")
+ .appendField(new Blockly.FieldDropdown([["Servo", "0"], ["Timer2ServoPwm", "1"]]), "mode");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SERVO)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendValueInput("DEGREE", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DEGREE_0_180);
+ this.appendValueInput("DELAY_TIME", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DELAY + '(' + Blockly.Msg.MIXLY_MILLIS + ')');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERVO_MOVE);
+ // this.setFieldValue("2", "PIN");
+ }
+};
+
+export const servo_writeMicroseconds1 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput()
+ .appendField("模式")
+ .appendField(new Blockly.FieldDropdown([["Servo", "0"], ["Timer2ServoPwm", "1"]]), "mode");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SERVO)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendValueInput("DEGREE", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SERVO_WRITEMICROSECONDS);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SERVO_WRITEMICROSECONDS);
+ // this.setFieldValue("2", "PIN");
+ }
+};
+
+export const servo_read_degrees1 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput()
+ .appendField("模式")
+ .appendField(new Blockly.FieldDropdown([["Servo", "0"], ["Timer2ServoPwm", "1"]]), "mode");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SERVO)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_READ_DEGREES)
+ this.setOutput(true, Number);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERVO_READ);
+ // this.setFieldValue("2", "PIN");
+ }
+};
+
+export const tone_notes = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(tone_notes.TONE_NOTES), 'STAT');
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TONE_NOTE);
+ },
+ TONE_NOTES: [
+ ["NOTE_C3", "131"],
+ ["NOTE_D3", "147"],
+ ["NOTE_E3", "165"],
+ ["NOTE_F3", "175"],
+ ["NOTE_G3", "196"],
+ ["NOTE_A3", "220"],
+ ["NOTE_B3", "247"],
+ ["NOTE_C4", "262"],
+ ["NOTE_D4", "294"],
+ ["NOTE_E4", "330"],
+ ["NOTE_F4", "349"],
+ ["NOTE_G4", "392"],
+ ["NOTE_A4", "440"],
+ ["NOTE_B4", "494"],
+ ["NOTE_C5", "523"],
+ ["NOTE_D5", "587"],
+ ["NOTE_E5", "659"],
+ ["NOTE_F5", "698"],
+ ["NOTE_G5", "784"],
+ ["NOTE_A5", "880"],
+ ["NOTE_B5", "988"],
+ ["NOTE_C6", "1047"],
+ ["NOTE_D6", "1175"],
+ ["NOTE_E6", "1319"],
+ ["NOTE_F6", "1397"],
+ ["NOTE_G6", "1568"],
+ ["NOTE_A6", "1760"],
+ ["NOTE_B6", "1976"],
+ ["NOTE_C7", "2093"],
+ ["NOTE_D7", "2349"],
+ ["NOTE_E7", "2637"],
+ ["NOTE_F7", "2794"],
+ ["NOTE_G7", "3136"],
+ ["NOTE_A7", "3520"],
+ ["NOTE_B7", "3951"]
+ ]
+};
+
+export const controls_tone = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_TONE)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput('FREQUENCY')
+ .setCheck(Number)
+ //.setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_FREQUENCY);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_TONE);
+ }
+};
+
+export const controls_notone = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_NOTONE)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_NOTONE);
+ }
+};
+
+export const controls_tone_noTimer = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_TONE_NOTIMER)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput('FREQUENCY')
+ .setCheck(Number)
+ //.setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_FREQUENCY);
+ this.appendValueInput('DURATION')
+ .setCheck(Number)
+ //.setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DURATION);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MILLIS);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_TONE2);
+ }
+};
+
+export const controls_notone_noTimer = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_NOTONE_NOTIMER)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_NOTONE);
+ }
+};
+
+export const group_stepper_setup = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_STEPPER_SETUP_STEPPER)
+ .appendField(new Blockly.FieldTextInput('mystepper'), 'VAR');
+ this.appendValueInput("PIN1", Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_PIN1)
+ .setCheck(Number);
+ this.appendValueInput("PIN2", Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_PIN2)
+ .setCheck(Number);
+ this.appendValueInput('steps')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPSPERREVOLUTION);
+ this.appendValueInput('speed')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_SET_SPEED);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STEPPER_STEP);
+ }
+};
+
+export const group_stepper_setup2 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_STEPPER_SETUP_STEPPER)
+ .appendField(new Blockly.FieldTextInput('mystepper'), 'VAR');
+ this.appendValueInput("PIN1", Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_PIN1)
+ .setCheck(Number);
+ this.appendValueInput("PIN2", Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_PIN2)
+ .setCheck(Number);
+ this.appendValueInput("PIN3", Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_PIN3)
+ .setCheck(Number);
+ this.appendValueInput("PIN4", Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_PIN4)
+ .setCheck(Number);
+ this.appendValueInput('steps')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPSPERREVOLUTION);
+ this.appendValueInput('speed')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_SET_SPEED);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STEPPER_STEP2);
+ }
+};
+
+export const group_stepper_move = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_STEPPER)
+ .appendField(new Blockly.FieldTextInput('mystepper'), 'VAR');
+ this.appendValueInput('step')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEPPER_STEP);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STEPPER_MOVE);
+ }
+};
+
+export const RGB_color_seclet = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldColour("ff0000"), "COLOR");
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_PIXE_TOOLTIP);
+ }
+};
+
+export const RGB_color_rgb = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendValueInput("R")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_R);
+ this.appendValueInput("G")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_G);
+ this.appendValueInput("B")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_B);
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip('');
+ }
+};
+
+//RGB
+export const display_rgb_init = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB + Blockly.Msg.MIXLY_SETUP)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_TYPE)
+ .appendField(new Blockly.FieldDropdown(display_rgb_init.DISPLAY_RGB_TYPE), "TYPE");
+ this.appendValueInput("LEDCOUNT")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_COUNT);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip('');
+ // this.setFieldValue("12", "PIN");
+ },
+ DISPLAY_RGB_TYPE: [
+ ["NEO_GRB", "NEO_GRB"],
+ ["NEO_RGB", "NEO_RGB"],
+ ["NEO_RGBW", "NEO_RGBW"]
+ ]
+};
+
+export const display_rgb_Brightness = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendValueInput("Brightness")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_BRIGHTNESS);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip('');
+ // this.setFieldValue("12", "PIN");
+ }
+};
+
+export const display_rgb = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendValueInput("_LED_")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_NUM);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip('');
+ // this.setFieldValue("12", "PIN");
+ }
+};
+
+export const display_rgb_show = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB_SHOW)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};
+
+export const display_rgb_rainbow1 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendValueInput("WAIT")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGBdisplay_rgb_rainbow1);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ // this.setFieldValue("12", "PIN");
+ }
+};
+
+export const display_rgb_rainbow2 = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendValueInput("WAIT")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGBdisplay_rgb_rainbow2);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ //this.setFieldValue("12", "PIN");
+ }
+};
+
+export const display_rgb_rainbow3 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(display_rgb_rainbow3.DISPLAY_RAINBOW_TYPE), "TYPE");
+ this.appendValueInput("rainbow_color")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_display_rgb_rainbow3);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ // this.setFieldValue("12", "PIN");
+ },
+ DISPLAY_RAINBOW_TYPE: [
+ [Blockly.Msg.MIXLY_RGB_DISPLAY_RAINBOW_TYPE_1, "normal"],
+ [Blockly.Msg.MIXLY_RGB_DISPLAY_RAINBOW_TYPE_2, "change"]
+ ]
+};
+
+export const RGB_color_HSV = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RGB)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendValueInput("_LED_")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_NUM);
+ this.appendValueInput("H")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.HSV_H);
+ this.appendValueInput("S")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.HSV_S);
+ this.appendValueInput("V")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.HSV_V);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip('色调范围0-65536;饱和度范围0-255;明度范围0-255');
+ }
+};
+
+export const Mixly_motor = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MOTOR)
+ .appendField(new Blockly.FieldDropdown(Mixly_motor.MOTOR_TYPE), "MOTOR_TYPE");
+ this.appendDummyInput("")
+ this.appendValueInput("PIN1")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_DIR_PIN + "1");
+ this.appendValueInput("PIN2")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_DIR_PIN + "2");
+ this.appendValueInput("PIN_EN")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("EN" + Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput('speed')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_SPEED);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ },
+ MOTOR_TYPE: [
+ ["L293", "L293"],
+ ["L298", "L298"],
+ ["TB6612FNG", "TB6612FNG"]
+ ]
+};
+
+export const Motor_8833 = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("L293/298/DRV8833")
+ .appendField(Blockly.Msg.MIXLY_MOTOR);
+ this.appendDummyInput("")
+ this.appendValueInput("PIN1")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_SPEED_PIN);
+ this.appendValueInput("PIN2")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_DIR_PIN);
+ this.appendValueInput('speed')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_SPEED);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+//GD5800 MP3播放设备选择
+export const GD5800_MP3_Set_Device = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("GD5800" + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("RXPIN", Number)
+ .appendField("TX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("TXPIN", Number)
+ .appendField("RX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MP3_SOURCE)
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown(GD5800_MP3_Set_Device.GD5800_MP3_Device), "DEVICEID");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ },
+ GD5800_MP3_Device: [
+ ["Flash", "MP3_DEVICE_FLASH"],//内部Flash
+ [Blockly.Msg.MIXLY_MP3_UDISK, "MP3_DEVICE_UDISK"]//外部U盘
+ ]
+};
+
+//GD5800 MP3模块
+export const GD5800_MP3_CONTROL = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("GD5800" + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("RXPIN", Number)
+ .appendField("TX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("TXPIN", Number)
+ .appendField("RX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown(GD5800_MP3_CONTROL.GD5800_MP3_CONTROL_TYPE), "CONTROL_TYPE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ },
+ GD5800_MP3_CONTROL_TYPE: [
+ [Blockly.Msg.MIXLY_MP3_PLAY, "play();"],
+ [Blockly.Msg.MIXLY_MP3_PAUSE, "pause();"],
+ [Blockly.Msg.MIXLY_MP3_NEXT, "next();"],
+ [Blockly.Msg.MIXLY_MP3_PREV, "prev();"],
+ [Blockly.Msg.MIXLY_MP3_VOL_UP, "volumeUp();"],
+ [Blockly.Msg.MIXLY_MP3_VOL_DOWN, "volumeDn();"]
+ ]
+};
+
+//GD5800 MP3模块循环模式
+export const GD5800_MP3_LOOP_MODE = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("GD5800" + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("RXPIN", Number)
+ .appendField("TX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("TXPIN", Number)
+ .appendField("RX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MP3_LOOP_MODE)
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown(GD5800_MP3_LOOP_MODE.GD5800_MP3_LOOP_MODE_TYPE), "LOOP_MODE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ },
+ GD5800_MP3_LOOP_MODE_TYPE: [
+ [Blockly.Msg.MIXLY_MP3_LOOP_ALL, "MP3_LOOP_ALL"],
+ [Blockly.Msg.MIXLY_MP3_LOOP_FOLDER, "MP3_LOOP_FOLDER"],
+ [Blockly.Msg.MIXLY_MP3_LOOP_ONE, "MP3_LOOP_ONE"],
+ [Blockly.Msg.MIXLY_MP3_LOOP_RAM, "MP3_LOOP_RAM"]
+ ]
+};
+
+//GD5800 MP3模块EQ模式
+export const GD5800_MP3_EQ_MODE = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("GD5800" + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("RXPIN", Number)
+ .appendField("TX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("TXPIN", Number)
+ .appendField("RX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MP3_EQ_MODE)
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown(GD5800_MP3_EQ_MODE.GD5800_MP3_EQ_MODE_TYPE), "EQ_MODE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ },
+ GD5800_MP3_EQ_MODE_TYPE: [
+ [Blockly.Msg.MIXLY_MP3_EQ_NORMAL, "MP3_EQ_NORMAL"],
+ [Blockly.Msg.MIXLY_MP3_EQ_POP, "MP3_EQ_POP"],
+ [Blockly.Msg.MIXLY_MP3_EQ_ROCK, "MP3_EQ_ROCK"],
+ [Blockly.Msg.MIXLY_MP3_EQ_JAZZ, "MP3_EQ_JAZZ"],
+ [Blockly.Msg.MIXLY_MP3_EQ_CLASSIC, "MP3_EQ_CLASSIC"],
+ [Blockly.Msg.MIXLY_MP3_EQ_BASS, "MP3_EQ_BASS"]
+ ]
+};
+
+//GD5800 MP3模块设置音量
+export const GD5800_MP3_VOL = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("GD5800" + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("RXPIN", Number)
+ .appendField("TX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("TXPIN", Number)
+ .appendField("RX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MP3_VOL);
+ this.appendValueInput("vol", Number)
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//GD5800 MP3模块播放第N首
+export const GD5800_MP3_PLAY_NUM = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("GD5800" + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("RXPIN", Number)
+ .appendField("TX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("TXPIN", Number)
+ .appendField("RX" + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.MIXLY_MP3_PLAY_NUM)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField("首");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+export const voice_module = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("语音模块(68段日常用语)");
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MP3_PLAY)
+ .appendField(new Blockly.FieldDropdown(voice_module.VOICE_LIST), "VOICE");
+ this.appendValueInput("WAIT").setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_WAIT);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ },
+ VOICE_LIST: [
+ ["老师", "0x00"],
+ ["爸爸", "0x01"],
+ ["妈妈", "0x02"],
+ ["爷爷", "0x03"],
+ ["奶奶", "0x04"],
+ ["姥姥", "0x05"],
+ ["姥爷", "0x06"],
+ ["哥哥", "0x07"],
+ ["姐姐", "0x08"],
+ ["叔叔", "0x09"],
+ ["阿姨", "0x0A"],
+ ["上午", "0x0B"],
+ ["下午", "0x0C"],
+ ["晚上", "0x0D"],
+ ["前方", "0x0E"],
+ ["厘米", "0x0F"],
+ ["新年快乐", "0x10"],
+ ["身体健康", "0x11"],
+ ["工作顺利", "0x12"],
+ ["学习进步", "0x13"],
+ ["您好", "0x14"],
+ ["谢谢", "0x15"],
+ ["的", "0x16"],
+ ["祝", "0x17"],
+ ["慢走", "0x18"],
+ ["欢迎光临", "0x19"],
+ ["亲爱的", "0x1A"],
+ ["同学们", "0x1B"],
+ ["工作辛苦了", "0x1C"],
+ ["点", "0x1D"],
+ ["打开", "0x1E"],
+ ["关闭", "0x1F"],
+ ["千", "0x20"],
+ ["百", "0x21"],
+ ["十", "0x22"],
+ ["1", "0x23"],
+ ["2", "0x24"],
+ ["3", "0x25"],
+ ["4", "0x26"],
+ ["5", "0x27"],
+ ["6", "0x28"],
+ ["7", "0x29"],
+ ["8", "0x2A"],
+ ["9", "0x2B"],
+ ["0", "0x2C"],
+ ["当前", "0x2D"],
+ ["转", "0x2E"],
+ ["左", "0x2F"],
+ ["右", "0x30"],
+ ["请", "0x31"],
+ ["已", "0x32"],
+ ["现在", "0x33"],
+ ["是", "0x34"],
+ ["红灯", "0x35"],
+ ["绿灯", "0x36"],
+ ["黄灯", "0x37"],
+ ["温度", "0x38"],
+ ["湿度", "0x39"],
+ ["欢迎常来", "0x3A"],
+ ["还有", "0x3B"],
+ ["秒", "0x3C"],
+ ["分", "0x3D"],
+ ["变", "0x3E"],
+ ["等", "0x3F"],
+ ["下一次", "0x40"],
+ ["功能", "0x41"],
+ ["障碍物", "0x42"],
+ ["世界那么大,我想去看看", "0x43"]
+ ]
+};
+
+
+//DCMotorRun
+export const AFMotorRun = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("AFMotor" + Blockly.Msg.MIXLY_MOTOR)
+ .appendField(new Blockly.FieldDropdown(AFMotorRun.MOTOR), "motor")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_Direction)
+ .appendField(new Blockly.FieldDropdown(AFMotorRun.DIRECTION), "direction")
+ .appendField(Blockly.Msg.MIXLY_SPEED);
+ this.appendValueInput("speed", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip('');
+ },
+ MOTOR: [
+ ["M1", "1"],
+ ["M2", "2"],
+ ["M3", "3"],
+ ["M4", "4"],
+ ],
+ DIRECTION: [
+ [Blockly.Msg.MIXLY_FORWARD, "FORWARD"],
+ [Blockly.Msg.MIXLY_BACKWARD, "BACKWARD"],
+ ]
+};
+
+//DCMotorStop
+export const AFMotorStop = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_STOP + "AFMotor" + Blockly.Msg.MIXLY_MOTOR)
+ .appendField(new Blockly.FieldDropdown(AFMotorStop.MOTOR), "motor");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ },
+ MOTOR: [
+ ["M1", "1"],
+ ["M2", "2"],
+ ["M3", "3"],
+ ["M4", "4"],
+ ]
+};
+
+//初始化DFPlayer Mini
+export const arduino_dfplayer_mini_begin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + " " + Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("dfplayer_pin")
+ .setCheck(null)
+ .appendField(Blockly.Msg.USE_SERIAL_PORT);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_SETUP + " DFPlayer Mini");
+ this.setHelpUrl("");
+ }
+};
+
+//定义DFPlayer Mini 所使用的串口类型
+export const arduino_dfplayer_mini_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ ["Serial", "Serial"],
+ ["SoftwareSerial", "mySerial"],
+ ["SoftwareSerial1", "mySerial1"],
+ ["SoftwareSerial2", "mySerial2"],
+ ["SoftwareSerial3", "mySerial3"]
+ ]), "pin_type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(65);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 设置串口通信的超时时间
+export const arduino_dfplayer_mini_setTimeOut = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("timeout_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DFPLAYER_MINI_SET_TIMEOUT);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_MILLIS);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_SET_TIMEOUT_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 设置音量
+export const arduino_dfplayer_mini_volume = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("volume_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DFPLAYER_MINI_SET_VOLUME);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_SET_VOLUME_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 音量+|-
+export const arduino_dfplayer_mini_volume_up_down = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_MP3_VOL_UP, "volumeUp"],
+ [Blockly.Msg.MIXLY_MP3_VOL_DOWN, "volumeDown"]
+ ]), "volume_type");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_VOLUME_UP_DOWN_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 设置音效
+export const arduino_dfplayer_mini_EQ = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("eq_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DFPLAYER_MINI_SET_EQ);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_SET_EQ_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 定义音效类型
+export const arduino_dfplayer_mini_EQ_type = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_MP3_EQ_NORMAL, "DFPLAYER_EQ_NORMAL"],
+ [Blockly.Msg.MIXLY_MP3_EQ_POP, "DFPLAYER_EQ_POP"],
+ [Blockly.Msg.MIXLY_MP3_EQ_ROCK, "DFPLAYER_EQ_ROCK"],
+ [Blockly.Msg.MIXLY_MP3_EQ_CLASSIC, "DFPLAYER_EQ_CLASSIC"],
+ [Blockly.Msg.MIXLY_MP3_EQ_JAZZ, "DFPLAYER_EQ_JAZZ"],
+ [Blockly.Msg.MIXLY_MP3_EQ_BASS, "DFPLAYER_EQ_BASS"]
+ ]), "eq_type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 指定播放设备
+export const arduino_dfplayer_mini_outputDevice = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("outputdevice_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DFPLAYER_MINI_SET_OUTPUTDEVICE);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_SET_OUTPUTDEVICE_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 定义播放设备类型
+export const arduino_dfplayer_mini_outputDevice_type = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ ["SD卡", "DFPLAYER_DEVICE_SD"],
+ ["U盘", "DFPLAYER_DEVICE_U_DISK"],
+ ["AUX", "DFPLAYER_DEVICE_AUX"],
+ ["SLEEP", "DFPLAYER_DEVICE_SLEEP"],
+ ["FLASH", "DFPLAYER_DEVICE_FLASH"]
+ ]), "outputdevice_type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 设置-1
+export const arduino_dfplayer_set_1 = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name")
+ .appendField(" ")
+ .appendField(new Blockly.FieldDropdown(arduino_dfplayer_set_1.DATA), "set_data");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ },
+ DATA: [
+ [Blockly.Msg.MIXLY_MP3_PREV, "previous"],
+ [Blockly.Msg.MIXLY_MP3_NEXT, "next"],
+ [Blockly.Msg.MIXLY_MP3_PLAY, "start"],
+ [Blockly.Msg.MIXLY_MP3_PAUSE, "pause"],
+ [Blockly.Msg.DFPLAYER_MINI_STOP_ADVERTISE, "stopAdvertise"],
+ [Blockly.Msg.DFPLAYER_MINI_ENABLE_LOOP, "enableLoop"],
+ [Blockly.Msg.DFPLAYER_MINI_DISABLE_LOOP, "disableLoop"],
+ [Blockly.Msg.DFPLAYER_MINI_ENABLE_LOOP_ALL, "enableLoopAll"],
+ [Blockly.Msg.DFPLAYER_MINI_DISABLE_LOOP_ALL, "disableLoopAll"],
+ [Blockly.Msg.DFPLAYER_MINI_RANDOM_ALL, "randomAll"],
+ [Blockly.Msg.DFPLAYER_MINI_ENABLE_DAC, "enableDAC"],
+ [Blockly.Msg.DFPLAYER_MINI_DISABLE_DAC, "disableDAC"],
+ [Blockly.Msg.DFPLAYER_MINI_SLEEP, "sleep"],
+ [Blockly.Msg.HTML_RESET, "reset"]
+ ]
+};
+
+//DFPlayer Mini 播放和循环指定曲目
+export const arduino_dfplayer_play_loop = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("play_data")
+ .setCheck(null)
+ .appendField(" ")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_MP3_PLAY, "play"],
+ [Blockly.Msg.MIXLY_MP3_LOOP_ONE, "loop"],
+ [Blockly.Msg.DFPLAYER_MINI_ADVERTISE, "advertise"],
+ [Blockly.Msg.DFPLAYER_MINI_PLAYMP3FOLDER, "playMp3Folder"]
+ ]), "play_type")
+ .appendField(Blockly.Msg.DFPLAYER_MINI_SONG);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_LOOP_TOOLTIP);
+ this.setHelpUrl("");
+ },
+ onchange: function () {
+ var dropdown_play_type = this.getFieldValue('play_type');
+ if (dropdown_play_type == 'advertise')
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_ADVERTISE_TOOLTIP);
+ else if (dropdown_play_type == 'playMp3Folder')
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_PLAYMP3FOLDER_TOOLTIP);
+ else
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_LOOP_TOOLTIP);
+ }
+};
+
+//DFPlayer Mini 播放指定文件夹下的曲目
+export const arduino_dfplayer_playFolder = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("fold_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_MP3_PLAY)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.DFPLAYER_MINI_FOLDER, "playFolder"],
+ [Blockly.Msg.DFPLAYER_MINI_LARGEFOLDER, "playLargeFolder"]
+ ]), "fold_type");
+ this.appendValueInput("play_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DFPLAYER_MINI_SONG);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_PLAYFOLDER_TOOLTIP);
+ this.setHelpUrl("");
+ },
+ onchange: function () {
+ var dropdown_fold_type = this.getFieldValue('fold_type');
+ if (dropdown_fold_type == 'playFolder')
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_PLAYFOLDER_TOOLTIP);
+ else
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_PLAY_PLAYLARGEFOLDER_TOOLTIP);
+ }
+};
+
+//DFPlayer Mini 循环播放指定文件夹下的曲目
+export const arduino_dfplayer_loopFolder = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("fold_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DFPLAYER_MINI_LOOP_FOLDER);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_LOOP_FOLDER_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 获取当前信息
+export const arduino_dfplayer_read_now = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendDummyInput()
+ .appendField(' ' + Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_PULSEIN_STAT, "readState"],
+ [Blockly.Msg.MIXLY_MP3_VOL, "readVolume"],
+ [Blockly.Msg.MIXLY_MP3_EQ_MODE, "readEQ"]
+ ]), "read_type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_READ_NOW_DATA_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 获取U盘|SD卡|FLASH的总文件数
+export const arduino_dfplayer_readFileCounts = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("device_type")
+ .setCheck(null)
+ .appendField(' ' + Blockly.Msg.MIXLY_GET);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.DFPLAYER_MINI_READ_FILE_COUNTS, "readFileCounts"],
+ [Blockly.Msg.DFPLAYER_MINI_READ_CURRENT_FILE_NUMBER, "readCurrentFileNumber"]
+ ]), "play_data");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_READ_FILE_COUNTS_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+//DFPlayer Mini 获取指定文件夹下的文件数
+export const arduino_dfplayer_readFileCountsInFolder = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendValueInput("folder_data")
+ .setCheck(null)
+ .appendField(' ' + Blockly.Msg.MIXLY_GET + ' ' + Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MKDIR);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.DFPLAYER_MINI_READ_FILE_COUNTS);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_READ_FILE_COUNTS_INFOLDER_TOOLTIP);
+ this.setHelpUrl("");
+ }
+};
+
+export const arduino_dfplayer_available = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.YX5200_MP3)
+ .appendField(new Blockly.FieldTextInput("myPlayer"), "dfplayer_name");
+ this.appendDummyInput()
+ .appendField(".")
+ .appendField(new Blockly.FieldDropdown([
+ ["available", "available"],
+ ["readType", "readType"], ["read", "read"]
+ ]), "type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(ACTUATOR_HUE);
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_AVAILABLE_TOOLTIP);
+ this.setHelpUrl("");
+ },
+ onchange: function () {
+ var dropdown_type = this.getFieldValue('type');
+ if (dropdown_type == 'available')
+ this.setTooltip(Blockly.Msg.DFPLAYER_MINI_AVAILABLE_TOOLTIP);
+ else if (dropdown_type == 'readType')
+ this.setTooltip(
+ Blockly.Msg.DFPLAYER_MINI_READ_TYPE_TOOLTIP
+ + "\n" + Blockly.Msg.RETURN_DATA_ANALYSIS + ":"
+ + "\n0 - TimeOut"
+ + "\n1 - WrongStack"
+ + "\n2 - DFPlayerCardInserted"
+ + "\n3 - DFPlayerCardRemoved"
+ + "\n4 - DFPlayerCardOnline"
+ + "\n5 - DFPlayerUSBInserted"
+ + "\n6 - DFPlayerUSBRemoved"
+ + "\n7 - DFPlayerPlayFinished"
+ + "\n8 - DFPlayerError"
+ );
+ else
+ this.setTooltip(
+ Blockly.Msg.DFPLAYER_MINI_READ_TOOLTIP
+ + "\n" + Blockly.Msg.RETURN_DATA_ANALYSIS + ":"
+ + "\n1 - Busy"
+ + "\n2 - Sleeping"
+ + "\n3 - SerialWrongStack"
+ + "\n4 - CheckSumNotMatch"
+ + "\n5 - FileIndexOut"
+ + "\n6 - FileMismatch"
+ + "\n7 - Advertise"
+ );
+ }
+};
+
+export const I2Cmotor = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("")
+ .appendField("I2C" + Blockly.Msg.MIXLY_MOTOR)
+ .appendField(new Blockly.FieldDropdown(I2Cmotor.I2C_Motor_SELECT), "motor");
+ this.appendValueInput("SPEED")
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_MOTOR_SPEED);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ },
+ I2C_Motor_SELECT: [
+ ["M0", "0"],
+ ["M1", "1"],
+ ["M2", "2"],
+ ["M3", "3"],
+ ["M4", "4"],
+ ["M5", "5"],
+ ["M6", "6"],
+ ["M7", "7"]
+ ]
+};
+
+export const M9101X_S_MP3_CONTROL = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("").appendField("N9X01 " + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown(M9101X_S_MP3_CONTROL.M9101X_S_MP3_CONTROL_TYPE), "CONTROL_TYPE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ },
+ M9101X_S_MP3_CONTROL_TYPE: [
+ [Blockly.Msg.MIXLY_MP3_PLAY, "play();"],
+ [Blockly.Msg.MIXLY_MP3_PAUSE, "pause();"],
+ [Blockly.Msg.MIXLY_STOP, "stop();"],
+ [Blockly.Msg.MIXLY_MP3_NEXT, "play_down();"],
+ [Blockly.Msg.MIXLY_MP3_PREV, "play_up();"],
+ [Blockly.Msg.MIXLY_MP3_LOOP_ALL, "cycle_all();"],
+ [Blockly.Msg.MIXLY_MP3_LOOP_ONE, "cycle_single();"],
+ ["切换到TF卡", "set_sd();"],
+ ["切换到" + Blockly.Msg.MIXLY_MP3_UDISK, "set_usb_flash();"],
+ ["切换到MP3模式", "set_mp3();"],
+ ["切换到flash模式", "set_flash();"],
+ ["切换音乐风格", "set_eq();"],
+ ]
+};
+
+//N910X MP3模块 音量设置
+export const M9101X_S_MP3_VOL_CONTROL = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("").appendField("N9X01 " + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("PIN", Number).appendField(Blockly.Msg.MIXLY_PIN).setCheck(Number);
+ this.appendDummyInput("").appendField(Blockly.Msg.MIXLY_MP3_VOL);
+ this.appendValueInput("NUM", Number).appendField(Blockly.Msg.MIXLY_STAT).setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//N910X MP3模块播放第N首
+export const M9101X_S_MP3_PLAY_NUM = {
+ init: function () {
+ this.setColour(ACTUATOR_HUE);
+ this.appendDummyInput("").appendField("N9X01 " + Blockly.Msg.GD5800_MP3);
+ this.appendValueInput("PIN", Number).appendField(Blockly.Msg.MIXLY_PIN).setCheck(Number);
+ this.appendValueInput("NUM", Number).appendField(Blockly.Msg.MIXLY_MP3_PLAY_NUM).setCheck(Number);
+ this.appendDummyInput("").appendField("首");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/blynk.js b/mixly/boards/default_src/arduino_avr/blocks/blynk.js
new file mode 100644
index 00000000..7f5b7ba5
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/blynk.js
@@ -0,0 +1,1376 @@
+import * as Blockly from 'blockly/core';
+
+// const BLYNK0_HUE = 0; //红色
+const BLYNK1_HUE = 159; //Mountain Meadow
+
+//物联网-服务器信息
+export const blynk_usb_server = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 25, 25))
+ .appendField(Blockly.Msg.blynk_USB_SERVER_INFO);
+ this.appendValueInput("auth_key", String)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH)
+ .setCheck([String, Number]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-一键配网
+export const blynk_smartconfig = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField("SmartConfig" + Blockly.Msg.blynk_smartconfig);
+ this.appendValueInput("server_add")
+ .appendField(Blockly.Msg.blynk_SERVER_ADD)
+ .setCheck(String);
+ this.appendValueInput("auth_key", String)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH)
+ .setCheck([String, Number]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl("https://gitee.com/hznupeter/Blynk_IOT/wikis/pages");
+ }
+};
+
+//物联网-服务器信息_uno
+export const blynk_server = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_SERVER_INFO);
+ this.appendValueInput("server_add")
+ .appendField(Blockly.Msg.blynk_SERVER_ADD)
+ .setCheck(String);
+ this.appendValueInput("wifi_ssid")
+ .appendField(Blockly.Msg.blynk_WIFI_SSID)
+ .setCheck(String);
+ this.appendValueInput("wifi_pass")
+ .appendField(Blockly.Msg.blynk_WIFI_PASS)
+ .setCheck(String);
+ this.appendValueInput("auth_key", String)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH)
+ .setCheck([String, Number]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl("https://gitee.com/hznupeter/Blynk_IOT/wikis/pages");
+ }
+};
+
+//虚拟管脚选择
+const BLYNK_VIRTUALPIN_SELECT = [
+ ["V0", "V0"],
+ ["V1", "V1"],
+ ["V2", "V2"],
+ ["V3", "V3"],
+ ["V4", "V4"],
+ ["V5", "V5"],
+ ["V6", "V6"],
+ ["V7", "V7"],
+ ["V8", "V8"],
+ ["V9", "V9"],
+ ["V10", "V10"],
+ ["V11", "V11"],
+ ["V12", "V12"],
+ ["V13", "V13"],
+ ["V14", "V14"],
+ ["V15", "V15"],
+ ["V16", "V16"],
+ ["V17", "V17"],
+ ["V18", "V18"],
+ ["V19", "V19"],
+ ["V20", "V20"],
+ ["V21", "V21"],
+ ["V22", "V22"],
+ ["V23", "V23"],
+ ["V24", "V24"],
+ ["V25", "V25"],
+ ["V26", "V26"],
+ ["V27", "V27"],
+ ["V28", "V28"],
+ ["V29", "V29"],
+ ["V30", "V30"],
+ ["V31", "V31"],
+ ["V32", "V32"],
+ ["V33", "V33"],
+ ["V34", "V34"],
+ ["V35", "V35"],
+ ["V36", "V36"],
+ ["V37", "V37"],
+ ["V38", "V38"],
+ ["V39", "V39"],
+ ["V40", "V40"]
+];
+
+//定时器选择
+const BLYNK_TIMER_SELECT = [
+ ["1", "1"],
+ ["2", "2"],
+ ["3", "3"],
+ ["4", "4"],
+ ["5", "5"],
+ ["6", "6"],
+ ["7", "7"],
+ ["8", "8"],
+ ["9", "9"],
+ ["10", "10"],
+ ["11", "11"],
+ ["12", "12"],
+ ["13", "13"],
+ ["14", "14"],
+ ["15", "15"],
+ ["16", "16"],
+];
+
+//物联网-发送数据到app
+export const blynk_iot_push_data = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_IOT_PUSH_DATA);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendValueInput("data")
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(" ");
+ this.setHelpUrl();
+ }
+};
+
+//从app端获取数据
+export const blynk_iot_get_data = {
+ /**
+ * Block for defining a procedure with no return value.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_IOT_GET_DATA);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendDummyInput()
+ .appendField("", "PARAMS");
+ this.setMutator(new Blockly.icons.MutatorIcon(["procedures_mutatorarg"], this));//添加齿轮
+ this.arguments_ = [];//新增参数名称
+ this.argumentstype_ = [];//新增参数类型
+ this.setStatements_(true);
+ this.setInputsInline(true);
+ this.setPreviousStatement(false, null);
+ this.setNextStatement(false, null);
+ this.statementConnection_ = null;
+ },
+ getVars: function () {
+ return [this.getFieldValue("VAR")];
+ },
+ renameVar: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getFieldValue("VAR"))) {
+ this.setTitleValue(newName, "VAR");
+ }
+ },
+ /**
+ * Add or remove the statement block from this function definition.
+ * @param {boolean} hasStatements True if a statement block is needed.
+ * @this Blockly.Block
+ */
+ setStatements_: function (hasStatements) {
+ if (this.hasStatements_ === hasStatements) {
+ return;
+ }
+ if (hasStatements) {
+ this.appendStatementInput("STACK")
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
+ if (this.getInput("RETURN")) {
+ this.moveInputBefore("STACK", "RETURN");
+ }
+ } else {
+ this.removeInput("STACK", true);
+ }
+ this.hasStatements_ = hasStatements;
+ },
+ /**
+ * Update the display of parameters for this procedure definition block.
+ * Display a warning if there are duplicately named parameters.
+ * @private
+ * @this Blockly.Block
+ */
+ updateParams_: function () {
+ // Check for duplicated arguments.
+ var badArg = false;
+ var hash = {};
+ for (var i = 0; i < this.arguments_.length; i++) {
+ if (hash["arg_" + this.arguments_[i].toLowerCase()]) {
+ badArg = true;
+ break;
+ }
+ hash["arg_" + this.arguments_[i].toLowerCase()] = true;
+ }
+ if (badArg) {
+ this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING);
+ } else {
+ this.setWarningText(null);
+ }
+ // Merge the arguments into a human-readable list.
+ var paramString = "";
+ if (this.arguments_.length) {
+ paramString = Blockly.Msg.PROCEDURES_BEFORE_PARAMS +
+ " " + this.arguments_.join(", ");
+ }
+ // The params field is deterministic based on the mutation,
+ // no need to fire a change event.
+ Blockly.Events.disable();
+ this.setFieldValue(paramString, "PARAMS");
+ Blockly.Events.enable();
+ },
+ /**
+ * Create XML to represent the argument inputs.
+ * @param {=boolean} opt_paramIds If true include the IDs of the parameter
+ * quarks. Used by Blockly.Procedures.mutateCallers for reconnection.
+ * @return {!Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = document.createElement("mutation");
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var parameter = document.createElement("arg");
+ parameter.setAttribute("name", this.arguments_[i]);
+ parameter.setAttribute("vartype", this.argumentstype_[i]);//新增
+ container.appendChild(parameter);
+ }
+
+ // Save whether the statement input is visible.
+ if (!this.hasStatements_) {
+ container.setAttribute("statements", "false");
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the argument inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ this.arguments_ = [];
+ this.argumentstype_ = [];//新增
+ for (var i = 0; xmlElement.childNodes[i]; i++) {
+ let childNode = xmlElement.childNodes[i]
+ if (childNode.nodeName.toLowerCase() == "arg") {
+ this.arguments_.push(childNode.getAttribute("name"));
+ this.argumentstype_.push(childNode.getAttribute("vartype"));//新增
+ }
+ }
+ this.updateParams_();
+ // Blockly.Procedures.mutateCallers(this);
+ // Show or hide the statement input.
+ this.setStatements_(xmlElement.getAttribute("statements") !== "false");
+ },
+ /**
+ * 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("procedures_mutatorcontainer");
+ containerBlock.initSvg();
+
+ // Check/uncheck the allow statement box.
+ if (this.getInput("RETURN")) {
+ containerBlock.setFieldValue(this.hasStatements_ ? "TRUE" : "FALSE",
+ "STATEMENTS");
+ } else {
+ containerBlock.getInput("STATEMENT_INPUT").setVisible(false);
+ }
+
+ // Parameter list.
+ var connection = containerBlock.getInput("STACK").connection;
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var paramBlock = workspace.newBlock("procedures_mutatorarg");
+ paramBlock.initSvg();
+ paramBlock.setFieldValue(this.arguments_[i], "NAME");
+ paramBlock.setFieldValue(this.argumentstype_[i], "TYPEVAR");//新增
+ // Store the old location.
+ paramBlock.oldLocation = i;
+ connection.connect(paramBlock.previousConnection);
+ connection = paramBlock.nextConnection;
+ }
+ // Initialize procedure"s callers with blank IDs.
+ // Blockly.Procedures.mutateCallers(this);
+ 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) {
+ // Parameter list.
+ this.arguments_ = [];
+ this.paramIds_ = [];
+ this.argumentstype_ = [];//新增
+ var paramBlock = containerBlock.getInputTargetBlock("STACK");
+ while (paramBlock) {
+ this.arguments_.push(paramBlock.getFieldValue("NAME"));
+ this.argumentstype_.push(paramBlock.getFieldValue("TYPEVAR"));//新增
+ this.paramIds_.push(paramBlock.id);
+ paramBlock = paramBlock.nextConnection &&
+ paramBlock.nextConnection.targetBlock();
+ }
+ this.updateParams_();
+ // Blockly.Procedures.mutateCallers(this);
+
+ // Show/hide the statement input.
+ var hasStatements = containerBlock.getFieldValue("STATEMENTS");
+ if (hasStatements !== null) {
+ hasStatements = hasStatements == "TRUE";
+ if (this.hasStatements_ != hasStatements) {
+ if (hasStatements) {
+ this.setStatements_(true);
+ // Restore the stack, if one was saved.
+ this.statementConnection_ && this.statementConnection_.reconnect(this, "STACK");
+ this.statementConnection_ = null;
+ } else {
+ // Save the stack, then disconnect it.
+ var stackConnection = this.getInput("STACK").connection;
+ this.statementConnection_ = stackConnection.targetConnection;
+ if (this.statementConnection_) {
+ var stackBlock = stackConnection.targetBlock();
+ stackBlock.unplug();
+ stackBlock.bumpNeighbours_();
+ }
+ this.setStatements_(false);
+ }
+ }
+ }
+ },
+ /**
+ * Dispose of any callers.
+ * @this Blockly.Block
+ */
+ dispose: function () {
+ // var name = this.getFieldValue("NAME");
+ // Blockly.Procedures.disposeCallers(name, this.workspace);
+ // Call parent"s destructor.
+ this.constructor.prototype.dispose.apply(this, arguments);
+ },
+ /**
+ * Return the signature of this procedure definition.
+ * @return {!Array} Tuple containing three elements:
+ * - the name of the defined procedure,
+ * - a list of all its arguments,
+ * - that it DOES NOT have a return value.
+ * @this Blockly.Block
+ */
+ // getProcedureDef: function () {
+ // return ["ignoreProcedureIotGetData", this.arguments_, false];
+ // },
+ /**
+ * Return all variables referenced by this block.
+ * @return {!Array.} List of variable names.
+ * @this Blockly.Block
+ */
+ // eslint-disable-next-line no-dupe-keys
+ getVars: function () {
+ return this.arguments_;
+ },
+ /**
+ * Notification that a variable is renaming.
+ * If the name matches one of this block"s variables, rename it.
+ * @param {string} oldName Previous name of variable.
+ * @param {string} newName Renamed variable.
+ * @this Blockly.Block
+ */
+ // eslint-disable-next-line no-dupe-keys
+ renameVar: function (oldName, newName) {
+ var change = false;
+ for (var i = 0; i < this.arguments_.length; i++) {
+ if (Blockly.Names.equals(oldName, this.arguments_[i])) {
+ this.arguments_[i] = newName;
+ change = true;
+ }
+ }
+ if (change) {
+ this.updateParams_();
+ // Update the mutator"s variables if the mutator is open.
+ if (this.mutator.isVisible()) {
+ var blocks = this.mutator.workspace_.getAllBlocks();
+ for (var i = 0; blocks[i]; i++) {
+ let block = blocks[i];
+ if (block.type == "procedures_mutatorarg" &&
+ Blockly.Names.equals(oldName, block.getFieldValue("NAME"))) {
+ block.setFieldValue(newName, "NAME");
+ }
+ }
+ }
+ }
+ },
+ /**
+ * Add custom menu options to this block"s context menu.
+ * @param {!Array} options List of menu options to add to.
+ * @this Blockly.Block
+ */
+ customContextMenu: function (options) {
+ // Add option to create caller.
+ var option = { enabled: true };
+ var name = this.getFieldValue("NAME");
+ option.text = Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1", name);
+ var xmlMutation = Blockly.utils.xml.createElement("mutation");
+ xmlMutation.setAttribute("name", name);
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var xmlArg = Blockly.utils.xml.createElement("arg");
+ xmlArg.setAttribute("name", this.arguments_[i]);
+ xmlArg.setAttribute("type", this.argumentstype_[i]);//新增
+ xmlMutation.appendChild(xmlArg);
+ }
+ var xmlBlock = Blockly.utils.xml.createElement("block", null, xmlMutation);
+ xmlBlock.setAttribute("type", this.callType_);
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+
+ // Add options to create getters for each parameter.
+ if (!this.isCollapsed()) {
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var option = { enabled: true };
+ var name = this.arguments_[i];
+ option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1", name);
+ var xmlField = Blockly.utils.xml.createElement("field", null, name);
+ xmlField.setAttribute("name", "VAR");
+ xmlField.setAttribute("type", "TYPEVAR");//新增
+ var xmlBlock = Blockly.utils.xml.createElement("block", null, xmlField);
+ xmlBlock.setAttribute("type", "variables_get");
+ option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
+ options.push(option);
+ }
+ }
+ },
+ callType_: "procedures_callnoreturn"
+};
+
+//blynk定时器
+export const Blynk_iot_timer = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendValueInput("TIME")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.blynk_TIMER)
+ .appendField(new Blockly.FieldDropdown(BLYNK_TIMER_SELECT), "timerNo");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MILLIS);
+ this.appendStatementInput("DO")
+ .appendField(Blockly.Msg.MIXLY_MSTIMER2_DO);
+ this.setPreviousStatement(false);
+ this.setNextStatement(false);
+ }
+};
+
+//blynk服务器连接状态
+export const Blynk_connect_state = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.Blynk_connect_state);
+ this.setOutput(true, null);
+ this.setHelpUrl("");
+ }
+};
+
+const BLYNK_CONNECT_STATE_SELECT = [
+ [Blockly.Msg.BLYNK_CONNECTED, 'BLYNK_CONNECTED'],
+ [Blockly.Msg.BLYNK_DISCONNECTED, 'BLYNK_DISCONNECTED'],
+ [Blockly.Msg.BLYNK_APP_CONNECTED, 'BLYNK_APP_CONNECTED'],
+ [Blockly.Msg.BLYNK_APP_DISCONNECTED, 'BLYNK_APP_DISCONNECTED'],
+];
+
+//blynk 连接状态函数
+export const Blynk_iot_CONNECT_STATE = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_CONNECT_STATE_SELECT), "state");
+ this.appendStatementInput("DO")
+ .appendField(Blockly.Msg.MIXLY_MSTIMER2_DO);
+ this.setPreviousStatement(false);
+ this.setNextStatement(false);
+ }
+};
+
+//blynk同步所有管脚状态
+export const Blynk_iot_BLYNK_syncAll = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.BLYNK_syncAll);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+//blynk同步虚拟管脚状态
+export const blynk_iot_syncVirtual = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_IOT_syncVirtual);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(" ");
+ this.setHelpUrl();
+ }
+};
+
+//物联网-LED组件颜色&开关
+export const blynk_iot_WidgetLED_COLOR = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_led.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_IOT_WidgetLED);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.appendValueInput("STAT")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .setCheck([Number, Boolean]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(" ");
+ this.setHelpUrl();
+ }
+};
+
+//物联网-LED组件颜色&亮度
+export const blynk_iot_WidgetLED_VALUE = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_led.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_IOT_WidgetLED);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.MIXLY_BRIGHTNESS)
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(" ");
+ this.setHelpUrl();
+ }
+};
+
+const AC_TYPE = [
+ [Blockly.Msg.blynk_IOT_GREE, "Gree"],
+ [Blockly.Msg.blynk_IOT_MIDEA, "Midea"],
+];
+
+const AC_POWER = [
+ [Blockly.Msg.MIXLY_ON, "true"],
+ [Blockly.Msg.MIXLY_OFF, "false"]
+];
+
+const AC_MODE = [
+ [Blockly.Msg.blynk_IOT_FAN, "FAN"],
+ [Blockly.Msg.blynk_IOT_HEAT, "HEAT"],
+ [Blockly.Msg.blynk_IOT_COOL, "COOL"],
+ [Blockly.Msg.blynk_IOT_DRY, "DRY"],
+ [Blockly.Msg.blynk_IOT_AUTO, "AUTO"]
+];
+
+const AC_FAN = [
+ [Blockly.Msg.blynk_IOT_FAN_3, "FAN_3"],
+ [Blockly.Msg.blynk_IOT_FAN_2, "FAN_2"],
+ [Blockly.Msg.blynk_IOT_FAN_1, "FAN_1"],
+ [Blockly.Msg.blynk_IOT_FAN_0, "FAN_0"]
+];
+
+//红外控制空调
+export const blynk_iot_ir_send_ac = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.blynk_IOT_IR_SEND)
+ .appendField(new Blockly.FieldDropdown(AC_TYPE), "AC_TYPE");
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.blynk_IOT_IR_POWER)
+ .appendField(new Blockly.FieldDropdown(AC_POWER), "AC_POWER");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MODE)
+ .appendField(new Blockly.FieldDropdown(AC_MODE), "AC_MODE");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.blynk_IOT_IR_FAN)
+ .appendField(new Blockly.FieldDropdown(AC_FAN), "AC_FAN");
+ this.appendValueInput("AC_TEMP", Number)
+ .appendField(Blockly.Msg.blynk_IOT_IR_TEMP)
+ .setCheck(Number);
+ this.setPreviousStatement(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_IR_SEND_NEC_TOOLTIP);
+ }
+};
+
+//红外接收模块(raw)
+export const blynk_iot_ir_recv_raw = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.blynk_IOT_IR_RECEIVE_RAW)
+ .setCheck(Number);
+ // this.appendValueInput("PIN", Number).appendField(Blockly.Msg.MIXLY_PIN).setCheck(Number);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.blynk_IOT_IR_RECEIVE_RAW_TOOLTIP);
+ }
+};
+
+//红外发送
+export const blynk_iot_ir_send = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.blynk_IOT_IR_SEND)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.blynk_IOT_IR_SEND_CODE)
+ .appendField(new Blockly.FieldTextInput('0,0,0'), 'IR_CODE');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.blynk_IOT_IR_SEND_CODE_TOOLTIP);
+ }
+}
+
+//物联网-发送邮件
+export const blynk_email = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_email.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_EMAIL);
+ this.appendValueInput("email_add")
+ .appendField(Blockly.Msg.blynk_EMAIL_ADD)
+ .setCheck(String);
+ this.appendValueInput("Subject")
+ .appendField(Blockly.Msg.blynk_EMAIL_SUBJECT)
+ .setCheck(String);
+ this.appendValueInput("content")
+ .appendField(Blockly.Msg.blynk_EMAIL_CONTENT)
+ .setCheck(String);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-发送通知
+export const blynk_notify = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_push_notifications.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_NOTIFY);
+ this.appendValueInput("content")
+ .appendField(Blockly.Msg.OLED_STRING)
+ .setCheck([String, Number, Boolean]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-终端组件显示文本
+export const blynk_terminal = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_terminal.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_terminal)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ this.appendValueInput("content")
+ .appendField(Blockly.Msg.OLED_STRING)
+ .setCheck([String, Number, Boolean]);
+ this.appendDummyInput("");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-视频流
+export const blynk_videourl = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_video.png'), 20, 20))
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendValueInput("url")
+ .appendField(Blockly.Msg.blynk_VIDEOURL)
+ .setCheck(String);
+ this.appendDummyInput("");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-桥接授权码
+export const blynk_bridge_auth = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_bridge.png'), 20, 20))
+ .appendField(Blockly.Msg.BLYNK_BRIDGE_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendValueInput("auth")
+ .appendField(Blockly.Msg.blynk_BRIDGE_AUTH)
+ .setCheck(String);
+ this.appendDummyInput("");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-桥接数字输出
+export const blynk_bridge_digitalWrite = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_bridge.png'), 20, 20));
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.BLYNK_BRIDGE_VIRTUALPIN);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendValueInput("PIN", Number)
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_DIGITALWRITE_PIN);
+ this.appendValueInput("STAT")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .setCheck([Number, Boolean]);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-桥接模拟输出
+export const blynk_bridge_AnaloglWrite = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_bridge.png'), 20, 20));
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.BLYNK_BRIDGE_VIRTUALPIN);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendValueInput("PIN", Number)
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_ANALOGWRITE_PIN);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.MIXLY_VALUE2)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-桥接虚拟管脚
+export const blynk_bridge_VPin = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_bridge.png'), 20, 20));
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.BLYNK_BRIDGE_VIRTUALPIN);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin2");
+ this.appendValueInput("NUM")
+ .appendField(Blockly.Msg.MIXLY_VALUE2);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//物联网-RTC组件初始化
+export const blynk_WidgetRTC_init = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_rtc.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_WidgetRTC_init);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.blynk_WidgetRTC_setSyncInterval)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.blynk_WidgetRTC_mintues);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//传感器-实时时钟块_时间变量
+var BLYNK_RTC_TIME_TYPE = [
+ [Blockly.Msg.MIXLY_YEAR, "year"],
+ [Blockly.Msg.MIXLY_MONTH, "month"],
+ [Blockly.Msg.MIXLY_DAY, "day"],
+ [Blockly.Msg.MIXLY_HOUR, "hour"],
+ [Blockly.Msg.MIXLY_MINUTE, "minute"],
+ [Blockly.Msg.MIXLY_SECOND, "second"],
+ [Blockly.Msg.MIXLY_WEEK, "weekday"]
+];
+
+//传感器-实时时钟块_获取时间
+export const blynk_WidgetRTC_get_time = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_rtc.png'), 20, 20))
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.blynk_WidgetRTC_get_time);
+
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(BLYNK_RTC_TIME_TYPE), "TIME_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ }
+};
+
+//播放音乐
+export const blynk_iot_playmusic = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_player.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_iot_playmusic);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setInputsInline(true);
+ this.setTooltip("");
+ }
+};
+
+//从终端获取字符串
+export const blynk_iot_terminal_get = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_terminal.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_IOT_terminal_get);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setInputsInline(true);
+ this.setTooltip("");
+ }
+};
+
+//光线传感器
+export const blynk_light = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_light_sensor.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_LIGHT);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setInputsInline(true);
+ this.setTooltip("");
+ }
+};
+
+//重力传感器
+export const blynk_gravity = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_gravity_sensor.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_GRAVITY);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setInputsInline(true);
+ this.setTooltip("");
+ }
+};
+
+//加速度传感器
+export const blynk_acc = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_accelerometer_sensor.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_ACC);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.blynk_ACC_tooltip);
+ }
+};
+
+//时间输入-简单
+export const blynk_time_input_1 = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/widget_timeinput.png'), 20, 20))
+ .appendField(Blockly.Msg.blynk_time_input_1);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.blynk_ACC_tooltip);
+ }
+};
+
+//lm35温度传感器-arduino
+export const LM35ESP = {
+ init: function () {
+ this.setColour(Blockly.Msg['SENSOR_HUE']);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_LM35);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip('');
+ }
+};
+
+//一键配网(无需安可信)
+export const blynk_AP_config = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_AP_config);
+ this.appendValueInput("server_add")
+ .setCheck(String)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.appendValueInput("auth_key")
+ .setCheck(String)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH)
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.blynk_AP_config_tooltip);
+ this.setHelpUrl("");
+ }
+};
+
+//一键配网手动配置授权码
+export const blynk_AP_config_2 = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_AP_config2);
+ this.appendValueInput("server_add")
+ .setCheck(String)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.blynk_AP_config_tooltip);
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk终端清屏
+export const blynk_terminal_clear = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_terminal_clear);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk LCD显示
+export const blynk_lcd = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_lcd)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ESP32_MIXGO_MUSIC_SHOW_IN + Blockly.Msg.MIXLY_4DIGITDISPLAY_NOMBER1);
+ this.appendValueInput("x")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.DATAFRAME_COLUMN + Blockly.Msg.MIXLY_4DIGITDISPLAY_NOMBER1);
+ this.appendValueInput("y")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.DATAFRAME_RAW);
+ this.appendValueInput("value")
+ .appendField(Blockly.Msg.OLEDDISPLAY)
+ .setCheck(null);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setHelpUrl("");
+ this.setInputsInline(true);
+ }
+};
+
+//Blynk LCD清屏
+export const blynk_lcd_clear = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_lcd)
+ .appendField(Blockly.Msg.MIXLY_LCD_STAT_CLEAR);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setHelpUrl("");
+ }
+};
+
+//ESP32 blynk BLE连接方式
+export const blynk_esp32_ble = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_esp32_ble);
+ this.appendValueInput("auth")
+ .appendField(Blockly.Msg.blynk_IOT_AUTH);
+ this.appendValueInput("name")
+ .setCheck(String)
+ .appendField("BLE")
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.setHelpUrl("");
+ }
+};
+
+//ESP32 blynk Bluetooth连接方式
+export const blynk_esp32_Bluetooth = {
+ init: function () {
+ this.setColour(BLYNK1_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_esp32_Bluetooth);
+ this.appendValueInput("auth")
+ .setCheck(String)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH);
+ this.appendValueInput("name")
+ .setCheck(String)
+ .appendField("Bluetooth")
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.setHelpUrl("");
+ }
+};
+
+//Arduino blynk Bluetooth 连接方式
+export const arduino_blynk_bluetooth = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.arduino_blynk_bluetooth);
+ this.appendValueInput("auth")
+ .setCheck(String)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH);
+ this.appendValueInput("RX")
+ .setCheck(null)
+ .appendField("RX");
+ this.appendValueInput("TX")
+ .setCheck(null)
+ .appendField("TX");
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk Table小部件添加数据
+export const blynk_table = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_table)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ .appendField("ID");
+ this.appendValueInput("id")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.appendValueInput("mingcheng")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.appendValueInput("shujv")
+ .setCheck(null);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk Table小部件更新数据
+export const blynk_table_update = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_table_update)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ .appendField("ID");
+ this.appendValueInput("id")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.appendValueInput("mingcheng")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.appendValueInput("shujv")
+ .setCheck(null);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk Table小部件高亮显示数据
+export const blynk_table_highlight = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_table_highlight)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ .appendField("ID");
+ this.appendValueInput("id")
+ .setCheck(null);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk Table小部件选择数据
+export const blynk_table_select = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_table_select)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ .appendField("ID");
+ this.appendValueInput("id")
+ .setCheck(null);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk Table小部件取消选择数据
+export const blynk_table_unselect = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_table_unselect)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ .appendField("ID");
+ this.appendValueInput("id")
+ .setCheck(null);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+//Blynk Table小部件数据清除
+export const blynk_table_cleardata = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_table_cleardata)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+//ESP32 CAM相机
+export const esp_camera = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("ESP32 CAM mode")
+ .appendField(new Blockly.FieldDropdown([["STA", "1"], ["AP", "0"]]), "mode");
+ this.appendValueInput("wifi_ssid")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_WIFI_SSID);
+ this.appendValueInput("wifi_pass")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_WIFI_PASS);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip(Blockly.Msg.esp_camera);
+ this.setHelpUrl("");
+ }
+};
+
+//ESP32 CAM相机 & blynk
+export const esp_camera_blynk = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("ESP32 CAM & Blynk");
+ this.appendValueInput("wifi_ssid")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_WIFI_SSID);
+ this.appendValueInput("wifi_pass")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_WIFI_PASS);
+ this.appendValueInput("server")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.appendValueInput("auth")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_IOT_AUTH);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip(Blockly.Msg.esp_camera);
+ this.setHelpUrl("");
+ }
+};
+
+export const take_a_photo1 = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.take_a_photo1);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip(Blockly.Msg.take_a_photo1);
+ this.setHelpUrl("");
+ }
+};
+
+export const blynk_table_click = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.BLYNK_TABLE_CLICK)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput("function")
+ .setCheck(null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Advanced/Table_Advanced.ino");
+ }
+};
+
+export const blynk_table_order = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.BLYNK_TABLE_ORDER)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin");
+ this.appendStatementInput("function")
+ .setCheck(null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Advanced/Table_Advanced.ino");
+ }
+};
+
+export const blynk_table_add_data = {
+ init: function () {
+ this.appendValueInput("name")
+ .appendField(Blockly.Msg.blynk_table)
+ .appendField(Blockly.Msg.BLYNK_VIRTUALPIN)
+ .appendField(new Blockly.FieldDropdown(BLYNK_VIRTUALPIN_SELECT), "Vpin")
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.appendValueInput("data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(BLYNK1_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Advanced/Table_Advanced.ino");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/communicate.js b/mixly/boards/default_src/arduino_avr/blocks/communicate.js
new file mode 100644
index 00000000..d2fd513e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/communicate.js
@@ -0,0 +1,776 @@
+import * as Blockly from 'blockly/core';
+import { Profile } from 'mixly';
+
+const COMMUNICATE_HUE = 140;
+
+//红外接收模块
+export const ir_recv = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(new Blockly.FieldTextInput('ir_item'), 'VAR')
+ .appendField(Blockly.Msg.MIXLY_IR_RECEIVE)
+ .setCheck(Number);
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_IR_RECEIVE_YES);
+ this.appendStatementInput('DO2')
+ .appendField(Blockly.Msg.MIXLY_IR_RECEIVE_NO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_IR_RECIEVE_TOOLTIP);
+ },
+ getVars: function () {
+ return [this.getFieldValue('VAR')];
+ },
+ renameVar: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
+ this.setTitleValue(newName, 'VAR');
+ }
+ }
+};
+
+const TYPE = [
+ ['RC5', 'RC5'],
+ ['RC6', 'RC6'],
+ ['NEC', 'NEC'],
+ ['Sony', 'Sony'],
+ ['Panasonic', 'Panasonic'],
+ ['JVC', 'JVC'],
+ ['SAMSUNG', 'SAMSUNG'],
+ ['Whynter', 'Whynter'],
+ ['AiwaRCT501', 'AiwaRCT501'],
+ ['LG', 'LG'],
+ ['Sanyo', 'Sanyo'],
+ ['Mitsubishi', 'Mitsubishi'],
+ ['DISH', 'DISH'],
+ ['SharpRaw', 'SharpRaw'],
+ ['Denon', 'Denon']
+];
+
+//红外发射模块(NEC)
+export const ir_send_nec = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_IR_SEND_NEC1)
+ .appendField(new Blockly.FieldDropdown(TYPE), 'TYPE')
+ .appendField(Blockly.Msg.MIXLY_IR_SEND_NEC2)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendValueInput('data')
+ .setCheck(Number)
+ .appendField(' ' + Blockly.Msg.MIXLY_DATA);
+ this.appendValueInput('bits')
+ .setCheck(Number)
+ .appendField(' ' + Blockly.Msg.MIXLY_BITS);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_IR_SEND_NEC_TOOLTIP);
+ }
+}
+
+//红外接收使能
+export const ir_recv_enable = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_IR_RECEIVE_ENABLE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_IR_ENABLE);
+ }
+};
+
+//红外接收模块(raw)
+export const ir_recv_raw = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_IR_RECEIVE_RAW)
+ .setCheck(Number);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_IR_RECIEVE_RAW_TOOLTIP);
+ }
+};
+
+//红外发射模块(raw)
+export const ir_send_raw = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_IR_SEND_RAW)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendDummyInput("")
+ .appendField(' ' + Blockly.Msg.MIXLY_I2C_SLAVE_WRITE_ARRAY_ARRAYNAME)
+ .appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT');
+ this.appendValueInput('length')
+ .setCheck(Number)
+ .appendField(' ' + Blockly.Msg.MIXLY_LIST_LENGTH);
+ this.appendValueInput('freq')
+ .setCheck(Number)
+ .appendField(' ' + Blockly.Msg.MIXLY_FREQUENCY);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_IR_SEND_RAW_TOOLTIP);
+ }
+};
+
+// IIC通信
+// IIC初始化主机
+export const i2c_master_Init = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + 'I2C' + Blockly.Msg.MIXLY_MASTER);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+// IIC初始化从机
+export const i2c_slave_Init = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + 'I2C' + Blockly.Msg.MIXLY_SALVE + Blockly.Msg.MIXLY_LCD_ADDRESS);
+ this.appendValueInput("i2c_address")
+ .setCheck(null);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_I2C_MASTER_INITHelp);
+ this.setHelpUrl("");
+ }
+};
+
+//IIC主机发送数据
+export const i2c_begin_end_transmission = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("I2C" + Blockly.Msg.MIXLY_MASTER + Blockly.Msg.MIXLY_SEND_DATA);
+ this.appendValueInput("i2c_address")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LCD_ADDRESS);
+ this.appendStatementInput("transmission_data")
+ .setCheck(null);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//IIC写入主从机数据
+export const i2c_write = {
+ init: function () {
+ this.appendValueInput("i2c_write_data")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("I2C" + Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_SEND);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ }
+};
+
+// IIC写入数线数据
+export const i2c_slave_write_array = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('array')
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_WRITE_ARRAY)
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_WRITE_ARRAY_ARRAYNAME);
+ this.appendValueInput('length')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LIST_LEN);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_SLAVE_WRITE_ARRAY);
+ }
+};
+
+// IIC从机读取字节数
+export const i2c_howmany = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_I2C_HOWMANY);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_HOWMANY);
+ }
+};
+
+// IIC主机或从机读取成功吗?
+export const i2c_available = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_I2C_AVAILABLE);
+ this.setOutput(true, Boolean);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_AVAILABLE);
+ }
+};
+
+// IIC主机或从机读取的数据
+export const i2c_read = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_I2C_MASTER_READ2);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_MASTER_READ2);
+ }
+};
+
+//写入寄存器地址
+export const i2c_master_writerReg = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('device')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_MASTER_WRITE);
+ this.appendValueInput('regadd')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_REGADD);
+ this.appendValueInput('value')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_I2C_VALUE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
+//读取寄存器地址
+export const i2c_master_readerReg = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('device')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_MASTER_READ);
+ this.appendValueInput('regadd')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_REGADD);
+ this.appendValueInput('bytes')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_BYTES);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
+export const i2c_slave_onrequest = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_ONREQUEST);
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_SLAVE_ONREQUEST);
+ }
+};
+
+export const i2c_master_writer = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('device')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_MASTER_WRITE);
+ this.appendValueInput('value')
+ .setCheck([String, Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.HTML_VALUE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_MASTER_WRITE);
+ }
+};
+
+export const i2c_master_reader = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('device')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_MASTER_READ);
+ this.appendValueInput('bytes')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_BYTES);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_MASTER_READ);
+ }
+};
+
+export const i2c_master_reader2 = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_I2C_MASTER_READ2);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_MASTER_READ2);
+ }
+};
+
+export const i2c_slave_onreceive = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_ONRECEIVE);
+ this.appendValueInput("onReceive_length")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_I2C_BYTES);
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_SLAVE_ONRECEIVE);
+ }
+};
+
+export const i2c_slave_write = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('value')
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_WRITE)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.HTML_VALUE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_I2C_SLAVE_WRITE);
+ }
+};
+
+//SPI
+export const spi_transfer = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput('pin')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.TO_SPI_SLAVE_PIN);
+ this.appendValueInput('value')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.SPI_TRANSFER);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ const pinValue = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SPI_TRANSFER.replace('%1', pinValue));
+ }
+};
+
+//RFID
+export const RFID_init = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_INITIAL);
+ this.appendDummyInput("")
+ .appendField("SDA")
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SDA");
+ this.appendDummyInput("")
+ .appendField("SCK")
+ .appendField(new Blockly.FieldDropdown(Profile.default.SCK), "SCK");
+ this.appendDummyInput("")
+ .appendField("MOSI")
+ .appendField(new Blockly.FieldDropdown(Profile.default.MOSI), "MOSI");
+ this.appendDummyInput("")
+ .appendField("MISO")
+ .appendField(new Blockly.FieldDropdown(Profile.default.MISO), "MISO");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_INIT);
+ // this.setFieldValue("10", "SDA");
+ }
+};
+
+export const RFID_on = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField("RFID")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_ON_DETECTED);
+ this.appendStatementInput("do_");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_ON);
+ }
+};
+
+//读卡号
+export const RFID_readcardnum = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_READ_CARDNUM)
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_READ);
+
+ }
+};
+
+//串口打印卡号
+/* export const RFID_serialprintcardnum = {
+ init: function() {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField('打印RFID卡号');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+}; */
+
+export const RFID_in = {
+ init: function () {
+ this.appendValueInput("uid_")
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF)
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_READ_CARDNUM_IS);
+ this.appendStatementInput("do_")
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip('');
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_IN);
+ }
+};
+
+//写数据块
+export const RFID_writecarddata = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput("address1")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_WRITE)
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_DATA_BLOCK)
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_WRITE_NUM)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'data1')
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_WRITEBLOCK);
+ }
+};
+
+//读数据块的内容
+export const RFID_readcarddata = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput("address")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_READ)
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_DATA_BLOCK)
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_DATA_FROM)
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_READBLOCK);
+ }
+};
+
+/* //串口打印数据内容
+export const RFID_serialprintcarddata = {
+ init: function() {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendValueInput("address")
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField("打印RFID数据块");
+ this.appendDummyInput("")
+ .appendField("内容")
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};*/
+
+//关闭RFID
+export const RFID_off = {
+ init: function () {
+ this.setColour(COMMUNICATE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_RFID_OFF);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RFID_OFF);
+ }
+};
+
+//初始化RFID
+export const MFRC522_init = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + " RFID")
+ .appendField(new Blockly.FieldTextInput("rfid"), "rfid_name");
+ this.appendValueInput("PIN_SDA")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(" SDA");
+ this.appendValueInput("PIN_SCK")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("SCK");
+ this.appendValueInput("PIN_MOSI")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MOSI");
+ this.appendValueInput("PIN_MISO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MISO");
+ this.appendValueInput("PIN_RST")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("RST");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//RFID侦测到信号
+export const MFRC522_IsNewCard = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("RFID")
+ .appendField(new Blockly.FieldTextInput("rfid"), "rfid_name")
+ .appendField(" " + Blockly.Msg.MIXLY_COMMUNICATION_RFID_ON_DETECTED);
+ this.appendStatementInput("DO")
+ .setCheck(null);
+ this.setInputsInline(false);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//RFID读取卡号
+export const MFRC522_ReadCardUID = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("RFID")
+ .appendField(new Blockly.FieldTextInput("rfid"), "rfid_name")
+ .appendField(" " + Blockly.Msg.MIXLY_RFID_READ_CARD_UID);
+ this.setInputsInline(false);
+ this.setOutput(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//RFID写卡
+export const MFRC522_WriteCard = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("RFID")
+ .appendField(new Blockly.FieldTextInput("rfid"), "rfid_name")
+ .appendField(" " + Blockly.Msg.MIXLY_RFID_WRITE_CARD);
+ this.appendValueInput("block")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_DATA_BLOCK);
+ this.appendValueInput("buffer")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RFID_BYTE_ARRAY);
+ this.appendValueInput("length")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_WRITE_ARRAY_ARRAYLENGTH);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//RFID读卡
+export const MFRC522_ReadCard = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("RFID")
+ .appendField(new Blockly.FieldTextInput("rfid"), "rfid_name")
+ .appendField(" " + Blockly.Msg.MIXLY_RFID_READ_CARD);
+ this.appendValueInput("block")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_COMMUNICATION_DATA_BLOCK);
+ this.appendValueInput("buffer")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.SAVETO + " " + Blockly.Msg.MIXLY_RFID_BYTE_ARRAY);
+ this.appendValueInput("length")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_I2C_SLAVE_WRITE_ARRAY_ARRAYLENGTH);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//SPI 初始化从机
+export const spi_begin_slave = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(
+ Blockly.Msg.MIXLY_SETUP
+ + "SPI" + Blockly.Msg.MIXLY_DEVICE
+ + Blockly.Msg.MIXLY_AS
+ + Blockly.Msg.MIXLY_SALVE
+ );
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const spi_begin_master = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(
+ Blockly.Msg.MIXLY_SETUP
+ + "SPI" + Blockly.Msg.MIXLY_DEVICE
+ + Blockly.Msg.MIXLY_AS
+ + Blockly.Msg.MIXLY_MASTER
+ );
+ this.appendValueInput("spi_slave_pin")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SALVE + Blockly.Msg.MIXLY_PIN);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const spi_transfer_Init = {
+ init: function () {
+ this.appendValueInput("slave_pin")
+ .setCheck(null)
+ .appendField(
+ "SPI" + Blockly.Msg.MIXLY_SEND_DATA
+ + Blockly.Msg.MIXLY_SALVE
+ + Blockly.Msg.MIXLY_PIN
+ );
+ this.appendStatementInput("transfer_data")
+ .setCheck(null);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const spi_transfer_1 = {
+ init: function () {
+ this.appendValueInput("transfer_data")
+ .setCheck(null)
+ .appendField("SPI" + Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_SEND);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const spi_transfer_2 = {
+ init: function () {
+ this.appendValueInput("transfer_data")
+ .setCheck(null)
+ .appendField("SPI" + Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_SEND);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RETURN_DATA);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const spi_slave_interrupt = {
+ init: function () {
+ this.appendValueInput("slave_interrupt_input")
+ .setCheck(null)
+ .appendField(
+ "SPI " + Blockly.Msg.MIXLY_STM32_I2C_SLAVE_RECEIVE_EVENT
+ + " " + Blockly.Msg.MIXLY_STM32_SPI_GET_REGISTER_DATA
+ );
+ this.appendStatementInput("slave_interrupt_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_MSTIMER2_DO);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const spi_slave_receive = {
+ init: function () {
+ this.appendValueInput("slave_receive_data")
+ .setCheck(null)
+ .appendField(
+ "SPI " + Blockly.Msg.MIXLY_SALVE
+ + " " + Blockly.Msg.MIXLY_STM32_SPI_GET_REGISTER_DATA
+ );
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(COMMUNICATE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/control.js b/mixly/boards/default_src/arduino_avr/blocks/control.js
new file mode 100644
index 00000000..d8102747
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/control.js
@@ -0,0 +1,962 @@
+import * as Blockly from "blockly/core";
+
+const LOOPS_HUE = 120;
+
+export const base_setup = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField(Blockly.Msg.MIXLY_SETUP);
+ this.appendStatementInput("DO").appendField("");
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_SETUP);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id2"
+ );
+ }
+};
+
+export const controls_delay = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendValueInput("DELAY_TIME", Number)
+ .appendField(Blockly.Msg.MIXLY_DELAY)
+ .appendField(new Blockly.FieldDropdown(controls_delay.UNIT), "UNIT")
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_DELAY);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id9"
+ );
+ },
+ UNIT: [
+ [Blockly.Msg.MIXLY_MILLIS, "delay"],
+ [Blockly.Msg.MIXLY_MILLISECOND, "delayMicroseconds"],
+ ]
+};
+
+export const controls_for = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_WITH)
+ .appendField(new Blockly.FieldTextInput("i"), "VAR");
+ this.appendValueInput("FROM")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_FROM);
+ this.appendValueInput("TO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_TO);
+ this.appendValueInput("STEP")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_STEP);
+ this.appendStatementInput("DO").appendField(Blockly.Msg.MIXLY_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#for"
+ );
+ var thisBlock = this;
+ this.setTooltip(function () {
+ return Blockly.Msg.CONTROLS_FOR_TOOLTIP.replace(
+ "%1",
+ thisBlock.getFieldValue("VAR")
+ );
+ });
+ },
+ getVars: function () {
+ return [this.getFieldValue("VAR")];
+ },
+ renameVar: function (oldName, newName) {
+ if (Blockly.Names.equals(oldName, this.getFieldValue("VAR"))) {
+ this.setTitleValue(newName, "VAR");
+ }
+ }
+};
+
+export const controls_whileUntil = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendValueInput("BOOL")
+ .setCheck([Boolean, Number])
+ .appendField(Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_TITLE_REPEAT)
+ .appendField(new Blockly.FieldDropdown(controls_whileUntil.OPERATORS), "MODE");
+ this.appendStatementInput("DO")
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#while"
+ );
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var op = thisBlock.getFieldValue("MODE");
+ var TOOLTIPS = {
+ WHILE: Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE,
+ UNTIL: Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL,
+ };
+ return TOOLTIPS[op];
+ });
+ },
+ OPERATORS: [
+ [Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_WHILE, "WHILE"],
+ [Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, "UNTIL"]
+ ]
+};
+
+export const controls_flow_statements = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ var dropdown = new Blockly.FieldDropdown(controls_flow_statements.OPERATORS);
+ this.appendDummyInput()
+ .appendField(dropdown, "FLOW")
+ .appendField(Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_INPUT_OFLOOP);
+ this.setPreviousStatement(true);
+ var thisBlock = this;
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh_CN/latest/arduino/03.Control.html#id2"
+ );
+ this.setTooltip(function () {
+ var op = thisBlock.getFieldValue("FLOW");
+ var TOOLTIPS = {
+ BREAK: Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK,
+ CONTINUE: Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE,
+ };
+ return TOOLTIPS[op];
+ });
+ },
+ onchange: function () {
+ if (!this.workspace) {
+ // Block has been deleted.
+ return;
+ }
+ var legal = false;
+ // Is the block nested in a control statement?
+ var block = this;
+ do {
+ if (
+ block.type == "controls_repeat" ||
+ block.type == "controls_forEach" ||
+ block.type == "controls_for" ||
+ block.type == "controls_whileUntil"
+ ) {
+ legal = true;
+ break;
+ }
+ block = block.getSurroundParent();
+ } while (block);
+ if (legal) {
+ this.setWarningText(null);
+ } else {
+ this.setWarningText(Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_WARNING);
+ }
+ },
+ OPERATORS: [
+ [Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK, "BREAK"],
+ [Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE, "CONTINUE"],
+ ]
+};
+
+export const controls_millis = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_RUNTIME)
+ .appendField(new Blockly.FieldDropdown(controls_millis.UNIT), "UNIT");
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_MILLIS);
+ },
+ UNIT: [
+ [Blockly.Msg.MIXLY_MILLIS, "millis"],
+ [Blockly.Msg.MIXLY_MILLISECOND, "micros"],
+ ]
+};
+
+export const controls_if = {
+ /**
+ * Block for if/elseif/else condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ //this.setHelpUrl(Blockly.Msg.CONTROLS_IF_HELPURL);
+ this.setColour(LOOPS_HUE);
+ this.appendValueInput("IF0")
+ .setCheck([Boolean, Number])
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
+ this.appendStatementInput("DO0").appendField(
+ Blockly.Msg.CONTROLS_IF_MSG_THEN
+ );
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#if"
+ );
+ this.setMutator(
+ new Blockly.icons.MutatorIcon(
+ ["controls_if_elseif", "controls_if_else"],
+ this
+ )
+ );
+ // 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) {
+ var containerBlock = this;
+ var valueConnections = [];
+ var statementConnections = [];
+ // var elseStatementConnection = null;
+ if (this.elseCount_) {
+ // if (containerBlock.getInputTargetBlock('ELSE') && containerBlock.getInputTargetBlock('ELSE').previousConnection)
+ // elseStatementConnection = containerBlock.getInputTargetBlock('ELSE').previousConnection;
+ this.removeInput("ELSE");
+ }
+ for (var i = this.elseifCount_; i > 0; i--) {
+ if (
+ containerBlock.getInputTargetBlock("IF" + i) &&
+ containerBlock.getInputTargetBlock("IF" + i).previousConnection
+ )
+ valueConnections[i] = containerBlock.getInputTargetBlock(
+ "IF" + i
+ ).previousConnection;
+ else valueConnections[i] = null;
+ this.removeInput("IF" + i);
+ if (
+ containerBlock.getInputTargetBlock("DO" + i) &&
+ containerBlock.getInputTargetBlock("DO" + i).previousConnection
+ )
+ statementConnections[i] = containerBlock.getInputTargetBlock(
+ "DO" + i
+ ).previousConnection;
+ else statementConnections[i] = null;
+ this.removeInput("DO" + i);
+ }
+ this.elseifCount_ = parseInt(xmlElement.getAttribute("elseif"), 10);
+ this.elseCount_ = parseInt(xmlElement.getAttribute("else"), 10);
+ //this.compose(containerBlock);
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ this.appendValueInput("IF" + i)
+ .setCheck([Boolean, Number])
+ .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
+ );
+ }
+ for (var i = valueConnections.length - 2; i > 0; i--) {
+ if (valueConnections[i]) valueConnections[i].reconnect(this, "IF" + i);
+ }
+ for (var i = statementConnections.length - 2; i > 0; i--) {
+ if (statementConnections[i])
+ statementConnections[i].reconnect(this, "DO" + i);
+ }
+ },
+ /**
+ * 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.getInput("STACK").connection;
+ 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) {
+ // Disconnect the else input blocks and remove the inputs.
+ if (this.elseCount_) {
+ this.removeInput("ELSE");
+ }
+ this.elseCount_ = 0;
+ // Disconnect all the elseif input blocks and remove the inputs.
+ for (var i = this.elseifCount_; i > 0; i--) {
+ this.removeInput("IF" + i);
+ this.removeInput("DO" + i);
+ }
+ this.elseifCount_ = 0;
+ // Rebuild the block's optional inputs.
+ var clauseBlock = containerBlock.getInputTargetBlock("STACK");
+ 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 Error("Unknown block type: " + clauseBlock.type);
+ }
+ clauseBlock =
+ clauseBlock.nextConnection && clauseBlock.nextConnection.targetBlock();
+ }
+
+ this.updateShape_();
+ // Reconnect any child blocks.
+ this.reconnectChildBlocks_(
+ valueConnections,
+ statementConnections,
+ elseStatementConnection
+ );
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var clauseBlock = containerBlock.getInputTargetBlock("STACK");
+ var i = 1;
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case "controls_if_elseif":
+ var inputIf = this.getInput("IF" + i);
+ var inputDo = this.getInput("DO" + i);
+ clauseBlock.valueConnection_ =
+ inputIf && inputIf.connection.targetConnection;
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ i++;
+ break;
+ case "controls_if_else":
+ var inputDo = this.getInput("ELSE");
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ break;
+ default:
+ throw "Unknown block type.";
+ }
+ clauseBlock =
+ clauseBlock.nextConnection && clauseBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Reconstructs the block with all child blocks attached.
+ */
+ rebuildShape_: function () {
+ var valueConnections = [null];
+ var statementConnections = [null];
+ var elseStatementConnection = null;
+
+ if (this.getInput("ELSE")) {
+ elseStatementConnection =
+ this.getInput("ELSE").connection.targetConnection;
+ }
+ var i = 1;
+ while (this.getInput("IF" + i)) {
+ var inputIf = this.getInput("IF" + i);
+ var inputDo = this.getInput("DO" + i);
+ console.log(inputIf.connection.targetConnection);
+ valueConnections.push(inputIf.connection.targetConnection);
+ statementConnections.push(inputDo.connection.targetConnection);
+ i++;
+ }
+ this.updateShape_();
+ this.reconnectChildBlocks_(
+ valueConnections,
+ statementConnections,
+ elseStatementConnection
+ );
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @this Blockly.Block
+ * @private
+ */
+ updateShape_: function () {
+ // Delete everything.
+ if (this.getInput("ELSE")) {
+ this.removeInput("ELSE");
+ }
+ var i = 1;
+ while (this.getInput("IF" + i)) {
+ this.removeInput("IF" + i);
+ this.removeInput("DO" + i);
+ i++;
+ }
+ // Rebuild block.
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ this.appendValueInput("IF" + i)
+ .setCheck([Number, 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"]
+ );
+ }
+ },
+ /**
+ * Reconnects child blocks.
+ * @param {!Array} valueConnections List of value
+ * connectsions for if input.
+ * @param {!Array} statementConnections List of
+ * statement connections for do input.
+ * @param {?Blockly.RenderedConnection} elseStatementConnection Statement
+ * connection for else input.
+ */
+ reconnectChildBlocks_: function (
+ valueConnections,
+ statementConnections,
+ elseStatementConnection
+ ) {
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ valueConnections[i] && valueConnections[i].reconnect(this, "IF" + i);
+ statementConnections[i] &&
+ statementConnections[i].reconnect(this, "DO" + i);
+ }
+ elseStatementConnection && elseStatementConnection.reconnect(this, "ELSE");
+ }
+};
+
+export const controls_if_if = {
+ /**
+ * Mutator block for if container.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField(Blockly.Msg.CONTROLS_IF_IF_TITLE_IF);
+ this.appendStatementInput("STACK");
+ this.setTooltip(Blockly.Msg.CONTROLS_IF_IF_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+export const controls_if_elseif = {
+ /**
+ * Mutator bolck for else-if condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ 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;
+ }
+};
+
+export const controls_if_else = {
+ /**
+ * Mutator block for else condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField(
+ Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE
+ );
+ this.setPreviousStatement(true);
+ this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+export const controls_switch_case = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendValueInput("IF0")
+ .setCheck([Number, Boolean])
+ .appendField("switch");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#switch"
+ );
+ this.setMutator(
+ new Blockly.icons.MutatorIcon(["controls_case", "controls_default"], this)
+ );
+ 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.compose(this);
+ this.elseifCount_ = parseInt(xmlElement.getAttribute("elseif"), 10);
+ this.elseCount_ = parseInt(xmlElement.getAttribute("else"), 10);
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ this.appendValueInput("IF" + i)
+ .setCheck([Number, Boolean])
+ .appendField("case");
+ this.appendStatementInput("DO" + i).appendField("");
+ }
+ if (this.elseCount_) {
+ this.appendStatementInput("ELSE").appendField("default");
+ }
+ },
+ /**
+ * 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_switch");
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput("STACK").connection;
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ var elseifBlock = workspace.newBlock("controls_case");
+ elseifBlock.initSvg();
+ connection.connect(elseifBlock.previousConnection);
+ connection = elseifBlock.nextConnection;
+ }
+ if (this.elseCount_) {
+ var elseBlock = workspace.newBlock("controls_default");
+ 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) {
+ // console.log(arguments.callee.caller.name);
+ // Disconnect the else input blocks and remove the inputs.
+ if (this.elseCount_) {
+ this.removeInput("ELSE");
+ }
+ this.elseCount_ = 0;
+ // Disconnect all the elseif input blocks and remove the inputs.
+ for (var i = this.elseifCount_; i > 0; i--) {
+ this.removeInput("IF" + i);
+ this.removeInput("DO" + i);
+ }
+ this.elseifCount_ = 0;
+ // Rebuild the block's optional inputs.
+ var clauseBlock = containerBlock.getInputTargetBlock("STACK");
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case "controls_case":
+ this.elseifCount_++;
+ var ifInput = this.appendValueInput("IF" + this.elseifCount_)
+ .setCheck([Number, Boolean])
+ .appendField("case");
+ var doInput = this.appendStatementInput("DO" + this.elseifCount_);
+ doInput.appendField("");
+ // Reconnect any child blocks.
+ if (clauseBlock.valueConnection_) {
+ ifInput.connection.connect(clauseBlock.valueConnection_);
+ }
+ if (clauseBlock.statementConnection_) {
+ doInput.connection.connect(clauseBlock.statementConnection_);
+ }
+ break;
+ case "controls_default":
+ this.elseCount_++;
+ var elseInput = this.appendStatementInput("ELSE");
+ elseInput.appendField("default");
+ // Reconnect any child blocks.
+ if (clauseBlock.statementConnection_) {
+ elseInput.connection.connect(clauseBlock.statementConnection_);
+ }
+ break;
+ default:
+ throw "Unknown block type.";
+ }
+ clauseBlock =
+ clauseBlock.nextConnection && clauseBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var clauseBlock = containerBlock.getInputTargetBlock("STACK");
+ var i = 1;
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case "controls_case":
+ var inputIf = this.getInput("IF" + i);
+ var inputDo = this.getInput("DO" + i);
+ clauseBlock.valueConnection_ =
+ inputIf && inputIf.connection.targetConnection;
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ i++;
+ break;
+ case "controls_default":
+ var inputDo = this.getInput("ELSE");
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ break;
+ default:
+ throw "Unknown block type.";
+ }
+ clauseBlock =
+ clauseBlock.nextConnection && clauseBlock.nextConnection.targetBlock();
+ }
+ }
+};
+
+export const controls_switch = {
+ /**
+ * Mutator block for if container.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField("switch");
+ this.appendStatementInput("STACK");
+ this.contextMenu = false;
+ }
+};
+
+export const controls_case = {
+ /**
+ * Mutator bolck for else-if condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField("case");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.contextMenu = false;
+ }
+};
+
+export const controls_default = {
+ /**
+ * Mutator block for else condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField("default");
+ this.setPreviousStatement(true);
+ this.contextMenu = false;
+ }
+};
+
+export const controls_mstimer2 = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendValueInput("TIME")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MsTimer2" + Blockly.Msg.MIXLY_MSTIMER2_EVERY);
+ this.appendDummyInput().appendField("ms");
+ this.appendStatementInput("DO")
+ .appendField(Blockly.Msg.MIXLY_MSTIMER2_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_MSTIMER2);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#mstimer2"
+ );
+ }
+};
+
+export const controls_mstimer2_start = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput().appendField(
+ "MsTimer2" + Blockly.Msg.MIXLY_MSTIMER2_START
+ );
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id36"
+ );
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_MSTIMER2_START);
+ }
+};
+
+export const controls_mstimer2_stop = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField("MsTimer2")
+ .appendField(Blockly.Msg.MIXLY_STOP);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_MSTIMER2_STOP);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id38"
+ );
+ }
+};
+
+export const controls_end_program = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_CONTROL_END_PROGRAM);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_END_PROGRAM);
+ }
+};
+export const controls_soft_reset = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.SOFT_RESET);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_END_PROGRAM);
+ }
+};
+
+export const controls_interrupts = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_CONTROL_INTERRUPTS);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_ALLOW_INTERRUPT);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id43"
+ );
+ }
+};
+
+export const controls_nointerrupts = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_CONTROL_NOINTERRUPTS);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_CONTROL_NOINTERRUPTS);
+ this.setHelpUrl(
+ "https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id46"
+ );
+ }
+};
+export const base_delay = controls_delay;
+
+//简单定时器
+export const simple_timer = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SIMPLE_TIMER)
+ .appendField(new Blockly.FieldDropdown(simple_timer.NUMBER), "NO")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_MONITOR_SCROLL_INTERVAL);
+ this.appendValueInput("timein")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_mSecond);
+ this.appendStatementInput("zxhs")
+ .setCheck(null)
+ .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
+ this.setColour(120);
+ this.setTooltip();
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#id40");
+ },
+ NUMBER: [
+ ["1", "1"],
+ ["2", "2"],
+ ["3", "3"],
+ ["4", "4"],
+ ["5", "5"],
+ ["6", "6"],
+ ["7", "7"],
+ ["8", "8"],
+ ["9", "9"],
+ ["10", "10"],
+ ["11", "11"],
+ ["12", "12"],
+ ["13", "13"],
+ ["14", "14"],
+ ["15", "15"],
+ ["16", "16"],
+ ]
+};
+
+//do-while循环
+export const do_while = {
+ init: function () {
+ this.appendStatementInput("input_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.appendValueInput("select_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_TITLE_REPEAT)
+ .appendField(
+ new Blockly.FieldDropdown([
+ [Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_WHILE, "true"],
+ [Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, "false"],
+ ]),
+ "type"
+ );
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(120);
+ this.setTooltip("do-while loop");
+ this.setHelpUrl("");
+ },
+};
+
+//注册超级延时函数
+export const super_delay_function1 = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.super_delay_function)
+ .appendField(new Blockly.FieldDropdown(super_delay_function1.NUMBER), "number");
+ this.appendStatementInput("delay_function")
+ .setCheck(null);
+ this.setColour(120);
+ this.setTooltip(Blockly.Msg.super_delay_function_help);
+ this.setHelpUrl("");
+ },
+ NUMBER: [
+ ["1", "1"],
+ ["2", "2"],
+ ["3", "3"],
+ ["4", "4"],
+ ["5", "5"],
+ ["6", "6"],
+ ["7", "7"],
+ ["8", "8"],
+ ["9", "9"],
+ ["10", "10"],
+ ["11", "11"],
+ ["12", "12"],
+ ["13", "13"],
+ ["14", "14"],
+ ["15", "15"],
+ ["16", "16"],
+ ]
+};
+
+//执行超级延时函数
+export const execute_super_delay_function1 = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.execute_super_delay_function)
+ .appendField(new Blockly.FieldDropdown(execute_super_delay_function1.NUMBER), "number");
+ this.appendValueInput("time_interval")
+ .setCheck(null)
+ .appendField(Blockly.Msg.time_interval);
+ this.appendValueInput("frequency")
+ .setCheck(null)
+ .appendField(Blockly.Msg.number_of_executions);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(120);
+ this.setTooltip(Blockly.Msg.execute_super_delay_function_help);
+ this.setHelpUrl("");
+ },
+ NUMBER: [
+ ["1", "1"],
+ ["2", "2"],
+ ["3", "3"],
+ ["4", "4"],
+ ["5", "5"],
+ ["6", "6"],
+ ["7", "7"],
+ ["8", "8"],
+ ["9", "9"],
+ ["10", "10"],
+ ["11", "11"],
+ ["12", "12"],
+ ["13", "13"],
+ ["14", "14"],
+ ["15", "15"],
+ ["16", "16"],
+ ]
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/display.js b/mixly/boards/default_src/arduino_avr/blocks/display.js
new file mode 100644
index 00000000..bbc0644e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/display.js
@@ -0,0 +1,2814 @@
+import * as Blockly from 'blockly/core';
+import * as layui from 'layui';
+import $ from 'jquery';
+import {
+ Profile,
+ LayerExt,
+ XML,
+ MFile
+} from 'mixly';
+
+const { layer } = layui;
+
+const DISPLAY_HUE = 180;
+
+const DRAWFIll = [
+ [Blockly.Msg.OLED_HOLLOW, "draw"],
+ [Blockly.Msg.OLED_SOLID, "fill"]
+];
+
+export const group_lcd_init2 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput('device')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(Blockly.Msg.MIXLY_DF_LCD)
+ .appendField(new Blockly.FieldDropdown([['1602', '16,2'], ['2004', '20,4']]), 'TYPE')
+ .appendField(new Blockly.FieldTextInput('mylcd'), 'VAR')
+ .appendField(Blockly.Msg.MIXLY_LCD_ADDRESS);
+ this.appendDummyInput("")
+ .appendField('SCL')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SCL")
+ .appendField('SDA')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SDA");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LCD_INIT2);
+ this.setFieldValue(Profile.default.SCL[0][1], "SCL");
+ this.setFieldValue(Profile.default.SDA[0][1], "SDA");
+ }
+};
+
+export const group_lcd_init3 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(Blockly.Msg.MIXLY_DF_LCD)
+ .appendField(new Blockly.FieldDropdown([['1602', '16,2'], ['2004', '20,4']]), 'TYPE')
+ .appendField(new Blockly.FieldTextInput('mylcd'), 'VAR')
+ .setAlign(Blockly.inputs.Align.LEFT);
+ this.appendDummyInput()
+ .appendField('RS')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "RS")
+ .appendField('EN')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "EN")
+ .appendField('D4')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "D4")
+ .appendField('D5')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "D5")
+ .appendField('D6')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "D6")
+ .appendField('D7')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "D7");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LCD_INIT3);
+ }
+};
+
+export const group_lcd_print = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput("TEXT", String)
+ .setCheck([String, Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DF_LCD)
+ .appendField(new Blockly.FieldTextInput('mylcd'), 'VAR')
+ .appendField(Blockly.Msg.MIXLY_LCD_PRINT1);
+ this.appendValueInput("TEXT2", String)
+ .setCheck([String, Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LCD_PRINT2);
+ /*
+ this.appendValueInput("TEXT3", String)
+ .setCheck([String,Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LCD_PRINT3);
+ this.appendValueInput("TEXT4", String)
+ .setCheck([String,Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LCD_PRINT4);
+ */
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LCD_PRINT);
+ }
+};
+
+export const group_lcd_print2 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput("row", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DF_LCD)
+ .appendField(new Blockly.FieldTextInput('mylcd'), 'VAR')
+ .appendField(Blockly.Msg.MIXLY_LCD_ROW);
+ this.appendValueInput("column", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LCD_COLUMN);
+ this.appendValueInput("TEXT", String)
+ .setCheck([String, Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_LCD_PRINT);
+ this.setPreviousStatement(true, null);
+ this.setInputsInline(true);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LCD_PRINT2.replace('%1', Blockly.Arduino.valueToCode(this, 'row', Blockly.Arduino.ORDER_ATOMIC)).replace('%2', Blockly.Arduino.valueToCode(this, 'column', Blockly.Arduino.ORDER_ATOMIC)));
+ }
+};
+
+export const group_lcd_power = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_DF_LCD)
+ .appendField(new Blockly.FieldTextInput('mylcd'), 'VAR')
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ON, "display"],
+ [Blockly.Msg.MIXLY_OFF, "noDisplay"],
+ [Blockly.Msg.MIXLY_LCD_STAT_CURSOR, "cursor"],
+ [Blockly.Msg.MIXLY_LCD_STAT_NOCURSOR, "noCursor"],
+ [Blockly.Msg.MIXLY_LCD_STAT_BLINK, "blink"],
+ [Blockly.Msg.MIXLY_LCD_STAT_NOBLINK, "noBlink"],
+ [Blockly.Msg.MIXLY_LCD_STAT_CLEAR, "clear"],
+ [Blockly.Msg.MIXLY_LCD_NOBACKLIGHT, "noBacklight"],
+ [Blockly.Msg.MIXLY_LCD_BACKLIGHT, "backlight"]
+ ]), "STAT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LCD_POWER);
+ }
+};
+//RGB has been moved to actuator
+
+export const display_4digitdisplay_power = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "_TM1650")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ON, "displayOn"],
+ [Blockly.Msg.MIXLY_OFF, "displayOff"],
+ [Blockly.Msg.MIXLY_LCD_STAT_CLEAR, "clear"]
+ ]), "STAT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_4digitdisplay_power);
+ }
+};
+
+export const display_4digitdisplay_displayString = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "_TM1650")
+ this.appendValueInput("VALUE")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.OLED_DRAWSTR);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_4digitdisplay_displayString);
+ }
+};
+
+export const display_4digitdisplay_showDot = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "_TM1650")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY_NOMBER1)
+ .appendField(new Blockly.FieldDropdown([["1", "0"], ["2", "1"], ["3", "2"], ["4", "3"]]), "NO")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY_NOMBER2)
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY_DOT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_4DIGITDISPLAY_ON, "true"],
+ [Blockly.Msg.MIXLY_4DIGITDISPLAY_OFF, "false"]
+ ]), "STAT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_4digitdisplay_showDot);
+ }
+};
+
+export const display_TM1637_init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField('CLK')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "CLK")
+ .appendField('DIO')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DIO");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_TIP);
+ this.setHelpUrl('');
+ // this.setFieldValue("2", "CLK");
+ // this.setFieldValue("4", "DIO");
+ }
+};
+
+export const display_TM1637_displyPrint = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput("VALUE")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.OLEDDISPLAY);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_DISPLAYSTRING_TIP);
+ }
+};
+
+export const display_TM1637_displayTime = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.MIXLY_SHOW_FACE_TIME);
+ this.appendValueInput("hour")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_HOUR);
+ this.appendValueInput("minute")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MINUTE);
+ // .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_ON, "displayOn"], [Blockly.Msg.MIXLY_OFF, "displayOff"], [Blockly.Msg.MIXLY_LCD_STAT_CLEAR, "clear"]]), "STAT");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_TM1637_Time_Point)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ON, "true"],
+ [Blockly.Msg.MIXLY_OFF, "false"]
+ ]), "STAT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_DISPLAYTIME_TOOLTIP);
+ }
+};
+
+export const display_TM1637_Brightness = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_MONITOR_SET_BRIGHTNESS);
+ this.appendValueInput("Brightness")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_4DIGITDISPLAY_BRIGHTNESS_TOOLTIP);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_4DIGITDISPLAY_TM1637_BRIGHTNESS);
+ }
+};
+
+export const display_TM1637_clearDisplay = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_LCD_STAT_CLEAR, "clear"],
+ [Blockly.Msg.MIXLY_LCD_STAT_BLINK, "blink"],
+ [Blockly.Msg.MIXLY_ON, "on"],
+ [Blockly.Msg.MIXLY_OFF, "off"]
+ ]), "STAT");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_CLEARDISPLAY);
+ }
+};
+
+//HT16K33点阵屏幕初始化
+export const HT16K33_Init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_INIT);
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_INIT)
+ .appendField('SCL')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SCL")
+ .appendField('SDA')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SDA");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_INIT);
+ this.setFieldValue(Profile.default.SCL[0][1], "SCL");
+ this.setFieldValue(Profile.default.SDA[0][1], "SDA");
+ }
+};
+
+//MAX7219点阵屏幕初始化
+export const MAX7219_init = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MAX7219_INIT);
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendValueInput("PIN1")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("DIN(MOSI)")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN2")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("CS")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN3")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("CLK(SCK)")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("hDisplays")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MAX7219_HDISPALY);
+ this.appendValueInput("vDisplays")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MAX7219_VDISPALY);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(DISPLAY_HUE);
+ this.setInputsInline(false);
+ this.setTooltip(Blockly.Msg.MAX7219_INIT_TOOLTIP);
+ this.setHelpUrl('');
+ }
+};
+
+const MATRIX_TYPES = [['MAX7219', 'MAX7219'], ['HT16K33', 'HT16K33']];
+
+//点阵屏显示点
+export const display_Matrix_DrawPixel = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE');
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendValueInput('XVALUE')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_X);
+ this.appendValueInput("YVALUE")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_Y);
+ this.appendValueInput("STAT")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .setCheck([Number, Boolean]);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_WRITE_NOW, "ON"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_DONT_WRITE, "OFF"]
+ ]), "WRITE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip();
+ }
+};
+
+
+//点阵屏 旋转变量
+const display_Rotation_NUM = [
+ [Blockly.Msg.MIXLY_0DEGREE, "0"],
+ [Blockly.Msg.MIXLY_90DEGREE, "3"],
+ [Blockly.Msg.MIXLY_180DEGREE, "2"],
+ [Blockly.Msg.MIXLY_270DEGREE, "1"]
+];
+
+//点阵屏旋转
+export const display_Max7219_Rotation = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField('MAX7219');
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendValueInput("NO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MAX7219_NO);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE)
+ .appendField(new Blockly.FieldDropdown(display_Rotation_NUM), "Rotation_TYPE");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_ROTATION);
+ }
+};
+
+//点阵屏旋转
+export const display_Max7219_setPosition = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField('MAX7219');
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendValueInput("NO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MAX7219_NO);
+ this.appendValueInput("X")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("X");
+ this.appendValueInput("Y")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("Y");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_ROTATION);
+ }
+};
+
+//点阵屏旋转
+export const display_HT16K33_Rotation = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField('HT16K33');
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE)
+ .appendField(new Blockly.FieldDropdown(display_Rotation_NUM), "Rotation_TYPE");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_ROTATION);
+ }
+};
+
+//点阵屏滚动显示字符
+export const display_Matrix_TEXT = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE');
+ this.appendValueInput("TEXT", String)
+ .setCheck([Number, String])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.texttodisplay);
+ this.appendValueInput("Speed")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SPEED);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_TEXT);
+ }
+};
+
+//点阵屏滚动显示文本
+export const display_Matrix_print = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE');
+ this.appendValueInput("TEXT", String)
+ .setCheck([Number, String])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.texttodisplay);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_WRITE_NOW, "ON"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_DONT_WRITE, "OFF"]
+ ]), "WRITE");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_TEXT);
+ }
+};
+
+//点阵屏显示_显示图案
+export const display_Matrix_DisplayChar = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE')
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_WRITE_NOW, "ON"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_DONT_WRITE, "OFF"]
+ ]), "WRITE");
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendValueInput("NO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MAX7219_NO);
+ this.appendValueInput("LEDArray")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_PICARRAY);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(false);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_DISPLAYCHAR);
+ }
+};
+
+//点阵屏显示_图案数组
+export const display_Matrix_LedArray = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ARRAYVAR)
+ .appendField(new Blockly.FieldTextInput("LedArray1"), "VAR");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a81")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a82")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a83")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a84")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a85")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a86")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a87")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a88");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a71")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a72")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a73")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a74")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a75")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a76")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a77")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a78");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a61")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a62")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a63")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a64")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a65")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a66")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a67")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a68");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a51")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a52")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a53")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a54")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a55")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a56")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a57")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a58");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a41")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a42")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a43")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a44")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a45")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a46")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a47")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a48");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a31")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a32")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a33")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a34")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a35")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a36")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a37")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a38");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a21")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a22")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a23")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a24")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a25")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a26")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a27")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a28");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a11")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a12")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a13")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a14")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a15")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a16")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a17")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a18");
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_LEDARRAY);
+ }
+};
+
+export const display_matrix_bitmap = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ARRAYVAR)
+ .appendField(new Blockly.FieldTextInput("LedArray1"), "VAR");
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(new Blockly.FieldBitmap([
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0]
+ ], null, {
+ filledColor: '#000',
+ emptyColor: '#5ba5a5',
+ bgColor: '#e5e7f1'
+ }), 'BITMAP');
+ this.setOutput(true, Number);
+ this.setTooltip("");
+ }
+};
+
+//点阵屏亮度
+export const display_Matrix_Brightness = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE');
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendValueInput("Brightness")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_BRIGHTNESS);
+ this.setTooltip(Blockly.Msg.MIXLY_MAX7219_BRIGHTNESS_TOOLTIP);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
+var MAX7219_FILLSCREEN_SELECT = [
+ [Blockly.Msg.MAX7219_FILLSCREEN_ON, "fillScreen(1)"],
+ [Blockly.Msg.MAX7219_FILLSCREEN_OFF, "fillScreen(0)"],
+ //[Blockly.Msg.MAX7219_SHUTDOWN_ON, "shutdown(1)"],
+ // [Blockly.Msg.MAX7219_SHUTDOWN_OFF, "shutdown(0)"]
+];
+
+//点阵屏 全屏亮灭
+export const display_Matrix_fillScreen = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE');
+ // this.appendDummyInput("")
+ // .appendField(Blockly.Msg.MIXLY_MATRIX_NAME)
+ // .appendField(new Blockly.FieldTextInput('myMatrix'), 'matrixName');
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_STAT);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(MAX7219_FILLSCREEN_SELECT), "FILLSCREEN_TYPE");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_WRITE_NOW, "ON"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_DONT_WRITE, "OFF"]
+ ]), "WRITE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_POS);
+ }
+};
+
+//点阵屏预设图案
+export const Matrix_img = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MAX7219_IMG)
+ .appendField(new Blockly.FieldDropdown([
+ ["↑", "18181818db7e3c18"],
+ ["↓", "183c7edb18181818"],
+ ["←", "080c06ffff060c08"],
+ ["→", "103060ffff603010"],
+ ["♥", "183c7effffffe742"],
+ ["▲", "00000000ff7e3c18"],
+ ["▼", "183c7eff00000000"],
+ ["◄", "080c0e0f0f0e0c08"],
+ ["►", "103070f0f0703010"],
+ ["△", "00000000ff422418"],
+ ["▽", "182442ff00000000"],
+ ["☺", "3c4299a581a5423c"],
+ ["○", "3c4281818181423c"],
+ ["◑", "3c72f1f1f1f1723c"],
+ ["◐", "3c4e8f8f8f8f4e3c"],
+ ["¥", "101010ff10ff2442"],
+ ["Χ", "8142241818244281"],
+ ["√", "0000010204885020"],
+ ["□", "007e424242427e00"],
+ ["▣", "007e425a5a427e00"],
+ ["◇", "1824428181422418"],
+ ["♀", "083e081c2222221c"],
+ ["♂", "0e1b111b9ea0c0f0"],
+ ["♪", "061f1e1010d07030"],
+ ["✈", "203098ffff983020"],
+ ["卍", "00f21212fe90909e"],
+ ["卐", "009e9090fe1212f2"],
+ ["|", "1010101010101010"],
+ ["—", "000000ff00000000"],
+ ["╱", "0102040810204080"],
+ ["\", "8040201008040201"],
+ ["大", "41221408087f0808"],
+ ["中", "1010fe9292fe1010"],
+ ["小", "0e08492a2a080808"],
+ ["米", "00925438fe385492"],
+ ["正", "7f0a0a3a08087f00"],
+ ["囧", "ffa5a5bdc3a5a5ff"]
+ ]), "img_");
+ this.setOutput(true);
+ this.setTooltip('');
+ this.setColour(DISPLAY_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_MAX7219_PREDEFARR);
+ this.setHelpUrl('');
+ }
+};
+
+//点阵屏 设置生效
+export const display_Matrix_write = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MATRIX_TYPE)
+ .appendField(new Blockly.FieldDropdown(MATRIX_TYPES), 'TYPE')
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_WRITE);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+//OLED -based on U8G2
+//显示-OLED-变量
+const LINESELECT = [
+ [Blockly.Msg.OLED_HOR, "H"],
+ [Blockly.Msg.OLED_VER, "V"]
+];
+
+const FRAMESELECT = [
+ [Blockly.Msg.OLED_HOLLOW, "drawFrame"],
+ [Blockly.Msg.OLED_SOLID, "drawBox"]
+];
+
+const CIRCLESELECT = [
+ [Blockly.Msg.OLED_HOLLOW, "drawCircle"],
+ [Blockly.Msg.OLED_SOLID, "drawDisc"]
+];
+
+const RADSELECT = [
+ [Blockly.Msg.OLED_HOLLOW, "drawRFrame"],
+ [Blockly.Msg.OLED_SOLID, "drawRBox"]
+];
+
+//圆选择
+const CIRCLEOPTELECT = [
+ [Blockly.Msg.OLED_WHOLE_CICILE, "U8G2_DRAW_ALL"],
+ [Blockly.Msg.OLED_UP_R, "U8G2_DRAW_UPPER_RIGHT"],
+ [Blockly.Msg.OLED_UP_L, "U8G2_DRAW_UPPER_LEFT"],
+ [Blockly.Msg.OLED_LOW_R, "U8G2_DRAW_LOWER_RIGHT"],
+ [Blockly.Msg.OLED_LOW_L, "U8G2_DRAW_LOWER_LEFT"]
+];
+
+//空心、实心椭圆
+const ELLIPSESELECT = [
+ [Blockly.Msg.OLED_HOLLOW, "drawEllipse"],
+ [Blockly.Msg.OLED_SOLID, "drawFilledEllipse"]
+];
+
+const EN_FONT_NAME = [
+ ["Times New Roman", "tim"],
+ ["Helvetica", "helv"],
+ ["ncen", "ncen"],
+ ["courier new", "cour"]
+];
+
+const OLED_TYPE = [
+ ["SSD1306(128×64)", "SSD1306_128X64_NONAME"],
+ ["SSD1306(128×32)", "SSD1306_128X32_UNIVISION"],
+ ["SH1106(128×64)", "SH1106_128X64_NONAME"]
+];
+
+const U8G2_TYPE_SSD1306_NOKIA5110 = [
+ ["SSD1306(128×64)", "SSD1306_128X64_NONAME"],
+ ["LCM12864", "ST7565_NHD_C12864"],
+ ["NOKIA5110", "PCD8544_84X48"]
+];
+
+const ROTATION_TYPE = [
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE + " 0°", "U8G2_R0"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE + " 90°", "U8G2_R1"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE + " 180°", "U8G2_R2"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE + " 270°", "U8G2_R3"],
+ [Blockly.Msg.MIRROR, "U8G2_MIRROR"]
+];
+
+const EN_FONT_SIZE = [
+ ["08", "08"],
+ ["10", "10"],
+ ["12", "12"],
+ ["14", "14"],
+ ["18", "18"],
+ ["24", "24"],
+];
+
+const EN_FONT_STYLE = [
+ ["常规", "R"],
+ ["加粗", "B"]
+];
+
+const CN_FONT_NAME = [
+ [Blockly.Msg.OLED_FONT_chinese1, "_t_chinese1"],
+ [Blockly.Msg.OLED_FONT_chinese2, "_t_chinese2"],
+ [Blockly.Msg.OLED_FONT_chinese3, "_t_chinese3"],
+ [Blockly.Msg.OLED_FONT_gb2312a, "_t_gb2312a"],
+ [Blockly.Msg.OLED_FONT_gb2312b, "_t_gb2312b"],
+ [Blockly.Msg.OLED_FONT_gb2312, "_t_gb2312"],
+];
+
+const CN_FONT_SIZE = [
+ ["12", "wqy12"],
+ ["13", "wqy13"],
+ ["14", "wqy14"],
+ ["15", "wqy15"],
+ ["16", "wqy16"],
+];
+
+const ICON_IMAGE = [
+ [{ 'src': require('../media/oled_icons/64.png'), 'width': 24, 'height': 24, 'alt': '64' }, '64'],
+ [{ 'src': require('../media/oled_icons/65.png'), 'width': 24, 'height': 24, 'alt': '65' }, '65'],
+ [{ 'src': require('../media/oled_icons/66.png'), 'width': 24, 'height': 24, 'alt': '66' }, '66'],
+ [{ 'src': require('../media/oled_icons/67.png'), 'width': 24, 'height': 24, 'alt': '67' }, '67'],
+ [{ 'src': require('../media/oled_icons/68.png'), 'width': 24, 'height': 24, 'alt': '68' }, '68'],
+ [{ 'src': require('../media/oled_icons/69.png'), 'width': 24, 'height': 24, 'alt': '69' }, '69'],
+ [{ 'src': require('../media/oled_icons/70.png'), 'width': 24, 'height': 24, 'alt': '70' }, '70'],
+ [{ 'src': require('../media/oled_icons/71.png'), 'width': 24, 'height': 24, 'alt': '71' }, '71'],
+ [{ 'src': require('../media/oled_icons/72.png'), 'width': 24, 'height': 24, 'alt': '72' }, '72'],
+ [{ 'src': require('../media/oled_icons/73.png'), 'width': 24, 'height': 24, 'alt': '73' }, '73'],
+ [{ 'src': require('../media/oled_icons/74.png'), 'width': 24, 'height': 24, 'alt': '74' }, '74'],
+ [{ 'src': require('../media/oled_icons/75.png'), 'width': 24, 'height': 24, 'alt': '75' }, '75'],
+ [{ 'src': require('../media/oled_icons/76.png'), 'width': 24, 'height': 24, 'alt': '76' }, '76'],
+ [{ 'src': require('../media/oled_icons/77.png'), 'width': 24, 'height': 24, 'alt': '77' }, '77'],
+ [{ 'src': require('../media/oled_icons/78.png'), 'width': 24, 'height': 24, 'alt': '78' }, '78'],
+ [{ 'src': require('../media/oled_icons/79.png'), 'width': 24, 'height': 24, 'alt': '79' }, '79'],
+ [{ 'src': require('../media/oled_icons/80.png'), 'width': 24, 'height': 24, 'alt': '80' }, '80'],
+ [{ 'src': require('../media/oled_icons/81.png'), 'width': 24, 'height': 24, 'alt': '81' }, '81'],
+ [{ 'src': require('../media/oled_icons/82.png'), 'width': 24, 'height': 24, 'alt': '82' }, '82'],
+ [{ 'src': require('../media/oled_icons/83.png'), 'width': 24, 'height': 24, 'alt': '83' }, '83'],
+ [{ 'src': require('../media/oled_icons/84.png'), 'width': 24, 'height': 24, 'alt': '84' }, '84'],
+ [{ 'src': require('../media/oled_icons/85.png'), 'width': 24, 'height': 24, 'alt': '85' }, '85'],
+ [{ 'src': require('../media/oled_icons/86.png'), 'width': 24, 'height': 24, 'alt': '86' }, '86'],
+ [{ 'src': require('../media/oled_icons/87.png'), 'width': 24, 'height': 24, 'alt': '87' }, '87'],
+ [{ 'src': require('../media/oled_icons/88.png'), 'width': 24, 'height': 24, 'alt': '88' }, '88'],
+ [{ 'src': require('../media/oled_icons/89.png'), 'width': 24, 'height': 24, 'alt': '89' }, '89'],
+ [{ 'src': require('../media/oled_icons/90.png'), 'width': 24, 'height': 24, 'alt': '90' }, '90'],
+ [{ 'src': require('../media/oled_icons/91.png'), 'width': 24, 'height': 24, 'alt': '91' }, '91'],
+ [{ 'src': require('../media/oled_icons/92.png'), 'width': 24, 'height': 24, 'alt': '92' }, '92'],
+ [{ 'src': require('../media/oled_icons/93.png'), 'width': 24, 'height': 24, 'alt': '93' }, '93'],
+ [{ 'src': require('../media/oled_icons/94.png'), 'width': 24, 'height': 24, 'alt': '94' }, '94'],
+ [{ 'src': require('../media/oled_icons/95.png'), 'width': 24, 'height': 24, 'alt': '95' }, '95'],
+ [{ 'src': require('../media/oled_icons/96.png'), 'width': 24, 'height': 24, 'alt': '96' }, '96'],
+ [{ 'src': require('../media/oled_icons/97.png'), 'width': 24, 'height': 24, 'alt': '97' }, '97'],
+ [{ 'src': require('../media/oled_icons/98.png'), 'width': 24, 'height': 24, 'alt': '98' }, '98'],
+ [{ 'src': require('../media/oled_icons/99.png'), 'width': 24, 'height': 24, 'alt': '99' }, '99'],
+ [{ 'src': require('../media/oled_icons/100.png'), 'width': 24, 'height': 24, 'alt': '100' }, '100'],
+ [{ 'src': require('../media/oled_icons/101.png'), 'width': 24, 'height': 24, 'alt': '101' }, '101'],
+ [{ 'src': require('../media/oled_icons/102.png'), 'width': 24, 'height': 24, 'alt': '102' }, '102'],
+ [{ 'src': require('../media/oled_icons/103.png'), 'width': 24, 'height': 24, 'alt': '103' }, '103'],
+ [{ 'src': require('../media/oled_icons/104.png'), 'width': 24, 'height': 24, 'alt': '104' }, '104'],
+ [{ 'src': require('../media/oled_icons/105.png'), 'width': 24, 'height': 24, 'alt': '105' }, '105'],
+ [{ 'src': require('../media/oled_icons/106.png'), 'width': 24, 'height': 24, 'alt': '106' }, '106'],
+ [{ 'src': require('../media/oled_icons/107.png'), 'width': 24, 'height': 24, 'alt': '107' }, '107'],
+ [{ 'src': require('../media/oled_icons/108.png'), 'width': 24, 'height': 24, 'alt': '108' }, '108'],
+ [{ 'src': require('../media/oled_icons/109.png'), 'width': 24, 'height': 24, 'alt': '109' }, '109'],
+ [{ 'src': require('../media/oled_icons/110.png'), 'width': 24, 'height': 24, 'alt': '110' }, '110'],
+ [{ 'src': require('../media/oled_icons/111.png'), 'width': 24, 'height': 24, 'alt': '111' }, '111'],
+ [{ 'src': require('../media/oled_icons/112.png'), 'width': 24, 'height': 24, 'alt': '112' }, '112'],
+ [{ 'src': require('../media/oled_icons/113.png'), 'width': 24, 'height': 24, 'alt': '113' }, '113'],
+ [{ 'src': require('../media/oled_icons/114.png'), 'width': 24, 'height': 24, 'alt': '114' }, '114'],
+ [{ 'src': require('../media/oled_icons/115.png'), 'width': 24, 'height': 24, 'alt': '115' }, '115'],
+ [{ 'src': require('../media/oled_icons/116.png'), 'width': 24, 'height': 24, 'alt': '116' }, '116'],
+ [{ 'src': require('../media/oled_icons/117.png'), 'width': 24, 'height': 24, 'alt': '117' }, '117'],
+ [{ 'src': require('../media/oled_icons/118.png'), 'width': 24, 'height': 24, 'alt': '118' }, '118'],
+ [{ 'src': require('../media/oled_icons/119.png'), 'width': 24, 'height': 24, 'alt': '119' }, '119'],
+ [{ 'src': require('../media/oled_icons/120.png'), 'width': 24, 'height': 24, 'alt': '120' }, '120'],
+ [{ 'src': require('../media/oled_icons/121.png'), 'width': 24, 'height': 24, 'alt': '121' }, '121'],
+ [{ 'src': require('../media/oled_icons/122.png'), 'width': 24, 'height': 24, 'alt': '122' }, '122'],
+ [{ 'src': require('../media/oled_icons/123.png'), 'width': 24, 'height': 24, 'alt': '123' }, '123'],
+ [{ 'src': require('../media/oled_icons/124.png'), 'width': 24, 'height': 24, 'alt': '124' }, '124'],
+ [{ 'src': require('../media/oled_icons/125.png'), 'width': 24, 'height': 24, 'alt': '125' }, '125'],
+ [{ 'src': require('../media/oled_icons/126.png'), 'width': 24, 'height': 24, 'alt': '126' }, '126'],
+ [{ 'src': require('../media/oled_icons/127.png'), 'width': 24, 'height': 24, 'alt': '127' }, '127'],
+ [{ 'src': require('../media/oled_icons/128.png'), 'width': 24, 'height': 24, 'alt': '128' }, '128'],
+ [{ 'src': require('../media/oled_icons/129.png'), 'width': 24, 'height': 24, 'alt': '129' }, '129'],
+ [{ 'src': require('../media/oled_icons/130.png'), 'width': 24, 'height': 24, 'alt': '130' }, '130'],
+ [{ 'src': require('../media/oled_icons/131.png'), 'width': 24, 'height': 24, 'alt': '131' }, '131'],
+ [{ 'src': require('../media/oled_icons/132.png'), 'width': 24, 'height': 24, 'alt': '132' }, '132'],
+ [{ 'src': require('../media/oled_icons/133.png'), 'width': 24, 'height': 24, 'alt': '133' }, '133'],
+ [{ 'src': require('../media/oled_icons/134.png'), 'width': 24, 'height': 24, 'alt': '134' }, '134'],
+ [{ 'src': require('../media/oled_icons/135.png'), 'width': 24, 'height': 24, 'alt': '135' }, '135'],
+ [{ 'src': require('../media/oled_icons/136.png'), 'width': 24, 'height': 24, 'alt': '136' }, '136'],
+ [{ 'src': require('../media/oled_icons/137.png'), 'width': 24, 'height': 24, 'alt': '137' }, '137'],
+ [{ 'src': require('../media/oled_icons/138.png'), 'width': 24, 'height': 24, 'alt': '138' }, '138'],
+ [{ 'src': require('../media/oled_icons/139.png'), 'width': 24, 'height': 24, 'alt': '139' }, '139'],
+ [{ 'src': require('../media/oled_icons/140.png'), 'width': 24, 'height': 24, 'alt': '140' }, '140'],
+ [{ 'src': require('../media/oled_icons/141.png'), 'width': 24, 'height': 24, 'alt': '141' }, '141'],
+ [{ 'src': require('../media/oled_icons/142.png'), 'width': 24, 'height': 24, 'alt': '142' }, '142'],
+ [{ 'src': require('../media/oled_icons/143.png'), 'width': 24, 'height': 24, 'alt': '143' }, '143'],
+ [{ 'src': require('../media/oled_icons/144.png'), 'width': 24, 'height': 24, 'alt': '144' }, '144'],
+ [{ 'src': require('../media/oled_icons/145.png'), 'width': 24, 'height': 24, 'alt': '145' }, '145'],
+ [{ 'src': require('../media/oled_icons/146.png'), 'width': 24, 'height': 24, 'alt': '146' }, '146'],
+ [{ 'src': require('../media/oled_icons/147.png'), 'width': 24, 'height': 24, 'alt': '147' }, '147'],
+ [{ 'src': require('../media/oled_icons/148.png'), 'width': 24, 'height': 24, 'alt': '148' }, '148'],
+ [{ 'src': require('../media/oled_icons/149.png'), 'width': 24, 'height': 24, 'alt': '149' }, '149'],
+ [{ 'src': require('../media/oled_icons/150.png'), 'width': 24, 'height': 24, 'alt': '150' }, '150'],
+ [{ 'src': require('../media/oled_icons/151.png'), 'width': 24, 'height': 24, 'alt': '151' }, '151'],
+ [{ 'src': require('../media/oled_icons/152.png'), 'width': 24, 'height': 24, 'alt': '152' }, '152'],
+ [{ 'src': require('../media/oled_icons/153.png'), 'width': 24, 'height': 24, 'alt': '153' }, '153'],
+ [{ 'src': require('../media/oled_icons/154.png'), 'width': 24, 'height': 24, 'alt': '154' }, '154'],
+ [{ 'src': require('../media/oled_icons/155.png'), 'width': 24, 'height': 24, 'alt': '155' }, '155'],
+ [{ 'src': require('../media/oled_icons/156.png'), 'width': 24, 'height': 24, 'alt': '156' }, '156'],
+ [{ 'src': require('../media/oled_icons/157.png'), 'width': 24, 'height': 24, 'alt': '157' }, '157'],
+ [{ 'src': require('../media/oled_icons/158.png'), 'width': 24, 'height': 24, 'alt': '158' }, '158'],
+ [{ 'src': require('../media/oled_icons/159.png'), 'width': 24, 'height': 24, 'alt': '159' }, '159'],
+ [{ 'src': require('../media/oled_icons/160.png'), 'width': 24, 'height': 24, 'alt': '160' }, '160'],
+ [{ 'src': require('../media/oled_icons/161.png'), 'width': 24, 'height': 24, 'alt': '161' }, '161'],
+ [{ 'src': require('../media/oled_icons/162.png'), 'width': 24, 'height': 24, 'alt': '162' }, '162'],
+ [{ 'src': require('../media/oled_icons/163.png'), 'width': 24, 'height': 24, 'alt': '163' }, '163'],
+ [{ 'src': require('../media/oled_icons/164.png'), 'width': 24, 'height': 24, 'alt': '164' }, '164'],
+ [{ 'src': require('../media/oled_icons/165.png'), 'width': 24, 'height': 24, 'alt': '165' }, '165'],
+ [{ 'src': require('../media/oled_icons/166.png'), 'width': 24, 'height': 24, 'alt': '166' }, '166'],
+ [{ 'src': require('../media/oled_icons/167.png'), 'width': 24, 'height': 24, 'alt': '167' }, '167'],
+ [{ 'src': require('../media/oled_icons/168.png'), 'width': 24, 'height': 24, 'alt': '168' }, '168'],
+ [{ 'src': require('../media/oled_icons/169.png'), 'width': 24, 'height': 24, 'alt': '169' }, '169'],
+ [{ 'src': require('../media/oled_icons/170.png'), 'width': 24, 'height': 24, 'alt': '170' }, '170'],
+ [{ 'src': require('../media/oled_icons/171.png'), 'width': 24, 'height': 24, 'alt': '171' }, '171'],
+ [{ 'src': require('../media/oled_icons/172.png'), 'width': 24, 'height': 24, 'alt': '172' }, '172'],
+ [{ 'src': require('../media/oled_icons/173.png'), 'width': 24, 'height': 24, 'alt': '173' }, '173'],
+ [{ 'src': require('../media/oled_icons/174.png'), 'width': 24, 'height': 24, 'alt': '174' }, '174'],
+ [{ 'src': require('../media/oled_icons/175.png'), 'width': 24, 'height': 24, 'alt': '175' }, '175'],
+ [{ 'src': require('../media/oled_icons/176.png'), 'width': 24, 'height': 24, 'alt': '176' }, '176'],
+ [{ 'src': require('../media/oled_icons/177.png'), 'width': 24, 'height': 24, 'alt': '177' }, '177'],
+ [{ 'src': require('../media/oled_icons/178.png'), 'width': 24, 'height': 24, 'alt': '178' }, '178'],
+ [{ 'src': require('../media/oled_icons/179.png'), 'width': 24, 'height': 24, 'alt': '179' }, '179'],
+ [{ 'src': require('../media/oled_icons/180.png'), 'width': 24, 'height': 24, 'alt': '180' }, '180'],
+ [{ 'src': require('../media/oled_icons/181.png'), 'width': 24, 'height': 24, 'alt': '181' }, '181'],
+ [{ 'src': require('../media/oled_icons/182.png'), 'width': 24, 'height': 24, 'alt': '182' }, '182'],
+ [{ 'src': require('../media/oled_icons/183.png'), 'width': 24, 'height': 24, 'alt': '183' }, '183'],
+ [{ 'src': require('../media/oled_icons/184.png'), 'width': 24, 'height': 24, 'alt': '184' }, '184'],
+ [{ 'src': require('../media/oled_icons/185.png'), 'width': 24, 'height': 24, 'alt': '185' }, '185'],
+ [{ 'src': require('../media/oled_icons/186.png'), 'width': 24, 'height': 24, 'alt': '186' }, '186'],
+ [{ 'src': require('../media/oled_icons/187.png'), 'width': 24, 'height': 24, 'alt': '187' }, '187'],
+ [{ 'src': require('../media/oled_icons/188.png'), 'width': 24, 'height': 24, 'alt': '188' }, '188'],
+ [{ 'src': require('../media/oled_icons/189.png'), 'width': 24, 'height': 24, 'alt': '189' }, '189'],
+ [{ 'src': require('../media/oled_icons/190.png'), 'width': 24, 'height': 24, 'alt': '190' }, '190'],
+ [{ 'src': require('../media/oled_icons/191.png'), 'width': 24, 'height': 24, 'alt': '191' }, '191'],
+ [{ 'src': require('../media/oled_icons/192.png'), 'width': 24, 'height': 24, 'alt': '192' }, '192'],
+ [{ 'src': require('../media/oled_icons/193.png'), 'width': 24, 'height': 24, 'alt': '193' }, '193'],
+ [{ 'src': require('../media/oled_icons/194.png'), 'width': 24, 'height': 24, 'alt': '194' }, '194'],
+ [{ 'src': require('../media/oled_icons/195.png'), 'width': 24, 'height': 24, 'alt': '195' }, '195'],
+ [{ 'src': require('../media/oled_icons/196.png'), 'width': 24, 'height': 24, 'alt': '196' }, '196'],
+ [{ 'src': require('../media/oled_icons/197.png'), 'width': 24, 'height': 24, 'alt': '197' }, '197'],
+ [{ 'src': require('../media/oled_icons/198.png'), 'width': 24, 'height': 24, 'alt': '198' }, '198'],
+ [{ 'src': require('../media/oled_icons/199.png'), 'width': 24, 'height': 24, 'alt': '199' }, '199'],
+ [{ 'src': require('../media/oled_icons/200.png'), 'width': 24, 'height': 24, 'alt': '200' }, '200'],
+ [{ 'src': require('../media/oled_icons/201.png'), 'width': 24, 'height': 24, 'alt': '201' }, '201'],
+ [{ 'src': require('../media/oled_icons/202.png'), 'width': 24, 'height': 24, 'alt': '202' }, '202'],
+ [{ 'src': require('../media/oled_icons/203.png'), 'width': 24, 'height': 24, 'alt': '203' }, '203'],
+ [{ 'src': require('../media/oled_icons/204.png'), 'width': 24, 'height': 24, 'alt': '204' }, '204'],
+ [{ 'src': require('../media/oled_icons/205.png'), 'width': 24, 'height': 24, 'alt': '205' }, '205'],
+ [{ 'src': require('../media/oled_icons/206.png'), 'width': 24, 'height': 24, 'alt': '206' }, '206'],
+ [{ 'src': require('../media/oled_icons/207.png'), 'width': 24, 'height': 24, 'alt': '207' }, '207'],
+ [{ 'src': require('../media/oled_icons/208.png'), 'width': 24, 'height': 24, 'alt': '208' }, '208'],
+ [{ 'src': require('../media/oled_icons/209.png'), 'width': 24, 'height': 24, 'alt': '209' }, '209'],
+ [{ 'src': require('../media/oled_icons/210.png'), 'width': 24, 'height': 24, 'alt': '210' }, '210'],
+ [{ 'src': require('../media/oled_icons/211.png'), 'width': 24, 'height': 24, 'alt': '211' }, '211'],
+ [{ 'src': require('../media/oled_icons/212.png'), 'width': 24, 'height': 24, 'alt': '212' }, '212'],
+ [{ 'src': require('../media/oled_icons/213.png'), 'width': 24, 'height': 24, 'alt': '213' }, '213'],
+ [{ 'src': require('../media/oled_icons/214.png'), 'width': 24, 'height': 24, 'alt': '214' }, '214'],
+ [{ 'src': require('../media/oled_icons/215.png'), 'width': 24, 'height': 24, 'alt': '215' }, '215'],
+ [{ 'src': require('../media/oled_icons/216.png'), 'width': 24, 'height': 24, 'alt': '216' }, '216'],
+ [{ 'src': require('../media/oled_icons/217.png'), 'width': 24, 'height': 24, 'alt': '217' }, '217'],
+ [{ 'src': require('../media/oled_icons/218.png'), 'width': 24, 'height': 24, 'alt': '218' }, '218'],
+ [{ 'src': require('../media/oled_icons/219.png'), 'width': 24, 'height': 24, 'alt': '219' }, '219'],
+ [{ 'src': require('../media/oled_icons/220.png'), 'width': 24, 'height': 24, 'alt': '220' }, '220'],
+ [{ 'src': require('../media/oled_icons/221.png'), 'width': 24, 'height': 24, 'alt': '221' }, '221'],
+ [{ 'src': require('../media/oled_icons/222.png'), 'width': 24, 'height': 24, 'alt': '222' }, '222'],
+ [{ 'src': require('../media/oled_icons/223.png'), 'width': 24, 'height': 24, 'alt': '223' }, '223'],
+ [{ 'src': require('../media/oled_icons/224.png'), 'width': 24, 'height': 24, 'alt': '224' }, '224'],
+ [{ 'src': require('../media/oled_icons/225.png'), 'width': 24, 'height': 24, 'alt': '225' }, '225'],
+ [{ 'src': require('../media/oled_icons/226.png'), 'width': 24, 'height': 24, 'alt': '226' }, '226'],
+ [{ 'src': require('../media/oled_icons/227.png'), 'width': 24, 'height': 24, 'alt': '227' }, '227'],
+ [{ 'src': require('../media/oled_icons/228.png'), 'width': 24, 'height': 24, 'alt': '228' }, '228'],
+ [{ 'src': require('../media/oled_icons/229.png'), 'width': 24, 'height': 24, 'alt': '229' }, '229'],
+ [{ 'src': require('../media/oled_icons/230.png'), 'width': 24, 'height': 24, 'alt': '230' }, '230'],
+ [{ 'src': require('../media/oled_icons/231.png'), 'width': 24, 'height': 24, 'alt': '231' }, '231'],
+ [{ 'src': require('../media/oled_icons/232.png'), 'width': 24, 'height': 24, 'alt': '232' }, '232'],
+ [{ 'src': require('../media/oled_icons/233.png'), 'width': 24, 'height': 24, 'alt': '233' }, '233'],
+ [{ 'src': require('../media/oled_icons/234.png'), 'width': 24, 'height': 24, 'alt': '234' }, '234'],
+ [{ 'src': require('../media/oled_icons/235.png'), 'width': 24, 'height': 24, 'alt': '235' }, '235'],
+ [{ 'src': require('../media/oled_icons/236.png'), 'width': 24, 'height': 24, 'alt': '236' }, '236'],
+ [{ 'src': require('../media/oled_icons/237.png'), 'width': 24, 'height': 24, 'alt': '237' }, '237'],
+ [{ 'src': require('../media/oled_icons/238.png'), 'width': 24, 'height': 24, 'alt': '238' }, '238'],
+ [{ 'src': require('../media/oled_icons/239.png'), 'width': 24, 'height': 24, 'alt': '239' }, '239'],
+ [{ 'src': require('../media/oled_icons/240.png'), 'width': 24, 'height': 24, 'alt': '240' }, '240'],
+ [{ 'src': require('../media/oled_icons/241.png'), 'width': 24, 'height': 24, 'alt': '241' }, '241'],
+ [{ 'src': require('../media/oled_icons/242.png'), 'width': 24, 'height': 24, 'alt': '242' }, '242'],
+ [{ 'src': require('../media/oled_icons/243.png'), 'width': 24, 'height': 24, 'alt': '243' }, '243'],
+ [{ 'src': require('../media/oled_icons/244.png'), 'width': 24, 'height': 24, 'alt': '244' }, '244'],
+ [{ 'src': require('../media/oled_icons/245.png'), 'width': 24, 'height': 24, 'alt': '245' }, '245'],
+ [{ 'src': require('../media/oled_icons/246.png'), 'width': 24, 'height': 24, 'alt': '246' }, '246'],
+ [{ 'src': require('../media/oled_icons/247.png'), 'width': 24, 'height': 24, 'alt': '247' }, '247'],
+ [{ 'src': require('../media/oled_icons/248.png'), 'width': 24, 'height': 24, 'alt': '248' }, '248'],
+ [{ 'src': require('../media/oled_icons/249.png'), 'width': 24, 'height': 24, 'alt': '249' }, '249'],
+ [{ 'src': require('../media/oled_icons/250.png'), 'width': 24, 'height': 24, 'alt': '250' }, '250'],
+ [{ 'src': require('../media/oled_icons/251.png'), 'width': 24, 'height': 24, 'alt': '251' }, '251'],
+ [{ 'src': require('../media/oled_icons/252.png'), 'width': 24, 'height': 24, 'alt': '252' }, '252'],
+ [{ 'src': require('../media/oled_icons/253.png'), 'width': 24, 'height': 24, 'alt': '253' }, '253'],
+ [{ 'src': require('../media/oled_icons/254.png'), 'width': 24, 'height': 24, 'alt': '254' }, '254'],
+ [{ 'src': require('../media/oled_icons/255.png'), 'width': 24, 'height': 24, 'alt': '255' }, '255'],
+ [{ 'src': require('../media/oled_icons/256.png'), 'width': 24, 'height': 24, 'alt': '256' }, '256'],
+ [{ 'src': require('../media/oled_icons/257.png'), 'width': 24, 'height': 24, 'alt': '257' }, '257'],
+ [{ 'src': require('../media/oled_icons/258.png'), 'width': 24, 'height': 24, 'alt': '258' }, '258'],
+ [{ 'src': require('../media/oled_icons/259.png'), 'width': 24, 'height': 24, 'alt': '259' }, '259'],
+ [{ 'src': require('../media/oled_icons/260.png'), 'width': 24, 'height': 24, 'alt': '260' }, '260'],
+ [{ 'src': require('../media/oled_icons/261.png'), 'width': 24, 'height': 24, 'alt': '261' }, '261'],
+ [{ 'src': require('../media/oled_icons/262.png'), 'width': 24, 'height': 24, 'alt': '262' }, '262'],
+ [{ 'src': require('../media/oled_icons/263.png'), 'width': 24, 'height': 24, 'alt': '263' }, '263'],
+ [{ 'src': require('../media/oled_icons/264.png'), 'width': 24, 'height': 24, 'alt': '264' }, '264'],
+ [{ 'src': require('../media/oled_icons/265.png'), 'width': 24, 'height': 24, 'alt': '265' }, '265'],
+ [{ 'src': require('../media/oled_icons/266.png'), 'width': 24, 'height': 24, 'alt': '266' }, '266'],
+ [{ 'src': require('../media/oled_icons/267.png'), 'width': 24, 'height': 24, 'alt': '267' }, '267'],
+ [{ 'src': require('../media/oled_icons/268.png'), 'width': 24, 'height': 24, 'alt': '268' }, '268'],
+ [{ 'src': require('../media/oled_icons/269.png'), 'width': 24, 'height': 24, 'alt': '269' }, '269'],
+ [{ 'src': require('../media/oled_icons/270.png'), 'width': 24, 'height': 24, 'alt': '270' }, '270'],
+ [{ 'src': require('../media/oled_icons/271.png'), 'width': 24, 'height': 24, 'alt': '271' }, '271'],
+ [{ 'src': require('../media/oled_icons/272.png'), 'width': 24, 'height': 24, 'alt': '272' }, '272'],
+ [{ 'src': require('../media/oled_icons/273.png'), 'width': 24, 'height': 24, 'alt': '273' }, '273'],
+ [{ 'src': require('../media/oled_icons/274.png'), 'width': 24, 'height': 24, 'alt': '274' }, '274'],
+ [{ 'src': require('../media/oled_icons/275.png'), 'width': 24, 'height': 24, 'alt': '275' }, '275'],
+ [{ 'src': require('../media/oled_icons/276.png'), 'width': 24, 'height': 24, 'alt': '276' }, '276'],
+ [{ 'src': require('../media/oled_icons/277.png'), 'width': 24, 'height': 24, 'alt': '277' }, '277'],
+ [{ 'src': require('../media/oled_icons/278.png'), 'width': 24, 'height': 24, 'alt': '278' }, '278'],
+ [{ 'src': require('../media/oled_icons/279.png'), 'width': 24, 'height': 24, 'alt': '279' }, '279'],
+ [{ 'src': require('../media/oled_icons/280.png'), 'width': 24, 'height': 24, 'alt': '280' }, '280'],
+ [{ 'src': require('../media/oled_icons/281.png'), 'width': 24, 'height': 24, 'alt': '281' }, '281'],
+ [{ 'src': require('../media/oled_icons/282.png'), 'width': 24, 'height': 24, 'alt': '282' }, '282'],
+ [{ 'src': require('../media/oled_icons/283.png'), 'width': 24, 'height': 24, 'alt': '283' }, '283'],
+ [{ 'src': require('../media/oled_icons/284.png'), 'width': 24, 'height': 24, 'alt': '284' }, '284'],
+ [{ 'src': require('../media/oled_icons/285.png'), 'width': 24, 'height': 24, 'alt': '285' }, '285'],
+ [{ 'src': require('../media/oled_icons/286.png'), 'width': 24, 'height': 24, 'alt': '286' }, '286']
+];
+
+const FACE_IMAGE = [
+ [{ 'src': require('../media/oled_icons/face/Eyes/Angry.png'), 'width': 35, 'height': 25, 'alt': 'Angry' }, 'Angry,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x78,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF8,0x01,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF8,0x07,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0xB8,0x1F,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x3E,0x00,0x38,0x7F,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x80,0x3F,0x00,0x38,0xFC,0x01,0x00,0xE0,0x00,0x0C,0x00,0x00,0xE0,0x3F,0x00,0x38,0xF0,0x07,0x00,0xE0,0x00,0x0C,0x00,0x00,0xF8,0x31,0x00,0x38,0xC0,0x1F,0x00,0xE0,0x00,0x0C,0x00,0x00,0x7E,0x30,0x00,0x38,0x00,0x7F,0x00,0xE0,0x00,0x0C,0x00,0x80,0x1F,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0xE0,0x07,0x30,0x00,0x38,0x00,0xF0,0x07,0xE0,0x00,0x0C,0x00,0xF8,0x01,0x30,0x00,0x38,0x00,0xE0,0x1F,0xE0,0x00,0x0C,0x00,0xFE,0x00,0x30,0x00,0x38,0x00,0xF0,0x7F,0xE0,0x00,0x0C,0x80,0x3F,0x00,0x30,0x00,0x38,0x00,0xF8,0xFF,0xE1,0x00,0x0C,0xE0,0x6F,0x01,0x30,0x00,0x38,0x00,0xFC,0xF9,0xE7,0x00,0x0C,0xF8,0x4F,0x00,0x30,0x00,0x38,0x00,0xFD,0xDD,0xFF,0x00,0x0C,0xFE,0xF7,0x00,0x30,0x00,0x38,0x00,0xFE,0x3F,0xFF,0x00,0x8C,0xFF,0xFF,0x02,0x30,0x00,0x38,0x00,0xFE,0x3F,0xFC,0x00,0xFC,0xFF,0xFF,0x00,0x30,0x00,0x38,0x00,0xFE,0x3F,0xF0,0x00,0xFC,0xF5,0xFF,0x02,0x30,0x00,0x38,0x00,0xFC,0x1F,0xE0,0x00,0x7C,0xF0,0xFF,0x00,0x30,0x00,0x38,0x00,0xFD,0x5F,0xE0,0x00,0x1C,0xE0,0x7F,0x00,0x38,0x00,0x70,0x00,0xF8,0x0F,0x70,0x00,0x1C,0xE8,0x7F,0x01,0x38,0x00,0x70,0x00,0xF0,0x07,0x70,0x00,0x3C,0xC0,0x3F,0x00,0x3C,0x00,0xF0,0x00,0xC0,0x01,0x78,0x00,0x38,0x20,0x4F,0x00,0x1C,0x00,0xE0,0x01,0x20,0x04,0x3C,0x00,0x78,0x80,0x10,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Awake.png'), 'width': 35, 'height': 25, 'alt': 'Awake' }, 'Awake,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF8,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x3E,0x00,0xF8,0x1F,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0xE0,0x3F,0x00,0xF8,0xFF,0x03,0x00,0xE0,0x00,0x0C,0x00,0x80,0xFF,0x3F,0x00,0x38,0xF8,0xFF,0x00,0xE0,0x00,0x0C,0x00,0xFC,0x7F,0x30,0x00,0x38,0x00,0xFF,0x0F,0xE0,0x00,0x0C,0xE0,0xFF,0x03,0x30,0x00,0x38,0x00,0xFC,0xFF,0xE1,0x00,0x0C,0xFE,0x7F,0x00,0x30,0x00,0x38,0x80,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0x00,0x30,0x00,0x38,0x00,0x7E,0x96,0xFF,0x00,0xFC,0x87,0xBF,0x05,0x30,0x00,0x38,0x40,0x7F,0x16,0xF0,0x00,0x3C,0xC0,0x9F,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x00,0xFF,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0x38,0x80,0xFE,0x0B,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0xF8,0x00,0xE0,0x00,0x0C,0x00,0x7E,0x00,0x30,0x00,0x38,0x00,0x02,0x02,0xE0,0x00,0x0C,0x00,0x81,0x00,0x30,0x00,0x38,0x00,0x50,0x00,0xE0,0x00,0x0C,0x00,0x14,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Black eye.png'), 'width': 35, 'height': 25, 'alt': 'Black_eye' }, 'Black_eye,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xF8,0xFF,0x7F,0x00,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x5F,0x55,0xD5,0x1F,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x4B,0xAA,0xA4,0x3E,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0xE0,0xB5,0x55,0x5B,0x3D,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0xF0,0x4A,0xAA,0xA4,0x7A,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0xF0,0xB6,0x55,0x5B,0x75,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x78,0x49,0xAA,0x24,0xF5,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xB8,0xB6,0x55,0xDB,0xEA,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x78,0x49,0xAA,0x24,0xF5,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xB8,0xB6,0x55,0xDB,0xEA,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x49,0xAA,0x24,0xF5,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF8,0xB6,0x55,0xDB,0xEA,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x49,0xAA,0x24,0xE9,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0x00,0x42,0x00,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0x80,0x1C,0x01,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0x00,0xFE,0x00,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0xA0,0xBF,0x05,0x30,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x0C,0x80,0x3F,0x01,0x30,0x00,0x38,0x40,0x7F,0x17,0xE0,0x00,0x0C,0xC0,0xDF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0x80,0x3C,0x01,0x30,0x00,0xB8,0xAA,0xAA,0xAA,0xEA,0x00,0x0C,0x00,0x42,0x00,0x30,0x00,0xB8,0x2A,0x49,0xAA,0xEA,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x78,0xD5,0xB6,0x55,0xF5,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xB8,0x2A,0x49,0xAA,0xEA,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF8,0xD2,0xB6,0x55,0xF5,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x70,0x2D,0x49,0xAA,0x75,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0xF0,0xD2,0xB6,0x55,0x7A,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0xE0,0x2D,0x49,0xAA,0x3D,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0xE0,0xD3,0xB6,0x55,0x3E,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xC0,0x2F,0x49,0xD2,0x1F,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Bottom left.png'), 'width': 35, 'height': 25, 'alt': 'Bottom_left' }, 'Bottom_left,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x40,0x01,0x00,0xE0,0x00,0x0C,0xA0,0x00,0x00,0x30,0x00,0x38,0x08,0x08,0x00,0xE0,0x00,0x0C,0x04,0x02,0x00,0x30,0x00,0x38,0xE0,0x13,0x00,0xE0,0x00,0x0C,0xF8,0x01,0x00,0x30,0x00,0x38,0xFA,0x0F,0x00,0xE0,0x00,0x0C,0xFC,0x03,0x00,0x30,0x00,0x38,0xF8,0x19,0x00,0xE0,0x00,0x8C,0xFE,0x16,0x00,0x30,0x00,0x38,0xFD,0x59,0x00,0xE0,0x00,0x0C,0x7F,0x0E,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x0C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x4C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x0C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x4C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFD,0x5F,0x00,0xE0,0x00,0x0C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFC,0x0F,0x00,0xE0,0x00,0x8C,0xFE,0x17,0x00,0x30,0x00,0x38,0xFA,0x2F,0x00,0xE0,0x00,0x0C,0xFC,0x03,0x00,0x30,0x00,0x38,0xE0,0x03,0x00,0xE0,0x00,0x0C,0xF8,0x01,0x00,0x30,0x00,0x38,0x08,0x08,0x00,0xE0,0x00,0x1C,0x04,0x02,0x00,0x38,0x00,0x70,0x40,0x01,0x00,0x70,0x00,0x1C,0x50,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Bottom right.png'), 'width': 35, 'height': 25, 'alt': 'Bottom_right' }, 'Bottom_right,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x14,0xE0,0x00,0x0C,0x00,0x00,0x0A,0x30,0x00,0x38,0x00,0x80,0x80,0xE0,0x00,0x0C,0x00,0x40,0x20,0x30,0x00,0x38,0x00,0x00,0x3E,0xE1,0x00,0x0C,0x00,0x80,0x1F,0x30,0x00,0x38,0x00,0xA0,0xFF,0xE0,0x00,0x0C,0x00,0xC0,0x3F,0x30,0x00,0x38,0x00,0x80,0x9F,0xE1,0x00,0x0C,0x00,0xE8,0x6F,0x31,0x00,0x38,0x00,0xD0,0x9F,0xE5,0x00,0x0C,0x00,0xF0,0xE7,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xD0,0xFF,0xE5,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xC0,0xFF,0xE0,0x00,0x0C,0x00,0xE8,0x7F,0x31,0x00,0x38,0x00,0xA0,0xFF,0xE2,0x00,0x0C,0x00,0xC0,0x3F,0x30,0x00,0x38,0x00,0x00,0x3E,0xE0,0x00,0x0C,0x00,0x80,0x1F,0x30,0x00,0x38,0x00,0x80,0x80,0xE0,0x00,0x1C,0x00,0x40,0x20,0x38,0x00,0x70,0x00,0x00,0x14,0x70,0x00,0x1C,0x00,0x00,0x05,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Crazy 1.png'), 'width': 35, 'height': 25, 'alt': 'Crazy_1' }, 'Crazy_1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x14,0xE0,0x00,0x0C,0x00,0x00,0x0A,0x30,0x00,0x38,0x00,0x80,0x80,0xE0,0x00,0x0C,0x00,0x40,0x20,0x30,0x00,0x38,0x00,0x00,0x3E,0xE1,0x00,0x0C,0x00,0x80,0x1F,0x30,0x00,0x38,0x00,0xA0,0xFF,0xE0,0x00,0x0C,0x00,0xC0,0x3F,0x30,0x00,0x38,0x00,0x80,0x9F,0xE1,0x00,0x0C,0x00,0xE8,0x6F,0x31,0x00,0x38,0x00,0xD0,0x9F,0xE5,0x00,0x0C,0x00,0xF0,0xE7,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xD0,0xFF,0xE5,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xC0,0xFF,0xE0,0x00,0x0C,0x00,0xE8,0x7F,0x31,0x00,0x38,0x00,0xA0,0xFF,0xE2,0x00,0x0C,0x00,0xC0,0x3F,0x30,0x00,0x38,0x00,0x00,0x3E,0xE0,0x00,0x0C,0x00,0x80,0x1F,0x30,0x00,0x38,0x00,0x80,0x80,0xE0,0x00,0x1C,0x00,0x40,0x20,0x38,0x00,0x70,0x00,0x00,0x14,0x70,0x00,0x1C,0x00,0x00,0x05,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Crazy 2.png'), 'width': 35, 'height': 25, 'alt': 'Crazy_2' }, 'Crazy_2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x20,0x04,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xC8,0x11,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xE0,0x0F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFA,0x5B,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xF8,0x13,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFC,0x3D,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFD,0xBF,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFC,0x3F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFD,0xBF,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFC,0x3F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xF8,0x1F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xFA,0x5F,0x30,0x00,0x38,0x00,0x05,0x00,0xE0,0x00,0x0C,0x00,0xF0,0x0F,0x30,0x00,0x38,0x20,0x20,0x00,0xE0,0x00,0x0C,0x00,0xC8,0x13,0x30,0x00,0x38,0x80,0x4F,0x00,0xE0,0x00,0x0C,0x00,0x20,0x04,0x30,0x00,0x38,0xE8,0x3F,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xE0,0x67,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF4,0x67,0x01,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF8,0xFF,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF8,0xFF,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF8,0xFF,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF8,0xFF,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF4,0x7F,0x01,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xF0,0x3F,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xE8,0xBF,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x80,0x0F,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x20,0x20,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x05,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Disappointed.png'), 'width': 35, 'height': 25, 'alt': 'Disappointed' }, 'Disappointed,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0xF8,0x1F,0x00,0xE0,0x3F,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x7C,0x3C,0x00,0xF0,0x78,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x3E,0x38,0x00,0x78,0xF0,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x1F,0x70,0x00,0x38,0xE0,0x01,0x00,0x1C,0x00,0x70,0x00,0x80,0x0F,0x70,0x00,0x1C,0xC0,0x03,0x00,0x38,0x00,0x38,0x00,0xC0,0x07,0xE0,0x00,0x1C,0x80,0x07,0x00,0x38,0x00,0x38,0x00,0xE0,0x03,0xE0,0x00,0x1C,0x00,0x0F,0x00,0x38,0x00,0x38,0x00,0xF0,0x01,0xE0,0x00,0x0C,0x00,0x1E,0x00,0x30,0x00,0x38,0x00,0xF8,0x00,0xE0,0x00,0x0C,0x00,0x3C,0x00,0x30,0x00,0x38,0x00,0x7C,0x00,0xE0,0x00,0x0C,0x00,0x78,0x00,0x30,0x00,0x38,0x00,0x3E,0x02,0xE0,0x00,0x0C,0x00,0xF9,0x00,0x30,0x00,0x38,0x00,0xFF,0x04,0xE0,0x00,0x0C,0x00,0xFE,0x01,0x30,0x00,0x38,0x80,0xFF,0x03,0xE0,0x00,0x0C,0x00,0xFF,0x03,0x30,0x00,0x38,0xC0,0x7F,0x06,0xE0,0x00,0x0C,0xA0,0xBF,0x07,0x30,0x00,0x38,0xE0,0x7F,0x16,0xE0,0x00,0x0C,0xC0,0x9F,0x0F,0x30,0x00,0x38,0xF0,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x1F,0x30,0x00,0x38,0xF8,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x3F,0x30,0x00,0x38,0xFC,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x7B,0x30,0x00,0x38,0xBE,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0xFB,0x30,0x00,0x38,0x5F,0xFF,0x17,0xE0,0x00,0x0C,0xC0,0xFF,0xE3,0x31,0x00,0xB8,0x0F,0xFF,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0xC5,0x33,0x00,0xF8,0x87,0xFE,0x0B,0xE0,0x00,0x0C,0x00,0xFF,0x80,0x3F,0x00,0xF8,0x03,0xF8,0x00,0xE0,0x00,0x0C,0x00,0x7E,0x00,0x3F,0x00,0xF8,0x01,0x02,0x02,0xE0,0x00,0x0C,0x00,0x81,0x00,0x3E,0x00,0xF8,0x00,0x50,0x00,0xE0,0x00,0x0C,0x00,0x14,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Dizzy.png'), 'width': 35, 'height': 25, 'alt': 'Dizzy' }, 'Dizzy,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x0C,0x00,0xE0,0x00,0x0C,0x00,0x03,0x00,0x30,0x00,0x38,0x00,0x0F,0x00,0xE0,0x00,0x0C,0xC0,0x03,0x00,0x30,0x00,0x38,0x80,0x03,0x00,0xE0,0x00,0x0C,0xE0,0x00,0x00,0x30,0x00,0x38,0xC0,0xF9,0x07,0xE0,0x00,0x0C,0x70,0xFE,0x01,0x30,0x00,0x38,0xE0,0x3C,0x1F,0xE0,0x00,0x0C,0x38,0xCF,0x07,0x30,0x00,0x38,0x60,0x06,0x38,0xE0,0x00,0x0C,0x98,0x01,0x0E,0x30,0x00,0x38,0x30,0xE3,0x33,0xE0,0x00,0x0C,0xCC,0xF8,0x0C,0x30,0x00,0x38,0x30,0xF3,0x67,0xE0,0x00,0x0C,0xCC,0xFC,0x19,0x30,0x00,0x38,0xB0,0x19,0x6E,0xE0,0x00,0x0C,0x6C,0x86,0x1B,0x30,0x00,0x38,0xB0,0xD9,0xCC,0xE0,0x00,0x0C,0x6C,0x36,0x33,0x30,0x00,0x38,0xB0,0xD9,0xCD,0xE0,0x00,0x0C,0x6C,0x76,0x33,0x30,0x00,0x38,0xB0,0xF9,0xCD,0xE0,0x00,0x0C,0x6C,0x7E,0x33,0x30,0x00,0x38,0x30,0xF3,0x6C,0xE0,0x00,0x0C,0xCC,0x3C,0x1B,0x30,0x00,0x38,0x70,0x07,0x66,0xE0,0x00,0x0C,0xDC,0x81,0x19,0x30,0x00,0x38,0x60,0x9E,0x77,0xE0,0x00,0x0C,0x98,0xE7,0x1D,0x30,0x00,0x38,0xC0,0xF8,0x31,0xE0,0x00,0x0C,0x30,0x7E,0x0C,0x30,0x00,0x38,0xC0,0x01,0x18,0xE0,0x00,0x0C,0x70,0x00,0x06,0x30,0x00,0x38,0x00,0x0F,0x0E,0xE0,0x00,0x0C,0xC0,0x83,0x03,0x30,0x00,0x38,0x00,0xFE,0x07,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xF0,0x00,0xE0,0x00,0x0C,0x00,0x3C,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Down.png'), 'width': 35, 'height': 25, 'alt': 'Down' }, 'Down,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x50,0x00,0xE0,0x00,0x0C,0x00,0x14,0x00,0x30,0x00,0x38,0x00,0x02,0x02,0xE0,0x00,0x0C,0x00,0x81,0x00,0x30,0x00,0x38,0x00,0xF9,0x00,0xE0,0x00,0x0C,0x00,0x7E,0x00,0x30,0x00,0x38,0x00,0xFE,0x0B,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x0C,0xA0,0xBF,0x05,0x30,0x00,0x38,0x40,0x7F,0x16,0xE0,0x00,0x0C,0xC0,0x9F,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x00,0xFE,0x07,0xE0,0x00,0x1C,0xA0,0xFF,0x05,0x38,0x00,0x70,0x80,0xFE,0x0B,0x70,0x00,0x1C,0x00,0xFF,0x00,0x38,0x00,0x70,0x00,0xF8,0x00,0x70,0x00,0x3C,0x00,0x7E,0x00,0x3C,0x00,0xF0,0x00,0x02,0x02,0x78,0x00,0x38,0x00,0x81,0x00,0x1C,0x00,0xE0,0x01,0xA8,0x00,0x3C,0x00,0x78,0x00,0x28,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Evil.png'), 'width': 35, 'height': 25, 'alt': 'Evil' }, 'Evil,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x0F,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0xC0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0xE0,0x1F,0x00,0x70,0x3C,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x70,0x1C,0x00,0x70,0x78,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x3C,0x38,0x00,0x38,0xF0,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x1E,0x38,0x00,0x38,0xE0,0x01,0x00,0xE0,0x00,0x1C,0x00,0x00,0x0F,0x38,0x00,0x38,0x80,0x07,0x00,0xE0,0x00,0x0C,0x00,0x80,0x07,0x30,0x00,0x38,0x00,0x0F,0x00,0xE0,0x00,0x0C,0x00,0xC0,0x03,0x30,0x00,0x38,0x00,0x1E,0x00,0xE0,0x00,0x0C,0x00,0xE0,0x01,0x30,0x00,0x38,0x00,0x3C,0x00,0xE0,0x00,0x0C,0x00,0x70,0x00,0x30,0x00,0x38,0x00,0x78,0x00,0xE0,0x00,0x0C,0x00,0x7C,0x00,0x30,0x00,0x38,0x00,0xF2,0x00,0xE0,0x00,0x0C,0x00,0x3E,0x01,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0xFE,0x07,0xE0,0x00,0x0C,0x80,0xBF,0x05,0x30,0x00,0x38,0x00,0x7F,0x0F,0xE0,0x00,0x0C,0xC0,0x3F,0x01,0x30,0x00,0x38,0x40,0x7F,0x1F,0xE0,0x00,0x0C,0xE0,0xDF,0x03,0x30,0x00,0x38,0x80,0xFF,0x3F,0xE0,0x00,0x0C,0xF8,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x7F,0xE0,0x00,0x0C,0xFC,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0xFF,0xE0,0x00,0x0C,0xFE,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0xC7,0xE3,0x00,0x0C,0xCF,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x97,0xE7,0x00,0x8C,0x87,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xEF,0x00,0xCC,0xA3,0xFF,0x05,0x30,0x00,0x38,0x00,0xFC,0x01,0xFE,0x00,0xFC,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xFC,0x00,0x7C,0x80,0x3C,0x01,0x30,0x00,0x38,0x00,0x08,0x01,0xF8,0x00,0x3C,0x00,0x42,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Hurt.png'), 'width': 35, 'height': 25, 'alt': 'Hurt' }, 'Hurt,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xF0,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xFC,0x00,0x7C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xFF,0x00,0xFC,0x01,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0xC0,0xFF,0x00,0xFC,0x07,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0xF0,0xE7,0x00,0x8C,0x1F,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0xFC,0xE1,0x00,0x0C,0x7E,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x7F,0xE0,0x00,0x0C,0xF8,0x01,0x00,0x30,0x00,0x38,0x00,0xC0,0x1F,0xE0,0x00,0x0C,0xE0,0x07,0x00,0x30,0x00,0x38,0x00,0xF0,0x0F,0xE0,0x00,0x0C,0xC0,0x1F,0x00,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x20,0x7F,0x00,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x01,0x30,0x00,0x38,0xC0,0xFF,0x0F,0xE0,0x00,0x0C,0xE8,0xFF,0x07,0x30,0x00,0x38,0xF0,0xFF,0x19,0xE0,0x00,0x0C,0xE0,0xCF,0x1F,0x30,0x00,0x38,0xFC,0xFD,0x5D,0xE0,0x00,0x0C,0xF0,0xF7,0x7E,0x30,0x00,0x38,0xFF,0xFE,0x3F,0xE0,0x00,0x0C,0xF4,0xFF,0xFA,0x31,0x00,0xB8,0x1F,0xFE,0x3F,0xE0,0x00,0x0C,0xF0,0xFF,0xE0,0x37,0x00,0xF8,0x07,0xFE,0x3F,0xE0,0x00,0x0C,0xF4,0xFF,0x82,0x3F,0x00,0xF8,0x01,0xFC,0x1F,0xE0,0x00,0x0C,0xF0,0xFF,0x00,0x3E,0x00,0x78,0x00,0xFD,0x5F,0xE0,0x00,0x1C,0xE0,0x7F,0x00,0x38,0x00,0x70,0x00,0xF8,0x0F,0x70,0x00,0x1C,0xE8,0x7F,0x01,0x38,0x00,0x70,0x00,0xF0,0x07,0x70,0x00,0x3C,0xC0,0x3F,0x00,0x3C,0x00,0xF0,0x00,0xC0,0x01,0x78,0x00,0x38,0x20,0x4F,0x00,0x1C,0x00,0xE0,0x01,0x20,0x04,0x3C,0x00,0x78,0x80,0x10,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Knocked out.png'), 'width': 35, 'height': 25, 'alt': 'Knocked_out' }, 'Knocked_out,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0xF0,0xFF,0x7F,0xE0,0x00,0x0C,0xF8,0xFF,0x1F,0x30,0x00,0x38,0xF0,0xFF,0x7F,0xE0,0x00,0x0C,0xFC,0xFF,0x3F,0x30,0x00,0x38,0xF0,0xFF,0x7F,0xE0,0x00,0x0C,0xFC,0xFF,0x1F,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Love.png'), 'width': 35, 'height': 25, 'alt': 'Love' }, 'Love,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xE0,0x07,0x3F,0xE0,0x00,0x0C,0xF0,0x81,0x0F,0x30,0x00,0x38,0xF0,0x8B,0x5F,0xE0,0x00,0x0C,0xF8,0xC2,0x1F,0x30,0x00,0x38,0xF8,0xD7,0xBF,0xE0,0x00,0x0C,0xFC,0xE5,0x2F,0x30,0x00,0x38,0xF8,0xFF,0xBF,0xE0,0x00,0x0C,0xFE,0xFF,0x5F,0x30,0x00,0x38,0xFC,0xFF,0x7F,0xE0,0x00,0x0C,0xFE,0xFF,0x5F,0x30,0x00,0x38,0xFC,0xFF,0xFF,0xE1,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xFC,0xFF,0xFF,0xE1,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xFC,0xFF,0xFF,0xE1,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xF8,0xFF,0xFF,0xE0,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xF8,0xFF,0xFF,0xE0,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xF8,0xFF,0xFF,0xE0,0x00,0x0C,0xFC,0xFF,0x3F,0x30,0x00,0x38,0xF0,0xFF,0x7F,0xE0,0x00,0x0C,0xF8,0xFF,0x1F,0x30,0x00,0x38,0xC0,0xFF,0x1F,0xE0,0x00,0x0C,0xF0,0xFF,0x0F,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xE0,0xFF,0x07,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0x7E,0x00,0x30,0x00,0x38,0x00,0xF8,0x00,0xE0,0x00,0x0C,0x00,0x3C,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x20,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Middle left.png'), 'width': 35, 'height': 25, 'alt': 'Middle_left' }, 'Middle_left,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x10,0x02,0x00,0xE0,0x00,0x0C,0x04,0x01,0x00,0x30,0x00,0x38,0xC0,0x01,0x00,0xE0,0x00,0x0C,0xE0,0x04,0x00,0x30,0x00,0x38,0xF0,0x07,0x00,0xE0,0x00,0x0C,0xFC,0x01,0x00,0x30,0x00,0x38,0xF8,0x0F,0x00,0xE0,0x00,0x8C,0xFE,0x17,0x00,0x30,0x00,0x38,0xFC,0x19,0x00,0xE0,0x00,0x0C,0xFE,0x04,0x00,0x30,0x00,0x38,0xFD,0x5D,0x00,0xE0,0x00,0x4C,0x7F,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x0C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x4C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x0C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFC,0x1F,0x00,0xE0,0x00,0x4C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFD,0x5F,0x00,0xE0,0x00,0x0C,0xFE,0x07,0x00,0x30,0x00,0x38,0xF8,0x0F,0x00,0xE0,0x00,0x8C,0xFE,0x17,0x00,0x30,0x00,0x38,0xF0,0x07,0x00,0xE0,0x00,0x0C,0xFC,0x03,0x00,0x30,0x00,0x38,0xC0,0x01,0x00,0xE0,0x00,0x0C,0xF2,0x04,0x00,0x30,0x00,0x38,0x10,0x02,0x00,0xE0,0x00,0x0C,0x08,0x01,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Middle right.png'), 'width': 35, 'height': 25, 'alt': 'Middle_right' }, 'Middle_right,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x21,0xE0,0x00,0x0C,0x00,0x40,0x10,0x30,0x00,0x38,0x00,0x00,0x1C,0xE0,0x00,0x0C,0x00,0x00,0x4E,0x30,0x00,0x38,0x00,0x00,0x7F,0xE0,0x00,0x0C,0x00,0xC0,0x1F,0x30,0x00,0x38,0x00,0x80,0xFF,0xE0,0x00,0x0C,0x00,0xE8,0x7F,0x31,0x00,0x38,0x00,0xC0,0x9F,0xE1,0x00,0x0C,0x00,0xE0,0x4F,0x30,0x00,0x38,0x00,0xD0,0xDF,0xE5,0x00,0x0C,0x00,0xF0,0xF7,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x32,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x30,0x00,0x38,0x00,0xC0,0xFF,0xE1,0x00,0x0C,0x00,0xF0,0xFF,0x32,0x00,0x38,0x00,0xD0,0xFF,0xE5,0x00,0x0C,0x00,0xE0,0x7F,0x30,0x00,0x38,0x00,0x80,0xFF,0xE0,0x00,0x0C,0x00,0xE8,0x7F,0x31,0x00,0x38,0x00,0x00,0x7F,0xE0,0x00,0x0C,0x00,0xC0,0x3F,0x30,0x00,0x38,0x00,0x00,0x1C,0xE0,0x00,0x0C,0x00,0x20,0x4F,0x30,0x00,0x38,0x00,0x00,0x21,0xE0,0x00,0x0C,0x00,0x80,0x10,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Neutral.png'), 'width': 35, 'height': 25, 'alt': 'Neutral' }, 'Neutral,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x41,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x38,0x01,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0x7F,0x00,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x0C,0x80,0x3F,0x01,0x30,0x00,0x38,0x40,0x7F,0x17,0xE0,0x00,0x0C,0xC0,0xDF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x80,0x3C,0x01,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x42,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Nuclear.png'), 'width': 35, 'height': 25, 'alt': 'Nuclear' }, 'Nuclear,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x78,0x00,0xE0,0x00,0x0C,0x00,0x3C,0x00,0x30,0x00,0x38,0x00,0xCF,0x03,0xE0,0x00,0x0C,0x80,0xE7,0x01,0x30,0x00,0x38,0xC0,0x01,0x0C,0xE0,0x00,0x0C,0xE0,0x00,0x06,0x30,0x00,0x38,0x60,0x00,0x10,0xE0,0x00,0x0C,0x30,0x00,0x08,0x30,0x00,0x38,0xB0,0x01,0x24,0xE0,0x00,0x0C,0xD8,0x00,0x12,0x30,0x00,0x38,0xD8,0x01,0x4E,0xE0,0x00,0x0C,0xEC,0x00,0x27,0x30,0x00,0x38,0xC8,0x03,0xDF,0xE0,0x00,0x0C,0xE4,0x81,0x6F,0x30,0x00,0x38,0xEC,0x07,0xBF,0xE0,0x00,0x0C,0xF6,0x83,0x5F,0x30,0x00,0x38,0xF4,0x87,0xBF,0xE1,0x00,0x0C,0xFA,0xC3,0xDF,0x30,0x00,0x38,0xF4,0x87,0x3F,0xE1,0x00,0x0C,0xFA,0xC3,0x9F,0x30,0x00,0x38,0xF6,0x27,0x7F,0xE1,0x00,0x0C,0xFB,0x93,0xBF,0x30,0x00,0x38,0xF2,0x73,0x7F,0xE1,0x00,0x0C,0xF9,0xB9,0xBF,0x30,0x00,0x38,0x02,0x78,0x00,0xE1,0x00,0x0C,0x01,0x3C,0x80,0x30,0x00,0x38,0x02,0x30,0x00,0xE1,0x00,0x0C,0x01,0x18,0x80,0x30,0x00,0x38,0x04,0x00,0x00,0xE1,0x00,0x0C,0x02,0x00,0x80,0x30,0x00,0x38,0x04,0x70,0x00,0xE1,0x00,0x0C,0x02,0x38,0x80,0x30,0x00,0x38,0x04,0xF8,0x80,0xE1,0x00,0x0C,0x02,0x7C,0xC0,0x30,0x00,0x38,0x08,0xFC,0x80,0xE0,0x00,0x0C,0x04,0x7E,0x40,0x30,0x00,0x38,0x18,0xFC,0x41,0xE0,0x00,0x0C,0x0C,0xFE,0x20,0x30,0x00,0x38,0x10,0xFE,0x61,0xE0,0x00,0x0C,0x08,0xFF,0x30,0x30,0x00,0x38,0x20,0xFE,0x33,0xE0,0x00,0x0C,0x10,0xFF,0x19,0x30,0x00,0x38,0xC0,0x78,0x18,0xE0,0x00,0x0C,0x60,0x3C,0x0C,0x30,0x00,0x38,0x80,0x03,0x06,0xE0,0x00,0x0C,0xC0,0x01,0x03,0x30,0x00,0x38,0x00,0xFE,0x01,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Pinch left.png'), 'width': 35, 'height': 25, 'alt': 'Pinch_left' }, 'Pinch_left,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xB8,0xFE,0xBD,0x00,0xE0,0x00,0x5C,0x7F,0x3F,0x00,0x38,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x4C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x0C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFC,0x1F,0x00,0xE0,0x00,0x4C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFD,0x5F,0x00,0xE0,0x00,0x0C,0xFE,0x07,0x00,0x30,0x00,0x38,0xF8,0x0F,0x00,0xE0,0x00,0x0C,0xFE,0x17,0x00,0x30,0x00,0x38,0xF0,0x07,0x00,0xE0,0x00,0x0C,0xFD,0x0B,0x00,0x30,0x00,0x38,0xC0,0x01,0x00,0xE0,0x00,0x0C,0xF0,0x00,0x00,0x30,0x00,0x38,0x18,0x06,0x00,0xE0,0x00,0x0C,0x0C,0x03,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Pinch middle.png'), 'width': 35, 'height': 25, 'alt': 'Pinch_middle' }, 'Pinch_middle,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0xA0,0x7F,0x2F,0xE0,0x00,0x1C,0xD0,0xDF,0x0F,0x38,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x80,0xFF,0x05,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x40,0xFF,0x02,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x3C,0x00,0x30,0x00,0x38,0x00,0x86,0x01,0xE0,0x00,0x0C,0x00,0xC3,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Pinch right.png'), 'width': 35, 'height': 25, 'alt': 'Pinch_right' }, 'Pinch_right,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0xE8,0xDF,0xEB,0x00,0x1C,0x00,0xF4,0xF7,0x3A,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x32,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x30,0x00,0x38,0x00,0xC0,0xFF,0xE1,0x00,0x0C,0x00,0xF0,0xFF,0x32,0x00,0x38,0x00,0xD0,0xFF,0xE5,0x00,0x0C,0x00,0xE0,0x7F,0x30,0x00,0x38,0x00,0x80,0xFF,0xE0,0x00,0x0C,0x00,0xE0,0x7F,0x31,0x00,0x38,0x00,0x00,0x7F,0xE0,0x00,0x0C,0x00,0xD0,0xBF,0x30,0x00,0x38,0x00,0x00,0x1C,0xE0,0x00,0x0C,0x00,0x00,0x0F,0x30,0x00,0x38,0x00,0x80,0xC2,0xE0,0x00,0x0C,0x00,0xC0,0x30,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Tear.png'), 'width': 35, 'height': 25, 'alt': 'Tear' }, 'Tear,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0xF0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0xFD,0x05,0xE0,0x00,0x1C,0x40,0x7F,0x02,0x38,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x0C,0xA0,0xBF,0x05,0x30,0x00,0x38,0x40,0x7F,0x16,0xE0,0x00,0x0C,0xC0,0x9F,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x04,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x04,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x04,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x0C,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x0E,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x0E,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x1F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x80,0x3F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x80,0x6F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xC0,0x5F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xC0,0x7F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0xC0,0x7F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x80,0x7F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x3F,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x0E,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Tired left.png'), 'width': 35, 'height': 25, 'alt': 'Tired_left' }, 'Tired_left,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0xFD,0x5D,0x00,0xE0,0x00,0x5C,0x7F,0x2E,0x00,0x38,0x00,0x38,0xFE,0x1F,0x00,0xE0,0x00,0x0C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x4C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x0C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xFE,0x3F,0x00,0xE0,0x00,0x4C,0xFF,0x2F,0x00,0x30,0x00,0x38,0xFD,0x5F,0x00,0xE0,0x00,0x0C,0xFF,0x0F,0x00,0x30,0x00,0x38,0xF8,0x1F,0x00,0xE0,0x00,0x9C,0xFE,0x17,0x00,0x38,0x00,0x70,0xFA,0x2F,0x00,0x70,0x00,0x1C,0xFC,0x03,0x00,0x38,0x00,0x70,0xE0,0x03,0x00,0x70,0x00,0x3C,0xF8,0x01,0x00,0x3C,0x00,0xF0,0x08,0x08,0x00,0x78,0x00,0x38,0x04,0x02,0x00,0x1C,0x00,0xE0,0xA1,0x02,0x00,0x3C,0x00,0x78,0xA0,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Tired middle.png'), 'width': 35, 'height': 25, 'alt': 'Tired_middle' }, 'Tired_middle,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x1C,0xD0,0xDF,0x0B,0x38,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x1C,0xA0,0xFF,0x05,0x38,0x00,0x70,0x00,0xFC,0x01,0x70,0x00,0x1C,0x00,0xFF,0x00,0x38,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x3C,0x80,0x3C,0x01,0x3C,0x00,0xF0,0x00,0x84,0x00,0x78,0x00,0x38,0x00,0x42,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Tired right.png'), 'width': 35, 'height': 25, 'alt': 'Tired_right' }, 'Tired_right,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0xD0,0xDF,0xE5,0x00,0x1C,0x00,0xF4,0xE7,0x3A,0x00,0x38,0x00,0xE0,0xFF,0xE1,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0xE0,0xFF,0xE3,0x00,0x0C,0x00,0xF4,0xFF,0x32,0x00,0x38,0x00,0xD0,0xFF,0xE5,0x00,0x0C,0x00,0xF0,0xFF,0x30,0x00,0x38,0x00,0x80,0xFF,0xE1,0x00,0x1C,0x00,0xE8,0x7F,0x39,0x00,0x70,0x00,0xA0,0xFF,0x72,0x00,0x1C,0x00,0xC0,0x3F,0x38,0x00,0x70,0x00,0x00,0x3E,0x70,0x00,0x3C,0x00,0x80,0x1F,0x3C,0x00,0xF0,0x00,0x80,0x80,0x78,0x00,0x38,0x00,0x40,0x20,0x1C,0x00,0xE0,0x01,0x00,0x14,0x3C,0x00,0x78,0x00,0x00,0x0A,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Toxic.png'), 'width': 35, 'height': 25, 'alt': 'Toxic' }, 'Toxic,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x1C,0x00,0x30,0x00,0x38,0x00,0xFE,0x02,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x80,0xFF,0x00,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x01,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0x23,0x0E,0xE0,0x00,0x0C,0xC0,0x18,0x03,0x30,0x00,0x38,0x80,0x23,0x0E,0xE0,0x00,0x0C,0xC0,0x10,0x03,0x30,0x00,0x38,0x00,0x73,0x06,0xE0,0x00,0x0C,0xC0,0x99,0x03,0x30,0x00,0x38,0x00,0x9F,0x07,0xE0,0x00,0x0C,0x80,0xE7,0x01,0x30,0x00,0x38,0x00,0x9E,0x03,0xE0,0x00,0x0C,0x00,0xE7,0x00,0x30,0x00,0x38,0x20,0xF8,0x40,0xE0,0x00,0x0C,0x18,0x7C,0x30,0x30,0x00,0x38,0xF0,0x51,0x78,0xE0,0x00,0x0C,0xFC,0x08,0x3C,0x30,0x00,0x38,0x30,0x0F,0xCF,0xE0,0x00,0x0C,0xCC,0x87,0x37,0x30,0x00,0x38,0x00,0x7C,0x02,0xE0,0x00,0x0C,0x00,0x3E,0x00,0x30,0x00,0x38,0xB0,0xC7,0x67,0xE0,0x00,0x0C,0xD8,0xF3,0x13,0x30,0x00,0x38,0xF0,0x03,0x7F,0xE0,0x00,0x0C,0xF8,0x81,0x3F,0x30,0x00,0x38,0x60,0x00,0x70,0xE0,0x00,0x0C,0x30,0x00,0x1C,0x30,0x00,0x38,0x60,0x00,0x30,0xE0,0x00,0x0C,0x10,0x00,0x18,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Up.png'), 'width': 35, 'height': 25, 'alt': 'Up' }, 'Up,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x84,0x00,0x38,0x00,0x78,0x00,0x41,0x00,0x1E,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x38,0x00,0x38,0x01,0x1C,0x00,0x70,0x00,0xFC,0x01,0x70,0x00,0x1C,0x00,0x7F,0x00,0x38,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x1C,0xA0,0xFF,0x05,0x38,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x1C,0x80,0x3F,0x01,0x38,0x00,0x38,0x40,0x7F,0x17,0xE0,0x00,0x0C,0xC0,0xDF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x80,0x3C,0x01,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x42,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Eyes/Winking.png'), 'width': 35, 'height': 25, 'alt': 'Winking' }, 'Winking,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x40,0x7F,0x17,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Big smile.png'), 'width': 35, 'height': 25, 'alt': 'Big_smile' }, 'Big_smile,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x00,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Heart large.png'), 'width': 35, 'height': 25, 'alt': 'Heart_large' }, 'Heart_large,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0x00,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xF8,0xBF,0x07,0x00,0xC0,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0xFC,0x3F,0x1C,0x00,0xF0,0xFF,0xE1,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x71,0x00,0xF8,0xFF,0xC3,0x01,0x00,0x00,0x00,0x00,0xFF,0xFF,0xE7,0x00,0xFC,0xFF,0x8F,0x03,0x00,0x00,0x00,0x80,0xFF,0xFF,0xCF,0x01,0xFE,0xFF,0x3F,0x07,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x9F,0x03,0xFF,0xFF,0x7F,0x06,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x3F,0x83,0xFF,0xFF,0xFF,0x0C,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x7F,0x87,0xFF,0xFF,0xFF,0x1D,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xC6,0xFF,0xFF,0xFF,0x19,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0x33,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x37,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x37,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x6F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Heart small.png'), 'width': 35, 'height': 25, 'alt': 'Heart_small' }, 'Heart_small,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x67,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xC7,0x00,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x9F,0x01,0xFF,0x8F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x3F,0x83,0xFF,0x1F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0xC6,0xFF,0x3F,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xCE,0xFF,0xFF,0x02,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xEF,0xFF,0xFF,0x06,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x05,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Mouth 1 open.png'), 'width': 35, 'height': 25, 'alt': 'Mouth_1_open' }, 'Mouth_1_open,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0xFC,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x7F,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x04,0x60,0x00,0xF8,0xFF,0xFF,0xFF,0x3F,0x00,0x18,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x38,0x00,0x30,0x00,0x18,0x00,0x00,0x04,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x04,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x04,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x40,0x00,0x04,0x30,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x40,0x00,0x04,0x30,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x40,0x00,0x0C,0x30,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x38,0x40,0x00,0x0C,0x78,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x38,0x60,0x00,0x18,0x7C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0x78,0x70,0x00,0xF8,0xEF,0x00,0x1E,0x00,0x38,0x00,0xF0,0x00,0xCC,0x3F,0x00,0xE4,0xD7,0xC3,0x37,0x00,0x38,0x00,0xD8,0x07,0x87,0x1F,0x00,0x08,0xA8,0xFF,0x71,0x00,0x38,0x00,0x1C,0xFF,0x23,0x40,0x00,0xA8,0x2A,0x00,0xE4,0x03,0xEF,0x81,0x2F,0x00,0xA8,0x2A,0x00,0x54,0x55,0x55,0x95,0xFF,0xC7,0xFF,0x53,0x55,0x55,0x55,0x00,0x28,0x55,0x55,0x15,0x00,0x28,0x00,0xA8,0xAA,0xAA,0x2A,0x00,0xD4,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x2A,0x55,0x55,0x00,0x28,0x55,0xAD,0xAA,0xAA,0x56,0x55,0x55,0xD5,0xAA,0x2A,0x00,0xD4,0xAA,0x52,0x55,0x55,0xA9,0xAA,0xAA,0x2A,0x55,0x55,0x00,0x28,0x55,0xAD,0xAA,0xAA,0x56,0x55,0x55,0xD5,0xAA,0x2A,0x00,0xD4,0xAA,0x52,0x55,0x55,0xA9,0xAA,0xAA,0x2A,0x55,0x55,0x00,0x28,0x55,0xAD,0xAA,0xAA,0x56,0x55,0x55,0xD5,0xAA,0x2A,0x00,0xD4,0xAA,0x52,0x55,0x55,0xA9,0xAA,0xAA,0x2A,0x55,0x55,0x00,0x28,0x55,0xAD,0xAA,0xAA,0x56,0x55,0x55,0xD5,0xAA,0x2A,0x00,0xD4,0xAA,0x52,0x55,0x55,0xA9,0xAA,0xAA,0x2A,0x55,0x55,0x00,0x28,0x55,0xAD,0xAA,0xAA,0x56,0x55,0x55,0xD5,0xAA,0x52,0x00,0xE8,0x55,0x51,0x55,0x55,0xA9,0xAA,0xAA,0x2A,0xAA,0x2E,0x00,0x0C,0x54,0xAF,0xAA,0xAA,0x56,0x55,0xAB,0xEA,0xAB,0x50,0x00,0xF0,0x57,0xA0,0xAA,0x54,0xA9,0xAA,0x54,0x15,0xA8,0x5F,0x00,0x04,0xD8,0x5F,0x55,0xAB,0x56,0x55,0x53,0xF5,0x2F,0x40,0x00,0xF0,0x27,0x40,0xAD,0x54,0xA9,0xAA,0xAC,0x0A,0xA0,0x3F,0x00,0x18,0xEE,0x7F,0x51,0xAB,0x56,0x55,0x53,0xFA,0xDF,0x71,0x00,0x0C,0x0C,0x00,0xDF,0x54,0x51,0xA5,0xDC,0x03,0xC0,0x60,0x00,0x0C,0xD8,0x7F,0x00,0x6B,0xDF,0x5D,0x03,0xF8,0x6F,0x40,0x00,0x0C,0xF8,0xE0,0xFC,0x08,0x20,0xC0,0xF8,0x1C,0x7C,0x40,0x00,0x0C,0x30,0x80,0xFF,0xF3,0x87,0x1F,0xFF,0x07,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0xFF,0xFF,0xFF,0x03,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x0E,0x78,0xC0,0x01,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0xE1,0xFF,0xFF,0xFF,0x1F,0x06,0x30,0x40,0x00,0x0C,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x40,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0xFC,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x7F,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Mouth 1 shut.png'), 'width': 35, 'height': 25, 'alt': 'Mouth_1_shut' }, 'Mouth_1_shut,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0xFC,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x7F,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x04,0x60,0x00,0xF8,0xFF,0xFF,0xFF,0x3F,0x00,0x18,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x38,0x00,0x30,0x00,0x18,0x00,0x00,0x04,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x04,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x00,0x00,0x04,0x20,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x40,0x00,0x04,0x30,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x40,0x00,0x04,0x30,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x18,0x40,0x00,0x0C,0x30,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x38,0x40,0x00,0x0C,0x38,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x38,0x60,0x00,0x18,0x7C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0x78,0x70,0x00,0xF8,0xEF,0x00,0x1E,0x00,0x38,0x00,0xF0,0x00,0xCC,0x3F,0x00,0xE0,0xC7,0xC3,0x37,0x00,0x38,0x00,0xD8,0x07,0x87,0x5F,0x00,0x04,0x90,0xFF,0x71,0x00,0x38,0x00,0x9C,0xFF,0x33,0x00,0x00,0xF0,0x17,0x00,0xE4,0x03,0xEF,0x81,0x4F,0x00,0x94,0x3F,0x00,0x18,0xEE,0x5F,0x95,0xFF,0xD7,0xFF,0xA3,0xFA,0xD7,0x71,0x00,0x0C,0x1C,0x00,0x6D,0x00,0x20,0x00,0xDC,0x02,0xC0,0x60,0x00,0x0C,0xD8,0x7F,0x01,0x55,0xAF,0x5D,0x01,0xFA,0x6F,0x40,0x00,0x0C,0xF8,0xE0,0xFC,0x08,0x50,0x40,0xF8,0x1D,0x7C,0x40,0x00,0x0C,0x30,0x80,0xFF,0xF3,0x87,0x1F,0xFF,0x07,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0xFF,0xEF,0xFF,0x03,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x0E,0x78,0xC0,0x01,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0x01,0x04,0x30,0x80,0x00,0x06,0x30,0x40,0x00,0x0C,0x30,0x80,0xE1,0xFF,0xFF,0xFF,0x1F,0x06,0x30,0x40,0x00,0x0C,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x40,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0xFC,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x7F,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Mouth 2 open.png'), 'width': 35, 'height': 25, 'alt': 'Mouth_2_open' }, 'Mouth_2_open,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x01,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x1A,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x60,0x00,0x19,0x00,0xC3,0xF0,0xFF,0xFF,0xFF,0x1F,0xE3,0x03,0x30,0x01,0x1A,0x00,0xC7,0x80,0x01,0x3C,0xC0,0x00,0x63,0x03,0x30,0x01,0x1A,0x80,0xCD,0x41,0x01,0x26,0xC0,0x81,0x33,0x03,0xB8,0x00,0x35,0x80,0xDD,0x41,0x02,0x2A,0x20,0x81,0x1B,0x03,0x98,0x00,0x32,0x80,0xFA,0xA3,0x02,0x6B,0x30,0xC1,0x4E,0x02,0x5C,0x01,0x35,0xC0,0x34,0xB3,0x04,0x55,0x50,0x42,0xA0,0x02,0x4C,0x01,0x25,0xC0,0x4A,0x53,0x8D,0xD5,0x48,0x63,0x55,0x02,0xAE,0x00,0x6A,0x40,0xAA,0x9E,0x8A,0x94,0xA8,0xB2,0xAA,0x02,0xA6,0x00,0x6A,0x40,0x55,0xAD,0xD2,0xAA,0x54,0x92,0xAA,0x02,0x57,0x01,0x55,0x60,0x55,0x41,0x65,0xAA,0xA3,0xAE,0xAA,0x02,0x53,0x01,0xD5,0x60,0x55,0x51,0x85,0x2A,0xA9,0x52,0x55,0x82,0xA9,0x00,0xAA,0x60,0x55,0x55,0x55,0x55,0x54,0xA9,0xAA,0x82,0xA9,0x00,0x95,0x20,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xC2,0x54,0x01,0xAA,0xB1,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xE2,0xAA,0x00,0x2A,0xB1,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x62,0x55,0x01,0x55,0x33,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x33,0x55,0x01,0x55,0xB2,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x2A,0xBB,0xAA,0x00,0xAA,0xB6,0xAA,0xAA,0xAA,0x6A,0x55,0x55,0x55,0x9F,0xAA,0x00,0xAA,0x5C,0x55,0x55,0x55,0x95,0xAA,0xAA,0x2A,0x4F,0x55,0x01,0x55,0x9D,0xAA,0xAA,0xAA,0x6A,0x55,0x55,0x55,0xA7,0xAA,0x00,0x55,0x59,0x55,0x55,0x55,0x95,0xAA,0xAA,0xAA,0x57,0x55,0x01,0xAA,0xBA,0xAA,0xAA,0xAA,0x6A,0x55,0x55,0x55,0xA9,0xAA,0x00,0xAA,0x52,0x55,0x55,0x55,0x95,0xAA,0xAA,0x4A,0x54,0x55,0x01,0x55,0x8D,0xAA,0xAA,0xAA,0x6A,0x55,0x55,0xB5,0xAA,0xAA,0x00,0xAA,0x52,0x55,0x55,0x55,0x95,0xAA,0xAA,0x4A,0x55,0x55,0x01,0x55,0xAD,0xAA,0xAA,0xAA,0x6A,0x55,0x55,0xB5,0xAA,0xAA,0x00,0xAA,0x52,0x55,0x55,0x55,0x95,0x2A,0x55,0x45,0x55,0x55,0x01,0x55,0xAD,0xAA,0xAA,0xAA,0x6A,0xD5,0xAA,0x7A,0xA5,0xAA,0x00,0xAA,0x52,0x55,0x55,0x55,0x95,0x2A,0x55,0x85,0x5A,0x55,0x01,0x55,0xAD,0xA9,0xAA,0xAA,0x6A,0xD5,0xAA,0x2A,0xA5,0xAA,0x00,0xAA,0x52,0x56,0x55,0x55,0x95,0x2A,0x55,0xF5,0x5A,0x55,0x01,0x55,0x2D,0xA9,0xAA,0xAA,0x6A,0xD5,0xAA,0xEA,0xA5,0xAA,0x00,0xAA,0x92,0x55,0x55,0x55,0x95,0x2A,0x55,0x65,0x59,0x55,0x01,0x55,0xCD,0x55,0x55,0x55,0x69,0xD5,0xAA,0x6A,0xA2,0xAA,0x00,0xAA,0xE2,0xAD,0xAA,0xAA,0x96,0x2A,0x55,0x65,0x56,0x55,0x01,0x55,0xB5,0x51,0x55,0x55,0x69,0xD5,0xAA,0x6A,0xAC,0xAA,0x00,0xAA,0x1A,0xAD,0xAA,0xAA,0x96,0x2A,0x55,0x65,0x4C,0x55,0x01,0x55,0x0D,0x53,0x55,0x55,0xE9,0xEA,0xAA,0x6A,0x58,0x55,0x01,0xAA,0x0C,0xAB,0x52,0x55,0x16,0x15,0xAA,0x6A,0x90,0xAA,0x00,0xD5,0x06,0x53,0x4D,0xAD,0xC9,0xAA,0xA9,0x6A,0xB0,0xAA,0x00,0x2A,0x06,0xAA,0xB2,0xD2,0xA5,0xAD,0x53,0x65,0x60,0x55,0x01,0x55,0x03,0xEA,0x32,0x4D,0x2B,0xB1,0xAC,0x6A,0x60,0xAA,0x00,0x2A,0x03,0x16,0x59,0x23,0x32,0xCA,0x48,0x6B,0xC0,0x56,0x01,0xB5,0x01,0x16,0x4C,0x14,0x16,0xB4,0x58,0x68,0xC0,0xA8,0x00,0x8A,0x01,0xC4,0x8E,0x1A,0x14,0xC4,0x30,0x6B,0x80,0x55,0x01,0xB5,0x01,0xE4,0x87,0x0A,0x1C,0x48,0xE0,0x67,0x80,0x55,0x01,0x8A,0x01,0x74,0x07,0x09,0x08,0x50,0xE0,0x6E,0x00,0xAB,0x00,0xD5,0x00,0x3C,0x07,0x04,0x08,0x70,0xC0,0x3C,0x00,0xAB,0x01,0xCA,0x00,0x1C,0x03,0x07,0x0C,0x30,0xC0,0x38,0x00,0x56,0x00,0xCD,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0xB6,0x01,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x01,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x01,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Mouth 2 shut.png'), 'width': 35, 'height': 25, 'alt': 'Mouth_2_shut' }, 'Mouth_2_shut,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x01,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0x1A,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x60,0x00,0x19,0x00,0xC3,0xF0,0xFF,0xFF,0xFF,0x1F,0xE3,0x03,0x30,0x01,0x1A,0x00,0xC7,0x80,0x01,0x3C,0xC0,0x00,0x63,0x03,0x30,0x01,0x1A,0x80,0xCD,0x41,0x01,0x26,0xC0,0x81,0x33,0x03,0xB8,0x00,0x35,0x80,0xDD,0x41,0x02,0x2A,0x20,0x81,0x1B,0x03,0x98,0x00,0x32,0x80,0xFA,0xA3,0x02,0x6B,0x30,0xC1,0x8E,0x02,0x5C,0x01,0x35,0xC0,0x34,0xB3,0x04,0x55,0x50,0x42,0x20,0x02,0x4C,0x01,0x25,0xC0,0x46,0x53,0x8D,0xD5,0x48,0x63,0xF5,0x02,0xAE,0x00,0x6A,0x40,0xA8,0x9E,0x8A,0x94,0xA8,0xB2,0xEA,0x02,0xA6,0x00,0x6A,0xC0,0x55,0xAD,0xD2,0xAA,0x54,0x92,0x6A,0x03,0x57,0x01,0x55,0x60,0x55,0x41,0x65,0xAA,0xA3,0xAE,0x6A,0x02,0x53,0x01,0xD5,0xE0,0xAD,0x52,0x85,0x2A,0xA9,0x52,0x65,0x82,0xA9,0x00,0xAA,0xE0,0x51,0x55,0x55,0x55,0x54,0xA9,0x6A,0x82,0xA9,0x00,0x95,0x20,0xAD,0xAA,0xAA,0xAA,0x2A,0x55,0x65,0xC2,0x54,0x01,0xAA,0x31,0x53,0x55,0x55,0xD5,0xEA,0xAA,0x6A,0xE2,0xAA,0x00,0x2A,0x31,0xAB,0x52,0x55,0x16,0x15,0xAA,0x6A,0x62,0x55,0x01,0x55,0x33,0x53,0x4D,0xAD,0xC9,0xAA,0xA9,0x6A,0x32,0xAA,0x00,0xAA,0x32,0xAA,0xB2,0xD2,0xA5,0xAD,0x53,0x65,0x3B,0x55,0x01,0x55,0x36,0xEA,0x32,0x4D,0x2B,0xB1,0xAC,0x6A,0x5F,0xAA,0x00,0x55,0x15,0x16,0x59,0x23,0x32,0xCA,0x48,0x6B,0xCF,0x56,0x01,0xAA,0x1D,0x16,0x4C,0x14,0x16,0xB4,0x58,0x68,0xC7,0xA8,0x00,0xAA,0x19,0xC4,0x8E,0x1A,0x14,0xC4,0x30,0x6B,0x87,0x55,0x01,0xB5,0x19,0xE4,0x87,0x0A,0x1C,0x48,0xE0,0x67,0x81,0x55,0x01,0x8A,0x11,0x74,0x07,0x09,0x08,0x50,0xE0,0x6E,0x00,0xAB,0x00,0xD5,0x00,0x3C,0x07,0x04,0x08,0x70,0xC0,0x3C,0x00,0xAB,0x01,0xCA,0x00,0x1C,0x03,0x07,0x0C,0x30,0xC0,0x38,0x00,0x56,0x00,0xCD,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x00,0xB6,0x01,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x01,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x01,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Sad.png'), 'width': 35, 'height': 25, 'alt': 'Sad' }, 'Sad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x83,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Sick.png'), 'width': 35, 'height': 25, 'alt': 'Sick' }, 'Sick,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0F,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x3F,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFC,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0xF0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Smile.png'), 'width': 35, 'height': 25, 'alt': 'Smile' }, 'Smile,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x83,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Swearing.png'), 'width': 35, 'height': 25, 'alt': 'Swearing' }, 'Swearing,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xC0,0x00,0x00,0x1A,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0xE0,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x60,0x28,0x00,0x00,0xC0,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x1F,0x64,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x4A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x28,0x00,0x00,0x00,0xC0,0x0B,0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0xF0,0x3F,0x00,0x00,0x00,0x00,0xC4,0x3F,0x04,0x00,0x00,0x00,0xF8,0x7F,0x00,0x40,0x03,0x00,0x76,0x60,0x00,0x18,0x00,0x00,0xFC,0x7F,0x00,0xC0,0x01,0x00,0x1A,0x40,0x00,0x18,0x00,0x00,0xFC,0xF7,0x00,0xE0,0x01,0x00,0xC9,0x41,0x40,0x08,0x00,0x00,0xFC,0xE3,0x00,0xC0,0x03,0x00,0x09,0x42,0x40,0x00,0x00,0x00,0xFC,0xC3,0x10,0x80,0x00,0x00,0x19,0x63,0xC0,0x00,0x00,0x00,0x3C,0x63,0x70,0x00,0x00,0x03,0xF1,0x31,0xF0,0x07,0x00,0x00,0x1C,0x7E,0x78,0x00,0xC0,0x03,0x01,0x18,0xFC,0x03,0x00,0x00,0x1C,0x72,0x2C,0x00,0xE0,0x03,0x03,0x0C,0xF0,0x03,0x00,0x00,0x38,0x33,0x06,0x00,0xF0,0x03,0x0E,0x07,0xB0,0x03,0x00,0x00,0xF0,0x7F,0xC3,0x01,0xF0,0x03,0xF8,0x01,0x10,0x07,0x00,0x00,0xE0,0x2F,0xE1,0x00,0xF0,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x80,0x02,0xFF,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xF0,0x01,0xF8,0xFE,0x01,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01,0xFC,0xFF,0x03,0x00,0x00,0x00,0x38,0x0C,0x00,0x00,0xF0,0x01,0xFE,0xFF,0x07,0x00,0x00,0x00,0x18,0x06,0x00,0x00,0xF0,0x00,0xBE,0xFE,0xFF,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xF8,0xC0,0xDF,0xFF,0xFF,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xF8,0xE0,0xFF,0xFF,0xFF,0x07,0x00,0x00,0xE0,0x01,0x00,0x00,0x78,0xE0,0xFF,0xFF,0x3F,0x0F,0x00,0x00,0xC0,0x01,0x00,0x00,0x70,0xE0,0xFF,0xFF,0x7F,0x0F,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xC0,0x00,0x08,0x80,0xFF,0xDF,0xFF,0x0F,0x00,0xF0,0x01,0x00,0xF0,0x03,0x1E,0x00,0xFF,0xFF,0xFF,0x1F,0x00,0x3C,0x07,0x00,0xF0,0x03,0x3C,0x00,0xC0,0xBF,0xFF,0x3F,0x00,0x04,0x0C,0x00,0xE0,0x01,0x1C,0x00,0x00,0xFF,0xFF,0x7F,0x00,0xE4,0x19,0x00,0xF0,0x01,0x18,0x3E,0x00,0xFE,0xFF,0x7F,0x00,0xB2,0x11,0x00,0x10,0x03,0x00,0xE3,0x00,0xFC,0xFF,0xEF,0x00,0x56,0x19,0x00,0x00,0x02,0x80,0x81,0x03,0xF4,0xFF,0xFF,0x00,0x34,0x09,0x00,0x04,0x00,0x80,0x00,0x02,0xE6,0xFF,0xEF,0x00,0x8C,0x09,0x30,0x02,0x00,0xC0,0x30,0x02,0x23,0xFE,0xFB,0x00,0xB8,0x08,0x00,0x20,0x30,0x40,0x10,0x03,0x11,0xFC,0xFF,0x00,0xE0,0x00,0x0C,0x04,0x30,0xC0,0x98,0x81,0x18,0xE4,0x7F,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x98,0x40,0x0C,0x27,0x7F,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x71,0x60,0x06,0x21,0x38,0x00,0x00,0x00,0x08,0x00,0x20,0x10,0x03,0x40,0x0C,0x31,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x8C,0x09,0x00,0x00,0x00,0x1C,0x40,0x18,0x40,0x10,0x06,0xC0,0xC4,0x04,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x10,0x00,0x40,0xC2,0x04,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0xD0,0x00,0x20,0xC1,0x0C,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x70,0x00,0x94,0xC1,0x0F,0x00,0x00,0x80,0x19,0x80,0xFF,0x00,0x70,0x00,0xDC,0x00,0x00,0x00,0x00,0x00,0x02,0xC0,0xFF,0x01,0x58,0x01,0x44,0x00,0x00,0x00,0x00,0x90,0x00,0xC0,0xFF,0x01,0xC0,0x00,0x44,0x00,0x00,0x00,0x00,0x30,0x18,0xC0,0xFF,0x03,0xC0,0x00,0x64,0x00,0x00,0x20,0x00,0x40,0x10,0xC0,0xFF,0x03,0xA0,0x00,0x1C,0x00,0x00,0x38,0x00,0x40,0x20,0xC0,0xFF,0x03,0xA0,0x00,0x00,0x00,0x00,0x70,0x00,0x80,0x54,0xC0,0xFF,0x01,0x80,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x04,0x80,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Talking.png'), 'width': 35, 'height': 25, 'alt': 'Talking' }, 'Talking,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x03,0x00,0x00,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0xF0,0x3F,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0xFC,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0xFC,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0xC0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0xE0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8E,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/Wink.png'), 'width': 35, 'height': 25, 'alt': 'Wink' }, 'Wink,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x3F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x7E,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+ [{ 'src': require('../media/oled_icons/face/Expressions/ZZZ.png'), 'width': 35, 'height': 25, 'alt': 'ZZZ' }, 'ZZZ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0x00,0xFE,0x3A,0x00,0x00,0x00,0xE0,0xFF,0x01,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0x0F,0x00,0x00,0x00,0xE0,0xFF,0x1F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x01,0x00,0x00,0xE0,0xEF,0x1F,0x00,0x00,0x00,0xFE,0xFF,0xBF,0x01,0x00,0x00,0x20,0xE0,0x0F,0x00,0x00,0x00,0xFE,0xFF,0x7F,0x81,0xFF,0x3F,0x00,0xF0,0x07,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x81,0xFF,0x6F,0x00,0xF8,0x07,0x00,0x00,0x00,0xFE,0xFF,0x7F,0x81,0xFF,0x5F,0x00,0xF8,0x03,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x81,0xFF,0x7F,0x00,0xFC,0x03,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x81,0xFF,0x3F,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0xC0,0xFF,0x01,0xDF,0x3F,0x00,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x1F,0x00,0xFE,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0xFF,0xBE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x80,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x80,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x87,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x8D,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x02,0x00,0x00,0xC0,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'],
+];
+
+//图标尺寸
+const ICON_SIZE = [
+ ["8", "1"],
+ ["16", "2"],
+ ["32", "4"],
+ ["48", "6"],
+ ["64", "8"],
+];
+
+//显示-OLED-初始化(iic)
+export const oled_init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(new Blockly.FieldDropdown(OLED_TYPE), "OLED_TYPE")
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(" " + Blockly.Msg.MIXLY_MICROBIT_monitor)
+ .appendField(new Blockly.FieldDropdown(ROTATION_TYPE), "ROTATION")
+ .appendField(' SCL')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SCL")
+ .appendField('SDA')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SDA");
+ this.appendValueInput("ADDRESS")
+ .appendField(Blockly.Msg.MIXLY_LCD_ADDRESS);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_INIT2_TOOLTIP);
+ this.setFieldValue(Profile.default.SCL[0][1], "SCL");
+ this.setFieldValue(Profile.default.SDA[0][1], "SDA");
+ }
+};
+
+export const u8g2_spi_init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(new Blockly.FieldDropdown(U8G2_TYPE_SSD1306_NOKIA5110), "U8G2_TYPE_SPI")
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(" " + Blockly.Msg.MIXLY_MICROBIT_monitor)
+ .appendField(new Blockly.FieldDropdown(ROTATION_TYPE), "ROTATION");
+ this.appendDummyInput()
+ .appendField('CLK')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "CLK")
+ .appendField('MOSI')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "MOSI");
+ this.appendDummyInput()
+ .appendField('CS')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "CS")
+ .appendField('DC')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DC")
+ .appendField('RST')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "RST");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(
+ "CLK - SCL(SSD1306) - CLK(NOKIA5110)\n"
+ + "MOSI - SDA(SSD1306) - DIN(NOKIA5110)"
+ );
+ this.setHelpUrl("");
+ this.setFieldValue(Profile.default.SCK[0][1], "CLK");
+ this.setFieldValue(Profile.default.MOSI[0][1], "MOSI");
+ }
+};
+
+export const u8g2_LCD12864_spi_init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + "LCD12864")
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(" " + Blockly.Msg.MIXLY_MICROBIT_monitor)
+ .appendField(new Blockly.FieldDropdown(ROTATION_TYPE), "ROTATION");
+ this.appendValueInput("CLK")
+ .setCheck(Number)
+ .appendField("CLK");
+ this.appendValueInput("MOSI")
+ .setCheck(Number)
+ .appendField("MOSI");
+ this.appendDummyInput()
+ .appendField('RS')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DC");
+ //.appendField(' RST'+Blockly.Msg.MIXLY_PIN)
+ //.appendField(new Blockly.FieldDropdown(Profile.default.digital), "RST");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip("PSB = 0");
+ this.setHelpUrl("");
+ }
+};
+
+export const u8g2_LCD12864_8080_init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + "LCD12864")
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(" " + Blockly.Msg.MIXLY_MICROBIT_monitor)
+ .appendField(new Blockly.FieldDropdown(ROTATION_TYPE), "ROTATION");
+ this.appendDummyInput()
+ .appendField('D0')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB0")
+ .appendField('D1')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB1")
+ .appendField('D2')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB2")
+ .appendField('D3')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB3")
+ .appendField('D4')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB4")
+ .appendField('D5')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB5")
+ .appendField('D6')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB6")
+ .appendField('D7')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DB7")
+ .appendField('E')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "ENABLE")
+ .appendField('RS')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DC");
+ //.appendField(' RST'+Blockly.Msg.MIXLY_PIN)
+ //.appendField(new Blockly.FieldDropdown(Profile.default.digital), "RST");
+ this.setInputsInline(false);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip("R/W = 0,PSB = 1");
+ this.setHelpUrl("");
+ }
+};
+
+//显示-OLED-清屏幕
+export const oled_clear = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_CLEAR);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip();
+ }
+};
+
+//显示-OLED-定义图像名称和数据
+export const oled_define_bitmap_data = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_BITMAP_NAME)
+ .appendField(new Blockly.FieldTextInput('bitmap1'), 'VAR')
+ .appendField(Blockly.Msg.OLED_BITMAP_DATA)
+ .appendField(new Blockly.FieldTextInput(''), 'TEXT');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DEF_BMP_DATA_TOOLTIP);
+ }
+};
+
+//显示-OLED-设置图标
+export const oled_icons = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_BITMAP);
+ this.appendValueInput("POS_X")
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y")
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_NUMBER)
+ .appendField(new Blockly.FieldDropdown(ICON_SIZE), "ICON_SIZE")
+ .appendField("px");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.OLED_ICON)
+ .appendField(new Blockly.FieldDropdown(ICON_IMAGE), 'ICON_IMAGE');
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-OLED-设置图标(表情)
+export const oled_face = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_BITMAP);
+ this.appendValueInput("POS_X")
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y")
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.OLED_ICON)
+ .appendField(new Blockly.FieldDropdown(FACE_IMAGE), 'FACE_IMAGE');
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-OLED-显示图像
+export const oled_showBitmap = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_BITMAP);
+ this.appendValueInput("START_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("START_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("WIDTH", Number)
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .setCheck(Number);
+ this.appendValueInput("HEIGHT", Number)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT)
+ .setCheck(Number);
+ this.appendValueInput("bitmap_name", String)
+ .appendField(Blockly.Msg.OLED_BITMAP_NAME)
+ .setCheck(String);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_SHOW_BMP_TOOLTIP);
+ }
+};
+
+//显示-OLED-画点
+export const oled_drawPixel = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAWPIXEL);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_POSX)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_POSY)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_PIXE_TOOLTIP);
+ }
+};
+
+//显示-OLED-画线
+export const oled_drawLine = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAWLINE);
+ this.appendValueInput("START_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("START_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("END_X", Number)
+ .appendField(Blockly.Msg.OLED_END_X)
+ .setCheck(Number);
+ this.appendValueInput("END_Y", Number)
+ .appendField(Blockly.Msg.OLED_END_Y)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_LINE_TOOLTIP);
+ }
+};
+
+//显示-OLED-画直线
+export const oled_draw_Str_Line = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAWSTRLINE);
+ this.appendValueInput("START_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("START_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("LENGTH", Number)
+ .appendField(Blockly.Msg.OLED_LENGTH)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(LINESELECT), "TYPE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-OLED-新建页面
+export const oled_page = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_PAGE);
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_page_tooltip);
+ }
+};
+
+//显示-OLED-画三角
+export const oled_drawTriangle = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAW_TRIANGLE);
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_D0_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_D0_Y)
+ .setCheck(Number);
+ this.appendValueInput("D1_X", Number)
+ .appendField(Blockly.Msg.OLED_D1_X)
+ .setCheck(Number);
+ this.appendValueInput("D1_Y", Number)
+ .appendField(Blockly.Msg.OLED_D1_Y)
+ .setCheck(Number);
+ this.appendValueInput("D2_X", Number)
+ .appendField(Blockly.Msg.OLED_D2_X)
+ .setCheck(Number);
+ this.appendValueInput("D2_Y", Number)
+ .appendField(Blockly.Msg.OLED_D2_Y)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("");
+ }
+};
+
+//显示-OLED-画长方形
+export const oled_drawFrame = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAW_RECTANGLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(FRAMESELECT), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_L_U_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_L_U_Y)
+ .setCheck(Number);
+ this.appendValueInput("WIDTH", Number)
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .setCheck(Number);
+ this.appendValueInput("HEIGHT", Number)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-OLED-画圆角矩形
+export const oled_drawRFrame = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAW_RAD_RECTANGLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(RADSELECT), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_L_U_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_L_U_Y)
+ .setCheck(Number);
+ this.appendValueInput("WIDTH", Number)
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .setCheck(Number);
+ this.appendValueInput("HEIGHT", Number)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT)
+ .setCheck(Number);
+ this.appendValueInput("RADIUS", Number)
+ .appendField(Blockly.Msg.OLED_RADIUS)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-OLED-画圆(空心,实心)
+export const oled_drawCircle = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAW_CIRCLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(CIRCLESELECT), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_CENTER_CIRCLE_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_CENTER_CIRCLE_Y)
+ .setCheck(Number);
+ this.appendValueInput("RADIUS", Number)
+ .appendField(Blockly.Msg.OLED_CIRCLE_RADIUS)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(CIRCLEOPTELECT), "OPT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-OLED-画椭圆(空心,实心)
+export const oled_drawEllipse = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAW_ELLIPSE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(ELLIPSESELECT), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_CENTER_CIRCLE_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_CENTER_CIRCLE_Y)
+ .setCheck(Number);
+ this.appendValueInput("RADIUS_X", Number)
+ .appendField(Blockly.Msg.OLED_ELLIPSE_RADIUS_X)
+ .setCheck(Number);
+ this.appendValueInput("RADIUS_Y", Number)
+ .appendField(Blockly.Msg.OLED_ELLIPSE_RADIUS_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(CIRCLEOPTELECT), "OPT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_ELLIPSE_TOOLTIP);
+ }
+};
+
+//显示-OLED-显示字符串
+export const oled_drawStr = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_DRAWSTR);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("TEXT", String)
+ .appendField(Blockly.Msg.OLED_STRING)
+ .setCheck([Number, String]);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-OLED-设置字体
+export const oled_set_EN_Font = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.set_EN_Font)
+ .appendField(new Blockly.FieldDropdown(EN_FONT_NAME), "FONT_NAME");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.FontSize)
+ .appendField(new Blockly.FieldDropdown(EN_FONT_SIZE), "FONT_SIZE");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.Font_Style)
+ .appendField(new Blockly.FieldDropdown(EN_FONT_STYLE), "FONT_STYLE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-OLED-设置字体
+export const oled_set_CN_Font = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.set_CN_Font)
+ .appendField(new Blockly.FieldDropdown(CN_FONT_NAME), "FONT_NAME");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.FontSize)
+ .appendField(new Blockly.FieldDropdown(CN_FONT_SIZE), "FONT_SIZE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-OLED-设置字体
+export const oled_set_ZH_TW_Font = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.set_ZH_TW_Font);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-OLED-显示字符串
+export const oled_print = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.OLED_PRINT_VAR);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("TEXT", String)
+ .appendField(Blockly.Msg.OLED_STRING)
+ .setCheck([Number, String]);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_print_tooltip);
+ }
+};
+
+//OLED背光亮度
+export const u8g2_setContrast = {
+ init: function () {
+ this.appendValueInput("Contrast")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(Blockly.Msg.TFT_Brightness + Blockly.Msg.MIXLY_BRIGHTNESS);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(DISPLAY_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_U8G2_SETCONTRAST_HELP);
+ this.setHelpUrl("");
+ }
+};
+
+//返回UTF8字符串宽度
+export const get_utf8_width = {
+ init: function () {
+ this.appendValueInput("str")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DISPLAY)
+ .appendField(new Blockly.FieldTextInput("u8g2"), "NAME")
+ .appendField(' ' + Blockly.Msg.OLED_DRAWSTR + Blockly.Msg.MIXLY_WIDTH);
+ this.setOutput(true, null);
+ this.setColour(DISPLAY_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://www.cnblogs.com/danpianjicainiao/p/11048729.html#_label3_1_39");
+ }
+};
+
+//LCD自定义图案显示
+export const lcd_display_pattern = {
+ init: function () {
+ this.appendValueInput("row")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_DF_LCD)
+ .appendField(new Blockly.FieldTextInput("mylcd"), "name")
+ .appendField(Blockly.Msg.MIXLY_LCD_ROW);
+ this.appendValueInput("column")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_LCD_COLUMN);
+ this.appendValueInput("pattern")
+ .setCheck(null)
+ .appendField(Blockly.Msg.COLUMN_DISPLAY_IMAGE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LCD_NUMBERING)
+ .appendField(new Blockly.FieldDropdown(lcd_display_pattern.NUMBER), "number");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(DISPLAY_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://www.arduino.cc/en/Reference/LiquidCrystalCreateChar");
+ },
+ NUMBER: [
+ ["0", "0"],
+ ["1", "1"],
+ ["2", "2"],
+ ["3", "3"],
+ ["4", "4"],
+ ["5", "5"],
+ ["6", "6"],
+ ["7", "7"]
+ ]
+};
+
+//点阵屏显示_图案数组
+export const lcd_pattern = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ARRAYVAR)
+ .appendField(new Blockly.FieldTextInput("lcd"), "VAR");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a81")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a82")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a83")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a84")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a85");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a71")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a72")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a73")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a74")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a75");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a61")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a62")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a63")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a64")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a65");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a51")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a52")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a53")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a54")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a55");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a41")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a42")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a43")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a44")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a45");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a31")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a32")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a33")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a34")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a35");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a21")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a22")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a23")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a24")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a25");
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a11")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a12")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a13")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a14")
+ .appendField(new Blockly.FieldCheckbox("FALSE"), "a15");
+ this.setOutput(true, Number);
+ this.setTooltip("");
+ }
+};
+
+export const display_lcd_bitmap = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ARRAYVAR)
+ .appendField(new Blockly.FieldTextInput("lcd"), "VAR");
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(new Blockly.FieldBitmap([
+ [0, 0, 0, 0, 0],
+ [0, 1, 1, 1, 0],
+ [1, 0, 0, 0, 1],
+ [1, 0, 1, 0, 1],
+ [1, 0, 1, 0, 1],
+ [1, 0, 0, 0, 1],
+ [0, 1, 1, 1, 0],
+ [0, 0, 0, 0, 0]
+ ], null, {
+ filledColor: '#000',
+ emptyColor: '#5ba5a5',
+ bgColor: '#e5e7f1'
+ }), 'BITMAP');
+ this.setOutput(true, Number);
+ this.setTooltip("");
+ }
+};
+
+export const TFT_init_with_pin = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SETUP + " TFT " + Blockly.Msg.DISPLAY);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_STM32_TFT_GREENTAB + "(ST7735)", "ST7735_INITR_GREENTAB"],
+ [Blockly.Msg.MIXLY_STM32_TFT_REDTAB + "(ST7735)", "ST7735_INITR_REDTAB"],
+ [Blockly.Msg.MIXLY_STM32_TFT_BLACKTAB + "(ST7735)", "ST7735_INITR_BLACKTAB"],
+ ["160×80(ST7735)", "ST7735_160×80"],
+ ["160×128(ST7789)", "ST7789_160×128"],
+ ["240×135(ST7789)", "ST7789_240×135"],
+ ["240×240(ST7789)", "ST7789_240×240"],
+ ["320×240(ST7789)", "ST7789_320×240"],
+ ["480×320(ST7796)", "ST7796_480×320"]
+ ]), "TYPE");
+ //.appendField(" "+Blockly.Msg.MIXLY_MICROBIT_monitor)
+ //.appendField(new Blockly.FieldDropdown(ROTATION_TYPE), "ROTATION");
+ this.appendValueInput("CLK")
+ .setCheck(Number)
+ .appendField("CLK");
+ this.appendValueInput("MOSI")
+ .setCheck(Number)
+ .appendField("MOSI");
+ this.appendDummyInput()
+ .appendField('CS')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "CS")
+ .appendField('DC')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DC")
+ .appendField('RST')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "RST");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};
+
+//显示汉字(使用位图显示)
+export const TFT_st7735_show_hz = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("TFT")
+ .appendField(Blockly.Msg.TFT_DISPLAY_CHINESE_CHARACTERS);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_TURTLE_WRITE_FONT_NAME)
+ .appendField(new Blockly.FieldDropdown([
+ ["华文黑体", "STHeiti"],
+ ["华文楷体", "STKaiti"],
+ ["华文细黑", "STXihei"],
+ ["华文宋体", "STSong"],
+ ["华文中宋", "STZhongsong"],
+ ["华文仿宋", "STFangsong"],
+ ["华文彩云", "STCaiyun"],
+ ["华文琥珀", "STHupo"],
+ ["华文隶书", "STLiti"],
+ ["华文行楷", "STXingkai"],
+ ["华文新魏", "STXinwei"],
+ ["黑体", "simHei"],
+ ["宋体", "simSun"],
+ ["新宋体", "NSimSun"],
+ ["仿宋", "FangSong"],
+ ["楷体", "KaiTi"],
+ ["仿宋_GB2312", "FangSong_GB2312"],
+ ["楷体_GB2312", "KaiTi_GB2312"],
+ ["隶书", "LiSu"],
+ ["幼圆", "YouYuan"],
+ ["新细明体", "PMingLiU"],
+ ["细明体", "MingLiU"],
+ ["标楷体", "DFKai-SB"],
+ ["微软正黑体", "Microsoft JhengHei"],
+ ["微软雅黑体", "Microsoft YaHei"],
+ ["AcadEref", "AcadEref"],
+ ["Adobe Ming Std L", "Adobe Ming Std L"],
+ ["Adobe Myungjo Std M", "Adobe Myungjo Std M"],
+ ["Adobe Pi Std", "Adobe Pi Std"],
+ ["AIGDT", "AIGDT"],
+ ["AIgerian", "AIgerian"],
+ ["AmdtSymbols", "AmdtSymbols"],
+ ["Arial", "Arial"],
+ ["Arial Rounded MT Bold", "Arial Rounded MT Bold"],
+ ["Arial Unicode MS", "Arial Unicode MS"],
+ ["BankGothic Lt BT", "BankGothic Lt BT"],
+ ["BankGothic Md BT", "BankGothic Md BT"],
+ ["Baskerville Old Face", "Baskerville Old Face"],
+ ["Bauhaus 93", "Bauhaus 93"],
+ ["Beranad MT Condensed", "Beranad MT Condensed"]
+ ]), "st7735_hz_sharp")
+ .appendField(" " + Blockly.Msg.MIXLY_TURTLE_WRITE_FONT_NUM)
+ .appendField(new Blockly.FieldTextInput("16"), "st7735_hz_line_height")
+ .appendField("px")
+ .appendField(Blockly.Msg.SAVETO + " flash")
+ .appendField(new Blockly.FieldCheckbox("true"), "st7735_show_hz_save");
+ this.appendValueInput("st7735_hz_data")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SD_DATA + "#");
+ this.appendValueInput("st7735_hz_x")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.OLED_L_U_X + "#");
+ this.appendValueInput("st7735_hz_y")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.OLED_L_U_Y + "#");
+ this.appendValueInput("st7735_hz_height")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT + "#");
+ this.appendValueInput("st7735_hz_width")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_WIDTH + "#");
+ this.appendValueInput("st7735_hz_color")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.blynk_iot_WidgetLED_COLOR);
+ this.setInputsInline(false);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(DISPLAY_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const TFT_Brightness = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput('BRIGHTNESS')
+ .setCheck(Number)
+ .appendField("TFT" + Blockly.Msg.TFT_Brightness + Blockly.Msg.MIXLY_BRIGHTNESS);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_ESP32_INOUT_PWM_ANALOG_WRITE_SET_FREQ_TOOLTIP);
+ }
+};
+
+export const TFT_color_seclet = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldColour("33ccff"), "COLOR");
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_PIXE_TOOLTIP);
+ }
+};
+
+export const TFT_color_rgb = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput("R")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_R);
+ this.appendValueInput("G")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_G);
+ this.appendValueInput("B")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RGB_B);
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip('');
+ }
+};
+
+export const TFT_init = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SETUP + " TFT " + Blockly.Msg.DISPLAY);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};
+
+export const TFT_fillScreen = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.MIXLY_BACKGROUND_COLOR);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};
+
+export const TFT_Rotation = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField('TFT');
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_MATRIX_ROTATE)
+ .appendField(new Blockly.FieldDropdown(TFT_Rotation.ROTATION_TYPE), "Rotation_TYPE");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_Matrix_HK16T33_ROTATION);
+ },
+ ROTATION_TYPE: [
+ [Blockly.Msg.MIXLY_0DEGREE, "0"],
+ [Blockly.Msg.MIXLY_90DEGREE, "1"],
+ [Blockly.Msg.MIXLY_180DEGREE, "2"],
+ [Blockly.Msg.MIXLY_270DEGREE, "3"]
+ ]
+};
+
+//显示-TFT-定义字模名称和数据
+export const tft_define_bitmap_data = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_BITMAP_NAME)
+ .appendField(new Blockly.FieldTextInput('bitmap1'), 'VAR')
+ .appendField(Blockly.Msg.OLED_BITMAP_DATA)
+ .appendField(new Blockly.FieldTextInput(''), 'TEXT');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DEF_BMP_DATA_TOOLTIP);
+ }
+};
+
+export const tft_generate_bitmap_data = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/btn/setting.png'), 20, 20, "*", () => {
+ this.showSettingDialog();
+ }))
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_BITMAP_NAME)
+ .appendField(new Blockly.FieldTextInput('bitmap1'), 'VAR')
+ .appendField(Blockly.Msg.OLED_BITMAP_DATA)
+ .appendField(new Blockly.FieldTextInput(''), 'TEXT');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DEF_BMP_DATA_TOOLTIP);
+ },
+ showSettingDialog: function () {
+ this.userImgSize = {
+ width: 100,
+ height: 100
+ };
+ const renderStr = XML.render(XML.TEMPLATE_STR.READ_BITMAP_DIV, {
+ btn1Name: '加载',
+ btn2Name: '保存'
+ });
+ this.canvas = $('');
+ this.ctx = this.canvas[0].getContext('2d');
+ this.ctx.textAlign = 'left';
+ this.ctx.textBaseline = 'top';
+ LayerExt.open({
+ title: '图片取模工具',
+ id: 'read-bitmap-layer',
+ area: ['50%', '250px'],
+ max: ['500px', '250px'],
+ min: ['350px', '100px'],
+ content: renderStr,
+ borderRadius: '5px',
+ shade: LayerExt.SHADE_ALL,
+ success: (layero) => {
+ $('#read-bitmap-layer').css('overflow', 'hidden');
+ this.addEvents(layero);
+ }
+ })
+ },
+ addEvents: function (layero) {
+ layero.find('button').click((event) => {
+ const mId = $(event.currentTarget).attr('m-id');
+ switch (mId) {
+ case '0':
+ this.loadImg(layero);
+ break;
+ case '1':
+ this.writeJson();
+ break;
+ }
+ });
+ },
+ loadImg: function (layero) {
+ MFile.openFile('.png,.jpg', 'url', (fileObj) => {
+ const { data } = fileObj;
+ const inputImg = new Image();
+ inputImg.src = data;
+ inputImg.onload = () => {
+ $('#read-bitmap-div-input-img').empty();
+ $('#read-bitmap-div-input-img').append(inputImg);
+ const imgSize = {
+ width: inputImg.naturalWidth,
+ height: inputImg.naturalHeight
+ };
+ const userImgSize = this.getUserImgSize(layero);
+ const px = userImgSize.width / imgSize.width,
+ py = userImgSize.height / imgSize.height;
+ if (!isNaN(imgSize.width) && !isNaN(imgSize.height))
+ if (py > px)
+ userImgSize.height = parseInt(px * imgSize.height);
+ else
+ userImgSize.width = parseInt(py * imgSize.width);
+ this.userImgSize = userImgSize;
+ this.imgSize = imgSize;
+ const outputImg = new Image();
+ outputImg.height = userImgSize.height;
+ outputImg.width = userImgSize.width;
+ outputImg.src = data;
+ outputImg.onload = () => {
+ const canvas = $('');
+ const ctx = canvas[0].getContext('2d');
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'top';
+ const ratio = window.devicePixelRatio || 1;
+ this.canvas[0].width = outputImg.width;
+ this.canvas[0].height = outputImg.height;
+ this.ctx.width = outputImg.width;
+ this.ctx.height = outputImg.height;
+ canvas[0].width = outputImg.width * ratio;
+ canvas[0].height = outputImg.height * ratio;
+ ctx.width = outputImg.width * ratio;
+ ctx.height = outputImg.height * ratio;
+ this.ctx.drawImage(outputImg, 0, 0, outputImg.width, outputImg.height);
+ ctx.drawImage(outputImg, 0, 0, outputImg.width * ratio, outputImg.height * ratio);
+ $('#read-bitmap-div-output-img').empty();
+ $('#read-bitmap-div-output-img').append(canvas);
+ }
+ const messageDom = $('#read-bitmap-div-message');
+ const message = '输入尺寸:' + imgSize.width + '×' + imgSize.height + '  '
+ + '输出尺寸:' + userImgSize.width + '×' + userImgSize.height;
+ messageDom.empty();
+ messageDom.append(``);
+ }
+ });
+ },
+ writeJson: function () {
+ const { userImgSize = {} } = this;
+ const { width = 100, height = 100 } = userImgSize;
+ const { data } = this.ctx.getImageData(0, 0, width, height);
+ let pixelData = 0, bitmapStr = '';
+ for (let i = 0; i < data.length; i++) {
+ const mark = (i + 1) % 4;
+ let hexData, addition = '';
+ switch (mark) {
+ case 1:
+ pixelData = (data[i] >> 3) & 0x001F;
+ break;
+ case 2:
+ pixelData = (pixelData & 0x001F) << 6;
+ pixelData = pixelData | ((data[i] >> 2) & 0x003F);
+ break;
+ case 3:
+ pixelData = (pixelData & 0x07FF) << 5;
+ pixelData = pixelData | ((data[i] >> 3) & 0x001F);
+ break;
+ default:
+ hexData = pixelData.toString(16);
+ for (let j = 4; j > hexData.length; j--) {
+ addition += '0';
+ }
+ hexData = addition + hexData;
+ bitmapStr += '0x' + hexData + (i === data.length - 1 ? '' : ',');
+ pixelData = 0;
+ }
+ if ((i + 1) % 400 === 0 && i !== data.length - 1)
+ bitmapStr += '\n ';
+ }
+ this.setFieldValue(bitmapStr, 'TEXT');
+ this.setTooltip('图片尺寸(宽×高):' + width + '×' + height);
+ layer.msg('保存成功', { time: 1000 });
+ },
+ getUserImgSize: function (layero) {
+ const inputsDom = layero.find('input');
+ const imgSize = {
+ width: 100,
+ height: 100
+ };
+ for (let i = 0; inputsDom[i]; i++) {
+ const inputDom = $(inputsDom[i]);
+ const mId = inputDom.attr('m-id');
+ switch (mId) {
+ case '0':
+ imgSize.width = parseInt(inputDom.val()) ?? 100;
+ break;
+ case '1':
+ imgSize.height = parseInt(inputDom.val()) ?? 100;
+ break;
+ }
+ }
+ if (imgSize.width > 300)
+ imgSize.width = 300;
+ if (imgSize.height > 300)
+ imgSize.height = 300;
+ return imgSize;
+ }
+};
+
+//显示-TFT-显示位图(汉字)
+export const tft_showBitmap = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_BITMAP);
+ this.appendValueInput("START_X", Number)
+ .appendField(Blockly.Msg.OLED_POSX)
+ .setCheck(Number);
+ this.appendValueInput("START_Y", Number)
+ .appendField(Blockly.Msg.OLED_POSY)
+ .setCheck(Number);
+ this.appendValueInput("WIDTH", Number)
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .setCheck(Number);
+ this.appendValueInput("HEIGHT", Number)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT)
+ .setCheck(Number);
+ this.appendValueInput("bitmap_name", String)
+ .appendField(Blockly.Msg.OLED_BITMAP_NAME)
+ .setCheck(String);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_SHOW_BMP_TOOLTIP);
+ }
+};
+
+export const tft_drawPixel = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAWPIXEL);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_POSX)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_POSY)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_PIXE_TOOLTIP);
+ }
+};
+
+//显示-TFT-画线
+export const tft_drawLine = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAWLINE);
+ this.appendValueInput("START_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("START_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("END_X", Number)
+ .appendField(Blockly.Msg.OLED_END_X)
+ .setCheck(Number);
+ this.appendValueInput("END_Y", Number)
+ .appendField(Blockly.Msg.OLED_END_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.OLED_DRAW_LINE_TOOLTIP);
+ }
+};
+
+//显示-TFT-画直线
+export const tft_drawFastLine = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAWSTRLINE);
+ this.appendValueInput("START_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("START_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendValueInput("LENGTH", Number)
+ .appendField(Blockly.Msg.OLED_LENGTH)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(LINESELECT), "TYPE");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+//显示-TFT-新建页面
+/*
+export const oled_page = {
+ init: function() {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_PAGE);
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_page_tooltip);
+}
+};
+*/
+
+//显示-TFT-画三角
+export const tft_Triangle = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAW_TRIANGLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DRAWFIll), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_D0_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_D0_Y)
+ .setCheck(Number);
+ this.appendValueInput("D1_X", Number)
+ .appendField(Blockly.Msg.OLED_D1_X)
+ .setCheck(Number);
+ this.appendValueInput("D1_Y", Number)
+ .appendField(Blockly.Msg.OLED_D1_Y)
+ .setCheck(Number);
+ this.appendValueInput("D2_X", Number)
+ .appendField(Blockly.Msg.OLED_D2_X)
+ .setCheck(Number);
+ this.appendValueInput("D2_Y", Number)
+ .appendField(Blockly.Msg.OLED_D2_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("");
+ }
+};
+
+//显示-TFT-画长方形
+export const tft_Rect = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAW_RECTANGLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DRAWFIll), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_L_U_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_L_U_Y)
+ .setCheck(Number);
+ this.appendValueInput("WIDTH", Number)
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .setCheck(Number);
+ this.appendValueInput("HEIGHT", Number)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-TFT-画圆角矩形
+export const tft_RoundRect = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAW_RAD_RECTANGLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DRAWFIll), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_L_U_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_L_U_Y)
+ .setCheck(Number);
+ this.appendValueInput("WIDTH", Number)
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .setCheck(Number);
+ this.appendValueInput("HEIGHT", Number)
+ .appendField(Blockly.Msg.MIXLY_HEIGHT)
+ .setCheck(Number);
+ this.appendValueInput("RADIUS", Number)
+ .appendField(Blockly.Msg.OLED_RADIUS)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+//显示-TFT-画圆(空心,实心)
+export const tft_Circle = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_DRAW_CIRCLE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DRAWFIll), "TYPE");
+ this.appendValueInput("D0_X", Number)
+ .appendField(Blockly.Msg.OLED_CENTER_CIRCLE_X)
+ .setCheck(Number);
+ this.appendValueInput("D0_Y", Number)
+ .appendField(Blockly.Msg.OLED_CENTER_CIRCLE_Y)
+ .setCheck(Number);
+ this.appendValueInput("RADIUS", Number)
+ .appendField(Blockly.Msg.OLED_CIRCLE_RADIUS)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(CIRCLEOPTELECT), "OPT");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("x(0~127),y(0~63)");
+ }
+};
+
+//显示-OLED-设置字体
+export const tft_set_EN_Font = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.set_EN_Font)
+ .appendField(new Blockly.FieldDropdown(EN_FONT_NAME), "FONT_NAME");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.FontSize)
+ .appendField(new Blockly.FieldDropdown(EN_FONT_SIZE), "FONT_SIZE");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.Font_Style)
+ .appendField(new Blockly.FieldDropdown(EN_FONT_STYLE), "FONT_STYLE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-OLED-设置字体
+export const tft_set_CN_Font = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.set_CN_Font)
+ .appendField(new Blockly.FieldDropdown(CN_FONT_NAME), "FONT_NAME");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.FontSize)
+ .appendField(new Blockly.FieldDropdown(CN_FONT_SIZE), "FONT_SIZE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-TFT-设置图标
+export const tft_icons = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_BITMAP);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_NUMBER)
+ .appendField(new Blockly.FieldDropdown(ICON_SIZE), "ICON_SIZE")
+ .appendField("px");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.OLED_ICON)
+ .appendField(new Blockly.FieldDropdown(ICON_IMAGE), 'ICON_IMAGE');
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_setFont_tooltip);
+ }
+};
+
+//显示-TFT-显示字符串
+export const tft_print = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_PRINT_VAR);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.appendValueInput("TEXT", String)
+ .appendField(Blockly.Msg.OLED_STRING)
+ .setCheck([Number, String]);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_print_tooltip);
+ }
+};
+
+//显示-TFT-显示字符串
+export const tft_print_refresh = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField("TFT")
+ .appendField(Blockly.Msg.OLED_PRINT_VAR);
+ this.appendValueInput("POS_X", Number)
+ .appendField(Blockly.Msg.OLED_START_X)
+ .setCheck(Number);
+ this.appendValueInput("POS_Y", Number)
+ .appendField(Blockly.Msg.OLED_START_Y)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_COLOUR);
+ this.appendValueInput("COLOR", Number)
+ .setCheck(Number);
+ this.appendValueInput("TEXT", String)
+ .appendField(Blockly.Msg.OLED_STRING)
+ .setCheck([Number, String]);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.oled_print_tooltip);
+ }
+};
+
+export const group_lcd_init = group_lcd_init2;
+
+export const display_TM1637_init_32 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField('CLK')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "CLK")
+ .appendField('DIO')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DIO");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_TIP);
+ this.setHelpUrl('');
+ // this.setFieldValue("2", "CLK");
+ // this.setFieldValue("4", "DIO");
+ }
+};
+
+export const display_TM1637_displyPrint_32 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendValueInput("VALUE")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.OLEDDISPLAY);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_DISPLAYSTRING_TIP1);
+ }
+};
+
+export const display_TM1637_displayTime_32 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.MIXLY_SHOW_FACE_TIME);
+ this.appendValueInput("hour")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_HOUR);
+ this.appendValueInput("minute")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MINUTE);
+ // .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_ON, "displayOn"], [Blockly.Msg.MIXLY_OFF, "displayOff"], [Blockly.Msg.MIXLY_LCD_STAT_CLEAR, "clear"]]), "STAT");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DISPLAY_TM1637_Time_Point)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ON, "(0x80 >> 1)"],
+ [Blockly.Msg.MIXLY_OFF, "(0x80 >> 2)"]
+ ]), "STAT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_DISPLAYTIME_TOOLTIP);
+ }
+};
+
+export const display_TM1637_Brightness_32 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_MONITOR_SET_BRIGHTNESS);
+ this.appendValueInput("Brightness")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_4DIGITDISPLAY_BRIGHTNESS_TOOLTIP);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOPTIP_4DIGITDISPLAY_TM1637_BRIGHTNESS);
+ }
+};
+
+export const display_TM1637_clearDisplay_32 = {
+ init: function () {
+ this.setColour(DISPLAY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_4DIGITDISPLAY + "TM1637")
+ .appendField(new Blockly.FieldTextInput("display"), "NAME")
+ .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_LCD_STAT_CLEAR, "clear"]]), "STAT");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_4DIGITDISPLAY_TM1637_CLEARDISPLAY);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/ethernet.js b/mixly/boards/default_src/arduino_avr/blocks/ethernet.js
new file mode 100644
index 00000000..2c2de02b
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/ethernet.js
@@ -0,0 +1,886 @@
+import * as Blockly from 'blockly/core';
+
+const ETHERNET_HUE = 0;
+
+export const ethernet_init_begin = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_BEGIN)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ETHERNET, 'Ethernet'],
+ [Blockly.Msg.MIXLY_ETHERNET2, 'Ethernet2']
+ ]), "Ethernet");
+ this.appendValueInput('MAC')
+ .setCheck(Array)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_MAC_ADDRESS);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_INIT);
+ }
+};
+
+export const ethernet_mac_address = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldTextInput('DE'), 'VAR1')
+ .appendField('-')
+ .appendField(new Blockly.FieldTextInput('AD'), 'VAR2')
+ .appendField('-')
+ .appendField(new Blockly.FieldTextInput('BE'), 'VAR3')
+ .appendField('-')
+ .appendField(new Blockly.FieldTextInput('EF'), 'VAR4')
+ .appendField('-')
+ .appendField(new Blockly.FieldTextInput('FE'), 'VAR5')
+ .appendField('-')
+ .appendField(new Blockly.FieldTextInput('ED'), 'VAR6');
+ this.setOutput(true, Array);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_MACADDRESS);
+ }
+};
+
+export const ethernet_init_local_ip = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_LOCALIP);
+ this.setOutput(true, 'IPAddress');
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_LOCALIP);
+ }
+};
+
+export const ethernet_client_connect_server = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_CONNECT_SERVER)
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput('mixly.org'), 'SERVER')
+ .appendField(this.newQuote_(false));
+ this.appendValueInput('PORT')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_PORT);
+ this.setOutput(true, Number);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_CONNECT);
+ },
+ newQuote_: function (open) {
+ if (open == this.RTL) {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
+ } else {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
+ }
+ return new Blockly.FieldImage(file, 12, 12, '"');
+ }
+}
+
+export const ethernet_client_stop = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_STOP);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_STOP);
+ }
+};
+
+export const ethernet_client_connected = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_CONNECTED);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_CONNECTED);
+ }
+};
+
+export const ethernet_client_available = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_AVAILABLE);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_CLIENT_AVAILABLE);
+ }
+};
+
+export const ethernet_client_print = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendValueInput('TEXT')
+ .setCheck(String)
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_PRINT);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_CLIENT_PRINT);
+ }
+};
+
+export const ethernet_client_println = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendValueInput('TEXT')
+ .setCheck(String)
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_PRINTLN);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_CLIENT_PRINTLN);
+ }
+};
+
+export const ethernet_client_read = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_READ);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_CLIENT_READ);
+ }
+};
+
+export const ethernet_client_get_request = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_GET_REQUEST);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_URL)
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput(''), 'URL')
+ .appendField(this.newQuote_(false));
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_SERVER)
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput(''), 'SERVER')
+ .appendField(this.newQuote_(false));
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_ETHERNET_GET_REQUEST);
+ },
+ newQuote_: function (open) {
+ if (open == this.RTL) {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
+ } else {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
+ }
+ return new Blockly.FieldImage(file, 12, 12, '"');
+ }
+};
+
+export const NTP_server = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.NTP_SERVER);
+ this.appendValueInput("server_add")
+ .appendField(Blockly.Msg.blynk_SERVER_ADD)
+ .setCheck(String);
+ this.appendValueInput("timeZone")
+ .appendField(Blockly.Msg.MIXLY_TimeZone)
+ .setCheck(Number);
+ this.appendValueInput("Interval")
+ .appendField(Blockly.Msg.blynk_WidgetRTC_setSyncInterval)
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//传感器-实时时钟块_获取时间
+export const NTP_server_get_time = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.NTP_server_get_time);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(NTP_server_get_time.NTP_TIME_TYPE), "TIME_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ },
+ NTP_TIME_TYPE: [
+ [Blockly.Msg.MIXLY_YEAR, "NTP.getDateYear()"],
+ [Blockly.Msg.MIXLY_MONTH, "NTP.getDateMonth()"],
+ [Blockly.Msg.MIXLY_DAY, "NTP.getDateDay()"],
+ [Blockly.Msg.MIXLY_HOUR, "NTP.getTimeHour24()"],
+ [Blockly.Msg.MIXLY_MINUTE, "NTP.getTimeMinute()"],
+ [Blockly.Msg.MIXLY_SECOND, "NTP.getTimeSecond()"],
+ [Blockly.Msg.MIXLY_WEEK, "NTP.getDateWeekday()"]
+ ]
+};
+
+export const MQTT_server = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.MQTT_SERVER);
+ this.appendValueInput("server_add")
+ .appendField(Blockly.Msg.MQTT_SERVER_ADD)
+ .setCheck(String);
+ this.appendValueInput("server_port")
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_PORT)
+ .setCheck(Number);
+ this.appendValueInput("IOT_ID")
+ .appendField(Blockly.Msg.MIXLY_EMQX_USERNAME)
+ .setCheck(String);
+ this.appendValueInput("IOT_PWD", String)
+ .appendField(Blockly.Msg.HTML_PASSWORD)
+ .setCheck([String, Number]);
+ this.appendValueInput("Client_ID")
+ .appendField(Blockly.Msg.MQTT_Client_ID)
+ .setCheck(String);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+//WIFI信息
+export const WIFI_info = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.MIXLY_NETWORK_INIT);
+ this.appendValueInput("SSID")
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.appendValueInput("PWD")
+ .appendField(Blockly.Msg.HTML_PASSWORD);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(" ");
+ this.setHelpUrl();
+ }
+};
+
+export const network_connect = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_ESP32_NETWORK_CONNECT);
+ this.appendValueInput('id')
+ .setCheck(String)
+ .appendField(Blockly.Msg.HTML_NAME);
+ this.appendValueInput('password')
+ .setCheck(String)
+ .appendField(Blockly.Msg.HTML_PASSWORD);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_ESP32_NETWORK_CONNECT_TOOLTIP);
+ }
+};
+
+export const network_wifi_connect = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_NETWORK_WIFI_CONNECT);
+ this.setOutput(true, Number);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_ESP32_NETWORK_WIFI_CONNECT_TOOLTIP);
+ }
+};
+
+export const network_get_connect = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_GET + Blockly.Msg.MIXLY_DEVICE)
+ .appendField(new Blockly.FieldDropdown([["MAC", "MAC"], ["IP", "IP"]]), "mode")
+ .appendField(Blockly.Msg.MQTT_SERVER_ADD);
+ this.setOutput(true);
+ this.setInputsInline(true);
+ }
+};
+
+export const MQTT_connect = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MQTT_connect);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip();
+ }
+};
+
+const Topic_validator = function (newValue) {
+ return newValue.replace(/\//g, '');
+};
+
+//MQTT-发送消息到topic
+export const MQTT_publish = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldImage(require('../media/blynk/iot.png'), 20, 20))
+ .appendField(Blockly.Msg.MQTT_publish);
+ this.appendValueInput("data");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.LANG_MATH_RANDOM_INT_INPUT_TO);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MQTT_Topic)
+ .appendField(new Blockly.FieldTextInput('Topic', Topic_validator), "Topic");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(" ");
+ this.setHelpUrl();
+ }
+};
+
+export const MQTT_subscribe_value = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MQTT_Topic)
+ .appendField(new Blockly.FieldTextInput('Topic_0', Topic_validator), "Topic_0");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.HTML_VALUE)
+ this.setInputsInline(true);
+ this.setOutput(true, String);
+ }
+};
+
+export const MQTT_add_subscribe_topic = {
+ /**
+ * Mutator bolck for else-if condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MQTT_Topic);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+export const MQTT_subscribe = {
+ /**
+ * Block for if/elseif/else condition.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_CURRENT)
+ .appendField(Blockly.Msg.MQTT_Topic + Blockly.Msg.MQTT_subscribe2)
+ .appendField(new Blockly.FieldTextInput('Topic_0', Topic_validator), "Topic_0");
+ this.appendStatementInput('DO0')
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
+ this.setPreviousStatement(false);
+ this.setNextStatement(false);
+ this.setMutator(new Blockly.icons.MutatorIcon(['MQTT_add_subscribe_topic'], this));
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function () {
+ if (!thisBlock.elseifCount_) {
+ return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
+ } else if (thisBlock.elseifCount_) {
+ return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
+ }
+ });
+ this.elseifCount_ = 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_);
+ }
+ return container;
+ },
+ /**
+ * Parse XML to restore the else-if and else inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ var containerBlock = this;
+ var statementConnections = [];
+ for (var i = this.elseifCount_; i > 0; i--) {
+ this.removeInput('DummyInput' + i);
+ if (containerBlock.getInputTargetBlock('DO' + i) && containerBlock.getInputTargetBlock('DO' + i).previousConnection)
+ statementConnections[i] = (containerBlock.getInputTargetBlock('DO' + i).previousConnection);
+ else
+ statementConnections[i] = null;
+ this.removeInput('DO' + i);
+ }
+ this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10);
+ //this.compose(containerBlock);
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ this.appendDummyInput('DummyInput' + i)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_CURRENT)
+ .appendField(Blockly.Msg.MQTT_Topic + Blockly.Msg.MQTT_subscribe2)
+ .appendField(new Blockly.FieldTextInput('Topic_' + i, Topic_validator), "Topic_" + i);
+ this.appendStatementInput('DO' + i)
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
+ }
+ for (var i = statementConnections.length - 2; i > 0; i--) {
+ if (statementConnections[i])
+ statementConnections[i] && statementConnections[i].reconnect(this, 'DO' + i);
+ }
+ },
+ /**
+ * 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('mqtt_topics_set');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ var elseifBlock = workspace.newBlock('MQTT_add_subscribe_topic');
+ 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) {
+ // Disconnect all the elseif input blocks and remove the inputs.
+ for (var i = this.elseifCount_; i > 0; i--) {
+ this.removeInput('DummyInput' + i);
+ this.removeInput('DO' + i);
+ }
+ this.elseifCount_ = 0;
+ // Rebuild the block's optional inputs.
+ var clauseBlock = containerBlock.getInputTargetBlock('STACK');
+ var statementConnections = [null];
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case 'MQTT_add_subscribe_topic':
+ this.elseifCount_++;
+ statementConnections.push(clauseBlock.statementConnection_);
+ break;
+ default:
+ throw Error('Unknown block type: ' + clauseBlock.type);
+ }
+ clauseBlock = clauseBlock.nextConnection &&
+ clauseBlock.nextConnection.targetBlock();
+ }
+ this.updateShape_();
+ // Reconnect any child blocks.
+ this.reconnectChildBlocks_(statementConnections);
+
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var clauseBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 1;
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case 'MQTT_add_subscribe_topic':
+ var inputDo = this.getInput('DO' + i);
+ clauseBlock.statementConnection_ =
+ inputDo && inputDo.connection.targetConnection;
+ i++;
+ break;
+ default:
+ throw 'Unknown block type.';
+ }
+ clauseBlock = clauseBlock.nextConnection &&
+ clauseBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Reconstructs the block with all child blocks attached.
+ */
+ rebuildShape_: function () {
+ var statementConnections = [null];
+
+ var i = 1;
+ while (this.getInput('DummyInput' + i)) {
+ var inputDo = this.getInput('DO' + i);
+ statementConnections.push(inputDo.connection.targetConnection);
+ i++;
+ }
+ this.updateShape_();
+ this.reconnectChildBlocks_(statementConnections);
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @this Blockly.Block
+ * @private
+ */
+ updateShape_: function () {
+ var i = 1;
+ while (this.getInput('DummyInput' + i)) {
+ this.removeInput('DummyInput' + i);
+ this.removeInput('DO' + i);
+ i++;
+ }
+ // Rebuild block.
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ this.appendDummyInput("DummyInput" + i)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_CURRENT)
+ .appendField(Blockly.Msg.MQTT_Topic + Blockly.Msg.MQTT_subscribe2)
+ .appendField(new Blockly.FieldTextInput('Topic_' + i, Topic_validator), "Topic_" + i);
+ this.appendStatementInput('DO' + i)
+ .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
+ }
+ },
+ /**
+ * Reconnects child blocks.
+ * @param {!Array} valueConnections List of value
+ * connectsions for if input.
+ * @param {!Array} statementConnections List of
+ * statement connections for do input.
+ * @param {?Blockly.RenderedConnection} elseStatementConnection Statement
+ * connection for else input.
+ */
+ reconnectChildBlocks_: function (statementConnections) {
+ for (var i = 1; i <= this.elseifCount_; i++) {
+ //valueConnections[i] && valueConnections[i].reconnect(this, 'IF' + i);
+ statementConnections[i] && statementConnections[i].reconnect(this, 'DO' + i);
+ }
+ }
+};
+
+export const mqtt_topics_set = {
+ /**
+ * Mutator block for if container.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_EMQX_SUBSCRIBE + Blockly.Msg.MQTT_Topic);
+ this.appendStatementInput('STACK');
+ this.contextMenu = false;
+ }
+};
+
+//GET请求
+export const http_get = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_GET_REQUEST);
+ this.appendValueInput("api")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.appendStatementInput("success")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SUCCESS);
+ this.appendStatementInput("failure")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_FAILED);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setTooltip("");
+ }
+};
+
+//自动配网
+export const WIFI_smartConfig = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.blynk_smartconfig)
+ .appendField(new Blockly.FieldDropdown([
+ ["SmartConfig", 'SmartConfig'],
+ ["AP", 'AP']
+ ]), "MODE");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);//可上下连接
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MQTT_TEST_TOOLTIP);
+ }
+};
+
+export const WIFI_ap_or_sta = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/blynk/wifi_udp.png'), 25, 25, "*"))
+ .appendField(Blockly.Msg.MIXLY_SETUP + " UDP WIFI");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE + ":")
+ .appendField(new Blockly.FieldDropdown([["STA", "STA"], ["AP", "AP"]]), "mode");
+ this.appendValueInput("SSID")
+ .setCheck(null)
+ .appendField("WIFI " + Blockly.Msg.HTML_NAME);
+ this.appendValueInput("PSK")
+ .setCheck(null)
+ .appendField("WIFI " + Blockly.Msg.HTML_PASSWORD);
+ this.appendValueInput("IP1")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_WIFI_LINK_DEVICE + " IP1");
+ this.appendValueInput("IP2")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_WIFI_LINK_DEVICE + " IP2");
+ this.appendValueInput("IP")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_ESP32_BLUETOOTH_FLAG + " IP");
+ this.appendValueInput("duankou")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_PORT);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setHelpUrl("");
+ }
+};
+
+export const WIFI_ap_and_sta = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/blynk/wifi_udp.png'), 25, 25, "*"))
+ .appendField(Blockly.Msg.MIXLY_SETUP + " UDP WIFI");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE + ": AP+STA");
+ this.appendValueInput("SSID1")
+ .setCheck(null)
+ .appendField("WIFI " + Blockly.Msg.HTML_NAME + "(STA)");
+ this.appendValueInput("SSID2")
+ .setCheck(null)
+ .appendField("WIFI " + Blockly.Msg.HTML_NAME + "(AP)");
+ this.appendValueInput("PSK1")
+ .setCheck(null)
+ .appendField("WIFI " + Blockly.Msg.HTML_PASSWORD + "(STA)");
+ this.appendValueInput("PSK2")
+ .setCheck(null)
+ .appendField("WIFI " + Blockly.Msg.HTML_PASSWORD + "(AP)");
+ this.appendValueInput("IP1")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_WIFI_LINK_DEVICE + " IP1");
+ this.appendValueInput("IP2")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_WIFI_LINK_DEVICE + " IP2");
+ this.appendValueInput("IP")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_ESP32_BLUETOOTH_FLAG + " IP");
+ this.appendValueInput("duankou")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_PORT);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setHelpUrl("");
+ }
+};
+
+export const WIFI_incomingPacket = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/blynk/wifi_udp.png'), 25, 25, "*"))
+ .appendField(
+ Blockly.Msg.CONTROLS_IF_MSG_IF + " WIFI UDP "
+ + Blockly.Msg.MIXLY_STM32_SPI_DATA_RECEIVED + "?"
+ )
+ this.appendValueInput("input_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS);
+ this.appendDummyInput()
+ .appendField("(" + Blockly.Msg.LANG_MATH_STRING + ")");
+ this.appendStatementInput("do")
+ .setCheck(null);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const WIFI_send_data = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/blynk/wifi_udp.png'), 25, 25, "*"))
+ .appendField("WIFI UDP " + Blockly.Msg.MIXLY_SEND_DATA);
+ this.appendValueInput("data")
+ .setCheck(null);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(ETHERNET_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//天气GET
+export const WeatherGet = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.WeatherGet)
+ .appendField(new Blockly.FieldTextInput('北京'), 'data')
+ .appendField("1", "check");
+ this.setOutput(true, Boolean);
+ this.setTooltip("输入正确的城市名(不用带“市”字)如:深圳 北京 广州,如果错误会显示'error'刷新成功则返回true\n天气接口优化注意:\n1. 接口每 8 小时更新一次,机制是 CDN 缓存 8 小时更新一次。注意:自己做缓存。\n2. 接口采用城市 ID 来精准查询请求,省份不能直接查询天气。\n3.每分钟阈值为 300 次,如果超过会禁用一天。请谨慎使用。");
+ }
+};
+
+//获取当天天气
+export const WeatherGetToday = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.WeatherGetToday)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_Humidity, "0"],
+ ['PM2.5', "1"],
+ ['PM1.0', "2"],
+ [Blockly.Msg.TodayQuality, "3"],
+ [Blockly.Msg.MIXLY_TEMPERATURE, "4"]
+ ]), "type");
+ this.setOutput(true, Number);
+ this.setTooltip("返回对应数据 字符串型。");
+ }
+};
+
+//获取当天天气
+export const WeatherGetForecast = {
+ init: function () {
+ this.setColour(ETHERNET_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.WeatherGetForecast)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GPS_DATE, "ForecastDate"],
+ [Blockly.Msg.ForecastHigh, "ForecastHigh"],
+ [Blockly.Msg.ForecastLow, "ForecastLow"],
+ [Blockly.Msg.ForecastYmd, "ForecastYmd"],
+ [Blockly.Msg.MIXLY_WEEK, "ForecastWeek"],
+ [Blockly.Msg.ForecastAqi, "ForecastAqi"],
+ [Blockly.Msg.ForecastFx, "ForecastFx"],
+ [Blockly.Msg.ForecastFl, "ForecastFl"],
+ [Blockly.Msg.ForecastType, "ForecastType"]
+ ]), "type");
+ this.appendValueInput('date', Number)
+ .appendField(Blockly.Msg.MIXLY_GPS_DATE + '(0~14)');
+ this.setOutput(true, Number);
+ this.setTooltip("返回预报天气内容0表示当天,最大为14,字符串型。");
+ this.setInputsInline(true);
+ }
+};
+
+export const mixio_mqtt_subscribe = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_CREATE_MQTT_CLIENT_AND_CONNECT);
+ this.appendValueInput("server")
+ .setCheck(null)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD);
+ this.appendValueInput("port")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_EMQX_PORT);
+ this.appendValueInput("mqtt_username")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_WIFI_USERNAME);
+ this.appendValueInput("mqtt_password")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_WIFI_PASSWORD);
+ this.appendValueInput("project")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_EMQX_PROJECT);
+ //this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(170);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const mixio_mqtt_subscribe_key = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.USE_MIXLY_KEY)
+ .appendField(new Blockly.FieldTextInput("1RFOH08C"), "key")
+ .appendField(Blockly.Msg.CONNECT_TO_MIXIO)
+ .appendField(Blockly.Msg.blynk_SERVER_ADD)
+ .appendField(new Blockly.FieldTextInput("mixio.mixly.cn"), "server");
+ this.setNextStatement(true, null);
+ this.setColour(170);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const mixio_mqtt_publish = {
+ init: function () {
+ this.appendValueInput("data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MQTT_SEND_MESSAGE);
+ this.appendValueInput("topic")
+ .setCheck(null)
+ .appendField(Blockly.Msg.TO_TOPIC);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([["MixIO", "1"], ["Mixly Key", "2"]]), "mode");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(170);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const mixio_mqtt_received_the_news = {
+ init: function () {
+ this.appendValueInput("topic")
+ .setCheck(null)
+ .appendField(Blockly.Msg.WHEN_THE_SUBJECT_IS_RECEIVED);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_MSG)
+ .appendField(new Blockly.FieldDropdown([["MixIO", "1"], ["Mixly Key", "2"]]), "mode");
+ this.appendStatementInput("function")
+ .setCheck(null);
+ this.setPreviousStatement(false, null);
+ this.setNextStatement(false, null);
+ this.setColour(170);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//OTA
+export const asyncelegantota = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/blocks_icons/loop.png'), 15, 15, { alt: "*", flipRtl: "FALSE" }))
+ .appendField("ElegantOTA");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(120);
+ this.setTooltip("http://ip/update");
+ this.setHelpUrl("");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/factory.js b/mixly/boards/default_src/arduino_avr/blocks/factory.js
new file mode 100644
index 00000000..39de28c9
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/factory.js
@@ -0,0 +1,324 @@
+import * as Blockly from 'blockly/core';
+
+const FACTORY_HUE = "#777777";
+
+export const factory_include = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField("#include <")
+ .appendField(new Blockly.FieldTextInput('Test'), 'INCLUDE')
+ .appendField(".h>");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const factory_function_noreturn = {
+ init: function () {
+ //console.log('init');
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('function'), 'NAME');
+ this.itemCount_ = 1;
+ this.arguments_ = ['x'];//add
+ this.updateShape_();
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['factory_create_with_item'], this));
+ },
+ mutationToDom: function () {
+ //console.log('mutationToDom');
+ var container = document.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ //add
+ for (var i = 0; i < this.arguments_.length; i++) {
+ var parameter = document.createElement('arg');
+ parameter.setAttribute('name', this.arguments_[i]);
+ container.appendChild(parameter);
+ }
+ return container;
+ },
+ domToMutation: function (xmlElement) {
+ //console.log('domToMutation');
+ this.arguments_ = [];//add
+ //add
+ for (var i = 0; xmlElement.childNodes[i]; i++) {
+ let childNode = xmlElement.childNodes[i];
+ if (childNode.nodeName.toLowerCase() == 'arg') {
+ this.arguments_.push(childNode.getAttribute('name'));
+ }
+ }
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ this.updateShape_();
+ },
+ decompose: function (workspace) {
+ //console.log('decompose');
+ var containerBlock =
+ workspace.newBlock('factory_create_with_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('factory_create_with_item');
+ itemBlock.initSvg();
+ itemBlock.setFieldValue(this.arguments_[i], 'NAME');//add
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.nextConnection;
+ }
+ return containerBlock;
+ },
+ compose: function (containerBlock) {
+ //console.log('compose');
+ this.arguments_ = [];//add
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ var i = 0;
+ while (itemBlock) {
+ this.arguments_.push(itemBlock.getFieldValue('NAME'));//add
+ connections[i] = itemBlock.valueConnection_;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ i++;
+ }
+ this.itemCount_ = i;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (connections[i]) {
+ this.getInput('ADD' + i).connection.connect(connections[i]);
+ }
+ }
+ },
+ saveConnections: function (containerBlock) {
+ //console.log('saveConnections');
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ updateShape_: function () {
+ //console.log('updateShape_');
+ // Delete everything.
+ if (this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else {
+ var i = 0;
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ }
+ // Rebuild block.
+ for (var i = 0; i < this.itemCount_; i++) {
+ this.appendValueInput('ADD' + i)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(this.arguments_[i]);
+ }
+ }
+};
+
+export const factory_create_with_container = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_PARAMS);
+ this.appendStatementInput('STACK');
+ this.contextMenu = false;
+ }
+};
+
+export const factory_create_with_item = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE + ':')
+ .appendField(new Blockly.FieldTextInput('x'), 'NAME');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.contextMenu = false;
+ }
+};
+
+export const factory_function_return = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('function'), 'NAME');
+ this.itemCount_ = 1;
+ this.arguments_ = ['x'];//add
+ this.updateShape_();
+ this.setOutput(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['factory_create_with_item'], this));
+ },
+ mutationToDom: factory_function_noreturn.mutationToDom,
+ domToMutation: factory_function_noreturn.domToMutation,
+ decompose: factory_function_noreturn.decompose,
+ compose: factory_function_noreturn.compose,
+ saveConnections: factory_function_noreturn.saveConnections,
+ updateShape_: factory_function_noreturn.updateShape_
+};
+
+export const factory_declare = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('Test'), 'TYPE')
+ .appendField(" ")
+ .appendField(new Blockly.FieldTextInput('test'), 'NAME')
+ .appendField(";");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const factory_declare2 = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldMultilineInput('//define user code;'), 'VALUE');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const factory_define = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('#define'), 'TYPE')
+ .appendField(" ")
+ .appendField(new Blockly.FieldTextInput('MYDEFINE 11'), 'NAME')
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const factory_static_method_noreturn = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('Test'), 'TYPE')
+ .appendField("::")
+ .appendField(new Blockly.FieldTextInput('staticMethod'), 'NAME');
+ this.itemCount_ = 1;
+ this.arguments_ = ['x'];//add
+ this.updateShape_();
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['factory_create_with_item'], this));
+ },
+ mutationToDom: factory_function_noreturn.mutationToDom,
+ domToMutation: factory_function_noreturn.domToMutation,
+ decompose: factory_function_noreturn.decompose,
+ compose: factory_function_noreturn.compose,
+ saveConnections: factory_function_noreturn.saveConnections,
+ updateShape_: factory_function_noreturn.updateShape_
+};
+
+export const factory_static_method_return = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('Test'), 'TYPE')
+ .appendField("::")
+ .appendField(new Blockly.FieldTextInput('staticMethod'), 'NAME');
+ this.itemCount_ = 1;
+ this.arguments_ = ['x'];//add
+ this.updateShape_();
+ this.setOutput(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['factory_create_with_item'], this));
+ },
+ mutationToDom: factory_function_noreturn.mutationToDom,
+ domToMutation: factory_function_noreturn.domToMutation,
+ decompose: factory_function_noreturn.decompose,
+ compose: factory_function_noreturn.compose,
+ saveConnections: factory_function_noreturn.saveConnections,
+ updateShape_: factory_function_noreturn.updateShape_
+};
+
+export const factory_callMethod_noreturn = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('test'), 'NAME')
+ .appendField('.')
+ .appendField(new Blockly.FieldTextInput('callMetod'), 'METHOD');
+ this.itemCount_ = 1;
+ this.arguments_ = ['x'];//add
+ this.updateShape_();
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['factory_create_with_item'], this));
+ },
+ mutationToDom: factory_function_noreturn.mutationToDom,
+ domToMutation: factory_function_noreturn.domToMutation,
+ decompose: factory_function_noreturn.decompose,
+ compose: factory_function_noreturn.compose,
+ saveConnections: factory_function_noreturn.saveConnections,
+ updateShape_: factory_function_noreturn.updateShape_
+};
+
+export const factory_callMethod_return = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('test'), 'NAME')
+ .appendField('.')
+ .appendField(new Blockly.FieldTextInput('callMetod'), 'METHOD');
+ this.itemCount_ = 1;
+ this.arguments_ = ['x'];//add
+ this.updateShape_();
+ this.setOutput(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['factory_create_with_item'], this));
+ },
+ mutationToDom: factory_function_noreturn.mutationToDom,
+ domToMutation: factory_function_noreturn.domToMutation,
+ decompose: factory_function_noreturn.decompose,
+ compose: factory_function_noreturn.compose,
+ saveConnections: factory_function_noreturn.saveConnections,
+ updateShape_: factory_function_noreturn.updateShape_
+};
+
+export const factory_block = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('Serial.println("hello");'), 'VALUE');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const factory_block_return = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldTextInput('test'), 'VALUE');
+ this.setOutput(true);
+ }
+};
+
+export const factory_block_with_textarea = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldMultilineInput('Serial.println("Hello");\nSerial.println("Mixly");'), 'VALUE');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const factory_block_return_with_textarea = {
+ init: function () {
+ this.setColour(FACTORY_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldMultilineInput('Hello\nMixly'), 'VALUE');
+ this.setOutput(true);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/inout.js b/mixly/boards/default_src/arduino_avr/blocks/inout.js
new file mode 100644
index 00000000..e35006f7
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/inout.js
@@ -0,0 +1,400 @@
+import * as Blockly from 'blockly/core';
+import { Profile } from 'mixly';
+
+const BASE_HUE = 20;//'#ae3838';//40;
+
+export const inout_highlow = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_HIGH, "HIGH"],
+ [Blockly.Msg.MIXLY_LOW, "LOW"]
+ ]), 'BOOL')
+ this.setOutput(true, Boolean);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_HIGHLOW);
+ }
+};
+
+export const inout_pinMode = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PINMODE)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_PINMODEIN, "INPUT"],
+ [Blockly.Msg.MIXLY_PINMODEOUT, "OUTPUT"],
+ [Blockly.Msg.MIXLY_PINMODEPULLUP, "INPUT_PULLUP"]
+ ]), "MODE")
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_pinMode);
+ }
+};
+
+export const inout_digital_write2 = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_DIGITALWRITE_PIN)
+ .setCheck(Number);
+ this.appendValueInput("STAT")
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .setCheck([Number, Boolean]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.LANG_INOUT_DIGITAL_WRITE_TOOLTIP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id2");
+ }
+};
+
+export const inout_digital_read = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DIGITALREAD_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.setOutput(true, [Boolean, Number]);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_DIGITAL_READ);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id6");
+ }
+};
+
+export const inout_digital_read2 = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_DIGITALREAD_PIN)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setOutput(true, [Boolean, Number]);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_DIGITAL_READ);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id6");
+ }
+};
+
+export const inout_analog_write = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_ANALOGWRITE_PIN)
+ .setCheck(Number);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.MIXLY_VALUE2)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_ANALOG_WRITE);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id16");
+ }
+};
+
+export const inout_analog_read = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_ANALOGREAD_PIN)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_ANALOG_READ);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id11");
+ }
+};
+
+export const inout_buildin_led = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_BUILDIN_LED)
+ .appendField(Blockly.Msg.MIXLY_STAT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ON, "HIGH"],
+ [Blockly.Msg.MIXLY_OFF, "LOW"]
+ ]), "STAT");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip('light or off the build-in LED');
+ }
+};
+
+export const OneButton_interrupt = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.ONEBUTTON + " " + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_CLICK, "attachClick"],
+ [Blockly.Msg.MIXLY_DOUBLE_CLICK, "attachDoubleClick"],
+ [Blockly.Msg.MIXLY_LONG_PRESS_START, "attachLongPressStart"],
+ [Blockly.Msg.MIXLY_DURING_LONG_PRESS, "attachDuringLongPress"],
+ [Blockly.Msg.MIXLY_LONG_PRESS_END, "attachLongPressStop"]
+ ]), "mode");
+ this.appendValueInput("STAT")
+ .appendField(Blockly.Msg.MIXLY_ELECLEVEL);
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_ATTACHINTERRUPT);
+ this.setHelpUrl();
+ }
+};
+
+export const controls_attachInterrupt = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_ATTACHINTERRUPT_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MODE)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_RISING, "RISING"],
+ [Blockly.Msg.MIXLY_FALLING, "FALLING"],
+ [Blockly.Msg.MIXLY_CHANGE, "CHANGE"]
+ ]), "mode");
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_ATTACHINTERRUPT);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id20");
+ }
+};
+
+export const controls_detachInterrupt = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_DETACHINTERRUPT_PIN)
+ .setCheck(Number);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_DETACHINTERRUPT);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id24");
+ }
+};
+
+export const controls_attachPinInterrupt = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_ATTACHPININTERRUPT_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MODE)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_RISING, "RISING"],
+ [Blockly.Msg.MIXLY_FALLING, "FALLING"],
+ [Blockly.Msg.MIXLY_CHANGE, "CHANGE"]
+ ]), "mode");
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_ATTACHINTERRUPT);
+ }
+};
+
+export const controls_detachPinInterrupt = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_DETACHPININTERRUPT_PIN)
+ .setCheck(Number);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_DETACHINTERRUPT);
+ }
+};
+
+export const inout_pulseIn = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PULSEIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_PULSEIN_STAT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_HIGH, "HIGH"],
+ [Blockly.Msg.MIXLY_LOW, "LOW"]
+ ]), "STAT");
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_pulseIn);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id27");
+ }
+};
+
+export const inout_pulseIn2 = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PULSEIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_PULSEIN_STAT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_HIGH, "HIGH"],
+ [Blockly.Msg.MIXLY_LOW, "LOW"]
+ ]), "STAT");
+ this.appendValueInput("TIMEOUT", Number)
+ .appendField(Blockly.Msg.MIXLY_PULSEIN_TIMEOUT)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_pulseIn2);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#id27");
+ }
+};
+
+export const inout_shiftout = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField("ShiftOut");
+ this.appendValueInput("PIN1", Number)
+ .appendField(Blockly.Msg.MIXLY_DATAPIN)
+ .setCheck(Number);
+ this.appendValueInput("PIN2", Number)
+ .appendField(Blockly.Msg.MIXLY_CLOCKPIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_BITORDER)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_MSBFIRST, "MSBFIRST"],
+ [Blockly.Msg.MIXLY_LSBFIRST, "LSBFIRST"]
+ ]), "ORDER");
+ this.appendValueInput("DATA", Number)
+ .appendField(Blockly.Msg.MIXLY_DATA)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_shiftout);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/01Input-Output.html#shiftout");
+ }
+};
+
+export const ESP32touchButton = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField("ESP32" + Blockly.Msg.MIXLY_ESP32_TOUCH + Blockly.Msg.ONEBUTTON + " " + Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MODE)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_CLICK, "attachClick"],
+ [Blockly.Msg.MIXLY_DOUBLE_CLICK, "attachDoubleClick"],
+ [Blockly.Msg.MIXLY_LONG_PRESS_START, "attachLongPressStart"],
+ [Blockly.Msg.MIXLY_DURING_LONG_PRESS, "attachDuringLongPress"],
+ [Blockly.Msg.MIXLY_LONG_PRESS_END, "attachLongPressStop"]
+ ]), "mode");
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+export const inout_soft_analog_write = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_SOFT_ANALOGWRITE_PIN)
+ .setCheck(Number);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.MIXLY_VALUE2)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_INOUT_ANALOG_WRITE);
+ this.setHelpUrl("");
+ }
+};
+
+export const inout_cancel_soft_analog_write = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_CANCEL_SOFT_ANALOGWRITE_PIN)
+ .setCheck(Number);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CANCEL_SOFT_ANALOGWRITE_PIN);
+ this.setHelpUrl("");
+ }
+};
+
+//ADS1015模拟数字转换模块-增益设置
+export const ADS1015_setGain = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SETTING)
+ .appendField(Blockly.Msg.ADS1015_setGain);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(ADS1015_setGain.GAIN_TYPE), "ADS1015_setGain");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ },
+ GAIN_TYPE: [
+ ["±6.144V 3mv/bit", "GAIN_TWOTHIRDS"],
+ ["±4.096V 2mv/bit", "GAIN_ONE"],
+ ["±2.048V 1mv/bit", "GAIN_TWO"],
+ ["±1.024V 0.5mv/bit", "GAIN_FOUR"],
+ ["±0.512V 0.25mv/bit", "GAIN_EIGHT"],
+ ["±0.256V 0.125mv/bit", "GAIN_SIXTEEN"],
+ ]
+};
+
+//ADS1015模拟数字转换模块 数值获取
+export const ADS1015_Get_Value = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField("ADS1015" + Blockly.Msg.ADS1015_Get_Value);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ ["AIN0", "ads.readADC_SingleEnded(0)"],
+ ["AIN1", "ads.readADC_SingleEnded(1)"],
+ ["AIN2", "ads.readADC_SingleEnded(2)"],
+ ["AIN3", "ads.readADC_SingleEnded(3)"]
+ ]), "ADS1015_AIN");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ }
+};
+
+//PCF8591T模拟数字转换模块 数值获取
+export const PCF8591T = {
+ init: function () {
+ this.setColour(BASE_HUE);
+ this.appendDummyInput("")
+ .appendField("PCF8591T" + Blockly.Msg.ADS1015_Get_Value);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ ["AIN0", "pcf8591.analogRead(AIN0)"],
+ ["AIN1", "pcf8591.analogRead(AIN1)"],
+ ["AIN2", "pcf8591.analogRead(AIN2)"],
+ ["AIN3", "pcf8591.analogRead(AIN3)"]
+ ]), "PCF8591T_AIN");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/lists.js b/mixly/boards/default_src/arduino_avr/blocks/lists.js
new file mode 100644
index 00000000..5af7e5ac
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/lists.js
@@ -0,0 +1,757 @@
+import * as Blockly from 'blockly/core';
+
+const LISTS_HUE = 260;
+
+const DATATYPES = [
+ [Blockly.Msg.LANG_MATH_INT, 'int'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_INT, 'unsigned int'],
+ [Blockly.Msg.LANG_MATH_WORD, 'word'],
+ [Blockly.Msg.LANG_MATH_LONG, 'long'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_LONG, 'unsigned long'],
+ [Blockly.Msg.LANG_MATH_FLOAT, 'float'],
+ [Blockly.Msg.LANG_MATH_DOUBLE, 'double'],
+ [Blockly.Msg.LANG_MATH_BOOLEAN, 'boolean'],
+ [Blockly.Msg.LANG_MATH_BYTE, 'byte'],
+ [Blockly.Msg.LANG_MATH_CHAR, 'char'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_CHAR, 'unsigned char'],
+ [Blockly.Msg.LANG_MATH_STRING, 'String']
+];
+
+export const lists_create_with = {
+ /**
+ * Block for creating a list with any number of elements of any type.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DATATYPES), "TYPE")
+ .appendField(' ')
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField('[')
+ .appendField(new Blockly.FieldTextInput('3', Blockly.FieldTextInput.math_number_validator), 'SIZE')
+ .appendField(']');
+ this.itemCount_ = 3;
+ this.updateShape_();
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this));
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP);
+ },
+ /**
+ * Create XML to represent list inputs.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = document.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ return container;
+ },
+ /**
+ * Parse XML to restore the list inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ 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('lists_create_with_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('lists_create_with_item');
+ itemBlock.initSvg();
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.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 itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ var i = 0;
+ while (itemBlock) {
+ connections[i] = itemBlock.valueConnection_;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ i++;
+ }
+ this.itemCount_ = i;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (connections[i]) {
+ this.getInput('ADD' + i).connection.connect(connections[i]);
+ }
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function () {
+ // Delete everything.
+ if (this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else {
+ var i = 0;
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ }
+ // Rebuild block.
+ if (this.itemCount_ == 0) {
+ this.appendDummyInput('EMPTY')
+ .appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);
+ } else {
+ for (var i = 0; i < this.itemCount_; i++) {
+ var input = this.appendValueInput('ADD' + i);
+ if (i == 0) {
+ input.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);
+ }
+ }
+ }
+ }
+};
+
+export const lists_create_with_text = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DATATYPES), "TYPE")
+ .appendField(' ')
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField('[')
+ .appendField(new Blockly.FieldTextInput('3', Blockly.FieldTextInput.math_number_validator), 'SIZE')
+ .appendField(']')
+ .appendField(Blockly.Msg.MIXLY_MAKELISTFROM)
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT')
+ .appendField(this.newQuote_(false))
+ .appendField(Blockly.Msg.MIXLY_SPLITBYDOU);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LISTS_CREATE_WITH_TEXT);
+ },
+ newQuote_: function (open) {
+ if (open == this.RTL) {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
+ } else {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
+ }
+ return new Blockly.FieldImage(file, 12, 12, '"');
+ }
+};
+
+export const lists_create_with2 = {
+ /**
+ * Block for creating a list with any number of elements of any type.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DATATYPES), "TYPE")
+ .appendField(' ')
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField('[')
+ //.appendField(new Blockly.FieldTextInput('3',Blockly.FieldTextInput.math_number_validator), 'SIZE')
+ .appendField(']');
+ this.itemCount_ = 3;
+ this.updateShape_();
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this));
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP);
+ },
+ /**
+ * Create XML to represent list inputs.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = document.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ return container;
+ },
+ /**
+ * Parse XML to restore the list inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ 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('lists_create_with_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('lists_create_with_item');
+ itemBlock.initSvg();
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.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 itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ var i = 0;
+ while (itemBlock) {
+ connections[i] = itemBlock.valueConnection_;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ i++;
+ }
+ this.itemCount_ = i;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (connections[i]) {
+ this.getInput('ADD' + i).connection.connect(connections[i]);
+ }
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function () {
+ // Delete everything.
+ if (this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else {
+ var i = 0;
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ }
+ // Rebuild block.
+ if (this.itemCount_ == 0) {
+ this.appendDummyInput('EMPTY')
+ .appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);
+ } else {
+ for (var i = 0; i < this.itemCount_; i++) {
+ var input = this.appendValueInput('ADD' + i);
+ if (i == 0) {
+ input.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);
+ }
+ }
+ }
+ }
+};
+
+export const lists_create_with_text2 = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(DATATYPES), "TYPE")
+ .appendField(' ')
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField('[')
+ .appendField(new Blockly.FieldTextInput("3"), "SIZE")
+ .appendField(']')
+ .appendField(Blockly.Msg.MIXLY_MAKELISTFROM)
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT')
+ .appendField(this.newQuote_(false))
+ .appendField(Blockly.Msg.MIXLY_SPLITBYDOU);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LISTS_CREATE_WITH_TEXT);
+ },
+ newQuote_: function (open) {
+ if (open == this.RTL) {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
+ } else {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
+ }
+ return new Blockly.FieldImage(file, 12, 12, '"');
+ }
+}
+
+export const lists_create_with_container = {
+ /**
+ * Mutator block for list container.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);
+ this.appendStatementInput('STACK');
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+export const lists_create_with_item = {
+ /**
+ * Mutator bolck for adding items.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+export const lists_getIndex = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('AT')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField(Blockly.Msg.LANG_LISTS_GET_INDEX1);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.LANG_LISTS_GET_INDEX2);
+ this.appendDummyInput()
+ .appendField('(' + Blockly.Msg.MIXLY_DEPRECATED + ')');
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.LANG_LISTS_GET_INDEX_TOOLTIP);
+ this.setWarningText(Blockly.Msg.MIXLY_DEPRECATED_WARNING_TEXT);
+ }
+};
+
+export const lists_setIndex = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput('AT')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField(Blockly.Msg.LANG_LISTS_SET_INDEX1);
+ this.appendValueInput('TO')
+ .appendField(Blockly.Msg.LANG_LISTS_SET_INDEX2);
+ this.appendDummyInput()
+ .appendField('(' + Blockly.Msg.MIXLY_DEPRECATED + ')');
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.LANG_LISTS_SET_INDEX_TOOLTIP);
+ this.setWarningText(Blockly.Msg.MIXLY_DEPRECATED_WARNING_TEXT);
+ }
+};
+
+export const listsGetValueByIndex = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('AT')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField(Blockly.Msg.LANG_LISTS_GET_INDEX1);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.LANG_LISTS_GET_INDEX2);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.LANG_LISTS_GET_VALUE_BY_INDEX_TOOLTIP);
+ }
+};
+
+export const listsSetValueByIndex = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput('AT')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField(Blockly.Msg.LANG_LISTS_SET_INDEX1);
+ this.appendValueInput('TO')
+ .appendField(Blockly.Msg.LANG_LISTS_SET_INDEX2);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.LANG_LISTS_SET_VALUE_BY_INDEX_TOOLTIP);
+ }
+};
+
+export const lists_length = {
+ /**
+ * Block for list length.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_LENGTH)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR');
+ this.setTooltip(Blockly.Msg.LISTS_LENGTH_TOOLTIP);
+ this.setOutput(true, Number);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/06Lists.html#mylist");
+ }
+};
+
+//创建二维数组
+export const create_array2_with_text = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput("name")
+ .setCheck(null)
+ .appendField(new Blockly.FieldDropdown(DATATYPES), "TYPE")
+ .appendField(Blockly.Msg.MIXLY_ARRAY2);
+ this.appendValueInput("line")
+ .setCheck(null)
+ .appendField(Blockly.Msg.array2_rows);
+ this.appendValueInput("list")
+ .setCheck(null)
+ .appendField(Blockly.Msg.array2_cols);
+ this.appendValueInput("String")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_MAKELISTFROM);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ESP32_SET);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/06Lists.html#array");
+ }
+};
+
+//二维数组赋值
+export const array2_assignment = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput("name")
+ .setCheck(null)
+ .appendField(Blockly.Msg.array2_assignment);
+ this.appendValueInput("line")
+ .appendField(Blockly.Msg.DATAFRAME_RAW)
+ this.appendValueInput("list")
+ .appendField(Blockly.Msg.DATAFRAME_COLUMN);
+ this.appendValueInput("assignment")
+ .appendField(Blockly.Msg.MIXLY_VALUE2);
+ this.appendDummyInput()
+ .appendField('(' + Blockly.Msg.MIXLY_DEPRECATED + ')');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setHelpUrl("");
+ this.setWarningText(Blockly.Msg.MIXLY_DEPRECATED_WARNING_TEXT);
+ }
+};
+
+//获取二维数组值
+export const get_array2_value = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput("name")
+ .setCheck(null)
+ .appendField(Blockly.Msg.get_array2_value);
+ this.appendValueInput("line")
+ .appendField(Blockly.Msg.DATAFRAME_RAW);
+ this.appendValueInput("list")
+ .appendField(Blockly.Msg.DATAFRAME_COLUMN);
+ this.appendDummyInput()
+ .appendField('(' + Blockly.Msg.MIXLY_DEPRECATED + ')');
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/06Lists.html#arraymn");
+ this.setWarningText(Blockly.Msg.MIXLY_DEPRECATED_WARNING_TEXT);
+ }
+};
+
+//二维数组赋值
+export const lists2SetValueByIndex = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput("name")
+ .setCheck(null)
+ .appendField(Blockly.Msg.array2_assignment);
+ this.appendValueInput("line")
+ .appendField(Blockly.Msg.DATAFRAME_RAW)
+ this.appendValueInput("list")
+ .appendField(Blockly.Msg.DATAFRAME_COLUMN);
+ this.appendValueInput("assignment")
+ .appendField(Blockly.Msg.MIXLY_VALUE2);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/06Lists.html#mn");
+ this.setTooltip(Blockly.Msg.LANG_LISTS_SET_VALUE_BY_INDEX_TOOLTIP);
+ }
+};
+
+//二维数组取值
+export const lists2GetValueByIndex = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendValueInput("name")
+ .setCheck(null)
+ .appendField(Blockly.Msg.get_array2_value);
+ this.appendValueInput("line")
+ .appendField(Blockly.Msg.DATAFRAME_RAW);
+ this.appendValueInput("list")
+ .appendField(Blockly.Msg.DATAFRAME_COLUMN);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/06Lists.html#arraymn");
+ this.setTooltip(Blockly.Msg.LANG_LISTS_GET_VALUE_BY_INDEX_TOOLTIP);
+ }
+};
+
+export const lists_array2_setup = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + Blockly.Msg.MIXLY_ARRAY2);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(DATATYPES), "lists_create_type")
+ .appendField(new Blockly.FieldTextInput("mylist"), "lists_create_name")
+ .appendField("[ ][ ]");
+ this.appendStatementInput("lists_with_2_1_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.VARIABLES_SET_TITLE);
+ this.setInputsInline(false);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(LISTS_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const lists_array2_setup_get_data = {
+ /**
+ * Block for creating a list with any number of elements of any type.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("");
+ this.itemCount_ = 3;
+ this.updateShape_();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this));
+ this.setTooltip("");
+ },
+ /**
+ * Create XML to represent list inputs.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = document.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ return container;
+ },
+ /**
+ * Parse XML to restore the list inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ 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('lists_create_with_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('lists_create_with_item');
+ itemBlock.initSvg();
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.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 itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ var i = 0;
+ while (itemBlock) {
+ connections[i] = itemBlock.valueConnection_;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ i++;
+ }
+ this.itemCount_ = i;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (connections[i]) {
+ this.getInput('ADD' + i).connection.connect(connections[i]);
+ }
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function () {
+ // Delete everything.
+ if (this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else {
+ var i = 0;
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ }
+ // Rebuild block.
+ if (this.itemCount_ == 0) {
+ this.appendDummyInput('EMPTY')
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("");
+ } else {
+ for (var i = 0; i <= this.itemCount_; i++) {
+
+ if (i > 0 && i < this.itemCount_) {
+ var input = this.appendValueInput('ADD' + i);
+ input.setAlign(Blockly.inputs.Align.RIGHT)
+ input.appendField(",");
+ }
+ if (i == 0) {
+ var input = this.appendValueInput('ADD' + i);
+ input.setAlign(Blockly.inputs.Align.RIGHT);
+ input.appendField("{");
+ }
+ else if (i == this.itemCount_) {
+ var input = this.appendDummyInput('ADD' + i);
+ input.setAlign(Blockly.inputs.Align.RIGHT);
+ input.appendField("}");
+ }
+ }
+ }
+ }
+};
+
+//一维数组循环
+export const loop_array = {
+ init: function () {
+ this.appendValueInput("name")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_LIST_NAME);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.LEFT_CYCLE, "0"],
+ [Blockly.Msg.RIGHT_CYCLE, "1"]
+ ]), "mode");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(LISTS_HUE);
+ this.setTooltip('');
+ this.setHelpUrl("");
+ }
+};
+
+//获取二维数组的行数与列数
+export const lists_array2_get_length = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_ARRAY2)
+ .appendField(new Blockly.FieldTextInput("mylist"), "list_name")
+ .appendField(" " + Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.array2_rows, "row"],
+ [Blockly.Msg.array2_cols, "col"]
+ ]), "type");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(LISTS_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/logic.js b/mixly/boards/default_src/arduino_avr/blocks/logic.js
new file mode 100644
index 00000000..4e508342
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/logic.js
@@ -0,0 +1,149 @@
+import * as Blockly from 'blockly/core';
+
+const LOGIC_HUE = 210;
+
+export const logic_compare = {
+ /**
+ * Block for comparison operator.
+ * @this Blockly.Block
+ */
+ init: function () {
+ var OPERATORS = Blockly.RTL ? [
+ ['=', 'EQ'],
+ ['\u2260', 'NEQ'],
+ ['>', 'LT'],
+ ['\u2265', 'LTE'],
+ ['<', 'GT'],
+ ['\u2264', 'GTE']
+ ] : [
+ ['=', 'EQ'],
+ ['\u2260', 'NEQ'],
+ ['<', 'LT'],
+ ['\u2264', 'LTE'],
+ ['>', 'GT'],
+ ['\u2265', 'GTE']
+ ];
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/04Logic.html#id2");
+ this.setColour(LOGIC_HUE);
+ this.setOutput(true, Boolean);
+ 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 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
+ };
+ return TOOLTIPS[op];
+ });
+ this.prevBlocks_ = [null, null];
+ }
+};
+
+export const logic_operation = {
+ /**
+ * Block for logical operations: 'and', 'or'.
+ * @this Blockly.Block
+ */
+ init: function () {
+ var OPERATORS = [
+ [Blockly.Msg.LOGIC_OPERATION_AND, 'AND'],
+ [Blockly.Msg.LOGIC_OPERATION_OR, 'OR']
+ ];
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/04Logic.html#id12");
+ this.setColour(LOGIC_HUE);
+ this.setOutput(true, Boolean);
+ this.appendValueInput('A')
+ .setCheck([Boolean, Number]);
+ this.appendValueInput('B')
+ .setCheck([Boolean, Number])
+ .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 TOOLTIPS = {
+ 'AND': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND,
+ 'OR': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR
+ };
+ return TOOLTIPS[op];
+ });
+ }
+};
+
+export const logic_negate = {
+ /**
+ * Block for negation.
+ * @this Blockly.Block
+ */
+ init: function () {
+ //this.setHelpUrl(Blockly.Msg.LOGIC_NEGATE_HELPURL);
+ this.setColour(LOGIC_HUE);
+ this.setOutput(true, Boolean);
+ this.appendValueInput('BOOL')
+ .setCheck([Number, Boolean])
+ .appendField(Blockly.Msg.LOGIC_NEGATE_TITLE);
+ //this.interpolateMsg(Blockly.Msg.LOGIC_NEGATE_TITLE,
+ // ['BOOL', Boolean, Blockly.inputs.Align.RIGHT],
+ // Blockly.inputs.Align.RIGHT);
+ this.setTooltip(Blockly.Msg.LOGIC_NEGATE_TOOLTIP);
+ }
+};
+
+export const logic_boolean = {
+ /**
+ * Block for boolean data type: true and false.
+ * @this Blockly.Block
+ */
+ init: function () {
+ var BOOLEANS = [
+ [Blockly.Msg.LOGIC_BOOLEAN_TRUE, 'TRUE'],
+ [Blockly.Msg.LOGIC_BOOLEAN_FALSE, 'FALSE']
+ ];
+ //this.setHelpUrl(Blockly.Msg.LOGIC_BOOLEAN_HELPURL);
+ this.setColour(LOGIC_HUE);
+ this.setOutput(true, Boolean);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(BOOLEANS), 'BOOL');
+ this.setTooltip(Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP);
+ }
+};
+
+export const logic_null = {
+ /**
+ * Block for null data type.
+ * @this Blockly.Block
+ */
+ init: function () {
+ //this.setHelpUrl(Blockly.Msg.LOGIC_NULL_HELPURL);
+ this.setColour(LOGIC_HUE);
+ this.setOutput(true);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LOGIC_NULL);
+ this.setTooltip(Blockly.Msg.LOGIC_NULL_TOOLTIP);
+ }
+};
+
+export const logic_true_or_false = {
+ init: function () {
+ this.setColour(LOGIC_HUE);
+ this.appendValueInput('A');
+ this.appendValueInput('B')
+ .appendField(Blockly.Msg.LOGIC_TERNARY_IF_TRUE);
+ this.appendValueInput('C')
+ .appendField(Blockly.Msg.LOGIC_TERNARY_IF_FALSE);
+ this.setOutput(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LOGIT_TRUEORFALSE);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/04Logic.html#id17");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/math.js b/mixly/boards/default_src/arduino_avr/blocks/math.js
new file mode 100644
index 00000000..4bd89098
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/math.js
@@ -0,0 +1,374 @@
+import * as Blockly from 'blockly/core';
+
+const MATH_HUE = 230;
+
+Blockly.FieldTextInput.math_number_validator = function (text) {
+ //return window.isNaN(text) ? null : String(text);
+ return String(text);//不再校验
+};
+
+export const math_number = {
+ /**
+ * Block for numeric value.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldTextInput('0',
+ Blockly.FieldTextInput.math_number_validator), 'NUM');
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MATH_NUMBER_TOOLTIP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#id2");
+ }
+};
+
+export const math_arithmetic = {
+ /**
+ * Block for basic arithmetic operator.
+ * @this Blockly.Block
+ */
+ init: function () {
+ //this.setHelpUrl(Blockly.Msg.MATH_ARITHMETIC_HELPURL);
+ this.setColour(MATH_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('A')
+ .setCheck(null);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#id4");
+ this.appendValueInput('B')
+ .setCheck(null)
+ .appendField(new Blockly.FieldDropdown(math_arithmetic.OPERATORS), 'OP');
+ this.setInputsInline(true);
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
+ 'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
+ 'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
+ 'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
+ 'QUYU': Blockly.Msg.MATH_MODULO_TOOLTIP,
+ 'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
+ };
+ return TOOLTIPS[mode];
+ });
+ },
+ OPERATORS: [
+ [Blockly.Msg.MATH_ADDITION_SYMBOL, 'ADD'],
+ [Blockly.Msg.MATH_SUBTRACTION_SYMBOL, 'MINUS'],
+ [Blockly.Msg.MATH_MULTIPLICATION_SYMBOL, 'MULTIPLY'],
+ [Blockly.Msg.MATH_DIVISION_SYMBOL, 'DIVIDE'],
+ [Blockly.Msg.MATH_QUYU_SYMBOL, 'QUYU'],
+ [Blockly.Msg.MATH_POWER_SYMBOL, 'POWER']
+ ]
+};
+
+export const math_bit = {
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('A')
+ .setCheck(Number);
+ this.appendValueInput('B')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldDropdown(math_bit.OPERATORS), 'OP');
+ this.setInputsInline(true);
+ this.setTooltip("");
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#id8");
+ },
+ OPERATORS: [
+ ['&', '&'],
+ ['|', '|'],
+ ['xor', '^'],
+ ['>>', '>>'],
+ ['<<', '<<']
+ ]
+};
+
+export const math_trig = {
+ /**
+ * Block for trigonometry operators.
+ * @this Blockly.Block
+ */
+ init: function () {
+ //this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL);
+ this.setColour(MATH_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('NUM')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldDropdown(math_trig.OPERATORS), 'OP');
+ // Assign 'this' to a variable for use in the tooltip closure below.
+ var thisBlock = this;
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#id21");
+ this.setTooltip(function () {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'SIN': Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,
+ 'COS': Blockly.Msg.MATH_TRIG_TOOLTIP_COS,
+ 'TAN': Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,
+ 'ASIN': Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,
+ 'ACOS': Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,
+ 'ATAN': Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN
+ };
+ return TOOLTIPS[mode];
+ });
+ },
+ OPERATORS: [
+ ['sin', 'SIN'],
+ ['cos', 'COS'],
+ ['tan', 'TAN'],
+ ['asin', 'ASIN'],
+ ['acos', 'ACOS'],
+ ['atan', 'ATAN'],
+ ['ln', 'LN'],
+ ['log10', 'LOG10'],
+ ['e^', 'EXP'],
+ ['10^', 'POW10'],
+ ['++', '++'],
+ ['--', '--'],
+ ['~', '~'],
+ ]
+};
+
+//取整等
+export const math_to_int = {
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.appendValueInput('A')
+ .setCheck(Number)
+ .appendField(new Blockly.FieldDropdown(math_to_int.OPERATORS), 'OP');
+ this.setOutput(true, Number);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#id35");
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'sqrt': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT,
+ 'abs': Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,
+ 'sq': Blockly.Msg.MATH_SINGLE_TOOLTIP_SQ,
+ 'log': Blockly.Msg.MATH_SINGLE_TOOLTIP_LN,
+ 'round': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROUND,
+ 'ceil': Blockly.Msg.MATH_SINGLE_TOOLTIP_CEIL,
+ 'floor': Blockly.Msg.MATH_SINGLE_TOOLTIP_FLOOR
+ };
+ return TOOLTIPS[mode];
+ });
+ },
+ OPERATORS: [
+ [Blockly.Msg.LANG_MATH_TO_ROUND, 'round'],
+ [Blockly.Msg.LANG_MATH_TO_CEIL, 'ceil'],
+ [Blockly.Msg.LANG_MATH_TO_FLOOR, 'floor'],
+ [Blockly.Msg.MATH_ABS, 'abs'],
+ [Blockly.Msg.MATH_SQ, 'sq'],
+ [Blockly.Msg.MATH_SQRT, 'sqrt']
+ ]
+};
+
+//变量定义
+export const arduino_variate_type = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(arduino_variate_type.DATATYPES), "variate_type");
+ this.setOutput(true, null);
+ this.setColour(MATH_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ },
+ DATATYPES: [
+ [Blockly.Msg.LANG_MATH_INT, 'int'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_INT, 'unsigned int'],
+ [Blockly.Msg.LANG_MATH_WORD, 'word'],
+ [Blockly.Msg.LANG_MATH_LONG, 'long'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_LONG, 'unsigned long'],
+ [Blockly.Msg.LANG_MATH_FLOAT, 'float'],
+ [Blockly.Msg.LANG_MATH_DOUBLE, 'double'],
+ [Blockly.Msg.LANG_MATH_BOOLEAN, 'boolean'],
+ [Blockly.Msg.LANG_MATH_BYTE, 'byte'],
+ [Blockly.Msg.LANG_MATH_CHAR, 'char'],
+ [Blockly.Msg.LANG_MATH_UNSIGNED_CHAR, 'unsigned char'],
+ [Blockly.Msg.LANG_MATH_STRING, 'String'],
+ ["uint8_t", "uint8_t"],
+ ["uint16_t", "uint16_t"],
+ ["uint32_t", "uint32_t"],
+ ["uint64_t", "uint64_t"]
+ ]
+};
+
+//获取某个变量在内存中所占用的字节数
+export const math_SizeOf = {
+ init: function () {
+ this.appendValueInput("data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_GET + " " + Blockly.Msg.MIXLY_I2C_BYTES);
+ this.setInputsInline(false);
+ this.setOutput(true, null);
+ this.setColour(MATH_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//最大最小值
+export const math_max_min = {
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.appendValueInput('A')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(math_max_min.OPERATORS), 'OP')
+ .appendField('(');
+ this.appendValueInput('B')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(',');
+ this.appendDummyInput('')
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(')');
+ this.setInputsInline(true);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#min-max");
+ this.setOutput(true, Number);
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var mode = thisBlock.getFieldValue('OP');
+ var TOOLTIPS = {
+ 'max': Blockly.Msg.MIXLY_TOOLTIP_MATH_MAX,
+ 'min': Blockly.Msg.MIXLY_TOOLTIP_MATH_MIN
+ };
+ return TOOLTIPS[mode];
+ });
+ },
+ OPERATORS: [
+ [Blockly.Msg.MIXLY_MAX, 'max'],
+ [Blockly.Msg.MIXLY_MIN, 'min'],
+ ]
+};
+
+export const math_random_seed = {
+ init: function () {
+ this.setColour(MATH_HUE);
+ // this.appendDummyInput()
+ // .appendField(Blockly.Msg.LANG_MATH_RANDOM_SEED);
+ this.appendValueInput('NUM')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.LANG_MATH_RANDOM_SEED);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_MATH_RANDOM_SEED);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#randomseed");
+ }
+};
+
+export const math_random_int = {
+ /**
+ * Block for random integer between [X] and [Y].
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('FROM')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.LANG_MATH_RANDOM_INT_INPUT_FROM);
+ this.appendValueInput('TO')
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.LANG_MATH_RANDOM_INT_INPUT_TO);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MATH_RANDOM_INT_TOOLTIP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#random");
+ }
+};
+
+export const math_constrain = {
+ /**
+ * Block for constraining a number between two limits.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.setOutput(true, Number);
+ this.appendValueInput('VALUE')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.LANG_MATH_CONSTRAIN_INPUT_CONSTRAIN);
+ this.appendValueInput('LOW')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.LANG_MATH_CONSTRAIN_INPUT_LOW);
+ this.appendValueInput('HIGH')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.LANG_MATH_CONSTRAIN_INPUT_HIGH);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MATH_CONSTRAIN_TOOLTIP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#constrain");
+ }
+};
+
+export const base_map = {
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.appendValueInput("NUM", Number)
+ .appendField(Blockly.Msg.MIXLY_MAP)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.LANG_MATH_INT, "map_int"],
+ [Blockly.Msg.LANG_MATH_FLOAT, "map_float"]
+ ]), "maptype")
+ .setCheck(Number);
+ this.appendValueInput("fromLow", Number)
+ .appendField(Blockly.Msg.MIXLY_MAP_FROM)
+ .setCheck(Number);
+ this.appendValueInput("fromHigh", Number)
+ .appendField(",")
+ .setCheck(Number);
+ this.appendValueInput("toLow", Number)
+ .appendField(Blockly.Msg.MIXLY_MAP_TO)
+ .setCheck(Number);
+ this.appendValueInput("toHigh", Number)
+ .appendField(",")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField("]");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_MATH_MAP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/03Mathematics.html#map");
+ }
+};
+
+export const variables_operation = {
+ init: function () {
+ this.setColour(MATH_HUE);
+ this.appendValueInput("variables")
+ .setCheck(null);
+ this.appendValueInput("data")
+ .setCheck(null)
+ .appendField(new Blockly.FieldDropdown([
+ ["+=", "+"],
+ ["-=", "-"],
+ ["*=", "*"],
+ ["/=", "/"]
+ ]), "type");
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+export const math_auto_add_or_minus = {
+ init: function () {
+ this.appendValueInput("math_auto_add_minus_output")
+ .setCheck(null);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ ["++", "++"],
+ ["--", "--"]
+ ]), "math_auto_add_minus_type");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(MATH_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/pinout.js b/mixly/boards/default_src/arduino_avr/blocks/pinout.js
new file mode 100644
index 00000000..bedb192d
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/pinout.js
@@ -0,0 +1,53 @@
+import * as Blockly from 'blockly/core';
+
+const PINOUT_HUE = '#555555';
+
+export const uno_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/boards/Uno.png'), 515, 372, '*'));
+ this.setColour(PINOUT_HUE);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+export const nano_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/boards/Nano.png'), 515, 368, '*'));
+ this.setColour(PINOUT_HUE);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+export const mega_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/boards/Mega.png'), 515, 736, '*'));
+ this.setColour(PINOUT_HUE);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+export const promini_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/boards/ProMini.png'), 515, 371, '*'));
+ this.setColour(PINOUT_HUE);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
+
+export const leonardo_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldImage(require('../media/boards/Leonardo.png'), 515, 371, '*'));
+ this.setColour(PINOUT_HUE);
+ this.setTooltip();
+ this.setHelpUrl();
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/pins.js b/mixly/boards/default_src/arduino_avr/blocks/pins.js
new file mode 100644
index 00000000..7ad5d81e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/pins.js
@@ -0,0 +1,85 @@
+import * as Blockly from 'blockly/core';
+import { Profile } from 'mixly';
+
+const PINS_HUE = 230;
+
+export const pins_digital = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_analog = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.analog), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_pwm = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.pwm), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_interrupt = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.interrupt), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_MOSI = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.MOSI), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_MISO = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.MISO), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_SCK = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.SCK), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_SCL = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.SCL), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
+
+export const pins_SDA = {
+ init: function () {
+ this.setColour(PINS_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown(Profile.default.SDA), 'PIN');
+ this.setOutput(true, Number);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/scoop.js b/mixly/boards/default_src/arduino_avr/blocks/scoop.js
new file mode 100644
index 00000000..1446d1d3
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/scoop.js
@@ -0,0 +1,57 @@
+import * as Blockly from 'blockly/core';
+
+const SCOOP_HUE = 120;
+
+export const SCoopTask = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("Scoop Task")
+ .appendField(new Blockly.FieldDropdown(SCoopTask.NUMBER), "_tasknum");
+ this.appendStatementInput("setup")
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .setCheck(null);
+ this.appendStatementInput("loop")
+ .appendField(Blockly.Msg.MIXLY_CONTROL_SCoop_loop)
+ .setCheck(null);
+ this.setColour(SCOOP_HUE);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SCOOP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#scoop-task");
+ },
+ NUMBER: [
+ ["1", "1"],
+ ["2", "2"],
+ ["3", "3"],
+ ["4", "4"],
+ ["5", "5"],
+ ["6", "6"],
+ ["7", "7"],
+ ["8", "8"]
+ ]
+};
+
+export const SCoop_yield = {
+ init: function () {
+ this.setColour(SCOOP_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_CONTROL_SCoop_yield);
+ this.setPreviousStatement(false, null);
+ this.setNextStatement(false, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SCOOP_YIELD);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/02Control.html#scoop-task");
+ }
+};
+
+export const SCoop_sleep = {
+ init: function () {
+ this.setColour(SCOOP_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_CONTROL_SCoop_sleep);
+ this.appendValueInput("sleeplength", Number)
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MILLIS);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SCOOP_SLEEP);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/sensor.js b/mixly/boards/default_src/arduino_avr/blocks/sensor.js
new file mode 100644
index 00000000..ae24f9a5
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/sensor.js
@@ -0,0 +1,1136 @@
+import * as Blockly from 'blockly/core';
+import { Profile } from 'mixly';
+
+const SENSOR_HUE = 40;
+
+export const gps_init = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GPS_INIT)
+ this.appendValueInput("RX", Number)
+ .appendField("RX#")
+ .setCheck(Number);
+ this.appendValueInput("TX", Number)
+ .appendField("TX#")
+ .setCheck(Number);
+ this.appendValueInput("CONTENT", Number)
+ .appendField(Blockly.Msg.MIXLY_SERIAL_BEGIN)
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_GPS_INIT);
+ }
+};
+
+export const gps_data_available = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GPS_DATA_AVAILABLE);
+ this.setOutput(true, Boolean);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_GPS_DATA_AVAILABLE);
+ }
+};
+
+export const gps_data_encode = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GPS_DATA_ENCODE);
+ this.setOutput(true, Boolean);
+ }
+};
+
+export const gps_xxx_isValid = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField("GPS")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GPS_LOCATION, "location"],
+ [Blockly.Msg.MIXLY_GPS_DATE, "date"],
+ [Blockly.Msg.MIXLY_GPS_TIME, "time"]
+ ]), "WHAT")
+ .appendField(Blockly.Msg.MIXLY_GPS_ISVALID);
+ this.setOutput(true, Boolean);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_GPS_DATA_VAILD);
+ }
+};
+
+export const gps_getData_xxx = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GPS_GET)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GPS_LOCATION_LAT, "location.lat"],
+ [Blockly.Msg.MIXLY_GPS_LOCATION_LNG, "location.lng"],
+ [Blockly.Msg.MIXLY_GPS_DATE_YEAR, "date.year"],
+ [Blockly.Msg.MIXLY_GPS_DATE_MONTH, "date.month"],
+ [Blockly.Msg.MIXLY_GPS_DATE_DAY, "date.day"],
+ [Blockly.Msg.MIXLY_GPS_TIME_HOUR, "time.hour"],
+ [Blockly.Msg.MIXLY_GPS_TIME_MINUTE, "time.minute"],
+ [Blockly.Msg.MIXLY_GPS_TIME_SECOND, "time.second"],
+ [Blockly.Msg.MIXLY_GPS_TIME_CENTISECOND, "time.centisecond"]
+ ]), "WHAT");
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_GPS_GETDATA.replace('%1', this.getFieldValue('WHAT')));
+ }
+};
+
+export const chaoshengbo2 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_CHAOSHENGBO);
+ this.appendDummyInput("")
+ .appendField('Trig#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "Trig")
+ .appendField('Echo#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "Echo");
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_CHAOSHENGBO);
+ // this.setFieldValue("2","Trig");
+ // this.setFieldValue("4","Echo");
+ }
+};
+
+//DHT11温湿度传感器
+export const DHT = {
+ init: function () {
+ var WHAT = [[Blockly.Msg.MIXLY_GETTEMPERATUE, 'temperature'], [Blockly.Msg.MIXLY_GETHUMIDITY, 'humidity']];
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([['DHT11', '11'], ['DHT21', '21'], ['DHT22', '22']]), 'TYPE')
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .appendField(new Blockly.FieldDropdown(WHAT), "WHAT");
+ this.setOutput(true, Number);
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var op = thisBlock.getFieldValue('WHAT');
+ var TOOLTIPS = {
+ 'temperature': Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_GET_TEM,
+ 'humidity': Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_GET_HUM
+ };
+ return TOOLTIPS[op];
+ });
+ }
+};
+
+//lm35温度传感器
+export const LM35 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField("LM35" + Blockly.Msg.MIXLY_TEMP);
+ this.appendValueInput("PIN", Number)
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LM35);
+ }
+};
+
+//DS18B20温度传感器
+export const ds18b20 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DS18B20)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN")
+ .appendField(Blockly.Msg.MIXLY_GETTEMPERATUE)
+ .appendField(new Blockly.FieldDropdown(ds18b20.UNIT), "UNIT");
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_DS18);
+ },
+ UNIT: [
+ [Blockly.Msg.MIXLY_DS18B20_C, '0'],
+ [Blockly.Msg.MIXLY_DS18B20_F, '1']
+ ]
+};
+
+//初始化MLX90614红外测温传感器
+export const mlx90614_init = {
+ init: function () {
+ this.appendValueInput("mlx90614_address")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SETUP + " MLX90614" + Blockly.Msg.MLX90614_TYPE)
+ .appendField(Blockly.Msg.MIXLY_LCD_ADDRESS);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(40);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//MLX90614获取数据
+export const mlx90614_get_data = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("MLX90614" + Blockly.Msg.MLX90614_TYPE)
+ .appendField(Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown(mlx90614_get_data.DATA_TYPE), "mlx90614_data");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(40);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_MLX90614_GET_DATA);
+ this.setHelpUrl("");
+ },
+ DATA_TYPE: [
+ [Blockly.Msg.MLX90614_TARGET_OBJECT_TEMP + "(℃)", "readObjectTempC"],
+ [Blockly.Msg.MLX90614_TARGET_OBJECT_TEMP + "(℉)", "readObjectTempF"],
+ [Blockly.Msg.MLX90614_AMBIENT_TEMP + "(℃)", "readAmbientTempC"],
+ [Blockly.Msg.MLX90614_AMBIENT_TEMP + "(℉)", "readAmbientTempF"]
+ ]
+};
+
+//DF称重模块
+export const weightSensor = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField("Hx711")
+ .appendField(Blockly.Msg.MIXLY_WEIGHTSENSOR);
+ this.appendDummyInput("")
+ .appendField('Dout#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "DOUT")
+ .appendField('SCK#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "SCK");
+ this.appendValueInput("scale")
+ .setCheck(Number)
+ .appendField(Blockly.Msg.HX711_scale);
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_WEIGHTSENSOR);
+ // this.setFieldValue("2","DOUT");
+ // this.setFieldValue("4","SCK");
+ }
+};
+
+//DS1302 RTC
+export const DS1302_init = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DS1302_INITPIN);
+ //.appendField(new Blockly.FieldTextInput('myRTC'), 'RTCName');
+ this.appendValueInput("RST", Number)
+ .appendField("RST#")
+ .setCheck(Number);
+ this.appendValueInput("DAT")
+ .appendField("DAT#")
+ .setCheck(Number);
+ this.appendValueInput("CLK")
+ .appendField("CLK#")
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_DS1302_INIT);
+ }
+};
+
+//DS1307 RTC
+export const DS1307_init = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_RTCINIT);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(DS1307_init.RTC_TYPE), 'RTCType');
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ //.appendField(new Blockly.FieldTextInput('myRTC'), 'RTCName');
+ this.appendValueInput("SDA")
+ .appendField("SDA#")
+ .setCheck(Number);
+ this.appendValueInput("SCL")
+ .appendField("SCL#")
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_DS1307_INIT);
+ },
+ RTC_TYPE: [['DS1307', 'RtcDS1307'], ['DS3231', 'RtcDS3231']]
+};
+
+//传感器-实时时钟块_获取时间
+export const RTC_get_time = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("RTC" + Blockly.Msg.MIXLY_RTCGETTIME);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ //.appendField(new Blockly.FieldTextInput('myRTC'), 'RTCName');
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(RTC_get_time.RTC_TIME_TYPE), "TIME_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RTC_GETTIME.replace('%1', this.getFieldValue("TIME_TYPE")));
+ },
+ RTC_TIME_TYPE: [
+ [Blockly.Msg.MIXLY_YEAR, "Year"],
+ [Blockly.Msg.MIXLY_MONTH, "Month"],
+ [Blockly.Msg.MIXLY_DAY, "Day"],
+ [Blockly.Msg.MIXLY_HOUR, "Hour"],
+ [Blockly.Msg.MIXLY_MINUTE, "Minute"],
+ [Blockly.Msg.MIXLY_SECOND, "Second"],
+ [Blockly.Msg.MIXLY_WEEK, "DayOfWeek"]
+ ]
+};
+
+// //传感器-实时时钟块_设置时间
+export const RTC_time = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendValueInput("hour")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_HOUR);
+ this.appendValueInput("minute")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MINUTE);
+ this.appendValueInput("second")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SECOND);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RTC_SETTIME);
+ }
+};
+
+export const RTC_date = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendValueInput("year")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_YEAR);
+ this.appendValueInput("month")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MONTH);
+ this.appendValueInput("day")
+ .setCheck(Number);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_DAY);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RTC_SETTIME);
+ }
+};
+
+//设置时间
+export const RTC_set_time = {
+ init: function () {
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("RTC" + Blockly.Msg.MIXLY_RTCSETTIME);
+ this.appendValueInput("date")
+ .appendField(Blockly.Msg.MIXLY_GPS_DATE);
+ this.appendValueInput("time")
+ .appendField(Blockly.Msg.MIXLY_GPS_TIME);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//获取烧录时间和日期
+export const get_system_date_time = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GET + " " + Blockly.Msg.MIXLY_SYSTEM)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GPS_DATE, "DATE"],
+ [Blockly.Msg.MIXLY_GPS_TIME, "TIME"]
+ ]), "type");
+ this.setInputsInline(false);
+ this.setOutput(true, null);
+ this.setColour(40);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//传感器-实时时钟块_设置日期
+export const RTC_set_date = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_RTCSETDATE);
+ // .appendField(new Blockly.FieldTextInput('myRTC'), 'RTCName');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_RTC_SETDATE);
+ }
+};
+
+export const SHT20 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField("SHT20" + Blockly.Msg.MIXLY_DHT11_T_H);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(SHT20.SHT20_TYPE), "SHT20_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip();
+ },
+ SHT20_TYPE: [
+ [Blockly.Msg.MIXLY_TEMPERATURE, "sht20.readTemperature()"],
+ [Blockly.Msg.MIXLY_Humidity, "sht20.readHumidity()"],
+ ]
+};
+
+//传感器-重力感应块-获取数据
+export const ADXL345 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_ADXL345);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(ADXL345.ADXL345_GETAB), "ADXL345_PIN");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip();
+ },
+ ADXL345_GETAB: [
+ [Blockly.Msg.MixGo_MPU9250_AX, "accel.getAccelerationX()"],
+ [Blockly.Msg.MixGo_MPU9250_AY, "accel.getAccelerationY()"],
+ [Blockly.Msg.MixGo_MPU9250_AZ, "accel.getAccelerationZ()"],
+ [Blockly.Msg.MixGo_MPU9250_AX + "(g)", "accel.getAccelerationX()/256.0"],
+ [Blockly.Msg.MixGo_MPU9250_AY + "(g)", "accel.getAccelerationY()/256.0"],
+ [Blockly.Msg.MixGo_MPU9250_AZ + "(g)", "accel.getAccelerationZ()/256.0"],
+ ]
+};
+
+var LIS3DHTR_GETDATA = [
+ [Blockly.Msg.MixGo_MPU9250_AX, "LIS.getAccelerationX()"],
+ [Blockly.Msg.MixGo_MPU9250_AY, "LIS.getAccelerationY()"],
+ [Blockly.Msg.MixGo_MPU9250_AZ, "LIS.getAccelerationZ()"],
+ [Blockly.Msg.MIXLY_TEMPERATURE, "LIS.getTemperature()"],
+];
+
+export const LIS3DHTR = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField('LIS3DHTR' + Blockly.Msg.MixGo_MPU9250);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(LIS3DHTR_GETDATA), "LIS3DHTR_GETDATA");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip();
+ }
+};
+
+export const ADXL345_setOffset = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SETTING)
+ .appendField('ADXL345')
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_OFFSET);
+ this.appendValueInput("OFFSET")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_X, "setOffsetX"],
+ [Blockly.Msg.MIXLY_DISPLAY_MATRIX_Y, "setOffsetY"],
+ [Blockly.Msg.MIXLY_Z_AXIS, "setOffsetZ"]
+ ]), "MIXEPI_ADXL345_OFFSET");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};
+
+//传感器-MPU6050-获取数据
+export const MPU6050 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MPU6050);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_Accel_X, "getAccX()"],
+ [Blockly.Msg.MIXLY_Accel_Y, "getAccY()"],
+ [Blockly.Msg.MIXLY_Accel_Z, "getAccZ()"],
+ [Blockly.Msg.MIXLY_Gyro_X, "getAngleX()"],
+ [Blockly.Msg.MIXLY_Gyro_Y, "getAngleY()"],
+ [Blockly.Msg.MIXLY_Gyro_Z, "getAngleZ()"],
+ [Blockly.Msg.MIXLY_readTempC, "getTemp()"]
+ ]), "MPU6050_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ }
+};
+
+//传感器-MPU6050-更新数据
+export const MPU6050_update = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_MPU6050 + Blockly.Msg.MIXLY_update_data);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
+const Encoder_NO = [
+ [Blockly.Msg.MIXLY_ENCODER + 1, "1"],
+ [Blockly.Msg.MIXLY_ENCODER + 2, "2"],
+ [Blockly.Msg.MIXLY_ENCODER + 3, "3"],
+ [Blockly.Msg.MIXLY_ENCODER + 4, "4"]
+];
+
+//旋转编码器定义
+export const encoder_init = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(Blockly.Msg.MIXLY_ENCODER);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "Encoder_NO");
+ this.appendDummyInput("")
+ .appendField('DT')
+ .appendField(new Blockly
+ .FieldDropdown(Profile.default.digital), "DT")
+ .appendField('CLK')
+ .appendField(new Blockly
+ .FieldDropdown(Profile.default.digital), "CLK");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ // this.setFieldValue("2","DT");
+ // this.setFieldValue("4","CLK");
+ }
+};
+
+//旋转编码器赋值
+export const encoder_write = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "Encoder_NO");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_VALUE2);
+ this.appendValueInput("value")
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ this.setInputsInline(true);
+ }
+};
+
+//旋转编码器读值
+export const encoder_read = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "Encoder_NO");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READ);
+ this.setOutput(true, Number);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ this.setInputsInline(true);
+ }
+};
+
+//旋转编码器定义
+export const encoder_init1 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(Blockly.Msg.MIXLY_ENCODER);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "Encoder_NO");
+ this.appendDummyInput("")
+ .appendField('DT')
+ .appendField(new Blockly
+ .FieldDropdown(Profile.default.digital), "DT")
+ .appendField('CLK')
+ .appendField(new Blockly
+ .FieldDropdown(Profile.default.digital), "CLK");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ // this.setFieldValue("2","DT");
+ // this.setFieldValue("4","CLK");
+ }
+};
+
+//旋转编码器赋值
+export const encoder_write1 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "Encoder_NO");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_VALUE2);
+ this.appendValueInput("value")
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ this.setInputsInline(true);
+ }
+};
+
+//旋转编码器读值
+export const encoder_read1 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "Encoder_NO");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READ);
+ this.setOutput(true, Number);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ this.setInputsInline(true);
+ }
+};
+
+// 旋转编码器定义
+export const sensor_encoder_init = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "TYPE")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE)
+ .appendField(new Blockly.FieldDropdown([["1", "2"], ["2", "4"]]), "mode");
+ this.appendValueInput("CLK")
+ .setCheck(null)
+ .appendField("CLK#");
+ this.appendValueInput("DT")
+ .setCheck(null)
+ .appendField("DT#");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+// 旋转编码器读取
+export const sensor_encoder_get = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "TYPE")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GPS_LOCATION, "getPosition"],
+ [Blockly.Msg.MIXLY_MICROBIT_Direction, "getDirection"],
+ [Blockly.Msg.MIXLY_INCREMENT, "getIncrement"],
+ [Blockly.Msg.MIXLY_UPPERBOUND, "getUpperBound"],
+ [Blockly.Msg.MIXLY_LOWERBOUND, "getLowerBound"]
+ ]), "OPERATE_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+// 旋转编码器设置
+export const sensor_encoder_set = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "TYPE");
+ this.appendValueInput("DATA")
+ .setCheck(null)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_GPS_LOCATION, "resetPosition"],
+ [Blockly.Msg.MIXLY_INCREMENT, "setIncrement"],
+ [Blockly.Msg.MIXLY_UPPERBOUND, "setUpperBound"],
+ [Blockly.Msg.MIXLY_LOWERBOUND, "setLowerBound"]
+ ]), "OPERATE_TYPE")
+ .appendField(Blockly.Msg.MIXLY_STAT);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+// 旋转编码器事件
+export const sensor_encoder_handle = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Encoder_NO), "TYPE")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ENCODER_CHANGED, "setChangedHandler"],
+ [Blockly.Msg.MIXLY_ENCODER_LEFT_ROTATION, "setLeftRotationHandler"],
+ [Blockly.Msg.MIXLY_ENCODER_RIGHT_ROTATION, "setRightRotationHandler"],
+ [Blockly.Msg.MIXLY_ENCODER_UPPER_OVERFLOW, "setUpperOverflowHandler"],
+ [Blockly.Msg.MIXLY_ENCODER_LOWER_OVERFLOW, "setLowerOverflowHandler"]
+ ]), "OPERATE_TYPE");
+ this.appendStatementInput("DO")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_MSTIMER2_DO);
+ this.setInputsInline(true);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//BME280读取
+export const BME280_READ = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READ)
+ .appendField(new Blockly.FieldDropdown([["BME280", "bme"], ["BMP280", "bmp"]]), 'TYPE');
+ this.appendValueInput("address")
+ .appendField(Blockly.Msg.MIXLY_LCD_ADDRESS);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDependentDropdown(
+ "TYPE", this.BMX280_VALUE_TYPE, this.BMX280_VALUE_TYPE['bme']), 'BME_TYPE'
+ );
+ this.setOutput(true, null);
+ this.setInputsInline(true);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ },
+ BMX280_VALUE_TYPE: {
+ bme: [
+ [Blockly.Msg.blynk_IOT_IR_TEMP, "readTemperature()"],
+ [Blockly.Msg.MIXLY_Humidity, "readHumidity()"],
+ [Blockly.Msg.MIXLY_Altitude, "readPressure()"],
+ [Blockly.Msg.MIXLY_HEIGHT, "readAltitude(SEALEVELPRESSURE_HPA)"]
+ ],
+ bmp: [
+ [Blockly.Msg.blynk_IOT_IR_TEMP, "readTemperature()"],
+ [Blockly.Msg.MIXLY_Altitude, "readPressure()"],
+ [Blockly.Msg.MIXLY_HEIGHT, "readAltitude(SEALEVELPRESSURE_HPA)"]
+ ]
+ }
+};
+
+//PS2
+export const PS2_init = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SETUP + Blockly.Msg.PS2);
+ this.appendDummyInput("")
+ .appendField('DAT#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PS2_DAT")
+ .appendField('CMD#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PS2_CMD")
+ .appendField('SEL#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PS2_SEL")
+ .appendField('CLK#')
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PS2_CLK");
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.PS2_setRumble)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_ON, "true"],
+ [Blockly.Msg.MIXLY_OFF, "false"]
+ ]), "rumble");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip('');
+ this.setFieldValue("2", "PS2_DAT");
+ this.setFieldValue("4", "PS2_CMD");
+ this.setFieldValue("5", "PS2_SEL");
+ this.setFieldValue("12", "PS2_CLK");
+ }
+};
+
+export const PS2_update = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.PS2 + Blockly.Msg.MIXLY_update_data);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
+//
+export const PS2_Button = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.PS2_BUTTON)
+ .appendField(new Blockly.FieldDropdown(PS2_Button.PSBUTTON), "psbt")
+ .appendField(Blockly.Msg.MIXLY_PULSEIN_STAT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_BUTTON_HOLD, "Button"],
+ [Blockly.Msg.MIXLY_BUTTON_PRESSED, "ButtonPressed"],
+ [Blockly.Msg.MIXLY_BUTTON_RELEASED, "ButtonReleased"],
+ [Blockly.Msg.MIXLY_CHANGE, "NewButtonState"]
+ ]), "btstate");
+ this.setOutput(true, Boolean);
+ this.setTooltip('');
+ },
+ PSBUTTON: [
+ [Blockly.Msg.PS2_TRIANGLE, "PSB_GREEN"],
+ [Blockly.Msg.PS2_CIRCLE, "PSB_RED"],
+ [Blockly.Msg.PS2_CROSS, "PSB_BLUE"],
+ [Blockly.Msg.PS2_SQUARE, "PSB_PINK"],
+ [Blockly.Msg.PS2_L1, "PSB_L1"],
+ [Blockly.Msg.PS2_L2, "PSB_L2"],
+ // ["PSB_L3","PSB_L3"],
+ [Blockly.Msg.PS2_R1, "PSB_R1"],
+ [Blockly.Msg.PS2_R2, "PSB_R2"],
+ // ["PSB_R3","PSB_R3"],
+ [Blockly.Msg.PS2_UP, "PSB_PAD_UP"],
+ [Blockly.Msg.PS2_RIGHT, "PSB_PAD_RIGHT"],
+ [Blockly.Msg.PS2_DOWN, "PSB_PAD_DOWN"],
+ [Blockly.Msg.PS2_LEFT, "PSB_PAD_LEFT"],
+ [Blockly.Msg.PS2_SELECT, "PSB_SELECT"],
+ [Blockly.Msg.PS2_START, "PSB_START"]
+ ]
+};
+
+export const PS2_stk = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.PS2_stick)
+ .appendField(new Blockly.FieldDropdown(PS2_stk.PSSTK), "psstk");
+ this.setOutput(true, Number);
+ this.setTooltip('');
+ },
+ PSSTK: [
+ [Blockly.Msg.PS2_RX, "PSS_RX"],
+ [Blockly.Msg.PS2_RY, "PSS_RY"],
+ [Blockly.Msg.PS2_LX, "PSS_LX"],
+ [Blockly.Msg.PS2_LY, "PSS_LY"],
+ ]
+};
+
+export const TCS34725_Get_RGB = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.TCS34725_Get_RGB)
+ .appendField(new Blockly.FieldDropdown(TCS34725_Get_RGB.DF_TCS34725_COLOR), "DF_TCS34725_COLOR");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ },
+ DF_TCS34725_COLOR: [
+ [Blockly.Msg.COLOUR_RGB_RED, "tcs34725.getRedToGamma()"],
+ [Blockly.Msg.COLOUR_RGB_GREEN, "tcs34725.getGreenToGamma()"],
+ [Blockly.Msg.COLOUR_RGB_BLUE, "tcs34725.getBlueToGamma()"],
+ ]
+};
+
+//初始化TCS230颜色传感器
+export const tcs230_init = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SETUP + " TCS230");
+ this.appendValueInput("tcs230_s0")
+ .setCheck(null)
+ .appendField("S0");
+ this.appendValueInput("tcs230_s1")
+ .setCheck(null)
+ .appendField("S1");
+ this.appendValueInput("tcs230_s2")
+ .setCheck(null)
+ .appendField("S2");
+ this.appendValueInput("tcs230_s3")
+ .setCheck(null)
+ .appendField("S3");
+ this.appendValueInput("tcs230_led")
+ .setCheck(null)
+ .appendField("LED");
+ this.appendValueInput("tcs230_out")
+ .setCheck(null)
+ .appendField("OUT");
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//TCS230颜色传感器 获取RGB值
+export const tcs230_Get_RGB = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("TCS230")
+ .appendField(Blockly.Msg.MIXLY_GET)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.COLOUR_RGB_RED, "R"],
+ [Blockly.Msg.COLOUR_RGB_GREEN, "G"],
+ [Blockly.Msg.COLOUR_RGB_BLUE, "B"]
+ ]), "tcs230_color");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const Arduino_keypad_4_4_start = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(Blockly.Msg.MIXLY_SETUP + Blockly.Msg.MIXLY_Keypad);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldTextInput("KEYPAD_4_4"), "keypad_name");
+ this.appendValueInput("keypad_row")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.DATAFRAME_RAW + Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("keypad_col")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.DATAFRAME_COLUMN + Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("keypad_type")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_Keypad_define);
+ this.setNextStatement(true, null);
+ this.setPreviousStatement(true);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const keypad_row_data = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendValueInput("keypad_row_1", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("1#");
+ this.appendValueInput("keypad_row_2", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("2#");
+ this.appendValueInput("keypad_row_3", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("3#");
+ this.appendValueInput("keypad_row_4", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("4#");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const keypad_col_data = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendValueInput("keypad_col_1", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("1#");
+ this.appendValueInput("keypad_col_2", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("2#");
+ this.appendValueInput("keypad_col_3", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("3#");
+ this.appendValueInput("keypad_col_4", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("4#");
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const keypad_type_data = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(new Blockly.FieldTextInput("1"), "keypad_1_1")
+ .appendField(new Blockly.FieldTextInput("2"), "keypad_1_2")
+ .appendField(new Blockly.FieldTextInput("3"), "keypad_1_3")
+ .appendField(new Blockly.FieldTextInput("A"), "keypad_1_4");
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(new Blockly.FieldTextInput("4"), "keypad_2_1")
+ .appendField(new Blockly.FieldTextInput("5"), "keypad_2_2")
+ .appendField(new Blockly.FieldTextInput("6"), "keypad_2_3")
+ .appendField(new Blockly.FieldTextInput("B"), "keypad_2_4");
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(new Blockly.FieldTextInput("7"), "keypad_3_1")
+ .appendField(new Blockly.FieldTextInput("8"), "keypad_3_2")
+ .appendField(new Blockly.FieldTextInput("9"), "keypad_3_3")
+ .appendField(new Blockly.FieldTextInput("C"), "keypad_3_4");
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.CENTRE)
+ .appendField(new Blockly.FieldTextInput("*"), "keypad_4_1")
+ .appendField(new Blockly.FieldTextInput("0"), "keypad_4_2")
+ .appendField(new Blockly.FieldTextInput("#"), "keypad_4_3")
+ .appendField(new Blockly.FieldTextInput("D"), "keypad_4_4");
+ this.setOutput(true, null);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const get_keypad_num = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldTextInput("KEYPAD_4_4"), "keypad_name")
+ .appendField(Blockly.Msg.MIXLY_Keypad_GETKEY);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(SENSOR_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const arduino_keypad_event = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_Keypad)
+ .appendField(new Blockly.FieldTextInput("KEYPAD_4_4"), "keypad_name");
+ this.appendValueInput("keypad_event_input")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_Keypad_EVENT);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_MONITOR_SCROLL_INTERVAL)
+ .appendField(new Blockly.FieldTextInput("1000"), "keypad_start_event_delay")
+ .appendField(Blockly.Msg.MIXLY_MILLIS);
+ this.appendStatementInput("keypad_event_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setInputsInline(false);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//传感器_重力感应块_获取9轴数据
+export const mixgo_MPU9250 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField("MPU9250" + Blockly.Msg.MixGo_MPU9250);
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown(mixgo_MPU9250.MixGo_MPU9250_GETAB), "MixGo_MPU9250_GETAB");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip("");
+ this.setHelpUrl('');
+ },
+ MixGo_MPU9250_GETAB: [
+ [Blockly.Msg.MixGo_MPU9250_AX, "a"],
+ [Blockly.Msg.MixGo_MPU9250_AY, "b"],
+ [Blockly.Msg.MixGo_MPU9250_AZ, "c"],
+ [Blockly.Msg.MixGo_MPU9250_GX, "d"],
+ [Blockly.Msg.MixGo_MPU9250_GY, "e"],
+ [Blockly.Msg.MixGo_MPU9250_GZ, "f"],
+ [Blockly.Msg.MixGo_MPU9250_MX, "g"],
+ [Blockly.Msg.MixGo_MPU9250_MY, "h"],
+ [Blockly.Msg.MixGo_MPU9250_MZ, "i"]
+ ]
+};
+
+//NTC电阻
+export const NTC_TEMP = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField("NTC")
+ .appendField(Blockly.Msg.MIXLY_TEMP);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_PIN)
+ .appendField(new Blockly.FieldDropdown(Profile.default.digital), "PIN");
+ this.appendValueInput("NominalResistance")
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_NominalResistance);
+ this.appendValueInput("betaCoefficient")
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_betaCoefficient);
+ this.appendValueInput("seriesResistor")
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_seriesResistor);
+ this.setInputsInline(false);
+ this.setOutput(true, Number);
+ this.setTooltip();
+ }
+};
+
+//AHT20/21温湿度传感器
+export const AHT20_21 = {
+ init: function () {
+ this.setColour(SENSOR_HUE);
+ this.appendDummyInput("")
+ .appendField("AHT20/21" + Blockly.Msg.MIXLY_TEM_HUM)
+ this.appendDummyInput("")
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_TEMPERATURE, "AHT21.GetTemperature()"],
+ [Blockly.Msg.MIXLY_Humidity, "AHT21.GetHumidity()"],
+ [Blockly.Msg.MIXLY_DewPoint, "AHT21.GetDewPoint()"]
+ ]), "AHT21_TYPE");
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip();
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/serial.js b/mixly/boards/default_src/arduino_avr/blocks/serial.js
new file mode 100644
index 00000000..bf5fdf7e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/serial.js
@@ -0,0 +1,198 @@
+import * as Blockly from 'blockly/core';
+import { Profile } from 'mixly';
+
+const SERIAL_HUE = 65;
+
+export const serial_begin = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendValueInput("CONTENT", Number)
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_BEGIN)
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SERIAL_BEGIN);
+ }
+};
+
+export const serial_write = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendValueInput("CONTENT", String)
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_WRITE);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.TEXT_WRITE_TOOLTIP);
+ }
+};
+
+export const serial_print = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendValueInput("CONTENT", String)
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_PRINT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_PRINT_INLINE, "print"],
+ [Blockly.Msg.TEXT_PRINT_Huanhang_TOOLTIP, "println"]
+ ]), "new_line");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.TEXT_PRINT_TOOLTIP);
+ }
+};
+
+export const serial_println = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendValueInput("CONTENT", String)
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_PRINT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.TEXT_PRINT_Huanhang_TOOLTIP, "println"],
+ [Blockly.Msg.MIXLY_PRINT_INLINE, "print"]
+ ]), "new_line");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.TEXT_PRINT_TOOLTIP);
+ }
+};
+
+export const serial_print_num = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_PRINT)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_PRINT_INLINE, "print"],
+ [Blockly.Msg.TEXT_PRINT_Huanhang_TOOLTIP, "println"]
+ ]), "new_line")
+ .appendField(Blockly.Msg.MIXLY_NUMBER);
+ this.appendValueInput("CONTENT", Number)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MATH_HEX, "HEX"],
+ [Blockly.Msg.MATH_BIN, "BIN"],
+ [Blockly.Msg.MATH_OCT, "OCT"],
+ [Blockly.Msg.MATH_DEC, "DEC"]
+ ]), "STAT")
+ .setCheck(Number);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.TEXT_PRINT_HEX_TOOLTIP);
+ }
+};
+
+export const serial_print_hex = serial_print_num;
+
+export const serial_available = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_AVAILABLE);
+ this.setOutput(true, Boolean);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERIAL_AVAILABLE);
+ }
+};
+
+export const serial_readstr = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READSTR);
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERIAL_READ_STR);
+ }
+};
+
+export const serial_readstr_until = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendValueInput("CONTENT", Number)
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READSTR_UNTIL)
+ .setCheck(Number);
+ this.setInputsInline(true);
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SERIAL_READSTRUNITL.replace('%1', Blockly.Arduino.valueToCode(this, 'CONTENT', Blockly.Arduino.ORDER_ATOMIC)));
+ }
+};
+
+export const serial_parseInt_Float = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ //.appendField(Blockly.Msg.MIXLY_SERIAL_READ)
+ .appendField(new Blockly.FieldDropdown([
+ ["read", "read"],
+ ["peek", "peek"],
+ ["parseInt", "parseInt"],
+ ["parseFloat", "parseFloat"]
+ ]), "STAT");
+ this.setOutput(true, Number);
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var op = thisBlock.getFieldValue('STAT');
+ var TOOLTIPS = {
+ 'parseInt': Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERIAL_READ_INT,
+ 'parseFloat': Blockly.Msg.MIXLY_TOOLTIP_BLOCKGROUP_SERIAL_READ_FLOAT
+ };
+ return TOOLTIPS[op];
+ });
+ }
+};
+
+export const serial_flush = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_FLUSH);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SERIAL_FLUSH);
+ }
+};
+
+export const serial_softserial = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SETUP)
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select");
+ this.appendValueInput("RX", Number)
+ .setCheck(Number)
+ .appendField("RX#")
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.appendValueInput("TX", Number)
+ .appendField("TX#")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SOFTSERIAL.replace('%1', Blockly.Arduino.valueToCode(this, 'RX', Blockly.Arduino.ORDER_ATOMIC))
+ .replace('%2', Blockly.Arduino.valueToCode(this, 'TX', Blockly.Arduino.ORDER_ATOMIC)));
+ }
+};
+
+export const serial_event = {
+ init: function () {
+ this.setColour(SERIAL_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown(Profile.default.serial_select), "serial_select")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_EVENT);
+ this.appendStatementInput('DO')
+ .appendField(Blockly.Msg.MIXLY_DO);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_SERIALEVENT);
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/storage.js b/mixly/boards/default_src/arduino_avr/blocks/storage.js
new file mode 100644
index 00000000..2c232300
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/storage.js
@@ -0,0 +1,309 @@
+import * as Blockly from 'blockly/core';
+
+const STORAGE_HUE = 0;
+
+export const store_sd_init = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField("SD")
+ .appendField(Blockly.Msg.MIXLY_SETUP);
+ this.appendValueInput("PIN_MOSI")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MOSI")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN_MISO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MISO")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN_SCK")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("CLK")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN_CS")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("CS")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setInputsInline(false);
+ this.setTooltip();
+ this.setHelpUrl('');
+ }
+};
+
+export const store_sd_init_32 = {
+ init: function () {
+ this.appendDummyInput("")
+ .appendField("SD")
+ .appendField(Blockly.Msg.MIXLY_SETUP);
+ this.appendValueInput("PIN_MOSI")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MOSI")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN_MISO")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("MISO")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN_SCK")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("CLK")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.appendValueInput("PIN_CS")
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField("CS")
+ .appendField(Blockly.Msg.MIXLY_PIN);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setInputsInline(false);
+ this.setTooltip();
+ this.setHelpUrl('');
+ }
+};
+
+export const sd_card_type = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("SD" + Blockly.Msg.MIXLY_TYPE);
+ this.setOutput(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const sd_card_root_files = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SD_LIST_FILES);
+ this.setOutput(false, null);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const sd_volume = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendDummyInput()
+ .appendField("SD")
+ .appendField(new Blockly.FieldDropdown(sd_volume.VOLUME_TYPE), 'volume_TYPE');
+ this.setOutput(true, Number);
+ this.setTooltip();
+ },
+ VOLUME_TYPE: [
+ [Blockly.Msg.MIXLY_SD_clusterCount, 'volume.clusterCount()'],
+ [Blockly.Msg.MIXLY_SD_blocksPerCluster, 'volume.blocksPerCluster()'],
+ [Blockly.Msg.MIXLY_SD_TOTAL_blocks, 'volume.blocksPerCluster() * volume.clusterCount()'],
+ ["FAT" + Blockly.Msg.MIXLY_TYPE, 'volume.fatType()'],
+ [Blockly.Msg.MIXLY_volume + "(KB)", 'volume.blocksPerCluster()*volume.clusterCount()/2'],
+ [Blockly.Msg.MIXLY_volume + "(MB)", 'volume.blocksPerCluster()*volume.clusterCount()/2/1024'],
+ [Blockly.Msg.MIXLY_volume + "(GB)", 'volume.blocksPerCluster()*volume.clusterCount()/2/1024/1024.0'],
+ ]
+};
+
+export const sd_exist = {
+ init: function () {
+ this.appendValueInput("FileName");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SD_FILE_Exist);
+ this.setOutput(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const sd_DelFile = {
+ init: function () {
+ this.appendValueInput("FileName")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_DELETE_VAR);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const sd_read = {
+ init: function () {
+ this.appendValueInput("FileName")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READ);
+ this.setOutput(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const store_sd_write = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("FILE")
+ .appendField(Blockly.Msg.MIXLY_WRITE_SD_FILE);
+ this.appendValueInput("DATA", String)
+ .setCheck([String, Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.appendValueInput("NEWLINE", Boolean)
+ .setCheck(Boolean)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SD_NEWLINE);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_SDWRITE);
+ }
+};
+
+export const store_eeprom_write_long = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("ADDRESS", Number)
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_EEPROM_WRITE_LONG);
+ this.appendValueInput("DATA", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DATA);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_EEPROM_WRITELONG);
+ }
+};
+
+export const store_eeprom_read_long = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("ADDRESS", Number)
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_EEPROM_READ_LONG);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_EEPROM_READLONG);
+ }
+};
+
+
+export const store_eeprom_write_byte = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("ADDRESS", Number)
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_EEPROM_WRITE_BYTE);
+ this.appendValueInput("DATA", Number)
+ .setCheck(Number)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_DATA);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_EEPROM_WRITEBYTE);
+ }
+};
+
+export const store_eeprom_read_byte = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("ADDRESS", Number)
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_EEPROM_READ_BYTE);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_EEPROM_READBYTE);
+ }
+};
+
+export const store_eeprom_put = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("ADDRESS")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_ESP32_WRITE)
+ .appendField("EEPROM")
+ .appendField(Blockly.Msg.MQTT_SERVER_ADD);
+ this.appendValueInput("DATA")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_EEPROM_PUT);
+ }
+};
+
+export const store_eeprom_get = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("ADDRESS")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READ)
+ .appendField("EEPROM")
+ .appendField(Blockly.Msg.MQTT_SERVER_ADD);
+ this.appendValueInput("DATA")
+ .setCheck(null)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.SAVETO + ' ' + Blockly.Msg.MSG["catVar"]);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_EEPROM_GET);
+ }
+};
+
+export const simple_spiffs_read = {
+ init: function () {
+ this.appendValueInput("FileName")
+ .appendField(Blockly.Msg.MIXLY_SERIAL_READ);
+ this.setOutput(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+export const simple_spiffs_store_spiffs_write = {
+ init: function () {
+ this.setColour(STORAGE_HUE);
+ this.appendValueInput("FILE")
+ .appendField(Blockly.Msg.MIXLY_WRITE_SPIFFS_FILE);
+ this.appendValueInput("DATA", String)
+ .setCheck([String, Number])
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SD_DATA);
+ this.appendValueInput("NEWLINE", Boolean)
+ .setCheck(Boolean)
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.MIXLY_SD_NEWLINE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_MODE)
+ .appendField(new Blockly.FieldDropdown(simple_spiffs_store_spiffs_write.OPEN_MODE), 'MODE');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_STORE_SDWRITE);
+ },
+ OPEN_MODE: [
+ [Blockly.Msg.TEXT_WRITE_TEXT, '1'],
+ [Blockly.Msg.TEXT_APPEND_APPENDTEXT, '2']
+ ]
+};
+
+export const simple_spiffs_DelFile = {
+ init: function () {
+ this.appendValueInput("FileName")
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_JS_DELETE_VAR);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(STORAGE_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/text.js b/mixly/boards/default_src/arduino_avr/blocks/text.js
new file mode 100644
index 00000000..1d9dfdeb
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/text.js
@@ -0,0 +1,589 @@
+import * as Blockly from 'blockly/core';
+
+const TEXTS_HUE = 160;
+
+export const text = {
+ /**
+ * Block for text value.
+ * @this Blockly.Block
+ */
+ init: function () {
+ //this.setHelpUrl(Blockly.Msg.TEXT_TEXT_HELPURL);
+ this.setColour(TEXTS_HUE);
+ this.appendDummyInput()
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput(''), 'TEXT')
+ .appendField(this.newQuote_(false));
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.TEXT_TEXT_TOOLTIP);
+ },
+ /**
+ * Create an image of an open or closed quote.
+ * @param {boolean} open True if open quote, false if closed.
+ * @return {!Blockly.FieldImage} The field image of the quote.
+ * @private
+ */
+ newQuote_: function (open) {
+ if (open == this.RTL) {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
+ } else {
+ var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
+ }
+ return new Blockly.FieldImage(file, 12, 12, '"');
+ }
+};
+
+const charValidator = function (text) {
+ if (text.length > 1) {
+ if (text.charAt(0) === "\\") {
+ var charAtOne = text.charAt(1);
+ if (charAtOne === "0" ||
+ charAtOne === "b" ||
+ charAtOne === "f" ||
+ charAtOne === "n" ||
+ charAtOne === "r" ||
+ charAtOne === "t" ||
+ charAtOne === "\\" ||
+ charAtOne === "'") {
+ return String(text).substring(0, 2);
+ } else if (charAtOne === "x" && text.charAt(2) === "0" && text.charAt(3) === "B") {
+ return String(text).substring(0, 4);
+ }
+ }
+ }
+ return String(text).substring(0, 1);
+};
+
+export const text_char = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendDummyInput()
+ .appendField(this.newQuote_(true))
+ .appendField(new Blockly.FieldTextInput('', charValidator), 'TEXT')
+ .appendField(this.newQuote_(false));
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.TEXT_CHAR_TOOLTIP);
+ },
+ newQuote_: function (open) {
+ if (open == true) {
+ var file = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAkBAMAAAB/KNeuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAbUExURQAAAP///////////////////////////////+tNPsIAAAAIdFJOUwAe1q4KRGaFPS0VAQAAAKlJREFUGNNVkD0LwkAMhlNsnUvBH+DmKnXoeODgWgXBsaOj+AGuVfTys8318l7OTA/hTe7JEWmVNwekA/fAHfNSsVoxew0/mfkbeSvo6wkLSbx0tJH2XdPS/pClsfxs7TA5WOQNl5M9X3bMF8RlS608z+JhFOZNMowybftw4GDvjHmTsc84PJJ4iPbgWcZVxuEUMHXKvS2dZHVgxJHpV4qr4Brei+Oe/usHT1JfDpNGeM0AAAAASUVORK5CYII=";
+
+ } else {
+ var file = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAkBAMAAAB/KNeuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAbUExURQAAAP///////////////////////////////+tNPsIAAAAIdFJOUwAe1q4KRGaFPS0VAQAAAKpJREFUGNNV0bEKAjEMBuActOd6KIKrg+h4cII3Cg6u5yA6Ot4DONxcUfPYJmnaxn/6KEmaUoD/LK+XxAUibhuhR85bvBLjQHR99DqXIL7ItTo0xdyQ3RrvjWlQZQyT8cnYjcXgbl2XzBmNe5kv4WUfar6kUc9o56N6nh4Zy1NrHZ8iuSN+lB5LCR0HnXIuy/hd7qymUs3bf7WajsNQrn9CHr7Jn+IOaUH4ATxJW2wDnL5kAAAAAElFTkSuQmCC";
+ }
+ return new Blockly.FieldImage(file, 7, 12, '"');
+ }
+};
+
+export const text_join = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput('A')
+ .setCheck([String, Number]);
+ this.appendValueInput('B')
+ .setCheck([String, Number])
+ .appendField(Blockly.Msg.MIXLY_TEXT_JOIN);
+ this.setInputsInline(true);
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_JOIN);
+ }
+};
+
+export const text_to_number = {
+ init: function () {
+ var TO_INT_FLOAT = [
+ [Blockly.Msg.MIXLY_TO_INT, 'toInt'],
+ [Blockly.Msg.MIXLY_TO_FLOAT, 'toFloat']
+ ];
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput('VAR')
+ .setCheck([String, Number])
+ .appendField(new Blockly.FieldDropdown(TO_INT_FLOAT), 'TOWHAT');
+ this.setOutput(true, Number);
+ var thisBlock = this;
+ this.setTooltip(function () {
+ var mode = thisBlock.getFieldValue('TOWHAT');
+ var TOOLTIPS = {
+ 'toInt': Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOINT,
+ 'toFloat': Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOFLOAT
+ };
+ return TOOLTIPS[mode];
+ });
+ }
+};
+
+export const ascii_to_char = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput('VAR')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_TOCHAR);
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOCHAR);
+ }
+};
+
+export const char_to_ascii = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_TOASCII)
+ .appendField("'")
+ .appendField(new Blockly.FieldTextInput('', charValidator), 'TEXT')
+ .appendField("'");
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOASCII);
+ }
+};
+
+export const number_to_text = {
+ init: function () {
+ var TO_INT_FLOAT = [
+ [Blockly.Msg.MATH_BIN, 'BIN'],
+ [Blockly.Msg.MATH_OCT, 'OCT'],
+ [Blockly.Msg.MATH_DEC, 'DEC'],
+ [Blockly.Msg.MATH_HEX, 'HEX']
+ ];
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput('VAR')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_TOSTRING)
+ .appendField(new Blockly.FieldDropdown(TO_INT_FLOAT), 'TOWHAT');
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOTEXT);
+ }
+};
+
+export const number_to_text_ = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput('VAR')
+ .setCheck(Number)
+ .appendField(Blockly.Msg.MIXLY_TOSTRING);
+ this.setOutput(true, String);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOTEXT);
+ }
+};
+
+export const text_length = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput("VAR")
+ .appendField(Blockly.Msg.MIXLY_LENGTH)
+ .setCheck(String);
+ this.setOutput(true, Number);
+ this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_LENGTH);
+ }
+};
+
+export const text_char_at = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput("VAR")
+ .setCheck(String);
+ this.appendValueInput("AT")
+ .appendField(Blockly.Msg.TEXT_CHARAT)
+ .setCheck(Number);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.TEXT_CHARAT2);
+ this.setOutput(true, Number);
+ this.setInputsInline(true);
+ var self = this;
+ this.setTooltip(function () {
+ return Blockly.Msg.MIXLY_TOOLTIP_TEXT_FIND_CHAR_AT.replace('%1', Blockly.Arduino.valueToCode(self, 'VAR', Blockly.Arduino.ORDER_ATOMIC));
+ });
+ }
+};
+
+export const text_equals_starts_ends = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput("STR1")
+ .setCheck([String, Number]);
+ this.appendValueInput("STR2")
+ .appendField(new Blockly.FieldDropdown(text_equals_starts_ends.TEXT_DOWHAT), 'DOWHAT')
+ .setCheck([String, Number]);
+ this.setOutput(true, [Boolean, Number]);
+ this.setInputsInline(true);
+ var self = this;
+ this.setTooltip(function () {
+ var op = self.getFieldValue('DOWHAT');
+ var TOOLTIPS = {
+ 'equals': Blockly.Msg.MIXLY_EQUALS,
+ 'startsWith': Blockly.Msg.MIXLY_STARTSWITH,
+ 'endsWith': Blockly.Msg.MIXLY_ENDSWITH
+ };
+ return Blockly.Msg.MIXLY_TOOLTIP_TEXT_EQUALS_STARTS_ENDS.replace('%1', TOOLTIPS[op]).replace('%2', Blockly.Arduino.valueToCode(self, 'STR2', Blockly.Arduino.ORDER_ATOMIC));
+ });
+ },
+ TEXT_DOWHAT: [
+ [Blockly.Msg.MIXLY_EQUALS, 'equals'],
+ [Blockly.Msg.MIXLY_STARTSWITH, 'startsWith'],
+ [Blockly.Msg.MIXLY_ENDSWITH, 'endsWith']
+ ]
+};
+
+export const text_compareTo = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput("STR1")
+ .setCheck([String, Number]);
+ this.appendValueInput("STR2")
+ .appendField(Blockly.Msg.MIXLY_COMPARETO)
+ .setCheck([String, Number]);
+ this.setOutput(true, Number);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.MIXLY_COMPARETO_HELP);
+ }
+};
+
+//小数获取有效位
+export const decimal_places = {
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendValueInput("numeral")
+ .setCheck(null)
+ .appendField(Blockly.Msg.LANG_MATH_FLOAT);
+ this.appendValueInput("decimal_places")
+ .setCheck(null)
+ .appendField(Blockly.Msg.TEXT_KEEP);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.TEXT_DECIMAL);
+ this.setOutput(true, null);
+ this.setTooltip(Blockly.Msg.DECIMAL_PLACES_HELP);
+ this.setHelpUrl("");
+ }
+};
+
+//截取字符串
+export const substring = {
+ init: function () {
+ this.appendValueInput("name")
+ .setCheck(null);
+ this.appendValueInput("Start")
+ .setCheck(null)
+ .appendField(Blockly.Msg.LISTS_GET_INDEX_GET);
+ this.appendValueInput("end")
+ .setCheck(null)
+ .appendField(Blockly.Msg.TEXT_TO);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LANG_MATH_STRING);
+ this.setOutput(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip(Blockly.Msg.SUBSTRING_HELP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/05Text.html#id13");
+ }
+};
+
+//字符串转化为大小写
+export const letter_conversion = {
+ init: function () {
+ this.appendValueInput("String")
+ .setCheck(null)
+ .appendField(Blockly.Msg.STRING_VARIABLE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LETTERS_ARE_CONVERTED_TO)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.CAPITAL, ".toUpperCase()"],
+ [Blockly.Msg.LOWER_CASE, ".toLowerCase()"]
+ ]), "type");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip(Blockly.Msg.LETTER_CONVERSION_HELP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/05Text.html#id19");
+ }
+};
+
+//字符串变量替换
+export const data_replacement = {
+ init: function () {
+ this.appendValueInput("String")
+ .setCheck(null)
+ .appendField(Blockly.Msg.STRING_VARIABLE);
+ this.appendValueInput("source_data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.LANG_MATH_STRING);
+ this.appendValueInput("replace")
+ .setCheck(null)
+ .appendField(Blockly.Msg.REPLACE_WITH);
+ this.appendDummyInput();
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip(Blockly.Msg.DATA_REPLACEMENT_HELP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/05Text.html#id23");
+ }
+};
+
+//消除非可视字符
+export const eliminate = {
+ init: function () {
+ this.appendValueInput("String")
+ .setCheck(null)
+ .appendField(Blockly.Msg.STRING_VARIABLE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.ELIMINATE_NON_VISUAL_CHARACTERS);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip(Blockly.Msg.ELIMINATE_HELP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/05Text.html#id27");
+ }
+};
+
+//检测是否以特定字符串开头或结尾
+export const first_and_last = {
+ init: function () {
+ this.appendValueInput("String")
+ .setCheck(null)
+ .appendField(Blockly.Msg.LANG_MATH_STRING);
+ this.appendValueInput("String1")
+ .setCheck(null)
+ .appendField(Blockly.Msg.AS_A_STRING);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.STARTSWITH, ".startsWith"],
+ [Blockly.Msg.ENDSWITH, ".endsWith"]
+ ]), "type");
+ this.setOutput(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip(Blockly.Msg.FIRST_AND_LAST_HELP);
+ this.setHelpUrl("https://mixly.readthedocs.io/zh-cn/latest/Arduino/AVR/05Text.html#id31");
+ }
+};
+
+//数据类型转换
+export const type_conversion = {
+ init: function () {
+ this.appendValueInput("variable")
+ .setCheck(null)
+ .appendField(Blockly.Msg.DATA_TYPE_CONVERSION)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.LANG_MATH_STRING, "String"],
+ [Blockly.Msg.LANG_MATH_CHAR, "char"],
+ [Blockly.Msg.LANG_MATH_BYTE, "byte"],
+ [Blockly.Msg.LANG_MATH_INT, "int"],
+ [Blockly.Msg.LANG_MATH_LONG, "long"],
+ [Blockly.Msg.LANG_MATH_FLOAT, "float"],
+ [Blockly.Msg.LANG_MATH_WORD, "word"]
+ ]), "type");
+ this.setOutput(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip(Blockly.Msg.TYPE_CONVERSION_HELP);
+ this.setHelpUrl("");
+ }
+};
+
+export const create_with_item = {
+ /**
+ * Mutator bolck for adding items.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);
+ this.contextMenu = false;
+ }
+};
+
+export const create_with_container = {
+ /**
+ * Mutator block for list container.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.HTML_TEXT);
+ this.appendStatementInput('STACK');
+ this.setTooltip("");
+ this.contextMenu = false;
+ }
+};
+
+export const String_indexOf = {
+ init: function () {
+ this.appendValueInput("str1")
+ .setCheck(null);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
+ this.appendValueInput("str2")
+ .setCheck(null);
+ this.appendDummyInput()
+ .setAlign(Blockly.inputs.Align.RIGHT)
+ .appendField(Blockly.Msg.SERIES_INDEX);
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setColour(160);
+ this.setTooltip();
+ this.setHelpUrl("");
+ }
+};
+
+export const text_join2 = {
+ /**
+ * Block for creating a list with any number of elements of any type.
+ * @this Blockly.Block
+ */
+ init: function () {
+ this.setColour(TEXTS_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_TEXT_JOIN + Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING);
+ this.itemCount_ = 3;
+ this.updateShape_();
+ this.setInputsInline(true);
+ this.setOutput(true, null);
+ this.setMutator(new Blockly.icons.MutatorIcon(['create_with_item'], this));
+ this.setTooltip("");
+ },
+ /**
+ * Create XML to represent list inputs.
+ * @return {Element} XML storage element.
+ * @this Blockly.Block
+ */
+ mutationToDom: function () {
+ var container = Blockly.utils.xml.createElement('mutation');
+ container.setAttribute('items', this.itemCount_);
+ return container;
+ },
+ /**
+ * Parse XML to restore the list inputs.
+ * @param {!Element} xmlElement XML storage element.
+ * @this Blockly.Block
+ */
+ domToMutation: function (xmlElement) {
+ this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
+ 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('create_with_container');
+ containerBlock.initSvg();
+ var connection = containerBlock.getInput('STACK').connection;
+ for (var i = 0; i < this.itemCount_; i++) {
+ var itemBlock = workspace.newBlock('create_with_item');
+ itemBlock.initSvg();
+ connection.connect(itemBlock.previousConnection);
+ connection = itemBlock.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 itemBlock = containerBlock.getInputTargetBlock('STACK');
+ // Count number of inputs.
+ var connections = [];
+ var i = 0;
+ while (itemBlock) {
+ connections[i] = itemBlock.valueConnection_;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ i++;
+ }
+ this.itemCount_ = i;
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 0; i < this.itemCount_; i++) {
+ if (connections[i]) {
+ this.getInput('ADD' + i).connection.connect(connections[i]);
+ }
+ }
+ },
+ /**
+ * Store pointers to any connected child blocks.
+ * @param {!Blockly.Block} containerBlock Root block in mutator.
+ * @this Blockly.Block
+ */
+ saveConnections: function (containerBlock) {
+ var itemBlock = containerBlock.getInputTargetBlock('STACK');
+ var i = 0;
+ while (itemBlock) {
+ var input = this.getInput('ADD' + i);
+ itemBlock.valueConnection_ = input && input.connection.targetConnection;
+ i++;
+ itemBlock = itemBlock.nextConnection &&
+ itemBlock.nextConnection.targetBlock();
+ }
+ },
+ /**
+ * Modify this block to have the correct number of inputs.
+ * @private
+ * @this Blockly.Block
+ */
+ updateShape_: function () {
+ // Delete everything.
+ if (this.getInput('EMPTY')) {
+ this.removeInput('EMPTY');
+ } else {
+ var i = 0;
+ while (this.getInput('ADD' + i)) {
+ this.removeInput('ADD' + i);
+ i++;
+ }
+ }
+ // Rebuild block.
+ if (this.itemCount_ == 0) {
+ this.appendDummyInput('EMPTY')
+ .appendField("无需要连接的字符串");
+ } else {
+ for (var i = 0; i < this.itemCount_; i++) {
+ var input = this.appendValueInput('ADD' + i);
+ if (i > 0) {
+ input.setAlign(Blockly.inputs.Align.RIGHT)
+ input.appendField("+");
+ }
+ }
+ }
+ }
+};
+
+//Arduinojson数据解析
+export const Arduinojson = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.ARDUINOJSON_STRING_PARSING);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldMultilineInput('const size_t capacity = JSON_ARRAY_SIZE(3) + 10;\nDynamicJsonBuffer jsonBuffer(capacity);\nconst char* json = "[\\"0\\",\\"74\\",\\"134\\"]";\nJsonArray& root = jsonBuffer.parseArray(json);\nconst char* root_0 = root[0]; // "0"\nconst char* root_1 = root[1]; // "74"\nconst char* root_2 = root[2]; // "134"'), 'VALUE');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setColour(120);
+ this.setTooltip(Blockly.Msg.ARDUINOJSON_STRING_PARSING1);
+ this.setHelpUrl("https://arduinojson.org/v5/assistant/");
+ }
+};
+
+//字符串转长整数
+export const String_to_Long_Integer = {
+ init: function () {
+ this.appendValueInput("data")
+ .setCheck(null)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING + Blockly.Msg.A_TO_B + Blockly.Msg.LANG_MATH_LONG)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MATH_HEX, "16"],
+ [Blockly.Msg.MATH_DEC, "10"],
+ [Blockly.Msg.MATH_OCT, "8"],
+ [Blockly.Msg.MATH_BIN, "2"],
+ [Blockly.Msg.blynk_IOT_AUTO, "0"]
+ ]), "type");
+ this.setOutput(true, null);
+ this.setColour(TEXTS_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://blog.csdn.net/lizhengze1117/article/details/103318662?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-10.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-10.base");
+ }
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/blocks/tools.js b/mixly/boards/default_src/arduino_avr/blocks/tools.js
new file mode 100644
index 00000000..54cb9f0f
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/blocks/tools.js
@@ -0,0 +1,160 @@
+import * as Blockly from 'blockly/core';
+
+const TOOLS_HUE = "#555555";
+const LISTS_HUE = 260;
+
+export const factory_notes = {
+ init: function () {
+ this.setColour(TOOLS_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_CONTROL_NOTES)
+ .appendField(new Blockly.FieldMultilineInput(''), 'VALUE');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ }
+};
+
+export const folding_block = {
+ init: function () {
+ this.setColour(TOOLS_HUE);
+ this.appendDummyInput()
+ .appendField(new Blockly.FieldTextInput(Blockly.Msg.FOLDING_BLOCK), "peien");
+ this.appendStatementInput('DO')
+ .appendField('');
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setTooltip(Blockly.Msg.FOLDING_BLOCK_HELP);
+ }
+};
+
+//IIC地址查找
+export const IICSCAN = {
+ init: function () {
+ this.setColour(TOOLS_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.IICSCAN);
+ this.setInputsInline(true);
+ this.setTooltip('');
+ }
+};
+
+//取模工具显示数据部分
+export const tool_modulus_show = {
+ init: function () {
+ this.setColour(LISTS_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.OLED_BITMAP_NAME)
+ .appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
+ .appendField('[')
+ .appendField(new Blockly.FieldTextInput('3'), 'x')
+ .appendField(']');
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.SAVETO + " flash")
+ .appendField(new Blockly.FieldCheckbox("true"), "save_hz");
+ this.appendValueInput("input_data");
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setTooltip("");
+ }
+};
+
+//取模工具设置部分
+export const tool_modulus = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("点阵格式")
+ .appendField(new Blockly.FieldDropdown([["阴码", "1"], ["阳码", "2"]]), "bitmap_formats")
+ .appendField(" 取模方式")
+ .appendField(new Blockly.FieldDropdown([["逐列式", "1"], ["逐行式", "2"], ["列行式", "3"], ["行列式", "4"]]), "modulus_way")
+ .appendField(" 取模走向")
+ .appendField(new Blockly.FieldDropdown([["顺向(高位在前)", "1"], ["逆向(低位在前)", "2"]]), "modulus_direction");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_TURTLE_WRITE_FONT_NAME)
+ .appendField(new Blockly.FieldDropdown([["华文黑体", "STHeiti"], ["华文楷体", "STKaiti"], ["华文细黑", "STXihei"], ["华文宋体", "STSong"], ["华文中宋", "STZhongsong"], ["华文仿宋", "STFangsong"], ["华文彩云", "STCaiyun"], ["华文琥珀", "STHupo"], ["华文隶书", "STLiti"], ["华文行楷", "STXingkai"], ["华文新魏", "STXinwei"], ["黑体", "simHei"], ["宋体", "simSun"], ["新宋体", "NSimSun"], ["仿宋", "FangSong"], ["楷体", "KaiTi"], ["仿宋_GB2312", "FangSong_GB2312"], ["楷体_GB2312", "KaiTi_GB2312"], ["隶书", "LiSu"], ["幼圆", "YouYuan"], ["新细明体", "PMingLiU"], ["细明体", "MingLiU"], ["标楷体", "DFKai-SB"], ["微软正黑体", "Microsoft JhengHei"], ["微软雅黑体", "Microsoft YaHei"]]), "hz_sharp")
+ .appendField(Blockly.Msg.MIXLY_TURTLE_WRITE_FONT_NUM)
+ .appendField(new Blockly.FieldTextInput("16"), "hz_line_height")
+ .appendField("px")
+ //.appendField("px "+Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_OFFSET+":")
+ //.appendField(new Blockly.FieldDropdown([["上移","hz_up"],["下移","hz_down"]]), "hz_up_down")
+ //.appendField(new Blockly.FieldTextInput("0"), "hz_up_down_data")
+ //.appendField("px ")
+ // .appendField(new Blockly.FieldDropdown([["左移","hz_left"],["右移","hz_right"]]), "hz_left_right")
+ //.appendField(new Blockly.FieldTextInput("0"), "hz_left_right_data")
+ //.appendField("px");
+ // this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_WIDTH)
+ .appendField(new Blockly.FieldTextInput("16"), "bitmap_width")
+ .appendField("px " + Blockly.Msg.MIXLY_HEIGHT)
+ .appendField(new Blockly.FieldTextInput("16"), "bitmap_height")
+ .appendField("px");
+ // .appendField(new Blockly.FieldCheckbox("true"), "show_hz");
+ this.appendDummyInput()
+ .appendField("输入数据")
+ .appendField(new Blockly.FieldTextInput(""), "input_data");
+ this.setInputsInline(false);
+ this.setOutput(true, null);
+ //this.setColour("#cc66cc");
+ this.setColour(180);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
+
+//获取两个日期差值
+export const get_the_number_of_days_between_the_two_dates = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.GET_THE_DIFFERENCE_BETWEEN_TWO_DATES);
+ this.appendValueInput("year_start")
+ .setCheck(null)
+ .appendField(Blockly.Msg.START + Blockly.Msg.MIXLY_GPS_DATE_YEAR);
+ this.appendValueInput("month_start")
+ .setCheck(null)
+ .appendField(Blockly.Msg.START + Blockly.Msg.MIXLY_GPS_DATE_MONTH);
+ this.appendValueInput("day_start")
+ .setCheck(null)
+ .appendField(Blockly.Msg.START + Blockly.Msg.MIXLY_GPS_DATE_DAY);
+ this.appendValueInput("year_end")
+ .setCheck(null)
+ .appendField(Blockly.Msg.END + Blockly.Msg.MIXLY_GPS_DATE_YEAR);
+ this.appendValueInput("month_end")
+ .setCheck(null)
+ .appendField(Blockly.Msg.END + Blockly.Msg.MIXLY_GPS_DATE_MONTH);
+ this.appendValueInput("day_end")
+ .setCheck(null)
+ .appendField(Blockly.Msg.END + Blockly.Msg.MIXLY_GPS_DATE_DAY);
+ this.setOutput(true, null);
+ this.setColour(TOOLS_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("https://blog.csdn.net/a_ran/article/details/43601699?utm_source=distribute.pc_relevant.none-task");
+ }
+};
+
+var esp8266_board_pin_type = [
+ ["D0", "16"],
+ ["D1", "5"],
+ ["D2", "4"],
+ ["D3", "0"],
+ ["D4", "2"],
+ ["D5", "14"],
+ ["D6", "12"],
+ ["D7", "13"],
+ ["D8", "15"],
+ ["RX", "3"],
+ ["TX", "1"],
+ ["A0", "A0"],
+ ["SD3", "10"],
+ ["SD2", "9"]
+];
+
+export const esp8266_board_pin = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField("ESP8266 GPIO")
+ .appendField(new Blockly.FieldDropdown(esp8266_board_pin_type), "pin");
+ this.setOutput(true, null);
+ this.setColour(TOOLS_HUE);
+ this.setTooltip("");
+ this.setHelpUrl("");
+ }
+};
diff --git a/mixly/boards/default_src/arduino_avr/css/color.css b/mixly/boards/default_src/arduino_avr/css/color.css
new file mode 100644
index 00000000..9bccb7c7
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/css/color.css
@@ -0,0 +1,319 @@
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(1)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/inout.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(1)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/inout2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(2)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/ctrl.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(2)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/ctrl2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(3)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/math.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(3)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/math2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(4)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/logic.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(4)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/logic2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(5)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/text.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(5)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/text2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(6)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/list.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(6)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/list2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(7)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/var.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(7)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/var2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(8)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/func.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(8)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/func2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(9)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/port.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(9)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/port2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(10)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/sensor.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(10)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/sensor2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(11)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/motor.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(11)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/motor2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(11)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/voice.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(11)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/voice2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(11)>div:nth-child(2)>div:nth-child(3)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/light.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(11)>div:nth-child(2)>div:nth-child(3)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/light2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/4Digitdisplay.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/4Digitdisplay2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第二个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/lcd.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第二个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/lcd2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第三个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(3)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/oled.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第三个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(3)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/oled2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第四个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(4)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/oled.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第四个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(4)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/oled2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第五个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(5)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/Matrix.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第五个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(12)>div:nth-child(2)>div:nth-child(5)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/Matrix2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div.blocklyTreeRow>span.blocklyTreeIcon.blocklyTreeIconNone {
+ background: url('../../../../common/media/mark/comuni.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div.blocklyTreeRow.blocklyTreeSelected>span.blocklyTreeIcon.blocklyTreeIconNone {
+ background: url('../../../../common/media/mark/comuni2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第1个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第1个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第2个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第2个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第3个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(3)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第3个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(3)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第4个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(4)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第4个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(13)>div:nth-child(2)>div:nth-child(4)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/comuni2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(14)>div.blocklyTreeRow>span.blocklyTreeIcon.blocklyTreeIconNone {
+ background: url('../../../../common/media/mark/store.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(14)>div.blocklyTreeRow.blocklyTreeSelected>span.blocklyTreeIcon.blocklyTreeIconNone {
+ background: url('../../../../common/media/mark/store2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(14)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/store.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第一个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(14)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/store2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第二个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(14)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/store.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第二个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(14)>div:nth-child(2)>div:nth-child(2)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/store2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第二个图标(未选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(15)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/blynk.png') no-repeat;
+ background-size: 100% auto;
+}
+
+/*子模块的第二个图标(选中时)*/
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(15)>div:nth-child(2)>div:nth-child(1)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/blynk2.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(17)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/factory3.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(17)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/factory4.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(18)>div.blocklyTreeRow>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/tool.png') no-repeat;
+ background-size: 100% auto;
+}
+
+div.blocklyToolboxDiv>div.blocklyToolboxContents>div:nth-child(18)>div.blocklyTreeRow.blocklyTreeSelected>div.blocklyTreeRowContentContainer>span.blocklyTreeIcon {
+ background: url('../../../../common/media/mark/tool2.png') no-repeat;
+ background-size: 100% auto;
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/export.js b/mixly/boards/default_src/arduino_avr/export.js
new file mode 100644
index 00000000..e2f4b279
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/export.js
@@ -0,0 +1,83 @@
+import ArduinoAVRPins from './pins/pins';
+
+import * as ArduinoAVRActuatorBlocks from './blocks/actuator';
+import * as ArduinoAVRBlynkBlocks from './blocks/blynk';
+import * as ArduinoAVRCommunicateBlocks from './blocks/communicate';
+import * as ArduinoAVRControlBlocks from './blocks/control';
+import * as ArduinoAVRDisplayBlocks from './blocks/display';
+import * as ArduinoAVREthernetBlocks from './blocks/ethernet';
+import * as ArduinoAVRFactoryBlocks from './blocks/factory';
+import * as ArduinoAVRInoutBlocks from './blocks/inout';
+import * as ArduinoAVRListsBlocks from './blocks/lists';
+import * as ArduinoAVRLogicBlocks from './blocks/logic';
+import * as ArduinoAVRMathBlocks from './blocks/math';
+import * as ArduinoAVRPinoutBlocks from './blocks/pinout';
+import * as ArduinoAVRPinsBlocks from './blocks/pins';
+import * as ArduinoAVRScoopBlocks from './blocks/scoop';
+import * as ArduinoAVRSensorBlocks from './blocks/sensor';
+import * as ArduinoAVRSerialBlocks from './blocks/serial';
+import * as ArduinoAVRStorageBlocks from './blocks/storage';
+import * as ArduinoAVRTextBlocks from './blocks/text';
+import * as ArduinoAVRToolsBlocks from './blocks/tools';
+
+import * as ArduinoAVRActuatorGenerators from './generators/actuator';
+import * as ArduinoAVRBlynkGenerators from './generators/blynk';
+import * as ArduinoAVRCommunicateGenerators from './generators/communicate';
+import * as ArduinoAVRControlGenerators from './generators/control';
+import * as ArduinoAVRDisplayGenerators from './generators/display';
+import * as ArduinoAVREthernetGenerators from './generators/ethernet';
+import * as ArduinoAVRFactoryGenerators from './generators/factory';
+import * as ArduinoAVRInoutGenerators from './generators/inout';
+import * as ArduinoAVRListsGenerators from './generators/lists';
+import * as ArduinoAVRLogicGenerators from './generators/logic';
+import * as ArduinoAVRMathGenerators from './generators/math';
+import * as ArduinoAVRPinoutGenerators from './generators/pinout';
+import * as ArduinoAVRPinsGenerators from './generators/pins';
+import * as ArduinoAVRScoopGenerators from './generators/scoop';
+import * as ArduinoAVRSensorGenerators from './generators/sensor';
+import * as ArduinoAVRSerialGenerators from './generators/serial';
+import * as ArduinoAVRStorageGenerators from './generators/storage';
+import * as ArduinoAVRTextGenerators from './generators/text';
+import * as ArduinoAVRToolsGenerators from './generators/tools';
+
+export {
+ ArduinoAVRPins,
+ ArduinoAVRActuatorBlocks,
+ ArduinoAVRBlynkBlocks,
+ ArduinoAVRCommunicateBlocks,
+ ArduinoAVRControlBlocks,
+ ArduinoAVRDisplayBlocks,
+ ArduinoAVREthernetBlocks,
+ ArduinoAVRFactoryBlocks,
+ ArduinoAVRInoutBlocks,
+ ArduinoAVRListsBlocks,
+ ArduinoAVRLogicBlocks,
+ ArduinoAVRMathBlocks,
+ ArduinoAVRPinoutBlocks,
+ ArduinoAVRPinsBlocks,
+ ArduinoAVRScoopBlocks,
+ ArduinoAVRSensorBlocks,
+ ArduinoAVRSerialBlocks,
+ ArduinoAVRStorageBlocks,
+ ArduinoAVRTextBlocks,
+ ArduinoAVRToolsBlocks,
+ ArduinoAVRActuatorGenerators,
+ ArduinoAVRBlynkGenerators,
+ ArduinoAVRCommunicateGenerators,
+ ArduinoAVRControlGenerators,
+ ArduinoAVRDisplayGenerators,
+ ArduinoAVREthernetGenerators,
+ ArduinoAVRFactoryGenerators,
+ ArduinoAVRInoutGenerators,
+ ArduinoAVRListsGenerators,
+ ArduinoAVRLogicGenerators,
+ ArduinoAVRMathGenerators,
+ ArduinoAVRPinoutGenerators,
+ ArduinoAVRPinsGenerators,
+ ArduinoAVRScoopGenerators,
+ ArduinoAVRSensorGenerators,
+ ArduinoAVRSerialGenerators,
+ ArduinoAVRStorageGenerators,
+ ArduinoAVRTextGenerators,
+ ArduinoAVRToolsGenerators
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/actuator.js b/mixly/boards/default_src/arduino_avr/generators/actuator.js
new file mode 100644
index 00000000..44f4397a
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/actuator.js
@@ -0,0 +1,733 @@
+import { JSFuncs } from 'mixly';
+import { Variables } from 'blockly/core';
+
+export const servo_move = function (_, generator) {
+ var dropdown_pin = this.getFieldValue('PIN');
+ var value_degree = generator.valueToCode(this, 'DEGREE', generator.ORDER_ATOMIC);
+ var delay_time = generator.valueToCode(this, 'DELAY_TIME', generator.ORDER_ATOMIC) || '0';
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Servo servo_' + dropdown_pin + ';';
+ generator.setups_['setup_servo_' + dropdown_pin] = 'servo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
+ var code = 'servo_' + dropdown_pin + '.write(' + value_degree + ');\n' + 'delay(' + delay_time + ');\n';
+ return code;
+};
+
+export const servo_writeMicroseconds = function (_, generator) {
+ var dropdown_pin = this.getFieldValue('PIN');
+ var value_degree = generator.valueToCode(this, 'DEGREE', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Servo servo_' + dropdown_pin + ';';
+ generator.setups_['setup_servo_' + dropdown_pin] = 'servo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
+ var code = 'servo_' + dropdown_pin + '.writeMicroseconds(' + value_degree + ');\n';
+ return code;
+};
+
+export const servo_read_degrees = function (_, generator) {
+ var dropdown_pin = this.getFieldValue('PIN');
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Servo servo_' + dropdown_pin + ';';
+ generator.setups_['setup_servo_' + dropdown_pin] = 'servo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
+ var code = 'servo_' + dropdown_pin + '.read()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const servo_move1 = function (_, generator) {
+ var mode = this.getFieldValue('mode');
+ var dropdown_pin = this.getFieldValue('PIN');
+ var value_degree = generator.valueToCode(this, 'DEGREE', generator.ORDER_ATOMIC);
+ var delay_time = generator.valueToCode(this, 'DELAY_TIME', generator.ORDER_ATOMIC) || '0'
+ if (mode == 0) {
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Servo servo_' + dropdown_pin + ';';
+ }
+ if (mode == 1) {
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Timer2Servo servo_' + dropdown_pin + ';';
+ }
+ generator.setups_['setup_servo_' + dropdown_pin] = 'servo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
+ var code = 'servo_' + dropdown_pin + '.write(' + value_degree + ');\n' + 'delay(' + delay_time + ');\n';
+ return code;
+};
+
+export const servo_writeMicroseconds1 = function (_, generator) {
+ var mode = this.getFieldValue('mode');
+ var dropdown_pin = this.getFieldValue('PIN');
+ var value_degree = generator.valueToCode(this, 'DEGREE', generator.ORDER_ATOMIC);
+ if (mode == 0) {
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Servo servo_' + dropdown_pin + ';';
+ }
+ if (mode == 1) {
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Timer2Servo servo_' + dropdown_pin + ';';
+ }
+ generator.setups_['setup_servo_' + dropdown_pin] = 'servo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
+ var code = 'servo_' + dropdown_pin + '.writeMicroseconds(' + value_degree + ');\n';
+ return code;
+};
+
+export const servo_read_degrees1 = function (_, generator) {
+ var mode = this.getFieldValue('mode');
+ var dropdown_pin = this.getFieldValue('PIN');
+ if (mode == 0) {
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Servo servo_' + dropdown_pin + ';';
+ }
+ if (mode == 1) {
+ generator.definitions_['include_Servo'] = '#include ';
+ generator.definitions_['var_declare_servo' + dropdown_pin] = 'Timer2Servo servo_' + dropdown_pin + ';';
+ }
+ generator.setups_['setup_servo_' + dropdown_pin] = 'servo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
+ var code = 'servo_' + dropdown_pin + '.read()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const tone_notes = function (_, generator) {
+ var code = this.getFieldValue('STAT');
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const controls_tone = function (_, generator) {
+ /*var xmlDom = Blockly.Xml.workspaceToDom(Mixly.Editor.blockEditor);
+ var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
+ if (xmlText.indexOf("type=\"ir_recv\"") == -1 && xmlText.indexOf("type=\"ir_recv_enable\"") == -1 && xmlText.indexOf("type=\"ir_recv_raw\"") == -1) {
+ this.setWarningText(null);
+ }
+ else {
+ this.setWarningText(Blockly.Msg.IR_AND_TONE_WARNING);
+ }*/
+
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var fre = generator.valueToCode(this, 'FREQUENCY',
+ generator.ORDER_ASSIGNMENT) || '0';
+ var code = "";
+ if (window.isNaN(dropdown_pin)) {
+ code = code + 'pinMode(' + dropdown_pin + ', OUTPUT);\n';
+ } else {
+ generator.setups_['setup_output_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ }
+ code += "tone(" + dropdown_pin + "," + fre + ");\n";
+ return code;
+};
+
+export const controls_notone = function (_, generator) {
+ /*var xmlDom = Blockly.Xml.workspaceToDom(Mixly.Editor.blockEditor);
+ var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
+ if (xmlText.indexOf("type=\"ir_recv\"") == -1 && xmlText.indexOf("type=\"ir_recv_enable\"") == -1 && xmlText.indexOf("type=\"ir_recv_raw\"") == -1) {
+ this.setWarningText(null);
+ }
+ else {
+ this.setWarningText(Blockly.Msg.IR_AND_TONE_WARNING);
+ }*/
+
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var code = '';
+ if (window.isNaN(dropdown_pin)) {
+ code = code + 'pinMode(' + dropdown_pin + ', OUTPUT);\n';
+ } else {
+ generator.setups_['setup_output_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ }
+ code += "noTone(" + dropdown_pin + ");\n";
+ return code;
+};
+
+// 执行器-蜂鸣器
+export const controls_tone_noTimer = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var fre = generator.valueToCode(this, 'FREQUENCY', generator.ORDER_ASSIGNMENT) || '0';
+ var dur = generator.valueToCode(this, 'DURATION', generator.ORDER_ASSIGNMENT) || '0';
+ generator.definitions_['include_NewTone'] = '#include ';
+ generator.setups_['setup_output_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ var code = "NewTone(" + dropdown_pin + "," + fre + "," + dur + ");\n";
+ return code;
+};
+
+// 执行器-蜂鸣器结束声音
+export const controls_notone_noTimer = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ generator.setups_['setup_output_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ var code = "NewNoTone(" + dropdown_pin + ");\n";
+ return code;
+};
+
+export const group_stepper_setup = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Variables.NAME_TYPE);
+ var dropdown_pin1 = generator.valueToCode(this, 'PIN1', generator.ORDER_ATOMIC);
+ var dropdown_pin2 = generator.valueToCode(this, 'PIN2', generator.ORDER_ATOMIC);
+ var steps = generator.valueToCode(this, 'steps', generator.ORDER_ATOMIC);
+ var speed = generator.valueToCode(this, 'speed', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Stepper'] = '#include ';
+ generator.definitions_['var_declare_stepper' + varName] = 'Stepper ' + varName + '(' + steps + ', ' + dropdown_pin1 + ', ' + dropdown_pin2 + ');';
+ generator.setups_['setup_stepper' + varName] = varName + '.setSpeed(' + speed + ');';
+ return '';
+};
+
+export const group_stepper_setup2 = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Variables.NAME_TYPE);
+ var dropdown_pin1 = generator.valueToCode(this, 'PIN1', generator.ORDER_ATOMIC);
+ var dropdown_pin2 = generator.valueToCode(this, 'PIN2', generator.ORDER_ATOMIC);
+ var dropdown_pin3 = generator.valueToCode(this, 'PIN3', generator.ORDER_ATOMIC);
+ var dropdown_pin4 = generator.valueToCode(this, 'PIN4', generator.ORDER_ATOMIC);
+ var steps = generator.valueToCode(this, 'steps', generator.ORDER_ATOMIC);
+ var speed = generator.valueToCode(this, 'speed', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Stepper'] = '#include ';
+ generator.definitions_['var_declare_stepper' + varName] = 'Stepper ' + varName + '(' + steps + ', ' + dropdown_pin1 + ', ' + dropdown_pin2 + ', ' + dropdown_pin3 + ', ' + dropdown_pin4 + ');';
+ generator.setups_['setup_stepper' + varName] = varName + '.setSpeed(' + speed + ');';
+ return '';
+};
+
+export const group_stepper_move = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Variables.NAME_TYPE);
+ var step = generator.valueToCode(this, 'step', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Stepper'] = '#include ';
+ return varName + '.step(' + step + ');\n';
+};
+
+export const RGB_color_seclet = function (_, generator) {
+ var colour = this.getFieldValue('COLOR');
+ colour = '0x' + colour.substring(1, colour.length);
+ return [colour, generator.ORDER_NONE];
+};
+
+export const RGB_color_rgb = function (_, generator) {
+ var R = generator.valueToCode(this, 'R', generator.ORDER_ATOMIC);
+ var G = generator.valueToCode(this, 'G', generator.ORDER_ATOMIC);
+ var B = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC);
+ var colour = "((" + R + " & 0xffffff) << 16) | ((" + G + " & 0xffffff) << 8) | " + B;
+ return [colour, generator.ORDER_NONE];
+};
+
+export const display_rgb_init = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var type = this.getFieldValue('TYPE');
+ var value_ledcount = generator.valueToCode(this, 'LEDCOUNT', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Adafruit_NeoPixel'] = '#include ';
+ generator.definitions_['var_declare_rgb_display' + dropdown_rgbpin] = 'Adafruit_NeoPixel rgb_display_' + dropdown_rgbpin + ' = Adafruit_NeoPixel(' + value_ledcount + ', ' + dropdown_rgbpin + ', ' + type + ' + NEO_KHZ800);';
+ generator.setups_['setup_rgb_display_begin_' + dropdown_rgbpin] = 'rgb_display_' + dropdown_rgbpin + '.begin();';
+ return '';
+};
+
+export const display_rgb_Brightness = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var Brightness = generator.valueToCode(this, 'Brightness', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Adafruit_NeoPixel'] = '#include ';
+ generator.setups_['setup_rgb_display_begin_' + dropdown_rgbpin] = 'rgb_display_' + dropdown_rgbpin + '.begin();';
+ var code = 'rgb_display_' + dropdown_rgbpin + '.setBrightness(' + Brightness + ');\n';
+ return code;
+};
+
+export const display_rgb = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var value_led = generator.valueToCode(this, '_LED_', generator.ORDER_ATOMIC);
+ var COLOR = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+ COLOR = COLOR.replace(/#/g, "0x");
+ var code = 'rgb_display_' + dropdown_rgbpin + '.setPixelColor(' + value_led + ' - 1, ' + COLOR + ');\n';
+ return code;
+};
+
+export const RGB_color_HSV = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var value_led = generator.valueToCode(this, '_LED_', generator.ORDER_ATOMIC);
+ var H = generator.valueToCode(this, 'H', generator.ORDER_ATOMIC);
+ var S = generator.valueToCode(this, 'S', generator.ORDER_ATOMIC);
+ var V = generator.valueToCode(this, 'V', generator.ORDER_ATOMIC);
+ var code = 'rgb_display_' + dropdown_rgbpin + '.setPixelColor(' + value_led + ' - 1, ' + 'rgb_display_' + dropdown_rgbpin + '.ColorHSV(' + H + ', ' + S + ', ' + V + '));\n';
+ return code;
+};
+
+export const display_rgb_show = function () {
+ var board_type = JSFuncs.getPlatform();
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var code = 'rgb_display_' + dropdown_rgbpin + '.show();\n';
+ if (board_type.match(RegExp(/ESP32/))) {
+ code += 'rgb_display_' + dropdown_rgbpin + '.show();\n';
+ }
+ return code;
+};
+
+export const display_rgb_rainbow1 = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var wait_time = generator.valueToCode(this, 'WAIT', generator.ORDER_ATOMIC);
+ generator.setups_['setup_rgb_display_begin_' + dropdown_rgbpin] = 'rgb_display_' + dropdown_rgbpin + '.begin();\n';
+ var funcName2 = 'Wheel';
+ var code2 = 'uint32_t Wheel(byte WheelPos) {\n'
+ + ' if(WheelPos < 85) {\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(WheelPos * 3, 255 - WheelPos * 3, 0);\n'
+ + ' } else if (WheelPos < 170) {\n'
+ + ' WheelPos -= 85;\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(255 - WheelPos * 3, 0, WheelPos * 3);\n'
+ + ' } else {\n'
+ + ' WheelPos -= 170;\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(0, WheelPos * 3, 255 - WheelPos * 3);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName2] = code2;
+ var funcName3 = 'rainbow';
+ var code3 = 'void rainbow(uint8_t wait) {\n'
+ + ' uint16_t i, j;\n'
+ + ' for(j = 0; j < 256; j++) {\n'
+ + ' for(i = 0; i < rgb_display_' + dropdown_rgbpin + '.numPixels(); i++){\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.setPixelColor(i, Wheel((i+j) & 255));\n'
+ + ' }\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.show();\n'
+ + ' delay(wait);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName3] = code3;
+ var code = 'rainbow(' + wait_time + ');\n'
+ return code;
+};
+
+export const display_rgb_rainbow2 = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var wait_time = generator.valueToCode(this, 'WAIT', generator.ORDER_ATOMIC);
+ var funcName2 = 'Wheel';
+ var code2 = 'uint32_t Wheel(byte WheelPos) {\n'
+ + ' if (WheelPos < 85) {\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(WheelPos * 3, 255 - WheelPos * 3, 0);\n'
+ + ' } else if (WheelPos < 170) {\n'
+ + ' WheelPos -= 85;\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(255 - WheelPos * 3, 0, WheelPos * 3);\n'
+ + ' } else {\n'
+ + ' WheelPos -= 170;\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(0, WheelPos * 3, 255 - WheelPos * 3);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName2] = code2;
+ var funcName3 = 'rainbow';
+ var code3 = 'void rainbow(uint8_t wait) {\n'
+ + ' uint16_t i, j;\n'
+ + ' for(j = 0; j < 256; j++){\n'
+ + ' for(i = 0; i < rgb_display_' + dropdown_rgbpin + '.numPixels(); i++) {\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.setPixelColor(i, Wheel((i+j) & 255));\n'
+ + ' }\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.show();\n'
+ + ' delay(wait);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName3] = code3;
+ var funcName4 = 'rainbowCycle';
+ var code4 = 'void rainbowCycle(uint8_t wait){\n'
+ + ' uint16_t i, j;\n'
+ + ' for(j = 0; j < 256 * 5; j++) {\n'
+ + ' for(i = 0; i < rgb_display_' + dropdown_rgbpin + '.numPixels(); i++){\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.setPixelColor(i, Wheel(((i * 256 / rgb_display_' + dropdown_rgbpin + '.numPixels()) + j) & 255));\n'
+ + ' }\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.show();\n'
+ + ' delay(wait);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName4] = code4;
+ var code = 'rainbowCycle(' + wait_time + ');\n'
+ return code;
+};
+
+export const display_rgb_rainbow3 = function (_, generator) {
+ var dropdown_rgbpin = this.getFieldValue('PIN');
+ var rainbow_color = generator.valueToCode(this, 'rainbow_color', generator.ORDER_ATOMIC);
+ var type = this.getFieldValue('TYPE');
+ var funcName2 = 'Wheel';
+ var code2 = 'uint32_t Wheel(byte WheelPos) {\n'
+ + ' if (WheelPos < 85) {\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(WheelPos * 3, 255 - WheelPos * 3, 0);\n'
+ + ' } else if (WheelPos < 170) {\n'
+ + ' WheelPos -= 85;\n'
+ + ' return rgb_display_' + dropdown_rgbpin + '.Color(255 - WheelPos * 3, 0, WheelPos * 3);\n'
+ + ' } else {\n'
+ + ' WheelPos -= 170;return rgb_display_' + dropdown_rgbpin + '.Color(0, WheelPos * 3, 255 - WheelPos * 3);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName2] = code2;
+ if (type == "normal")
+ var code3 = 'for (int RGB_RAINBOW_i = 0; RGB_RAINBOW_i < rgb_display_' + dropdown_rgbpin + '.numPixels(); RGB_RAINBOW_i++) {\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.setPixelColor(RGB_RAINBOW_i, Wheel(' + rainbow_color + ' & 255));\n'
+ + '}\n'
+ + 'rgb_display_' + dropdown_rgbpin + '.show();\n';
+ else
+ var code3 = 'for (int RGB_RAINBOW_i = 0; RGB_RAINBOW_i < rgb_display_' + dropdown_rgbpin + '.numPixels(); RGB_RAINBOW_i++) {\n'
+ + ' rgb_display_' + dropdown_rgbpin + '.setPixelColor(RGB_RAINBOW_i, Wheel(((RGB_RAINBOW_i * 256 / rgb_display_' + dropdown_rgbpin + '.numPixels()) + ' + rainbow_color + ') & 255));\n'
+ + '}\n'
+ + 'rgb_display_' + dropdown_rgbpin + '.show();\n';
+ return code3;
+};
+
+// 执行器-电机转动
+export const Mixly_motor = function (_, generator) {
+ var PIN1 = generator.valueToCode(this, 'PIN1', generator.ORDER_ATOMIC);
+ var PIN2 = generator.valueToCode(this, 'PIN2', generator.ORDER_ATOMIC);
+ var PIN_EN = generator.valueToCode(this, 'PIN_EN', generator.ORDER_ATOMIC);
+ var speed = generator.valueToCode(this, 'speed', generator.ORDER_ASSIGNMENT) || '0';
+ var code = 'setMotor(' + PIN1 + ', ' + PIN2 + ', ' + PIN_EN + ', ' + speed + ');\n';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_S'] = 'pinMode(' + PIN1 + ', OUTPUT);';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_D'] = 'pinMode(' + PIN2 + ', OUTPUT);';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_S_W'] = 'digitalWrite(' + PIN1 + ', LOW);';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_D_W'] = 'digitalWrite(' + PIN2 + ', LOW);';
+ var funcName = 'setMotor';
+ var code2 = 'void ' + funcName + '(int dirpin1, int dirpin2, int speedpin, int speed) {\n'
+ + ' digitalWrite(dirpin2, !digitalRead(dirpin1));\n'
+ + ' if (speed == 0) {\n'
+ + ' digitalWrite(dirpin1, LOW);\n'
+ + ' analogWrite(speedpin, 0);\n'
+ + ' } else if (speed > 0) {\n'
+ + ' digitalWrite(dirpin1, LOW);\n'
+ + ' analogWrite(speedpin, speed);\n'
+ + ' } else {\n'
+ + ' digitalWrite(dirpin1, HIGH);\n'
+ + ' analogWrite(speedpin, -speed);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName] = code2;
+ return code;
+};
+
+export const Motor_8833 = function (_, generator) {
+ var PIN1 = generator.valueToCode(this, 'PIN1', generator.ORDER_ATOMIC);
+ var PIN2 = generator.valueToCode(this, 'PIN2', generator.ORDER_ATOMIC);
+ var speed = generator.valueToCode(this, 'speed', generator.ORDER_ASSIGNMENT) || '0';
+ var code = 'setMotor8833(' + PIN1 + ', ' + PIN2 + ', ' + speed + ');\n';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_S'] = 'pinMode(' + PIN1 + ', OUTPUT);';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_D'] = 'pinMode(' + PIN2 + ', OUTPUT);';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_S_W'] = 'digitalWrite(' + PIN1 + ', LOW);';
+ generator.setups_['setup_output_' + PIN1 + PIN2 + '_D_W'] = 'digitalWrite(' + PIN2 + ', LOW);';
+ var funcName = 'setMotor8833';
+ var code2 = 'void ' + funcName + '(int speedpin, int dirpin, int speed) {\n'
+ + ' if (speed == 0) {\n'
+ + ' digitalWrite(dirpin, LOW);\n'
+ + ' analogWrite(speedpin, 0);\n'
+ + ' } else if (speed > 0) {\n'
+ + ' digitalWrite(dirpin, LOW);\n'
+ + ' analogWrite(speedpin, speed);\n'
+ + ' } else {\n'
+ + ' digitalWrite(dirpin, HIGH);\n'
+ + ' analogWrite(speedpin, 255 + speed);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName] = code2;
+ return code;
+};
+
+// 语音模块(68段日常用语)
+export const voice_module = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_voice = this.getFieldValue('VOICE');
+ var wait_time = generator.valueToCode(this, 'WAIT', generator.ORDER_ASSIGNMENT) || '0';
+ generator.setups_['setup_output_sda'] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ var code = 'send_data(' + dropdown_voice + '); // volume control 0xE0-E7;\n';
+ code += 'delay(' + wait_time + ');\n'
+ var code2 = 'void send_data(int addr) {\n'
+ + ' int i;\n'
+ + ' digitalWrite(' + dropdown_pin + ', LOW);\n'
+ + ' delay(3); // >2ms\n'
+ + ' for (i = 0; i < 8; i++) {\n'
+ + ' digitalWrite(' + dropdown_pin + ', HIGH);\n'
+ + ' if (addr & 1) {\n'
+ + ' delayMicroseconds(2400); // >2400us\n'
+ + ' digitalWrite(' + dropdown_pin + ', LOW);\n'
+ + ' delayMicroseconds(800);\n'
+ + ' } // >800us\n'
+ + ' else {\n'
+ + ' delayMicroseconds(800); // >800us\n'
+ + ' digitalWrite(' + dropdown_pin + ', LOW);\n'
+ + ' delayMicroseconds(2400);\n'
+ + ' } // >2400us\n'
+ + ' addr >>= 1;\n'
+ + ' }\n'
+ + ' digitalWrite(' + dropdown_pin + ', HIGH);\n'
+ + '}\n';
+ generator.definitions_['funcName'] = code2;
+ return code;
+};
+
+// gd5800 mp3 控制播放
+export const GD5800_MP3_CONTROL = function (_, generator) {
+ var rxpin = generator.valueToCode(this, 'RXPIN', generator.ORDER_ATOMIC);
+ var txpin = generator.valueToCode(this, 'TXPIN', generator.ORDER_ATOMIC);
+ var CONTROL_TYPE = this.getFieldValue('CONTROL_TYPE');
+ generator.definitions_['include_GD5800'] = '#include ';
+ generator.definitions_['var_declare_GD5800_ mp3' + rxpin + txpin] = 'GD5800_Serial mp3' + rxpin + txpin + '(' + rxpin + ', ' + txpin + ');';
+ generator.setups_['setup_ mp3' + rxpin + txpin] = 'mp3' + rxpin + txpin + '.begin(9600);';
+ var code = 'mp3' + rxpin + txpin + '.' + CONTROL_TYPE + '\n';
+ return code;
+};
+
+export const GD5800_MP3_Set_Device = function (_, generator) {
+ var rxpin = generator.valueToCode(this, 'RXPIN', generator.ORDER_ATOMIC);
+ var txpin = generator.valueToCode(this, 'TXPIN', generator.ORDER_ATOMIC);
+ var DEVICEID = this.getFieldValue('DEVICEID');
+ generator.definitions_['include_GD5800'] = '#include ';
+ generator.definitions_['var_declare_GD5800_ mp3' + rxpin + txpin] = 'GD5800_Serial mp3' + rxpin + txpin + '(' + rxpin + ', ' + txpin + ');';
+ generator.setups_['setup_ mp3' + rxpin + txpin] = 'mp3' + rxpin + txpin + '.begin(9600);';
+ var code = 'mp3' + rxpin + txpin + '.setDevice(' + DEVICEID + ');\n';
+ return code;
+
+};
+
+// gd5800 mp3 循环模式
+export const GD5800_MP3_LOOP_MODE = function (_, generator) {
+ var rxpin = generator.valueToCode(this, 'RXPIN', generator.ORDER_ATOMIC);
+ var txpin = generator.valueToCode(this, 'TXPIN', generator.ORDER_ATOMIC);
+ var LOOP_MODE = this.getFieldValue('LOOP_MODE');
+ generator.definitions_['include_GD5800'] = '#include ';
+ generator.definitions_['var_declare_GD5800_ mp3' + rxpin + txpin] = 'GD5800_Serial mp3' + rxpin + txpin + '(' + rxpin + ', ' + txpin + ');';
+ generator.setups_['setup_ mp3' + rxpin + txpin] = 'mp3' + rxpin + txpin + '.begin(9600);';
+ var code = 'mp3' + rxpin + txpin + '.setLoopMode(' + LOOP_MODE + ');\n';
+ return code;
+};
+
+// gd5800 mp3 EQ模式
+export const GD5800_MP3_EQ_MODE = function (_, generator) {
+ var rxpin = generator.valueToCode(this, 'RXPIN', generator.ORDER_ATOMIC);
+ var txpin = generator.valueToCode(this, 'TXPIN', generator.ORDER_ATOMIC);
+ var EQ_MODE = this.getFieldValue('EQ_MODE');
+ generator.definitions_['include_GD5800'] = '#include ';
+ generator.definitions_['var_declare_GD5800_ mp3' + rxpin + txpin] = 'GD5800_Serial mp3' + rxpin + txpin + '(' + rxpin + ', ' + txpin + ');';
+ generator.setups_['setup_ mp3' + rxpin + txpin] = 'mp3' + rxpin + txpin + '.begin(9600);';
+ var code = 'mp3' + rxpin + txpin + '.setEqualizer(' + EQ_MODE + ');\n';
+ return code;
+};
+
+// gd5800 mp3 设置音量
+export const GD5800_MP3_VOL = function (_, generator) {
+ var rxpin = generator.valueToCode(this, 'RXPIN', generator.ORDER_ATOMIC);
+ var txpin = generator.valueToCode(this, 'TXPIN', generator.ORDER_ATOMIC);
+ var vol = generator.valueToCode(this, 'vol', generator.ORDER_ATOMIC);
+ generator.definitions_['include_GD5800'] = '#include ';
+ generator.definitions_['var_declare_GD5800_ mp3' + rxpin + txpin] = 'GD5800_Serial mp3' + rxpin + txpin + '(' + rxpin + ', ' + txpin + ');';
+ generator.setups_['setup_ mp3' + rxpin + txpin] = 'mp3' + rxpin + txpin + '.begin(9600);';
+ var code = 'mp3' + rxpin + txpin + '.setVolume(' + vol + ');\n';
+ return code;
+};
+
+// gd5800 mp3 播放第N首
+export const GD5800_MP3_PLAY_NUM = function (_, generator) {
+ var rxpin = generator.valueToCode(this, 'RXPIN', generator.ORDER_ATOMIC);
+ var txpin = generator.valueToCode(this, 'TXPIN', generator.ORDER_ATOMIC);
+ var NUM = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ generator.definitions_['include_GD5800'] = '#include ';
+ generator.definitions_['var_declare_GD5800_ mp3' + rxpin + txpin] = 'GD5800_Serial mp3' + rxpin + txpin + '(' + rxpin + ', ' + txpin + ');';
+ generator.setups_['setup_ mp3' + rxpin + txpin] = 'mp3' + rxpin + txpin + '.begin(9600);';
+ var code = 'mp3' + rxpin + txpin + '.playFileByIndexNumber(' + NUM + ');\n';
+ return code;
+};
+
+export const AFMotorRun = function (_, generator) {
+ generator.definitions_['include_AFMotor'] = '#include ';
+ var motorNO = this.getFieldValue('motor');
+ var direction = this.getFieldValue('direction');
+ var speed = generator.valueToCode(this, 'speed', generator.ORDER_ATOMIC);
+ var code = "";
+ generator.definitions_['var_declare_motor_' + motorNO] = "AF_DCMotor" + ' motor' + motorNO + '(' + motorNO + ');';
+ code = 'motor' + motorNO + ".setSpeed(" + speed + ");\n" + 'motor' + motorNO + ".run(" + direction + ");\n";
+ return code;
+};
+
+export const AFMotorStop = function (_, generator) {
+ generator.definitions_['include_AFMotor'] = '#include ';
+ var motorNO = this.getFieldValue('motor');
+ var code = "";
+ generator.definitions_['var_declare_motor_' + motorNO] = "AF_DCMotor" + ' motor' + motorNO + '(' + motorNO + ');';
+ code = 'motor' + motorNO + ".setSpeed(0);\n" + 'motor' + motorNO + ".run(RELEASE);\n";
+ return code;
+};
+
+// 初始化DFPlayer Mini
+export const arduino_dfplayer_mini_begin = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_dfplayer_pin = generator.valueToCode(this, 'dfplayer_pin', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Arduino'] = '#include ';
+ generator.definitions_['include_DFRobotDFPlayerMini'] = '#include "DFRobotDFPlayerMini.h"';
+ generator.definitions_['var_declare_DFPlayerMini_' + text_dfplayer_name] = 'DFRobotDFPlayerMini ' + text_dfplayer_name + ';';
+ generator.setups_['setup_DFPlayerMini_' + text_dfplayer_name] = '' + text_dfplayer_name + '.begin(' + value_dfplayer_pin + ');';
+ var code = '';
+ return code;
+};
+
+// 定义DFPlayer Mini 所使用的串口类型
+export const arduino_dfplayer_mini_pin = function (_, generator) {
+ var dropdown_pin_type = this.getFieldValue('pin_type');
+ generator.definitions_['include_SoftwareSerial'] = '#include ';
+ var code = dropdown_pin_type;
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// DFPlayer Mini 设置串口通信的超时时间
+export const arduino_dfplayer_mini_setTimeOut = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_timeout_data = generator.valueToCode(this, 'timeout_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.setTimeOut(' + value_timeout_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 设置音量
+export const arduino_dfplayer_mini_volume = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_volume_data = generator.valueToCode(this, 'volume_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.volume(' + value_volume_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 音量+|-
+export const arduino_dfplayer_mini_volume_up_down = function () {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var dropdown_volume_type = this.getFieldValue('volume_type');
+ var code = '' + text_dfplayer_name + '.' + dropdown_volume_type + '();\n';
+ return code;
+};
+
+// DFPlayer Mini 设置音效
+export const arduino_dfplayer_mini_EQ = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_eq_data = generator.valueToCode(this, 'eq_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.EQ(' + value_eq_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 定义音效类型
+export const arduino_dfplayer_mini_EQ_type = function (_, generator) {
+ var dropdown_eq_type = this.getFieldValue('eq_type');
+ var code = dropdown_eq_type;
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// DFPlayer Mini 指定播放设备
+export const arduino_dfplayer_mini_outputDevice = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_outputdevice_data = generator.valueToCode(this, 'outputdevice_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.outputDevice(' + value_outputdevice_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 定义播放设备类型
+export const arduino_dfplayer_mini_outputDevice_type = function (_, generator) {
+ var dropdown_outputdevice_type = this.getFieldValue('outputdevice_type');
+ var code = dropdown_outputdevice_type;
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// DFPlayer Mini 设置-1
+export const arduino_dfplayer_set_1 = function () {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var dropdown_set_data = this.getFieldValue('set_data');
+ var code = '' + text_dfplayer_name + '.' + dropdown_set_data + '();\n';
+ return code;
+};
+
+// DFPlayer Mini 播放和循环指定曲目
+export const arduino_dfplayer_play_loop = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_play_data = generator.valueToCode(this, 'play_data', generator.ORDER_ATOMIC);
+ var dropdown_play_type = this.getFieldValue('play_type');
+ var code = '' + text_dfplayer_name + '.' + dropdown_play_type + '(' + value_play_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 播放指定文件夹下的曲目
+export const arduino_dfplayer_playFolder = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_fold_data = generator.valueToCode(this, 'fold_data', generator.ORDER_ATOMIC);
+ var dropdown_fold_type = this.getFieldValue('fold_type');
+ var value_play_data = generator.valueToCode(this, 'play_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.' + dropdown_fold_type + '(' + value_fold_data + ', ' + value_play_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 循环播放指定文件夹下的曲目
+export const arduino_dfplayer_loopFolder = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_fold_data = generator.valueToCode(this, 'fold_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.loopFolder(' + value_fold_data + ');\n';
+ return code;
+};
+
+// DFPlayer Mini 获取当前信息
+export const arduino_dfplayer_read_now = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var dropdown_read_type = this.getFieldValue('read_type');
+ var code = '' + text_dfplayer_name + '.' + dropdown_read_type + '()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// DFPlayer Mini 获取U盘|SD卡|FLASH的总文件数
+export const arduino_dfplayer_readFileCounts = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_device_type = generator.valueToCode(this, 'device_type', generator.ORDER_ATOMIC);
+ var dropdown_play_data = this.getFieldValue('play_data');
+ var code = '' + text_dfplayer_name + '.' + dropdown_play_data + '(' + value_device_type + ')';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// DFPlayer Mini 获取指定文件夹下的文件数
+export const arduino_dfplayer_readFileCountsInFolder = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var value_folder_data = generator.valueToCode(this, 'folder_data', generator.ORDER_ATOMIC);
+ var code = '' + text_dfplayer_name + '.readFileCountsInFolder(' + value_folder_data + ')';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const arduino_dfplayer_available = function (_, generator) {
+ var text_dfplayer_name = this.getFieldValue('dfplayer_name');
+ var dropdown_type = this.getFieldValue('type');
+ var code = '' + text_dfplayer_name + '.' + dropdown_type + '()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const I2Cmotor = function (_, generator) {
+ var motorNO = this.getFieldValue('motor');
+ var speed = generator.valueToCode(this, 'SPEED', generator.ORDER_ASSIGNMENT) || '0';
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_Adafruit_PWMServoDriver'] = '#include ';
+ generator.definitions_['var_declare_Adafruit_PWMServoDriver'] = 'Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();';
+ generator.setups_['setup_pwm_begin'] = 'pwm.begin();\n'
+ + 'pwm.setOscillatorFrequency(27000000);\n'
+ + 'pwm.setPWMFreq(400);\n'
+ + 'Wire.setClock(400000);';
+ var code2;
+ code2 = 'void motor(int ID, int SPEED) { // 0-7\n'
+ + ' if(SPEED > 0) {\n'
+ + ' pwm.setPin(ID * 2, 0);\n'
+ + ' pwm.setPin(ID * 2 + 1, (SPEED + 1) * 16 - 1);\n'
+ + ' } else if (SPEED == 0) {\n'
+ + ' pwm.setPin(ID * 2, 4095);\n'
+ + ' pwm.setPin(ID * 2 + 1, 4095);\n'
+ + ' } else if (SPEED < 0) {\n'
+ + ' pwm.setPin(ID * 2, 1 - (SPEED + 1) * 16);\n'
+ + ' pwm.setPin(ID * 2 + 1, 0);\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_['motor'] = code2;
+ var code = 'motor(' + motorNO + ',' + speed + ');\n';
+ return code;
+};
+
+// M9101X mp3 单线控制播放
+export const M9101X_S_MP3_CONTROL = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var CONTROL_TYPE = this.getFieldValue('CONTROL_TYPE');
+ generator.definitions_['include_N910X'] = '#include ';
+ generator.definitions_['var_declare_N910X_ mp3' + dropdown_pin] = 'N910X mp3_' + dropdown_pin + '(' + dropdown_pin + ');';
+ generator.setups_['setup_ mp3' + dropdown_pin] = 'mp3_' + dropdown_pin + '.begin();';
+ var code = 'mp3_' + dropdown_pin + '.' + CONTROL_TYPE + '\n';
+ return code;
+};
+
+// M9101X mp3 单线音量控制
+export const M9101X_S_MP3_VOL_CONTROL = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var vol = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ generator.definitions_['include_N910X'] = '#include ';
+ generator.definitions_['var_declare_N910X_ mp3' + dropdown_pin] = 'N910X mp3_' + dropdown_pin + '(' + dropdown_pin + ');';
+ generator.setups_['setup_ mp3' + dropdown_pin] = ' mp3_' + dropdown_pin + '.begin();';
+ var code = 'mp3_' + dropdown_pin + '.set_volume(' + vol + ');\n';
+ return code;
+};
+
+// M9101X mp3 单线播放第N首
+export const M9101X_S_MP3_PLAY_NUM = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ generator.definitions_['include_N910X'] = '#include ';
+ generator.definitions_['var_declare_N910X_ mp3' + dropdown_pin] = 'N910X mp3_' + dropdown_pin + '(' + dropdown_pin + ');';
+ generator.setups_['setup_ mp3' + dropdown_pin] = ' mp3_' + dropdown_pin + '.begin();';
+ var code = 'mp3_' + dropdown_pin + '.set_play_number(' + num + ');\n';
+ return code;
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/blynk.js b/mixly/boards/default_src/arduino_avr/generators/blynk.js
new file mode 100644
index 00000000..0f740777
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/blynk.js
@@ -0,0 +1,894 @@
+import { JSFuncs } from 'mixly';
+import { Variables } from 'blockly/core';
+
+// 物联网-授权码
+export const blynk_iot_auth = function () {
+ return '';
+};
+
+// 物联网-一键配网
+export const blynk_smartconfig = function (_, generator) {
+ let auth_key = generator.valueToCode(this, 'auth_key', generator.ORDER_ATOMIC);
+ let server_add = generator.valueToCode(this, 'server_add', generator.ORDER_ATOMIC);
+ if (!isNaN(server_add.charAt(2))) {
+ server_add = server_add.replace(/"/g, "").replace(/\./g, ",");
+ server_add = 'IPAddress(' + server_add + ')';
+ }
+ let board_type = JSFuncs.getPlatform();
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth_key + ';';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_smartconfig'] = 'WiFi.mode(WIFI_STA);\n'
+ + ' int cnt = 0;\n'
+ + ' while (WiFi.status() != WL_CONNECTED) {\n'
+ + ' delay(500); \n'
+ + ' Serial.print("."); \n'
+ + ' if (cnt++ >= 10) {\n'
+ + ' WiFi.beginSmartConfig();\n'
+ + ' while (1) {\n'
+ + ' delay(1000);\n'
+ + ' if (WiFi.smartConfigDone()) {\n'
+ + ' Serial.println();\n'
+ + ' Serial.println("SmartConfig: Success");\n'
+ + ' break;\n'
+ + ' }\n'
+ + ' Serial.print("|");\n'
+ + ' }\n'
+ + ' }\n'
+ + ' }\n'
+ + ' WiFi.printDiag(Serial);\n';
+ if (board_type.match(RegExp(/ESP8266/))) {
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp8266'] = '#include ';
+ }
+ else if (board_type.match(RegExp(/ESP32/))) {
+ generator.definitions_['include_WiFi'] = '#include ';
+ generator.definitions_['include_WiFiClient'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp32'] = '#include ';
+ }
+ generator.setups_['setup_smartconfig'] += 'Blynk.config(auth,' + server_add + ',8080);';
+ let code = "Blynk.run();\n";
+ return code;
+};
+
+// 物联网-wifi信息
+export const blynk_server = function (_, generator) {
+ let wifi_ssid = generator.valueToCode(this, 'wifi_ssid', generator.ORDER_ATOMIC);
+ let wifi_pass = generator.valueToCode(this, 'wifi_pass', generator.ORDER_ATOMIC);
+ let auth_key = generator.valueToCode(this, 'auth_key', generator.ORDER_ATOMIC);
+ let server_add = generator.valueToCode(this, 'server_add', generator.ORDER_ATOMIC);
+ let board_type = JSFuncs.getPlatform();
+ //let board_type ="ESP8266";
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth_key + ';';
+ generator.definitions_['var_declare_wifi_ssid'] = 'char ssid[] = ' + wifi_ssid + ';';
+ generator.definitions_['var_declare_wifi_pass'] = 'char pass[] = ' + wifi_pass + ';';
+ if (board_type.match(RegExp(/AVR/))) {
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp8266'] = '#include ';
+ generator.definitions_['define_BLYNK_PRINT'] = '#define ESP8266_BAUD 115200';
+ generator.definitions_['var_declare_ESP8266'] = 'ESP8266 wifi(&Serial);';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(115200);';
+ generator.setups_['delay_10_1'] = 'delay(10);';
+ generator.setups_['wifi.setOprToStation'] = 'wifi.setOprToStation(2, 2);';
+ generator.setups_['delay_10_2'] = 'delay(10);';
+ generator.setups_['wifi.enableMUX'] = 'wifi.enableMUX();';
+ generator.setups_['delay_10_3'] = 'delay(10);';
+ generator.setups_['setup_Blynk.begin'] = 'Blynk.begin(auth, wifi,ssid, pass,' + server_add + ',8080);';
+ }
+ if (!isNaN(server_add.charAt(2))) {
+ server_add = server_add.replace(/"/g, "").replace(/\./g, ",");
+ server_add = 'IPAddress(' + server_add + ')';
+ }
+ if (board_type.match(RegExp(/ESP8266/))) {
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp8266'] = '#include ';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = ' Blynk.begin(auth, ssid, pass,' + server_add + ',8080);';
+ }
+ else if (board_type.match(RegExp(/ESP32/))) {
+ generator.definitions_['include_WiFi'] = '#include ';
+ generator.definitions_['include_WiFiClient'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp32'] = '#include ';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = 'Blynk.begin(auth, ssid, pass,' + server_add + ',8080);';
+ }
+ let code = "Blynk.run();\n";
+ return code;
+};
+
+// 物联网-wifi信息
+export const blynk_usb_server = function (_, generator) {
+ // generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT DebugSerial';
+ generator.definitions_['include_SoftwareSerial'] = '#include ';
+ generator.definitions_['include_BlynkSimpleStream'] = '#include ';
+ generator.definitions_['var_declare_SoftwareSerial'] = 'SoftwareSerial DebugSerial(2, 3);';
+ let auth_key = generator.valueToCode(this, 'auth_key', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth_key + ';';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = 'Blynk.begin(Serial, auth);';
+ generator.setups_['setup_DebugSerial'] = 'DebugSerial.begin(9600);';
+ let code = "Blynk.run();\n";
+ return code;
+};
+
+// 物联网-发送数据到app
+export const blynk_iot_push_data = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ let code = 'Blynk.virtualWrite(' + Vpin + ', ' + data + ');\n';
+ return code;
+};
+
+// 从app接收数据
+export const blynk_iot_get_data = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'STACK');
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + this.id + '\'') + branch;
+ }
+ let args = [];
+ for (let x = 0; x < this.arguments_.length; x++) {
+ args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x], Variables.NAME_TYPE);
+ }
+ let GetDataCode = "";
+ if (this.arguments_.length == 1) {
+ GetDataCode = generator.variableDB_.getName(this.arguments_[0], Variables.NAME_TYPE);
+ if (this.argumentstype_[0] == "int")
+ GetDataCode = " " + GetDataCode + " = param.asInt();\n"
+ else if (this.argumentstype_[0] == "String")
+ GetDataCode = " " + GetDataCode + " = param.asStr();\n"
+ else if (this.argumentstype_[0] == "long")
+ GetDataCode = " " + GetDataCode + " = param.asDouble();\n"
+ else if (this.argumentstype_[0] == "float")
+ GetDataCode = " " + GetDataCode + " = param.asFloat();\n"
+ else if (this.argumentstype_[0] == "boolean")
+ GetDataCode = " " + GetDataCode + " = param.asInt();\n"
+ else if (this.argumentstype_[0] == "byte")
+ GetDataCode = " " + GetDataCode + " = param.asStr();\n"
+ else if (this.argumentstype_[0] == "char")
+ GetDataCode = " " + GetDataCode + " = param.asStr();\n"
+ }
+ else {
+ for (let x = 0; x < this.arguments_.length; x++) {
+ args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x], Variables.NAME_TYPE);
+
+ GetDataCode = GetDataCode + " " + generator.variableDB_.getName(this.arguments_[x], Variables.NAME_TYPE);
+ if (this.argumentstype_[x] == "int")
+ GetDataCode += " = param[" + x + "].asInt();\n"
+ else if (this.argumentstype_[x] == "String")
+ GetDataCode += " = param[" + x + "].asStr();\n"
+ else if (this.argumentstype_[x] == "long")
+ GetDataCode += " = param[" + x + "].asDouble();\n"
+ else if (this.argumentstype_[x] == "float")
+ GetDataCode += " = param[" + x + "].asFloat();\n"
+ else if (this.argumentstype_[x] == "boolean")
+ GetDataCode += " = param[" + x + "].asInt();\n"
+ else if (this.argumentstype_[x] == "byte")
+ GetDataCode += " = param[" + x + "].asStr();\n"
+ else if (this.argumentstype_[x] == "char")
+ GetDataCode += " = param[" + x + "].asStr();\n"
+ }
+ }
+ if (this.arguments_.length > 0)
+ generator.definitions_['var_declare_' + args] = args.join(';\n') + ";";
+ let code = 'BLYNK_WRITE(' + Vpin + ') {\n' + GetDataCode +
+ branch + '}\n';
+ // let code = 'BLYNK_WRITE(' + Vpin+ ') {\n'+letiable+" = param.as"+datatype+"();\n"+branch+'}\n';
+ code = generator.scrub_(this, code);
+ generator.definitions_[Vpin] = code;
+ return null;
+};
+
+// blynk 定时器
+export const Blynk_iot_timer = function (_, generator) {
+ generator.definitions_['var_declare_BlynkTimer'] = 'BlynkTimer timer;';
+ let timerNo = this.getFieldValue('timerNo');
+ let time = generator.valueToCode(this, 'TIME', generator.ORDER_ATOMIC);
+ let funcName = 'myTimerEvent' + timerNo;
+ let branch = generator.statementToCode(this, 'DO');
+ let code = 'void' + ' ' + funcName + '() {\n'
+ + branch
+ + '}\n';
+ generator.definitions_[funcName] = code;
+ generator.setups_[funcName] = 'timer.setInterval(' + time + 'L, ' + funcName + ');\n';
+ return "timer.run();\n";
+};
+
+// blynk 连接状态函数
+export const Blynk_iot_CONNECT_STATE = function (_, generator) {
+ let funcName = this.getFieldValue('state');
+ let branch = generator.statementToCode(this, 'DO');
+ let code = funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code;
+ return "";
+};
+
+// blynk 同步所有管脚状态
+export const Blynk_iot_BLYNK_syncAll = function () {
+ let code = 'Blynk.syncAll();\n';
+ return code;
+};
+
+// 物联网-发送数据到app
+export const blynk_iot_syncVirtual = function () {
+ let Vpin = this.getFieldValue('Vpin');
+ let code = 'Blynk.syncVirtual(' + Vpin + ');\n';
+ return code;
+};
+
+//LED组件颜色&开关
+export const blynk_iot_WidgetLED_COLOR = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let COLOR = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+ COLOR = COLOR.replace(/#/g, "").replace(/\(/g, "").replace(/\)/g, "").replace(/0x/g, '');
+ let dropdown_stat = generator.valueToCode(this, 'STAT', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_WidgetLED' + Vpin] = 'WidgetLED led' + Vpin + '(' + Vpin + ');';
+ let code = 'led' + Vpin + '.setColor("#' + COLOR + '");\n';
+ if (dropdown_stat == "HIGH")
+ code += 'led' + Vpin + '.on();\n';
+ else if (dropdown_stat == "LOW")
+ code += 'led' + Vpin + '.off();\n';
+ return code;
+};
+
+//LED组件颜色&亮度
+export const blynk_iot_WidgetLED_VALUE = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let COLOR = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+ COLOR = COLOR.replace(/#/g, "").replace(/\(/g, "").replace(/\)/g, "").replace(/0x/g, '');
+ let value_num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_WidgetLED' + Vpin] = 'WidgetLED led' + Vpin + '(' + Vpin + ');';
+ let code = 'led' + Vpin + '.setColor("#' + COLOR + '");\n';
+ code += 'led' + Vpin + '.setValue(' + value_num + ');';
+ return code;
+};
+
+// 红外控制空调
+export const blynk_iot_ir_send_ac = function (_, generator) {
+ let AC_TYPE = this.getFieldValue('AC_TYPE');
+ let AC_POWER = this.getFieldValue('AC_POWER');
+ let AC_MODE = this.getFieldValue('AC_MODE');
+ let AC_FAN = this.getFieldValue('AC_FAN');
+ let dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ let AC_TEMP = generator.valueToCode(this, 'AC_TEMP', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Arduino'] = '#ifndef UNIT_TEST\n#include \n#endif';
+ generator.definitions_['include_IRremoteESP8266'] = '#include ';
+ generator.definitions_['include_IRsend'] = '#include ';
+ generator.definitions_['include' + AC_TYPE] = '#include ';
+ generator.definitions_['define_IR_LED' + dropdown_pin] = '#define IR_LED ' + dropdown_pin;
+ generator.definitions_['IR' + AC_TYPE + 'AC'] = 'IR' + AC_TYPE + 'AC ' + AC_TYPE + 'AC(IR_LED); ';
+ generator.setups_['setup' + AC_TYPE] = AC_TYPE + 'AC.begin();';
+ let code = AC_TYPE + 'AC.setPower(' + AC_POWER + ');\n';
+ code += AC_TYPE + 'AC.setFan(' + AC_FAN + ');\n';
+ code += AC_TYPE + 'AC.setMode(' + AC_MODE + ');\n';
+ code += AC_TYPE + 'AC.setTemp(' + AC_TEMP + ');\n';
+ code += AC_TYPE + 'AC.send();\n';
+ return code;
+};
+
+// 红外接收
+export const blynk_iot_ir_recv_raw = function (_, generator) {
+ let dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ generator.definitions_['include_IRremote'] = '#ifndef UNIT_TEST\n'
+ + '#include \n'
+ + '#endif\n#include \n#include \n#include \n#if DECODE_AC\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#endif \n';
+ generator.definitions_['define_RECV_PIN' + dropdown_pin] = '#define RECV_PIN ' + dropdown_pin + '\n';
+ // generator.definitions_['define_BAUD_RATE'] = '#define BAUD_RATE 115200\n';
+ generator.definitions_['var_declare_CAPTURE_BUFFER_SIZE'] = '#define CAPTURE_BUFFER_SIZE 1024\n#if DECODE_AC\n#define TIMEOUT 50U\n#else\n#define TIMEOUT 15U \n#endif\n#define MIN_UNKNOWN_SIZE 12\n#define IN_UNKNOWN_SIZE 12\nIRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT, true);\ndecode_results results;';
+ generator.setups_['ir_recv_begin'] = 'while(!Serial)\n'
+ + ' delay(50);\n'
+ + ' #if DECODE_HASH\n'
+ + ' irrecv.setUnknownThreshold(MIN_UNKNOWN_SIZE);\n'
+ + ' #endif \n'
+ + ' irrecv.enableIRIn();';
+ let code = "if(irrecv.decode(&results)){\n"
+ + ' uint32_t now = millis();\n'
+ + ' dumpACInfo(&results);\n'
+ + ' Serial.println(resultToSourceCode(&results));\n'
+ + '}\n';
+ let funcode = 'void dumpACInfo(decode_results *results){\n'
+ + ' String description="";\n'
+ + ' #if DECODE_DAIKIN\n'
+ + ' if(results->decode_type == DAIKIN){\n'
+ + ' IRDaikinESP ac(0);\n'
+ + ' ac.setRaw(results->state);\n'
+ + ' description=ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' #if DECODE_FUJITSU_AC\n'
+ + ' if(results->decode_type==FUJITSU_AC){\n'
+ + ' IRFujitsuAC ac(0);\n'
+ + ' ac.setRaw(results->state, results->bits / 8);\n'
+ + ' description = ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' #if DECODE_KELVINATOR\n'
+ + ' if(results->decode_type == KELVINATOR){\n'
+ + ' IRKelvinatorAC ac(0);\n'
+ + ' ac.setRaw(results->state);\n'
+ + ' description = ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' #if DECODE_TOSHIBA_AC\n'
+ + ' if(results->decode_type == TOSHIBA_AC){\n'
+ + ' IRToshibaAC ac(0);\n'
+ + ' ac.setRaw(results->state);\n'
+ + ' description = ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' #if DECODE_GREE\n'
+ + ' if (results->decode_type == GREE){\n'
+ + ' IRGreeAC ac(0);\n'
+ + ' ac.setRaw(results->state);\n'
+ + ' description = ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' #if DECODE_MIDEA\n'
+ + ' if(results->decode_type == MIDEA){\n'
+ + ' IRMideaAC ac(0);\n'
+ + ' ac.setRaw(results->value);\n'
+ + ' description=ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' #if DECODE_HAIER_AC\n'
+ + ' if(results->decode_type == HAIER_AC){\n'
+ + ' IRHaierAC ac(0);\n'
+ + ' ac.setRaw(results->state);\n'
+ + ' description = ac.toString();\n'
+ + ' }\n'
+ + ' #endif\n'
+ + ' if(description != "")\n'
+ + ' Serial.println("Mesg Desc.: " + description);\n'
+ + '}\n';
+ generator.definitions_['dumpACInfo'] = funcode;
+ return code;
+};
+
+// 红外发射
+export const blynk_iot_ir_send = function (_, generator) {
+ let dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ let IR_CODE = this.getFieldValue('IR_CODE');
+ let IR_CODE_LENGTH = IR_CODE.split(',').length;
+ let random_num = Math.ceil(Math.random() * 100000);
+ generator.definitions_['define_IRremote'] = '#ifndef UNIT_TEST\n#include \n#endif\n#include \n#include \n#define IR_LED ' + dropdown_pin;
+ generator.definitions_['var_declare_IRsend_irsend'] = 'IRsend irsend(IR_LED);\n';
+ generator.definitions_['var_declare_send' + random_num] = 'uint16_t rawData' + random_num + '[' + IR_CODE_LENGTH + '] = {' + IR_CODE + '};';
+ // generator.setups_['Serial.begin'] = 'irsend.begin();\n Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);\n';
+ generator.setups_['irsend_begin'] = 'irsend.begin();\n';
+ let code = 'irsend.sendRaw(rawData' + random_num + ', ' + IR_CODE_LENGTH + ', 38);\ndelay(2000);\n';
+ return code;
+}
+
+// 发送邮件
+export const blynk_email = function (_, generator) {
+ let email_add = generator.valueToCode(this, 'email_add', generator.ORDER_ATOMIC);
+ let Subject = generator.valueToCode(this, 'Subject', generator.ORDER_ATOMIC);
+ let content = generator.valueToCode(this, 'content', generator.ORDER_ATOMIC);
+ generator.definitions_['define_BLYNK_MAX_SENDBYTES'] = '#define BLYNK_MAX_SENDBYTES 128 \n';
+ let code = 'Blynk.email(' + email_add + ', ' + Subject + ', ' + content + ');\n';
+ return code;
+};
+
+// 发送通知
+export const blynk_notify = function (_, generator) {
+ let content = generator.valueToCode(this, 'content', generator.ORDER_ATOMIC);
+ let code = 'Blynk.notify(' + content + ');\n';
+ return code;
+};
+
+// 物联网-终端组件显示文本
+export const blynk_terminal = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ generator.definitions_['var_declare_WidgetTerminal' + Vpin] = 'WidgetTerminal terminal' + Vpin + '(' + Vpin + ');\n';
+ let content = generator.valueToCode(this, 'content', generator.ORDER_ATOMIC);
+ let code = 'terminal' + Vpin + '.println(' + content + ');\nterminal' + Vpin + '.flush();\n';
+ return code;
+};
+
+// 从终端获取字符串
+export const blynk_iot_terminal_get = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ generator.definitions_['var_declare_WidgetTerminal'] = 'WidgetTerminal terminal(' + Vpin + ');\n';
+ generator.definitions_['var_declare_action'] = 'String terminal_text ;';
+ let branch = generator.statementToCode(this, 'DO');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格s
+ let code = 'BLYNK_WRITE' + '(' + Vpin + '){\n'
+ + ' terminal_text = param.asStr();\n'
+ + ' ' + branch + '\n'
+ + ' terminal.flush();\n'
+ + '}\n'
+ generator.definitions_[Vpin] = code;
+ return null;
+};
+
+// 视频流
+export const blynk_videourl = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let url = generator.valueToCode(this, 'url', generator.ORDER_ATOMIC);
+ let code = 'Blynk.setProperty(' + Vpin + ',"url",' + url + ');\n';
+ return code;
+};
+
+// 桥接授权码
+export const blynk_bridge_auth = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let auth = generator.valueToCode(this, 'auth', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_WidgetBridge' + Vpin] = 'WidgetBridge bridge' + Vpin + '(' + Vpin + ');\n';
+ let code = 'bridge' + Vpin + '.setAuthToken(' + auth + ');\n';
+ return code;
+};
+
+// 桥接数字输出
+export const blynk_bridge_digitalWrite = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ let dropdown_stat = generator.valueToCode(this, 'STAT', generator.ORDER_ATOMIC);
+ let code = 'bridge' + Vpin + '.digitalWrite(' + dropdown_pin + ', ' + dropdown_stat + ');\n';
+ return code;
+};
+
+// 桥接模拟输出
+export const blynk_bridge_AnaloglWrite = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ let value_num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ let code = 'bridge' + Vpin + '.analogWrite(' + dropdown_pin + ', ' + value_num + ');\n';
+ return code;
+};
+
+// 桥接虚拟管脚
+export const blynk_bridge_VPin = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let Vpin2 = this.getFieldValue('Vpin2');
+ let value_num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ let code = 'bridge' + Vpin + '.virtualWrite(' + Vpin2 + ', ' + value_num + ');\n';
+ return code;
+};
+
+// RTC组件初始化
+export const blynk_WidgetRTC_init = function (_, generator) {
+ generator.definitions_['include_TimeLib'] = '#include ';
+ generator.definitions_['include_WidgetRTC'] = '#include ';
+ let value_num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_WidgetRTC'] = 'WidgetRTC rtc;\n';
+ generator.setups_['setSyncInterval'] = 'setSyncInterval(' + value_num + '* 60);';
+ let code = 'rtc.begin();\n';
+ return code;
+};
+
+// RTC获取时间
+export const blynk_WidgetRTC_get_time = function (_, generator) {
+ let timeType = this.getFieldValue('TIME_TYPE');
+ let code = timeType + '()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// 播放音乐组件
+export const blynk_iot_playmusic = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'DO');
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + this.id + '\'') + branch;
+ }
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格
+ let code = 'BLYNK_WRITE(' + Vpin + '){\n'
+ + ' action = param.asStr();\n'
+ + ' ' + branch + '\n'
+ + ' Blynk.setProperty(' + Vpin + ', "label", action);\n'
+ + '}\n';
+ code = generator.scrub_(this, code);
+ generator.definitions_[Vpin] = code;
+ return "";
+};
+
+// 光线传感器
+export const blynk_light = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'DO');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格
+ let code = 'BLYNK_WRITE' + '(' + Vpin + '){\n'
+ + ' int lx = param.asInt();\n'
+ + ' ' + branch + '\n'
+ + '}\n';
+ generator.definitions_[Vpin] = code;
+ return "";
+};
+
+// 重力传感器
+export const blynk_gravity = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'DO');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格
+ let code = 'BLYNK_WRITE' + '(' + Vpin + '){\n'
+ + ' int x = param[0].asFloat();\n'
+ + ' int y = param[1].asFloat();\n'
+ + ' int z = param[2].asFloat();\n'
+ + ' ' + branch + '\n'
+ + '}\n';
+ generator.definitions_[Vpin] = code;
+ return "";
+};
+
+// 加速度传感器
+export const blynk_acc = blynk_gravity;
+
+// 时间输入
+export const blynk_time_input_1 = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'DO');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格
+ let code = 'BLYNK_WRITE' + '(' + Vpin + '){\n'
+ + ' long startTimeInSecs = param[0].asLong();\n'
+ + ' long hour =startTimeInSecs/3600;\n'
+ + ' long minute=(startTimeInSecs-3600*hour)/60;\n'
+ + ' long second=(startTimeInSecs-3600*hour)%60;\n'
+ + ' ' + branch + '\n'
+ + '}\n';
+ generator.definitions_[Vpin] = code;
+ return "";
+};
+
+// 执行器-蜂鸣器频率选择列表
+export const tone_notes = function (_, generator) {
+ let code = this.getFieldValue('STAT');
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const factory_declare2 = function (_, generator) {
+ let VALUE = this.getFieldValue('VALUE');
+ generator.definitions_['var_' + VALUE] = VALUE;
+ return '';
+};
+
+// 一键配网(无需安可信)
+export const blynk_AP_config = function (_, generator) {
+ let server_add = generator.valueToCode(this, 'server_add', generator.ORDER_ATOMIC);
+ let auth_key = generator.valueToCode(this, 'auth_key', generator.ORDER_ATOMIC);
+ let board_type = JSFuncs.getPlatform();
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ if (board_type.match(RegExp(/ESP8266/))) {
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp8266'] = '#include ';
+ }
+ else if (board_type.match(RegExp(/ESP32/))) {
+ generator.definitions_['include_WiFi'] = '#include ';
+ generator.definitions_['include_WiFiClient'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp32'] = '#include ';
+ }
+ generator.definitions_['include_DNSServer'] = '#include ';
+ generator.definitions_['include_ESP8266WebServer'] = '#include \n';
+ generator.definitions_['include_WiFiManager'] = '#include ';
+ generator.definitions_['var_declare_WiFiServer'] = 'WiFiServer server(80);';
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth_key + ';';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_WiFiManager'] = 'WiFiManager wifiManager;';
+ generator.setups_['setup_wifiManagerautoConnect'] = 'wifiManager.autoConnect("Blynk");';
+ generator.setups_['setup_server.begin'] = 'Serial.println("Connected.");\n server.begin();';
+ if (isNaN(server_add.charAt(2))) {
+ generator.setups_['setup_Blynkconfig'] = 'Blynk.config(auth, ' + server_add + ', 8080);';
+ }
+ else {
+ server_add = server_add.replace(/"/g, "").replace(/\./g, ",");
+ generator.setups_['setup_Blynkconfig'] = 'Blynk.config(auth, ' + 'IPAddress(' + server_add + '), 8080);';
+ }
+ let code = 'Blynk.run();';
+ return code;
+};
+
+// 一键配网手动配置授权码(无需安可信)
+export const blynk_AP_config_2 = function (_, generator) {
+ let server_add = generator.valueToCode(this, 'server_add', generator.ORDER_ATOMIC);
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['include_FS'] = '#include ';
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp8266'] = '#include ';
+ generator.definitions_['include_DNSServer'] = '#include ';
+ generator.definitions_['include_ESP8266WebServer'] = '#include ';
+ generator.definitions_['include_WiFiManager'] = '#include ';
+ generator.definitions_['include_ArduinoJson'] = '#include ';
+ generator.definitions_['var_declare_auth_key'] = 'char blynk_token[34] = "YOUR_BLYNK_TOKEN";';
+ generator.definitions_['var_declare_shouldSaveConfig'] = 'bool shouldSaveConfig = false;';
+ generator.definitions_['saveConfigCallback'] = 'void saveConfigCallback (){\n'
+ + ' Serial.println("Should save config");\n'
+ + ' shouldSaveConfig = true;\n'
+ + '}';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['otasetup1'] = 'Serial.println("mounting FS...");\n'
+ + ' if (SPIFFS.begin()){\n'
+ + ' Serial.println("mounted file system");\n'
+ + ' if (SPIFFS.exists("/config.json")) {\n'
+ + ' Serial.println("reading config file");\n'
+ + ' File configFile = SPIFFS.open("/config.json", "r");\n'
+ + ' if (configFile) {\n'
+ + ' Serial.println("opened config file");\n'
+ + ' size_t size = configFile.size();\n'
+ + ' std::unique_ptr buf(new char[size]);\n'
+ + ' configFile.readBytes(buf.get(), size);\n'
+ + ' DynamicJsonBuffer jsonBuffer;\n'
+ + ' JsonObject& json = jsonBuffer.parseObject(buf.get());\n'
+ + ' json.printTo(Serial);\n'
+ + ' if (json.success()){\n'
+ + ' Serial.println("parsed json");\n'
+ + ' strcpy(blynk_token, json["blynk_token"]);\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' Serial.println("failed to load json config");\n'
+ + ' }\n'
+ + ' configFile.close();\n'
+ + ' }\n'
+ + ' }\n'
+ + ' }'
+ + ' else{\n'
+ + ' Serial.println("failed to mount FS");\n'
+ + ' }\n'
+ + ' WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32);\n'
+ + ' WiFiManager wifiManager;\n'
+ + ' wifiManager.setSaveConfigCallback(saveConfigCallback);\n'
+ + ' wifiManager.addParameter(&custom_blynk_token);\n'
+ + ' wifiManager.setMinimumSignalQuality(10);\n'
+ + ' if (!wifiManager.autoConnect()){\n'
+ + ' Serial.println("failed to connect and hit timeout");\n'
+ + ' delay(3000);\n'
+ + ' ESP.reset();\n'
+ + ' delay(5000);\n'
+ + ' }\n'
+ + ' Serial.println("connected...yeey :)");\n'
+ + ' strcpy(blynk_token, custom_blynk_token.getValue());\n'
+ + ' if(shouldSaveConfig){\n'
+ + ' Serial.println("saving config");\n'
+ + ' DynamicJsonBuffer jsonBuffer;\n'
+ + ' JsonObject& json = jsonBuffer.createObject();\n'
+ + ' json["blynk_token"] = blynk_token;\n'
+ + ' File configFile = SPIFFS.open("/config.json", "w");\n'
+ + ' if(!configFile){\n'
+ + ' Serial.println("failed to open config file for writing");\n'
+ + ' }\n'
+ + ' json.printTo(Serial);\n'
+ + ' json.printTo(configFile);\n'
+ + ' configFile.close();\n'
+ + ' }\n'
+ + ' Serial.println("local ip");\n'
+ + ' Serial.println(WiFi.localIP());\n';
+ if (isNaN(server_add.charAt(2))) {
+ generator.setups_['otasetup1'] += ' Blynk.config(blynk_token,' + server_add + ',8080);';
+ }
+ else {
+ server_add = server_add.replace(/"/g, "").replace(/\./g, ",");
+ generator.setups_['otasetup1'] += ' Blynk.config(blynk_token,' + 'IPAddress(' + server_add + '),8080);';
+ }
+ let code = 'Blynk.run();\n';
+ return code;
+};
+
+export const Blynk_connect_state = function (_, generator) {
+ let code = 'Blynk.connected()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// Blynk终端清屏
+export const blynk_terminal_clear = function () {
+ let code = 'terminal.clear();\n';
+ return code;
+};
+
+// Blynk LCD显示
+export const blynk_lcd = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let x = generator.valueToCode(this, 'x', generator.ORDER_ATOMIC);
+ let y = generator.valueToCode(this, 'y', generator.ORDER_ATOMIC);
+ let value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC);
+ generator.definitions_['include_lcd'] = 'WidgetLCD lcd(' + Vpin + ');\n';
+ let code = 'lcd.print(' + x + ', ' + y + ', ' + value + ');\n';
+ return code;
+};
+
+// Blynk LCD清屏
+export const blynk_lcd_clear = function () {
+ let code = 'lcd.clear();\n';
+ return code;
+};
+
+// ESP32 blynk BLE连接方式
+export const blynk_esp32_ble = function (_, generator) {
+ let auth = generator.valueToCode(this, 'auth', generator.ORDER_ATOMIC);
+ let name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['define_BLYNK_USE_DIRECT_CONNECT'] = '#define BLYNK_USE_DIRECT_CONNECT';
+ generator.definitions_['include_BlynkSimpleEsp32_BLE'] = '#include ';
+ generator.definitions_['include_BLEDevice'] = '#include ';
+ generator.definitions_['include_BLEServer'] = '#include \n';
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth + ';';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = 'Serial.println("Waiting for connections...");\n'
+ + ' Blynk.setDeviceName(' + name + ');\n'
+ + ' Blynk.begin(auth);\n';
+ let code = 'Blynk.run();\n';
+ return code;
+};
+
+// ESP32 blynk Bluetooth连接方式
+export const blynk_esp32_Bluetooth = function (_, generator) {
+ let auth = generator.valueToCode(this, 'auth', generator.ORDER_ATOMIC);
+ let name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['define_BLYNK_USE_DIRECT_CONNECT'] = '#define BLYNK_USE_DIRECT_CONNECT';
+ generator.definitions_['include_BlynkSimpleEsp32_BT'] = '#include \n';
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth + ';';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = 'Serial.println("Waiting for connections...");\n'
+ + ' Blynk.setDeviceName(' + name + ');\n'
+ + ' Blynk.begin(auth);\n';
+ let code = 'Blynk.run();\n';
+ return code;
+};
+
+// Arduino blynk Bluetooth 连接方式
+export const arduino_blynk_bluetooth = function (_, generator) {
+ let auth = generator.valueToCode(this, 'auth', generator.ORDER_ATOMIC);
+ let RX = generator.valueToCode(this, 'RX', generator.ORDER_ATOMIC);
+ let TX = generator.valueToCode(this, 'TX', generator.ORDER_ATOMIC);
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['include_SoftwareSerial'] = '#include ';
+ generator.definitions_['include_BlynkSimpleSerialBLE'] = '#include ';
+ generator.definitions_['define_auth'] = 'char auth[] = ' + auth + ';';
+ if (RX != 0 || TX != 1) {
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.definitions_['var_declare_SoftwareSerial'] = 'SoftwareSerial SerialBLE(' + RX + ', ' + TX + ');';
+ generator.setups_['setup_SerialBLE_begin'] = 'SerialBLE.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = 'Blynk.begin(SerialBLE, auth);';
+ }
+ else {
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_Blynk.begin'] = 'Blynk.begin(Serial, auth);';
+ }
+ generator.setups_['setup_Serial.println'] = 'Serial.println("Waiting for connections...");';
+ let code = 'Blynk.run();\n';
+ return code;
+};
+
+// Blynk Table小部件添加数据
+export const blynk_table = function (_, generator) {
+ let id = generator.valueToCode(this, 'id', generator.ORDER_ATOMIC);
+ let mingcheng = generator.valueToCode(this, 'mingcheng', generator.ORDER_ATOMIC);
+ let shujv = generator.valueToCode(this, 'shujv', generator.ORDER_ATOMIC);
+ let Vpin = this.getFieldValue('Vpin');
+ let code = 'Blynk.virtualWrite(' + Vpin + ', "add", ' + id + ',' + mingcheng + ', ' + shujv + ');\n';
+ return code;
+};
+
+// Blynk Table小部件更新数据
+export const blynk_table_update = function (_, generator) {
+ let id = generator.valueToCode(this, 'id', generator.ORDER_ATOMIC);
+ let mingcheng = generator.valueToCode(this, 'mingcheng', generator.ORDER_ATOMIC);
+ let shujv = generator.valueToCode(this, 'shujv', generator.ORDER_ATOMIC);
+ let Vpin = this.getFieldValue('Vpin');
+ let code = 'Blynk.virtualWrite(' + Vpin + ', "update", ' + id + ',' + mingcheng + ', ' + shujv + ');\n';
+ return code;
+};
+
+// Blynk Table小部件高亮显示数据
+export const blynk_table_highlight = function (_, generator) {
+ let id = generator.valueToCode(this, 'id', generator.ORDER_ATOMIC);
+ let Vpin = this.getFieldValue('Vpin');
+ let code = 'Blynk.virtualWrite(' + Vpin + ', "pick", ' + id + ');\n';
+ return code;
+};
+
+// Blynk Table小部件选择数据
+export const blynk_table_select = function (_, generator) {
+ let id = generator.valueToCode(this, 'id', generator.ORDER_ATOMIC);
+ let Vpin = this.getFieldValue('Vpin');
+ let code = 'Blynk.virtualWrite(' + Vpin + ', "select", ' + id + ');\n';
+ return code;
+};
+
+// Blynk Table小部件取消选择数据
+export const blynk_table_unselect = function (_, generator) {
+ let id = generator.valueToCode(this, 'id', generator.ORDER_ATOMIC);
+ let Vpin = this.getFieldValue('Vpin');
+ let code = 'Blynk.virtualWrite(' + Vpin + ', "deselect", ' + id + ');\n';
+ return code;
+};
+
+// Blynk Table小部件数据清除
+export const blynk_table_cleardata = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ generator.definitions_["rowIndex_" + Vpin] = 'int rowIndex_' + Vpin + ' = 0;\n';
+ let code = 'Blynk.virtualWrite(' + Vpin + ', "clr");\nrowIndex_' + Vpin + ' = 0;\n';
+ return code;
+};
+
+// blynk服务器连接状态
+export const blynk_connected = function (_, generator) {
+ let code = 'Blynk.connected()';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// ESP32 CAM相机
+export const esp_camera = function (_, generator) {
+ let wifi_ssid = generator.valueToCode(this, 'wifi_ssid', generator.ORDER_ATOMIC);
+ let wifi_pass = generator.valueToCode(this, 'wifi_pass', generator.ORDER_ATOMIC);
+ let mode = this.getFieldValue('mode');
+ let code = "";
+ if (mode > 0) {
+ code = 'WiFi.begin(wif_ssid,wif_password);\n'
+ + ' while (WiFi.status() != WL_CONNECTED){\n'
+ + ' delay(500);\n'
+ + ' Serial.print(".");\n'
+ + ' }\n'
+ + ' Serial.println("");\n'
+ + ' Serial.println("WiFi connected");\n'
+ + ' Serial.print("Camera Stream Ready! Go to: http://");\n'
+ + ' Serial.print(WiFi.localIP());\n'
+ + ' Serial.println("");\n';
+ } else {
+ code = 'Serial.print("Setting AP (Access Point)…");\n'
+ + 'WiFi.softAP(wif_ssid,wif_password);\n'
+ + 'IPAddress IP = WiFi.softAPIP();\n'
+ + 'Serial.print("Camera Stream Ready! Connect to the ESP32 AP and go to: http://");\n'
+ + 'Serial.println(IP);\n'
+ + 'Serial.println("");\n';
+ }
+ generator.definitions_['esp_camera'] = '#include "esp_camera.h"\n#include \n#include "esp_timer.h"\n#include "img_converters.h"\n#include \n#include "fb_gfx.h"\n#include "soc/soc.h"\n#include "soc/rtc_cntl_reg.h"\n#include "dl_lib.h"\n#include "esp_http_server.h"\nconst char*wif_ssid = ' + wifi_ssid + ';\nconst char*wif_password = ' + wifi_pass + ';\n#define PART_BOUNDARY "123456789000000000000987654321"\n#define PWDN_GPIO_NUM 32\n#define RESET_GPIO_NUM -1\n#define XCLK_GPIO_NUM 0\n#define SIOD_GPIO_NUM 26\n#define SIOC_GPIO_NUM 27\n#define Y9_GPIO_NUM 35\n#define Y8_GPIO_NUM 34\n#define Y7_GPIO_NUM 39\n#define Y6_GPIO_NUM 36\n#define Y5_GPIO_NUM 21\n#define Y4_GPIO_NUM 19\n#define Y3_GPIO_NUM 18\n#define Y2_GPIO_NUM 5\n#define VSYNC_GPIO_NUM 25\n#define HREF_GPIO_NUM 23\n#define PCLK_GPIO_NUM 22\nstatic const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;\nstatic const char* _STREAM_BOUNDARY = "\\r\\n--" PART_BOUNDARY "\\r\\n";\nstatic const char* _STREAM_PART = "Content-Type: image/jpeg\\r\\nContent-Length: %u\\r\\n\\r\\n";\nhttpd_handle_t stream_httpd = NULL;\nstatic esp_err_t stream_handler(httpd_req_t *req){\n camera_fb_t * fb = NULL;\n esp_err_t res = ESP_OK;\n size_t _jpg_buf_len = 0;\n uint8_t * _jpg_buf = NULL;\n char * part_buf[64];\n res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);\n if(res != ESP_OK){\n return res;\n }\n while(true){\n fb = esp_camera_fb_get();\n if (!fb) {\n Serial.println("Camera capture failed");\n res = ESP_FAIL;\n } else {\n if(fb->width > 400){\n if(fb->format != PIXFORMAT_JPEG){\n bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);\n esp_camera_fb_return(fb);\n fb = NULL;\n if(!jpeg_converted){\n Serial.println("JPEG compression failed");\n res = ESP_FAIL;\n }\n } else {\n _jpg_buf_len = fb->len;\n _jpg_buf = fb->buf;\n }\n }\n }\n if(res == ESP_OK){\n size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);\n res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);\n }\n if(res == ESP_OK){\n res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);\n }\n if(res == ESP_OK){\n res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));\n }\n if(fb){\n esp_camera_fb_return(fb);\n fb = NULL;\n _jpg_buf = NULL;\n } else if(_jpg_buf){\n free(_jpg_buf);\n _jpg_buf = NULL;\n }\n if(res != ESP_OK){\n break;\n }\n }\n return res;\n}\nvoid startCameraServer(){\n httpd_config_t config = HTTPD_DEFAULT_CONFIG();\n config.server_port = 80;\n httpd_uri_t index_uri = {\n .uri = "/",\n .method = HTTP_GET,\n .handler = stream_handler,\n .user_ctx = NULL\n };\n if (httpd_start(&stream_httpd, &config) == ESP_OK) {\n httpd_register_uri_handler(stream_httpd, &index_uri);\n } \n}\n';
+ generator.setups_['setups_esp_camera'] = ' WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);\n Serial.begin(115200);\n Serial.setDebugOutput(false);\n camera_config_t config;\n config.ledc_channel = LEDC_CHANNEL_0;\n config.ledc_timer = LEDC_TIMER_0;\n config.pin_d0 = Y2_GPIO_NUM;\n config.pin_d1 = Y3_GPIO_NUM;\n config.pin_d2 = Y4_GPIO_NUM;\n config.pin_d3 = Y5_GPIO_NUM;\n config.pin_d4 = Y6_GPIO_NUM;\n config.pin_d5 = Y7_GPIO_NUM;\n config.pin_d6 = Y8_GPIO_NUM;\n config.pin_d7 = Y9_GPIO_NUM;\n config.pin_xclk = XCLK_GPIO_NUM;\n config.pin_pclk = PCLK_GPIO_NUM;\n config.pin_vsync = VSYNC_GPIO_NUM;\n config.pin_href = HREF_GPIO_NUM;\n config.pin_sscb_sda = SIOD_GPIO_NUM;\n config.pin_sscb_scl = SIOC_GPIO_NUM;\n config.pin_pwdn = PWDN_GPIO_NUM;\n config.pin_reset = RESET_GPIO_NUM;\n config.xclk_freq_hz = 20000000;\n config.pixel_format = PIXFORMAT_JPEG; \n if(psramFound()){\n config.frame_size = FRAMESIZE_UXGA;\n config.jpeg_quality = 10;\n config.fb_count = 2;\n } else {\n config.frame_size = FRAMESIZE_SVGA;\n config.jpeg_quality = 12;\n config.fb_count = 1;\n }\n esp_err_t err = esp_camera_init(&config);\n if (err != ESP_OK) {\n Serial.printf("Camera init failed with error 0x%x", err);\n return;\n }\n ' + code + ' startCameraServer();\n';
+ return 'delay(1);\n';
+};
+
+// ESP32 CAM相机 & blynk
+export const esp_camera_blynk = function (_, generator) {
+ let wifi_ssid = generator.valueToCode(this, 'wifi_ssid', generator.ORDER_ATOMIC);
+ let wifi_pass = generator.valueToCode(this, 'wifi_pass', generator.ORDER_ATOMIC);
+ let server_add = generator.valueToCode(this, 'server', generator.ORDER_ATOMIC);
+ if (!isNaN(server_add.charAt(2))) {
+ server_add = server_add.replace(/"/g, "").replace(/\./g, ",");
+ server_add = 'IPAddress(' + server_add + ')';
+ }
+ let auth = generator.valueToCode(this, 'auth', generator.ORDER_ATOMIC);
+ generator.definitions_['define_BLYNK_PRINT'] = '#define BLYNK_PRINT Serial';
+ generator.definitions_['include_WiFi'] = '#include ';
+ generator.definitions_['include_BlynkSimpleEsp32'] = '#include ';
+ generator.definitions_['include_WidgetRTC'] = '#include ';
+ generator.definitions_['include_WiFiClient'] = '#include ';
+ generator.definitions_['include_TimeLib'] = '#include ';
+ generator.definitions_['var_declare_auth_key'] = 'char auth[] = ' + auth + ';';
+
+ generator.definitions_['esp_camera'] = '#include "esp_camera.h"\n#include "esp_timer.h"\n#include "img_converters.h"\n#include \n#include "fb_gfx.h"\n#include "soc/soc.h"\n#include "soc/rtc_cntl_reg.h"\n#include "dl_lib.h"\n#include "esp_http_server.h"\nconst char*wif_ssid = ' + wifi_ssid + ';\nconst char*wif_password = ' + wifi_pass + ';\n#define PART_BOUNDARY "123456789000000000000987654321"\n#define PWDN_GPIO_NUM 32\n#define RESET_GPIO_NUM -1\n#define XCLK_GPIO_NUM 0\n#define SIOD_GPIO_NUM 26\n#define SIOC_GPIO_NUM 27\n#define Y9_GPIO_NUM 35\n#define Y8_GPIO_NUM 34\n#define Y7_GPIO_NUM 39\n#define Y6_GPIO_NUM 36\n#define Y5_GPIO_NUM 21\n#define Y4_GPIO_NUM 19\n#define Y3_GPIO_NUM 18\n#define Y2_GPIO_NUM 5\n#define VSYNC_GPIO_NUM 25\n#define HREF_GPIO_NUM 23\n#define PCLK_GPIO_NUM 22\nstatic const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;\nstatic const char* _STREAM_BOUNDARY = "\\r\\n--" PART_BOUNDARY "\\r\\n";\nstatic const char* _STREAM_PART = "Content-Type: image/jpeg\\r\\nContent-Length: %u\\r\\n\\r\\n";\nhttpd_handle_t stream_httpd = NULL;\nstatic esp_err_t stream_handler(httpd_req_t *req){\n camera_fb_t * fb = NULL;\n esp_err_t res = ESP_OK;\n size_t _jpg_buf_len = 0;\n uint8_t * _jpg_buf = NULL;\n char * part_buf[64];\n res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);\n if(res != ESP_OK){\n return res;\n }\n while(true){\n fb = esp_camera_fb_get();\n if (!fb) {\n Serial.println("Camera capture failed");\n res = ESP_FAIL;\n } else {\n if(fb->width > 400){\n if(fb->format != PIXFORMAT_JPEG){\n bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);\n esp_camera_fb_return(fb);\n fb = NULL;\n if(!jpeg_converted){\n Serial.println("JPEG compression failed");\n res = ESP_FAIL;\n }\n } else {\n _jpg_buf_len = fb->len;\n _jpg_buf = fb->buf;\n }\n }\n }\n if(res == ESP_OK){\n size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);\n res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);\n }\n if(res == ESP_OK){\n res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);\n }\n if(res == ESP_OK){\n res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));\n }\n if(fb){\n esp_camera_fb_return(fb);\n fb = NULL;\n _jpg_buf = NULL;\n } else if(_jpg_buf){\n free(_jpg_buf);\n _jpg_buf = NULL;\n }\n if(res != ESP_OK){\n break;\n }\n }\n return res;\n}\nvoid startCameraServer(){\n httpd_config_t config = HTTPD_DEFAULT_CONFIG();\n config.server_port = 80;\n httpd_uri_t index_uri = {\n .uri = "/",\n .method = HTTP_GET,\n .handler = stream_handler,\n .user_ctx = NULL\n };\n if (httpd_start(&stream_httpd, &config) == ESP_OK) {\n httpd_register_uri_handler(stream_httpd, &index_uri);\n } \n}\n';
+ generator.setups_['setups_esp_camera'] = 'WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);\n Serial.begin(115200);\n Serial.setDebugOutput(false);\n camera_config_t config;\n config.ledc_channel = LEDC_CHANNEL_0;\n config.ledc_timer = LEDC_TIMER_0;\n config.pin_d0 = Y2_GPIO_NUM;\n config.pin_d1 = Y3_GPIO_NUM;\n config.pin_d2 = Y4_GPIO_NUM;\n config.pin_d3 = Y5_GPIO_NUM;\n config.pin_d4 = Y6_GPIO_NUM;\n config.pin_d5 = Y7_GPIO_NUM;\n config.pin_d6 = Y8_GPIO_NUM;\n config.pin_d7 = Y9_GPIO_NUM;\n config.pin_xclk = XCLK_GPIO_NUM;\n config.pin_pclk = PCLK_GPIO_NUM;\n config.pin_vsync = VSYNC_GPIO_NUM;\n config.pin_href = HREF_GPIO_NUM;\n config.pin_sscb_sda = SIOD_GPIO_NUM;\n config.pin_sscb_scl = SIOC_GPIO_NUM;\n config.pin_pwdn = PWDN_GPIO_NUM;\n config.pin_reset = RESET_GPIO_NUM;\n config.xclk_freq_hz = 20000000;\n config.pixel_format = PIXFORMAT_JPEG; \n if(psramFound()){\n config.frame_size = FRAMESIZE_UXGA;\n config.jpeg_quality = 10;\n config.fb_count = 2;\n } else {\n config.frame_size = FRAMESIZE_SVGA;\n config.jpeg_quality = 12;\n config.fb_count = 1;\n }\n esp_err_t err = esp_camera_init(&config);\n if (err != ESP_OK) {\n Serial.printf("Camera init failed with error 0x%x", err);\n return;\n }\n WiFi.begin(wif_ssid,wif_password);\n while (WiFi.status() != WL_CONNECTED) {\n delay(500);\n Serial.print(".");\n }\n Serial.println("");\n Serial.println("WiFi connected");\n Serial.print("Camera Stream Ready! Go to: http://");\n Serial.print(WiFi.localIP());\n Serial.println("");\n startCameraServer();\n Blynk.config(auth,' + server_add + ',8080);\n';
+ return 'Blynk.run();\n';
+};
+
+export const take_a_photo1 = function (_, generator) {
+ generator.definitions_['take_a_photo'] = '#include "esp_camera.h"\n#include "esp_timer.h"\n#include "img_converters.h"\n#include \n#include "fb_gfx.h"\n#include "fd_forward.h"\n#include "fr_forward.h"\n#include "FS.h" \n#include "SD_MMC.h" \n#include "soc/soc.h"\n#include "soc/rtc_cntl_reg.h" \n#include "dl_lib.h"\n#include "driver/rtc_io.h"\n#include \n#define EEPROM_SIZE 1\n#define PWDN_GPIO_NUM 32\n#define RESET_GPIO_NUM -1\n#define XCLK_GPIO_NUM 0\n#define SIOD_GPIO_NUM 26\n#define SIOC_GPIO_NUM 27\n#define Y9_GPIO_NUM 35\n#define Y8_GPIO_NUM 34\n#define Y7_GPIO_NUM 39\n#define Y6_GPIO_NUM 36\n#define Y5_GPIO_NUM 21\n#define Y4_GPIO_NUM 19\n#define Y3_GPIO_NUM 18\n#define Y2_GPIO_NUM 5\n#define VSYNC_GPIO_NUM 25\n#define HREF_GPIO_NUM 23\n#define PCLK_GPIO_NUM 22\nint pictureNumber = 0;\n';
+ let code = 'WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);\nSerial.begin(115200);\ncamera_config_t config;\nconfig.ledc_channel = LEDC_CHANNEL_0;\nconfig.ledc_timer = LEDC_TIMER_0;\nconfig.pin_d0 = Y2_GPIO_NUM;\nconfig.pin_d1 = Y3_GPIO_NUM;\nconfig.pin_d2 = Y4_GPIO_NUM;\nconfig.pin_d3 = Y5_GPIO_NUM;\nconfig.pin_d4 = Y6_GPIO_NUM;\nconfig.pin_d5 = Y7_GPIO_NUM;\nconfig.pin_d6 = Y8_GPIO_NUM;\nconfig.pin_d7 = Y9_GPIO_NUM;\nconfig.pin_xclk = XCLK_GPIO_NUM;\nconfig.pin_pclk = PCLK_GPIO_NUM;\nconfig.pin_vsync = VSYNC_GPIO_NUM;\nconfig.pin_href = HREF_GPIO_NUM;\nconfig.pin_sscb_sda = SIOD_GPIO_NUM;\nconfig.pin_sscb_scl = SIOC_GPIO_NUM;\nconfig.pin_pwdn = PWDN_GPIO_NUM;\nconfig.pin_reset = RESET_GPIO_NUM;\nconfig.xclk_freq_hz = 20000000;\nconfig.pixel_format = PIXFORMAT_JPEG; \nif(psramFound()){\n config.frame_size = FRAMESIZE_UXGA;\n config.jpeg_quality = 10;\n config.fb_count = 2;\n} else {\n config.frame_size = FRAMESIZE_SVGA;\n config.jpeg_quality = 12;\n config.fb_count = 1;\n}\nesp_err_t err = esp_camera_init(&config);\nif (err != ESP_OK) {\n Serial.printf("Camera init failed with error 0x%x", err);\n return;\n}\nif(!SD_MMC.begin()){\n Serial.println("SD Card Mount Failed");\n return;\n}\nuint8_t cardType = SD_MMC.cardType();\nif(cardType == CARD_NONE){\n Serial.println("No SD Card attached");\n return;\n}\ncamera_fb_t * fb = NULL;\nfb = esp_camera_fb_get();\nif(!fb) {\n Serial.println("Camera capture failed");\n return;\n}\nEEPROM.begin(EEPROM_SIZE);\npictureNumber = EEPROM.read(0) + 1;\nString path = "/picture" + String(pictureNumber) +".jpg";\nfs::FS &fs = SD_MMC; \nSerial.printf("Picture file name: %s\\n", path.c_str());\nFile file = fs.open(path.c_str(), FILE_WRITE);\nif(!file){\n Serial.println("Failed to open file in writing mode");\n} \nelse {\n file.write(fb->buf, fb->len);\n Serial.printf("Saved file to path: %s\\n", path.c_str());\n EEPROM.write(0, pictureNumber);\n EEPROM.commit();\n}\nfile.close();\nesp_camera_fb_return(fb); \npinMode(4, OUTPUT);\ndigitalWrite(4, LOW);\nrtc_gpio_hold_en(GPIO_NUM_4);\n';
+ return code;
+};
+
+export const blynk_table_click = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'function');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ generator.definitions_["blynk_table" + Vpin] = 'WidgetTable table_' + Vpin + ';\nBLYNK_ATTACH_WIDGET(table_' + Vpin + ', ' + Vpin + ');\n';
+ generator.setups_["setup_blynk_table_click" + Vpin] = 'table_' + Vpin + '.onSelectChange([](int index, bool selected) {\n ' + branch + '\n });\n';
+ let code = '';
+ return code;
+};
+
+export const blynk_table_order = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let branch = generator.statementToCode(this, 'function');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ generator.definitions_["blynk_table" + Vpin] = 'WidgetTable table_' + Vpin + ';\nBLYNK_ATTACH_WIDGET(table_' + Vpin + ', ' + Vpin + ');\n';
+ generator.setups_["setup_blynk_table_order" + Vpin] = 'table_' + Vpin + '.onOrderChange([](int indexFrom, int indexTo) {\n ' + branch + '\n });\n';
+ let code = '';
+ return code;
+};
+
+export const blynk_table_add_data = function (_, generator) {
+ let Vpin = this.getFieldValue('Vpin');
+ let data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ let name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ generator.definitions_["rowIndex_" + Vpin] = 'int rowIndex_' + Vpin + ' = 0;\n';
+ let code = 'table_' + Vpin + '.addRow(rowIndex_' + Vpin + ', ' + name + ', ' + data + ');\ntable_' + Vpin + '.pickRow(rowIndex_' + Vpin + ');\nrowIndex_' + Vpin + '++;\n';
+ return code;
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/communicate.js b/mixly/boards/default_src/arduino_avr/generators/communicate.js
new file mode 100644
index 00000000..55fe3b1b
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/communicate.js
@@ -0,0 +1,696 @@
+import { Profile } from 'mixly';
+
+export const ir_recv = function (_, generator) {
+ /*var xmlDom = Blockly.Xml.workspaceToDom(Mixly.Editor.blockEditor);
+ var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
+ if (xmlText.indexOf("type=\"controls_tone\"") === -1 && xmlText.indexOf("type=\"controls_notone\"") === -1) {
+ this.setWarningText(null);
+ } else {
+ this.setWarningText(Blockly.Msg.IR_AND_TONE_WARNING);
+ }*/
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var branch = generator.statementToCode(this, 'DO');
+ var branch2 = generator.statementToCode(this, 'DO2');
+ generator.definitions_['include_IRremote'] = '#include \n';
+ generator.definitions_['var_declare_irProtocolList'] =
+ `const String IR_PROTOCOL_TYPE[] = {
+ "UNKNOWN",
+ "PULSE_DISTANCE",
+ "PULSE_WIDTH",
+ "DENON",
+ "DISH",
+ "JVC",
+ "LG",
+ "LG2",
+ "NEC",
+ "PANASONIC",
+ "KASEIKYO",
+ "KASEIKYO_JVC",
+ "KASEIKYO_DENON",
+ "KASEIKYO_SHARP",
+ "KASEIKYO_MITSUBISHI",
+ "RC5",
+ "RC6",
+ "SAMSUNG",
+ "SHARP",
+ "SONY",
+ "ONKYO",
+ "APPLE",
+ "BOSEWAVE",
+ "LEGO_PF",
+ "MAGIQUEST",
+ "WHYNTER"
+};`;
+ generator.definitions_['var_declare_irrecv_' + dropdown_pin] = `IRrecv irrecv_${dropdown_pin}(${dropdown_pin});\n`;
+ generator.setups_['setup_ir_recv_' + dropdown_pin] = `irrecv_${dropdown_pin}.enableIRIn();`;
+ var code =
+ `if (irrecv_${dropdown_pin}.decode()) {
+ struct IRData *pIrData = &irrecv_${dropdown_pin}.decodedIRData;
+ long ir_item = pIrData->decodedRawData;
+ String irProtocol = IR_PROTOCOL_TYPE[pIrData->protocol];
+ Serial.print("IR TYPE:" + irProtocol + "\\tVALUE:");
+ Serial.println(ir_item, HEX);
+ irrecv_${dropdown_pin}.resume();
+${branch}
+} else {
+${branch2}
+}\n`;
+ return code;
+};
+
+export const ir_recv_enable = function (_, generator) {
+ /*var xmlDom = Blockly.Xml.workspaceToDom(Mixly.Editor.blockEditor);
+ var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
+ if (xmlText.indexOf("type=\"controls_tone\"") == -1 && xmlText.indexOf("type=\"controls_notone\"") == -1) {
+ this.setWarningText(null);
+ }
+ else {
+ this.setWarningText(Blockly.Msg.IR_AND_TONE_WARNING);
+ }*/
+
+ generator.definitions_['include_IRremote'] = '#include ';
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var code = 'irrecv_' + dropdown_pin + '.enableIRIn();\n';
+ return code;
+}
+
+export const ir_send_nec = function (_, generator) {
+ var pin = this.getFieldValue('PIN');
+ generator.definitions_['include_IRremote'] = '#include \n';
+ generator.definitions_['var_declare_ir_send_' + pin] = `IRsend irsend_${pin}(${pin});`;
+ var data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC) || '0';
+ var bits = generator.valueToCode(this, 'bits', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var code = `irsend_${pin}.send${type}(${data},${bits});\n`;
+ return code;
+}
+
+export const ir_recv_raw = function (_, generator) {
+ /*var xmlDom = Blockly.Xml.workspaceToDom(Mixly.Editor.blockEditor);
+ var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
+ if (xmlText.indexOf("type=\"controls_tone\"") == -1 && xmlText.indexOf("type=\"controls_notone\"") == -1) {
+ this.setWarningText(null);
+ }
+ else {
+ this.setWarningText(Blockly.Msg.IR_AND_TONE_WARNING);
+ }*/
+
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ generator.definitions_['include_IRremote'] = '#include \n';
+ generator.definitions_['var_declare_ir_recv' + dropdown_pin] = 'IRrecv irrecv_' + dropdown_pin + '(' + dropdown_pin + ');\ndecode_results results_' + dropdown_pin + ';\n';
+ if (!generator.setups_['setup_serial_Serial']) {
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(' + Profile.default.serial + ');';
+ }
+ generator.setups_['setup_ir_recv_' + dropdown_pin] = 'irrecv_' + dropdown_pin + '.enableIRIn();\n';
+ var code = "if (irrecv_" + dropdown_pin + ".decode(&results_" + dropdown_pin + ")) {\n"
+ code += ' ' + 'dumpRaw(&results_' + dropdown_pin + ');\n';
+ code += ' irrecv_' + dropdown_pin + '.resume();\n'
+ code += '}\n';
+ var funcode = 'void dumpRaw(decode_results *results) {\n'
+ + ' int count = results->rawlen;\n'
+ + ' Serial.print("RawData (");\n'
+ + ' Serial.print(count, DEC);\n'
+ + ' Serial.print("): ");\n'
+ + ' for (int i = 0; i < count; i++) {\n'
+ + ' Serial.print(results->rawbuf[i]*MICROS_PER_TICK, DEC);\n'
+ + ' if(i!=count-1){\n'
+ + ' Serial.print(",");\n'
+ + ' }\n'
+ + ' }\n'
+ + ' Serial.println("");\n'
+ + '}\n';
+ generator.definitions_['dumpRaw'] = funcode;
+ return code;
+};
+
+export const ir_send_raw = function (_, generator) {
+ var pin = this.getFieldValue('PIN');
+ generator.definitions_['include_IRremote'] = '#include \n';
+ generator.definitions_['var_declare_ir_send_' + pin] = `IRsend irsend_${pin}(${pin});`;
+ var length = generator.valueToCode(this, 'length', generator.ORDER_ATOMIC) || '0';
+ var freq = generator.valueToCode(this, 'freq', generator.ORDER_ATOMIC) || '0';
+ var text = this.getFieldValue('TEXT');
+ var code = 'unsigned int buf_raw[' + length + ']={' + text + '};\n'
+ code = code + `irsend_${pin}.sendRaw(buf_raw,${length},${freq});\n`;
+ return code;
+}
+
+export const i2c_master_writer = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var device = generator.valueToCode(this, 'device', generator.ORDER_ATOMIC) || '0';
+ var value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC) || '0';
+ var code = "Wire.beginTransmission(" + device + ");\n";
+ code += "Wire.write(" + value + ");\n";
+ code += "Wire.endTransmission();\n";
+ return code;
+};
+
+export const i2c_master_reader2 = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ //generator.setups_['setup_wire_begin'] ='Wire.begin();';
+ var code = "Wire.read()";
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// YANG add slave write
+export const i2c_slave_write = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC) || '0';
+ var code = "Wire.write(" + value + ");\n";
+ return code;
+};
+
+export const RFID_init = function (_, generator) {
+ var sda = this.getFieldValue('SDA');
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.definitions_['include_RFID'] = '#include ';
+ generator.definitions_['var_declare_RFID'] = 'RFID rfid(' + sda + ',5);';
+ generator.definitions_['var_declare__i and tmp'] = 'unsigned char i,tmp;';
+ generator.definitions_['var_declare__status'] = 'unsigned char status;';
+ generator.definitions_['var_declare__strmax'] = 'unsigned char str[MAX_LEN];';
+ generator.definitions_['var_declare__RC_size'] = 'unsigned char RC_size;';
+ generator.definitions_['var_declare__blockAddr'] = 'unsigned char blockAddr; //选择操作的块地址0~63';
+ generator.definitions_['define_1'] = '//4字节卡序列号,第5字节为校验字节';
+ generator.definitions_['define_2'] = 'unsigned char serNum[5];';
+ generator.definitions_['define_3'] = '//写卡数据';
+ generator.definitions_['define_5'] = '//原扇区A密码,16个扇区,每个扇区密码6Byte';
+ generator.definitions_['define_6'] = 'unsigned char sectorKeyA[16][16] = {';
+ generator.definitions_['define_7'] = ' {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},';
+ generator.definitions_['define_8'] = ' {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},';
+ generator.definitions_['define_9'] = ' {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},};';
+
+ generator.definitions_['define_10'] = '//新扇区A密码,16个扇区,每个扇区密码6Byte';
+ generator.definitions_['define_11'] = 'unsigned char sectorNewKeyA[16][16] = {';
+ generator.definitions_['define_12'] = ' {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},';
+ generator.definitions_['define_13'] = ' {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xff,0x07,0x80,0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},';
+ generator.definitions_['define_14'] = ' {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xff,0x07,0x80,0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},};';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_output_2'] = 'SPI.begin();';
+ generator.setups_['setup_output_3'] = 'rfid.init();';
+ return "";
+};
+
+export const RFID_on = function (_, generator) {
+ // Do while/until loop.
+ var branch = generator.statementToCode(this, 'do_');
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
+ '\'' + this.id + '\'') + branch;
+ }
+
+ return 'if(rfid.isCard()){\n' + branch + '}\n';
+};
+
+export const RFID_readcardnum = function (_, generator) {
+ var funcName = 'RFID_readcardnum';
+ var code = 'String ' + funcName + '(){\n'
+ + ' rfid.readCardSerial();\n'
+ + ' String stringserNum = String(rfid.serNum[0], HEX)+String(rfid.serNum[1], HEX)+String(rfid.serNum[2], HEX)+String(rfid.serNum[3], HEX)+String(rfid.serNum[4], HEX);\n'
+ + ' //选卡,返回卡容量(锁定卡片,防止多次读写)\n'
+ + ' rfid.selectTag(rfid.serNum);\n'
+ + ' return stringserNum;\n'//直接返回string
+ + '}\n';
+ generator.definitions_[funcName] = code;
+ return [funcName + '()', generator.ORDER_ATOMIC];
+};
+
+/* export const RFID_serialprintcardnum = function() {
+ var funcName='RFID_serialprintcardnum';
+ var code='void'+ ' ' + funcName + '() {\n'
+ +"\n"+' //找卡 '
+ +"\n"+' //读取卡序列号 '
+ +"\n"+' if (rfid.readCardSerial()) '
+ +"\n"+' {'
+ +"\n"+' Serial.print("The card\'s number is : "); '
+ +"\n"+' Serial.print(rfid.serNum[0],HEX); '
+ +"\n"+' Serial.print(rfid.serNum[1],HEX); '
+ +"\n"+' Serial.print(rfid.serNum[2],HEX); '
+ +"\n"+' Serial.print(rfid.serNum[3],HEX); '
+ +"\n"+' Serial.print(rfid.serNum[4],HEX); '
+ +"\n"+' Serial.println(" "); '
+ +"\n"+' }'
+ +"\n"+' //选卡,返回卡容量(锁定卡片,防止多次读写)'
+ +"\n"+' rfid.selectTag(rfid.serNum);'
+ + '\n}\n';
+ generator.definitions_[funcName] = code;
+ return funcName+'();\n';
+}; */
+
+export const RFID_writecarddata = function (_, generator) {
+ var address2 = generator.valueToCode(this, 'address1', generator.ORDER_ATOMIC);
+ var data2 = this.getFieldValue('data1');
+ var funcName = 'RFID_writecarddata';
+ var code = 'void' + ' ' + funcName + '(int ad2){\n'
+ + ' rfid.readCardSerial();\n'
+ + ' //选卡,返回卡容量(锁定卡片,防止多次读写)\n'
+ + ' rfid.selectTag(rfid.serNum);\n'
+ + ' //写数据卡\n'
+ + ' blockAddr = ad2;\n'
+ + ' if(rfid.auth(PICC_AUTHENT1A, blockAddr, sectorKeyA[blockAddr/4], rfid.serNum) == MI_OK){\n'
+ + ' //写数据\n'
+ + ' status = rfid.write(blockAddr, sectorKeyA[blockAddr/4]);\n'
+ + ' Serial.print("set the new card password, and can modify the data of the Sector: ");\n'
+ + ' Serial.println(blockAddr/4,DEC);\n'
+ + ' blockAddr=blockAddr-3;\n'
+ + ' status=rfid.write(blockAddr,(unsigned char*)' + data2 + ');\n'
+ + ' if(status == MI_OK){\n'
+ + ' Serial.println("Write card OK!");\n'
+ + ' }\n'
+ + ' }\n'
+ + '}\n';
+ generator.definitions_[funcName] = code;
+ return funcName + '(' + address2 + ');\n';
+}
+
+export const RFID_readcarddata = function (_, generator) {
+ var address3 = generator.valueToCode(this, 'address', generator.ORDER_ATOMIC);
+ var funcName = 'RFID_readcarddata'
+ var code = 'String' + ' ' + funcName + '(int ad3){\n'
+ + ' //读卡\n'
+ + ' blockAddr =ad3;\n'
+ + ' status = rfid.auth(PICC_AUTHENT1A, blockAddr, sectorNewKeyA[blockAddr/4], rfid.serNum);\n'
+ + ' if(status == MI_OK){ //认证\n'
+ + ' //读数据\n'
+ + ' if(rfid.read(blockAddr, str) == MI_OK)\n'
+ + ' {\n'
+ + ' Serial.print("Read from the card ,the data is : ");\n'
+ + ' Serial.println((char *)str);\n'
+ + ' }\n'
+ + ' }\n'
+ + ' rfid.halt();\n'
+ + ' String stringstr((char*)str);\n'//str是一个char数组,必须先转换成char*,才能继续转换成string
+ + ' return stringstr;\n'
+ + '}\n';
+ generator.definitions_[funcName] = code;
+ return [funcName + '(' + address3 + ')', generator.ORDER_ATOMIC];
+};
+
+/* export const RFID_serialprintcarddata = function() {
+ var address3 = generator.valueToCode(this, 'address', generator.ORDER_ATOMIC);
+ var funcName='RFID_serialprintcarddata';
+ var code='void'+ ' ' + funcName + '(int ad3) {\n'
+ +"\n"+'//读卡 '
+ +"\n"+' blockAddr =ad3; '
+ +"\n"+' status = rfid.auth(PICC_AUTHENT1A, blockAddr, sectorNewKeyA[blockAddr/4], rfid.serNum);'
+ +"\n"+' if (status == MI_OK) //认证'
+ +"\n"+' {'
+ +"\n"+' //读数据'
+ +"\n"+' if( rfid.read(blockAddr, str) == MI_OK)'
+ +"\n"+' {'
+ +"\n"+' Serial.print("Read from the card ,the data is : ");'
+ +"\n"+' Serial.println((char *)str);'
+ +"\n"+' } '
+ +"\n"+' } '
+ +"\n"+' rfid.halt();'
+ + '\n}\n';
+ generator.definitions_[funcName] = code;
+ return funcName+'('+address3+');\n';
+}; */
+
+export const RFID_off = function (_, generator) {
+ var funcName = 'RFID_off';
+ var code = 'void' + ' ' + funcName + '() {\n'
+ + "\n" + ' rfid.halt(); '
+ + '\n}\n';
+ generator.definitions_[funcName] = code;
+ return funcName + '();\n';
+};
+
+export const RFID_in = function (_, generator) {
+ // Do while/until loop.
+ var funcName = 'RFID_readcardnum';
+ var code = 'String' + ' ' + funcName + '() {\n'
+ + "\n" + ' rfid.readCardSerial(); '
+ + "\n" + ' String stringserNum=String(rfid.serNum[0], HEX)+String(rfid.serNum[1], HEX)+String(rfid.serNum[2], HEX)+String(rfid.serNum[3], HEX)+String(rfid.serNum[4], HEX);'
+ + "\n" + ' //选卡,返回卡容量(锁定卡片,防止多次读写)'
+ + "\n" + ' rfid.selectTag(rfid.serNum);'
+ + "\n" + ' return stringserNum; '//直接返回string
+ + '\n}\n';
+ generator.definitions_[funcName] = code;
+ var argument0 = generator.valueToCode(this, 'uid_',
+ generator.ORDER_NONE) || 'false';
+ var branch = generator.statementToCode(this, 'do_');
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
+ '\'' + this.id + '\'') + branch;
+ }
+ /*
+ fixed bug caused by parameter of strcmp() must be const char*
+ author:zyc
+ date:2018-12-7
+ */
+ if (argument0 != 'false') {
+ if (argument0.indexOf('"') === 0)
+ return 'if (' + 'strcmp(RFID_readcardnum().c_str(),' + argument0 + ')==0' + ') {\n' + branch + '}\n';
+ return 'if (' + 'strcmp(RFID_readcardnum().c_str(),' + argument0 + '.c_str())==0' + ') {\n' + branch + '}\n';
+ }
+ return '';
+
+};
+
+// 初始化RFID
+export const MFRC522_init = function (_, generator) {
+ var text_rfid_name = this.getFieldValue('rfid_name');
+ var value_PIN_SDA = generator.valueToCode(this, 'PIN_SDA', generator.ORDER_ATOMIC);
+ var value_PIN_RST = generator.valueToCode(this, 'PIN_RST', generator.ORDER_ATOMIC);
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.definitions_['include_MFRC522'] = '#include ';
+ generator.definitions_['var_declare_' + text_rfid_name] = 'MFRC522 ' + text_rfid_name + '(' + value_PIN_SDA + ', ' + value_PIN_RST + ');';
+ generator.setups_['setup_spi'] = 'SPI.begin();';
+ generator.setups_['setup_mfc522_' + text_rfid_name] = text_rfid_name + '.PCD_Init();';
+ var code = '';
+ return code;
+};
+
+// RFID侦测到信号
+export const MFRC522_IsNewCard = function (_, generator) {
+ var text_rfid_name = this.getFieldValue('rfid_name');
+ var statements_DO = generator.statementToCode(this, 'DO');
+ generator.definitions_['function_MFRC522_IsNewCard'] = 'boolean MFRC522_IsNewCard(MFRC522 *_name){\n'
+ + ' if(!_name->PICC_IsNewCardPresent())\n'
+ + ' return false;\n'
+ + ' if(!_name->PICC_ReadCardSerial())\n'
+ + ' return false;\n'
+ + ' return true;\n'
+ + '}\n';
+ var code = 'if(MFRC522_IsNewCard(&' + text_rfid_name + ')){\n'
+ + (statements_DO != '' ? statements_DO : '')
+ + ' ' + text_rfid_name + '.PICC_HaltA();\n'
+ + ' ' + text_rfid_name + '.PCD_StopCrypto1();\n'
+ + '}\n';
+ return code;
+};
+
+// RFID读取卡号
+export const MFRC522_ReadCardUID = function (_, generator) {
+ var text_rfid_name = this.getFieldValue('rfid_name');
+ generator.definitions_['function_MFRC522_ReadCardUID'] = 'String MFRC522_ReadCardUID(MFRC522 *_name){\n'
+ + ' String _CardUID = "";\n'
+ + ' for (byte _i = 0; _i < _name->uid.size; _i++){\n'
+ + ' if(_name->uid.uidByte[_i] < 0x10)\n'
+ + ' _CardUID += "0";\n'
+ + ' _CardUID += String(_name->uid.uidByte[_i], HEX);\n'
+ + ' }\n'
+ + ' return _CardUID;\n'
+ + '}\n';
+ var code = 'MFRC522_ReadCardUID(&' + text_rfid_name + ')';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// RFID写卡
+export const MFRC522_WriteCard = function (_, generator) {
+ var text_rfid_name = this.getFieldValue('rfid_name');
+ var value_block = generator.valueToCode(this, 'block', generator.ORDER_ATOMIC);
+ var value_buffer = generator.valueToCode(this, 'buffer', generator.ORDER_ATOMIC);
+ var value_length = generator.valueToCode(this, 'length', generator.ORDER_ATOMIC);
+ generator.definitions_['function_MFRC522_WriteCard'] = 'boolean MFRC522_WriteCard(MFRC522 *_name, byte _block, byte *_buffer, byte _length){\n'
+ + ' MFRC522::MIFARE_Key _key;\n'
+ + ' for(byte i = 0; i < 6; i++)\n'
+ + ' _key.keyByte[i] = 0xFF;\n'
+ + ' MFRC522::StatusCode _status;\n'
+ + ' _status = _name->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, _block, &_key, &(_name->uid));\n'
+ + ' if(_status != MFRC522::STATUS_OK){\n'
+ + ' Serial.print(F("PCD_Authenticate() failed: "));\n'
+ + ' Serial.println(_name->GetStatusCodeName(_status));\n'
+ + ' return false;\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' Serial.println(F("PCD_Authenticate() success;"));\n'
+ + ' }\n'
+ + ' _status = _name->MIFARE_Write(_block, _buffer, _length);\n'
+ + ' if(_status != MFRC522::STATUS_OK){\n'
+ + ' Serial.print(F("MIFARE_Write() failed: "));\n'
+ + ' Serial.println(_name->GetStatusCodeName(_status));\n'
+ + ' return false;\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' Serial.println(F("MIFARE_Write() success;"));\n'
+ + ' }\n'
+ + ' return true;\n'
+ + '}\n'
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ var code = 'MFRC522_WriteCard(&' + text_rfid_name + ', ' + value_block + ', ' + value_buffer + ', ' + value_length + ');\n';
+ return code;
+};
+
+// RFID读卡
+export const MFRC522_ReadCard = function (_, generator) {
+ var text_rfid_name = this.getFieldValue('rfid_name');
+ var value_block = generator.valueToCode(this, 'block', generator.ORDER_ATOMIC);
+ var value_buffer = generator.valueToCode(this, 'buffer', generator.ORDER_ATOMIC);
+ var value_length = generator.valueToCode(this, 'length', generator.ORDER_ATOMIC);
+ generator.definitions_['function_MFRC522_ReadCard'] = 'boolean MFRC522_ReadCard(MFRC522 *_name, byte _block, byte *_buffer, byte _length){\n'
+ + ' MFRC522::MIFARE_Key _key;\n'
+ + ' for(byte i = 0; i < 6; i++)\n'
+ + ' _key.keyByte[i] = 0xFF;\n'
+ + ' MFRC522::StatusCode _status;\n'
+ + ' _status = _name->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, _block, &_key, &(_name->uid));\n'
+ + ' if(_status != MFRC522::STATUS_OK){\n'
+ + ' Serial.print(F("PCD_Authenticate() failed: "));\n'
+ + ' Serial.println(_name->GetStatusCodeName(_status));\n'
+ + ' return false;\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' Serial.println(F("PCD_Authenticate() success;"));\n'
+ + ' }\n'
+ + ' if(_length < 18){\n'
+ + ' byte _Read_buffer[18];\n'
+ + ' byte _Read_buffer_length = 18;\n'
+ + ' _status = _name->MIFARE_Read(_block, _Read_buffer, &_Read_buffer_length);\n'
+ + ' if(_status != MFRC522::STATUS_OK){\n'
+ + ' Serial.print(F("MIFARE_Read() failed: "));\n'
+ + ' Serial.println(_name->GetStatusCodeName(_status));\n'
+ + ' return false;\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' Serial.println(F("MIFARE_Read() success;"));\n'
+ + ' }\n'
+ + ' for(byte _i = 0; _i < _length; _i++)\n'
+ + ' _buffer[_i] = _Read_buffer[_i];\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' _status = _name->MIFARE_Read(_block, _buffer, &_length);\n'
+ + ' if(_status != MFRC522::STATUS_OK){\n'
+ + ' Serial.print(F("MIFARE_Read() failed: "));\n'
+ + ' Serial.println(_name->GetStatusCodeName(_status));\n'
+ + ' return false;\n'
+ + ' }\n'
+ + ' else{\n'
+ + ' Serial.println(F("MIFARE_Read() success;"));\n'
+ + ' }\n'
+ + ' }\n'
+ + ' return true;\n'
+ + '}\n'
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ var code = 'MFRC522_ReadCard(&' + text_rfid_name + ', ' + value_block + ', ' + value_buffer + ', ' + value_length + ');\n';
+ return code;
+};
+
+// IIC主机初始化
+export const i2c_master_Init = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var code = '';
+ return code;
+};
+
+// IIC从机初始化
+export const i2c_slave_Init = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ var value_i2c_address = generator.valueToCode(this, 'i2c_address', generator.ORDER_ATOMIC);
+ generator.setups_['setup_i2c'] = 'Wire.begin(' + value_i2c_address + ');';
+ var code = '';
+ return code;
+};
+
+// IIC发送数据
+export const i2c_begin_end_transmission = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ var value_i2c_address = generator.valueToCode(this, 'i2c_address', generator.ORDER_ATOMIC);
+ var statements_transmission_data = generator.statementToCode(this, 'transmission_data');
+ var code = 'Wire.beginTransmission(' + value_i2c_address + ');\n'
+ + statements_transmission_data
+ + 'Wire.endTransmission();\n';
+ return code;
+};
+
+// IIC写入数据
+export const i2c_write = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ var value_i2c_write_data = generator.valueToCode(this, 'i2c_write_data', generator.ORDER_ATOMIC);
+ var code = 'Wire.write(' + value_i2c_write_data + ');\n';
+ return code;
+};
+
+export const i2c_slave_write_array = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var array = generator.valueToCode(this, 'array', generator.ORDER_ATOMIC);
+ var length = generator.valueToCode(this, 'length', generator.ORDER_ATOMIC) || '1';
+ var code = "Wire.write(" + array + "," + length + ");\n";
+ return code;
+};
+
+export const i2c_available = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ var workspace = this.workspace;
+ var blocks = workspace.getAllBlocks();
+ var y = 0;
+ for (y = 0; y < blocks.length; y++) {
+ if (blocks[y].type == 'i2c_slave_Init')
+ break;
+ }
+ if (y == blocks.length)
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var code = "Wire.available()";
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// 从机接收字节数
+export const i2c_howmany = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var code = "howMany";
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// IIC读取数据
+export const i2c_read = function (_, generator) {
+ var code = "Wire.read()";
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// SPI
+export const spi_transfer = function (_, generator) {
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.setups_['setup_spi'] = 'SPI.begin();';
+ var pin = generator.valueToCode(this, 'pin', generator.ORDER_ATOMIC);
+ var value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC);
+ generator.setups_['setup_output_' + pin] = 'pinMode(' + pin + ', OUTPUT);';
+ var code = "digitalWrite(" + pin + ", LOW);\n";
+ code += "SPI.transfer(" + value + ");\n";
+ code += "digitalWrite(" + pin + ", HIGH);\n";
+ return code;
+};
+
+// SPI 初始化从机
+export const spi_begin_slave = function (_, generator) {
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.setups_['setup_spi'] = 'pinMode(12, OUTPUT);'
+ + '\n SPCR |= _BV(SPE);';
+ var code = '';
+ return code;
+};
+
+// 寄存器读写
+export const i2c_master_writerReg = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var device = generator.valueToCode(this, 'device', generator.ORDER_ATOMIC) || '0';
+ var regadd = generator.valueToCode(this, 'regadd', generator.ORDER_ATOMIC) || '0';
+ var value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC) || '0';
+ var code = "Wire.beginTransmission(" + device + ");\n";
+ code += "Wire.write(" + regadd + ");\n";
+ code += "Wire.write(" + value + ");\n";
+ code += "Wire.endTransmission();\n";
+ return code;
+};
+
+export const i2c_master_readerReg = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ var device = generator.valueToCode(this, 'device', generator.ORDER_ATOMIC) || '0';
+ var regadd = generator.valueToCode(this, 'regadd', generator.ORDER_ATOMIC) || '0';
+ var bytes = generator.valueToCode(this, 'bytes', generator.ORDER_ATOMIC) || '0';
+ var code = "Wire.beginTransmission(" + device + ");\n";
+ code += "Wire.write(" + regadd + ");\n";
+ code += "Wire.requestFrom(" + device + ", " + bytes + ");\n";
+ code += "Wire.endTransmission();\n";
+ return code;
+};
+
+export const i2c_slave_onreceive = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ var value_onReceive_length = generator.valueToCode(this, 'onReceive_length', generator.ORDER_ATOMIC);
+ var statements_i2c_onReceive_data = generator.statementToCode(this, 'DO');
+ generator.definitions_['function_receiveEvent'] = 'void receiveEvent(int ' + value_onReceive_length + ')'
+ + '\n{'
+ + ' ' + statements_i2c_onReceive_data
+ + '\n}\n'
+ generator.setups_['setup_i2c_receiveEvent'] = 'Wire.onReceive(receiveEvent);';
+ var code = '';
+ return code;
+}
+
+export const i2c_slave_onrequest = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ generator.setups_['setup_i2c_slave'] = 'Wire.setClock(400000);';
+ generator.setups_['setup_i2c_onRequest'] = 'Wire.onRequest(i2cRequestEvent);';
+ var funcName = 'i2cRequestEvent';
+ var branch = generator.statementToCode(this, 'DO');
+ var code2 = 'void' + ' ' + funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code2;
+ return '';
+}
+
+export const i2c_master_reader = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include \n';
+ var device = generator.valueToCode(this, 'device', generator.ORDER_ATOMIC) || '0';
+ var bytes = generator.valueToCode(this, 'bytes', generator.ORDER_ATOMIC) || '0';
+ var code = "Wire.requestFrom(" + device + ", " + bytes + ");\n";
+ return code;
+};
+
+export const spi_begin_master = function (_, generator) {
+ var value_spi_slave_pin = generator.valueToCode(this, 'spi_slave_pin', generator.ORDER_ATOMIC);
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.setups_['setup_spi'] = 'SPI.begin();';
+ generator.setups_['setup_spi_divider'] = 'SPI.setClockDivider(SPI_CLOCK_DIV8);';
+ generator.setups_['setup_spi_pin_' + value_spi_slave_pin] = 'digitalWrite(' + value_spi_slave_pin + ', HIGH);';
+ var code = '';
+ return code;
+};
+
+export const spi_transfer_Init = function (_, generator) {
+ var value_slave_pin = generator.valueToCode(this, 'slave_pin', generator.ORDER_ATOMIC);
+ var statements_transfer_data = generator.statementToCode(this, 'transfer_data');
+ var code = 'digitalWrite(' + value_slave_pin + ', LOW);\n'
+ + statements_transfer_data
+ + 'digitalWrite(' + value_slave_pin + ', HIGH);\n';
+ return code;
+};
+
+export const spi_transfer_1 = function (_, generator) {
+ var value_transfer_data = generator.valueToCode(this, 'transfer_data', generator.ORDER_ATOMIC);
+ var code = 'SPI.transfer(' + value_transfer_data + ');\n';
+ return code;
+};
+
+export const spi_transfer_2 = function (_, generator) {
+ var value_transfer_data = generator.valueToCode(this, 'transfer_data', generator.ORDER_ATOMIC);
+ var code = 'SPI.transfer(' + value_transfer_data + ')';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const spi_slave_interrupt = function (_, generator) {
+ var statements_slave_interrupt_data = generator.statementToCode(this, 'slave_interrupt_data');
+ generator.definitions_['function_ISR'] = 'ISR(SPI_STC_vect)'
+ + '\n{'
+ + '\n' + statements_slave_interrupt_data
+ + '\n}\n'
+ generator.setups_['setup_spi_interrupt'] = 'SPI.attachInterrupt();';
+ var code = '';
+ return code;
+};
+
+export const spi_slave_receive = function (_, generator) {
+ generator.definitions_['function_SPI_SlaveReceive'] = 'char SPI_SlaveReceive()'
+ + '\n{'
+ + '\n while(!(SPSR&(1<= ' : ' <= ') + argument1 + '; ' +
+ variable0 + ' = ' + variable0 + ' + (' + step + ')) {\n' +
+ branch + '}\n';
+ } else {
+ //起止数有变量
+ if (step.match(/^-?\d+(\.\d+)?$/)) {
+ //步长是常量
+ down = step < 0;
+ code = 'for (int ' + variable0 + ' = (' + argument0 + '); ' +
+ variable0 + (down ? ' >= ' : ' <= ') + '(' + argument1 + '); ' +
+ variable0 + ' = ' + variable0 + ' + (' + step + ')) {\n' +
+ branch + '}\n';
+ } else {
+ //步长是变量
+ code = 'for (int ' + variable0 + ' = (' + argument0 + '); ' +
+ '(' + argument1 + '>=' + argument0 + ')?(' + variable0 + '<=' + argument1 + '):(' + variable0 + '>=' + argument1 + '); ' +
+ variable0 + ' = ' + variable0 + ' + (' + step + ')) {\n' +
+ branch + '}\n';
+ }
+
+ }
+ return code;
+};
+
+export const controls_whileUntil = function (_, generator) {
+ // Do while/until loop.
+ var argument0 = generator.valueToCode(this, 'BOOL',
+ generator.ORDER_NONE) || 'false';
+ var branch = generator.statementToCode(this, 'DO');
+ if (generator.INFINITE_LOOP_TRAP) {
+ branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
+ '\'' + this.id + '\'') + branch;
+ }
+ if (this.getFieldValue('MODE') == 'UNTIL') {
+ if (!argument0.match(/^\w+$/)) {
+ argument0 = '(' + argument0 + ')';
+ }
+ argument0 = '!' + argument0;
+ }
+ return 'while (' + argument0 + ') {\n' + branch + '}\n';
+};
+
+export const controls_flow_statements = function () {
+ // Flow statements: continue, break.
+ switch (this.getFieldValue('FLOW')) {
+ case 'BREAK':
+ return 'break;\n';
+ case 'CONTINUE':
+ return 'continue;\n';
+ }
+ throw 'Unknown flow statement.';
+};
+
+export const controls_delay = function (_, generator) {
+ var delay_time = generator.valueToCode(this, 'DELAY_TIME', generator.ORDER_ATOMIC) || '1000'
+ var unit = this.getFieldValue('UNIT');
+ var code = unit + '(' + delay_time + ');\n';
+ return code;
+};
+
+export const controls_millis = function (_, generator) {
+ var unit = this.getFieldValue('UNIT');
+ var code = unit + "()";
+ return [code, generator.ORDER_ATOMIC];
+};
+
+export const controls_mstimer2 = function (_, generator) {
+ generator.definitions_['include_MsTimer2'] = '#include ';
+ var time = generator.valueToCode(this, 'TIME', generator.ORDER_ATOMIC);
+ var funcName = 'msTimer2_func';
+ var branch = generator.statementToCode(this, 'DO');
+ var code = 'void' + ' ' + funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code;
+ return 'MsTimer2::set(' + time + ', ' + funcName + ');\n';
+};
+
+export const controls_mstimer2_start = function (_, generator) {
+ generator.definitions_['include_MsTimer2'] = '#include ';
+ return 'MsTimer2::start();\n';
+};
+
+export const controls_mstimer2_stop = function (_, generator) {
+ generator.definitions_['include_MsTimer2'] = '#include ';
+ return 'MsTimer2::stop();\n';
+};
+
+export const controls_end_program = function () {
+ var board_type = JSFuncs.getPlatform();
+ if (board_type.match(RegExp(/ESP8266/)))
+ return 'while(true) delay(1000);\n';
+ return 'while(true);\n';
+};
+
+export const controls_soft_reset = function (_, generator) {
+ var funcName = 'resetFunc';
+ var code = 'void(* resetFunc) (void) = 0;\n';
+ generator.definitions_[funcName] = code;
+ return 'resetFunc();\n';
+};
+
+export const controls_interrupts = function () {
+ return 'interrupts();\n';
+};
+
+export const controls_nointerrupts = function () {
+ return 'noInterrupts();\n';
+};
+
+export const base_delay = controls_delay;
+
+// 简单定时器
+export const simple_timer = function (_, generator) {
+ var NO = this.getFieldValue('NO');
+ var timein = generator.valueToCode(this, 'timein', generator.ORDER_ATOMIC);
+ var funcName = 'Simple_timer_' + NO;
+ var branch = generator.statementToCode(this, 'zxhs');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ var code = 'void' + ' ' + funcName + '() {\n ' + branch + '\n}\n';
+ generator.definitions_[funcName] = code;
+ generator.definitions_['include_SimpleTimer'] = '#include \n';
+ generator.definitions_['var_declare_SimpleTimer'] = 'SimpleTimer timer;';
+ generator.setups_[funcName] = 'timer.setInterval(' + timein + 'L, ' + funcName + ');\n';
+ return 'timer.run();\n';
+};
+
+// do-while循环
+export const do_while = function (_, generator) {
+ var statements_input_data = generator.statementToCode(this, 'input_data');
+ var value_select_data = generator.valueToCode(this, 'select_data', generator.ORDER_ATOMIC);
+ var dropdown_type = this.getFieldValue('type');
+ if (dropdown_type == 'false') {
+ var code = 'do{\n'
+ + statements_input_data
+ + '}while(!(' + value_select_data + '));\n';
+ }
+ else {
+ var code = 'do{\n'
+ + statements_input_data
+ + '}while(' + value_select_data + ');\n';
+ }
+ return code;
+};
+
+// 注册超级延时函数
+export const super_delay_function1 = function (_, generator) {
+ var number = this.getFieldValue('number');
+ var funcName = 'super_delay_function' + number;
+ var branch = generator.statementToCode(this, 'delay_function');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ var code = 'void' + ' ' + funcName + '() {\n ' + branch + '\n}\n';
+ generator.definitions_[funcName] = code;
+ generator.definitions_['include_SimpleTimer'] = '#include \n';
+ generator.definitions_['var_declare_SimpleTimer'] = 'SimpleTimer timer;';
+ return 'timer.run();\n';
+};
+
+// 执行超级延时函数
+export const execute_super_delay_function1 = function (_, generator) {
+ var number = this.getFieldValue('number');
+ var time_interval = generator.valueToCode(this, 'time_interval', generator.ORDER_ATOMIC);
+ var frequency = generator.valueToCode(this, 'frequency', generator.ORDER_ATOMIC);
+ var code = 'timer.setTimer(' + time_interval + ', super_delay_function' + number + ', ' + frequency + ');\n';
+ return code;
+};
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/display.js b/mixly/boards/default_src/arduino_avr/generators/display.js
new file mode 100644
index 00000000..f948bd08
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/display.js
@@ -0,0 +1,1369 @@
+import { Profile, JSFuncs } from 'mixly';
+import { Variables } from 'blockly/core';
+
+export const group_lcd_init2 = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var TYPE = this.getFieldValue('TYPE');
+ var SCL = this.getFieldValue('SCL');
+ var SDA = this.getFieldValue('SDA');
+ var board_type = JSFuncs.getPlatform();
+ var device = generator.valueToCode(this, 'device', generator.ORDER_ATOMIC) || '0x27';
+ if (SDA == Profile.default.SDA[0][1] && SCL == Profile.default.SCL[0][1]) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_LiquidCrystal_I2C'] = '#include ';
+ generator.definitions_['var_declare_LiquidCrystal_I2C_' + varName] = 'LiquidCrystal_I2C ' + varName + '(' + device + ',' + TYPE + ');';
+ }
+ else {
+ if (board_type.match(RegExp(/AVR/))) {
+ generator.definitions_['include_SoftI2CMaster'] = '#include ';
+ generator.definitions_['include_LiquidCrystal_SoftI2C'] = '#include ';
+ generator.definitions_['var_declare_LiquidCrystal_SoftI2C_' + varName] = 'LiquidCrystal_SoftI2C ' + varName + '(' + device + ',' + TYPE + ',' + SCL + ',' + SDA + ');';
+ }
+ else {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_LiquidCrystal_SoftI2C'] = '#include ';
+ generator.definitions_['var_declare_LiquidCrystal_I2C_' + varName] = 'LiquidCrystal_I2C ' + varName + '(' + device + ',' + TYPE + ');';
+ generator.setups_["setup_Wire"] = 'Wire.begin(' + SDA + ',' + SCL + ');';
+ }
+ }
+ generator.setups_['setup_lcd_init_' + varName] = varName + '.init();';
+ generator.setups_['setup_lcd_backlight_' + varName] = varName + '.backlight();';
+ return '';
+};
+
+export const group_lcd_init3 = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var TYPE = this.getFieldValue('TYPE');
+ var RS = this.getFieldValue('RS');
+ var EN = this.getFieldValue('EN');
+ var D4 = this.getFieldValue('D4');
+ var D5 = this.getFieldValue('D5');
+ var D6 = this.getFieldValue('D6');
+ var D7 = this.getFieldValue('D7');
+ generator.definitions_['include_LiquidCrystal'] = '#include ';
+ generator.definitions_['var_declare_LiquidCrystal' + varName] = 'LiquidCrystal ' + varName + '(' + RS + ',' + EN + ',' + D4 + ',' + D5 + ',' + D6 + ',' + D7 + ');';
+ generator.setups_['setup_lcd_begin_' + varName] = varName + '.begin(' + TYPE + ');';
+
+ return '';
+};
+
+export const group_lcd_print = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var str1 = generator.valueToCode(this, 'TEXT', generator.ORDER_ATOMIC) || '""';
+ var str2 = generator.valueToCode(this, 'TEXT2', generator.ORDER_ATOMIC) || '""';
+
+ var code = varName + '.setCursor(0, 0);\n'
+ code += varName + '.print(' + str1 + ');\n';
+ code += varName + '.setCursor(0, 1);\n';
+ code += varName + '.print(' + str2 + ');\n';
+ //code+=varName+'.setCursor(0, 2);\n';
+ //code+=varName+'.print('+str3+');\n';
+ //code+=varName+'.setCursor(0, 3);\n';
+ //code+=varName+'.print('+str4+');\n';
+ return code;
+};
+
+export const group_lcd_print2 = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var str = generator.valueToCode(this, 'TEXT', generator.ORDER_ATOMIC) || 'String("")';
+ var row = generator.valueToCode(this, 'row', generator.ORDER_ATOMIC) || '1';
+ var column = generator.valueToCode(this, 'column', generator.ORDER_ATOMIC) || '1';
+ var code = varName + '.setCursor(' + column + '-1, ' + row + '-1);\n'
+ code += varName + '.print(' + str + ');\n';
+ return code;
+};
+
+export const group_lcd_power = function () {
+ var varName = this.getFieldValue('VAR');
+ var dropdown_stat = this.getFieldValue('STAT');
+ var code = varName + '.' + dropdown_stat + '();\n'
+ return code;
+};
+
+export const display_4digitdisplay_power = function (_, generator) {
+ var stat = this.getFieldValue("STAT");
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_TM1650'] = '#include ';
+ generator.definitions_['var_declare_display_4display'] = 'TM1650 tm_4display;';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ generator.setups_['setup_display_4display_init'] = 'tm_4display.init();';
+ return 'tm_4display.' + stat + '();\n';
+}
+
+export const display_4digitdisplay_displayString = function (_, generator) {
+ var value = generator.valueToCode(this, 'VALUE', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_TM1650'] = '#include ';
+ generator.definitions_['var_declare_display_4display'] = 'TM1650 tm_4display;';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ generator.setups_['setup_display_4display_init'] = 'tm_4display.init();';
+ return 'tm_4display.displayString(' + value + ');\n';
+}
+
+export const display_4digitdisplay_showDot = function (_, generator) {
+ var no = this.getFieldValue("NO");
+ var stat = this.getFieldValue("STAT");
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_TM1650'] = '#include ';
+ generator.definitions_['var_declare_display_4display'] = 'TM1650 tm_4display;';
+ generator.setups_['setup_wire_begin'] = 'Wire.begin();';
+ generator.setups_['setup_display_4display_init'] = 'tm_4display.init();';
+ return 'tm_4display.setDot(' + no + ',' + stat + ');\n';
+}
+
+var tm1637_DIO;
+var tm1637_CLK;
+
+export const display_TM1637_init = function (_, generator) {
+ tm1637_CLK = this.getFieldValue('CLK');
+ tm1637_DIO = this.getFieldValue('DIO');
+ var NAME = this.getFieldValue('NAME') || 'display';
+ generator.definitions_['include_SevenSegmentTM1637'] = '#include ';
+ generator.definitions_['var_declare_SevenSegmentTM1637' + NAME] = 'SevenSegmentTM1637 ' + NAME + '(' + tm1637_CLK + ',' + tm1637_DIO + ');';
+ generator.setups_['setup_' + NAME + '.begin()'] = NAME + '.begin();';
+ return '';
+};
+
+export const display_TM1637_displyPrint = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'display';
+ //var Speed = generator.valueToCode(this, 'Speed', generator.ORDER_ATOMIC);
+ var VALUE = generator.valueToCode(this, 'VALUE', generator.ORDER_ATOMIC);
+ var code = NAME + '.print(' + VALUE + ');' + '\n';
+ return code;
+};
+
+export const display_TM1637_displayTime = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'display';
+ generator.definitions_['include_SevenSegmentExtended'] = '#include ';
+ generator.definitions_['var_declare_SevenSegmentTM1637' + NAME] = 'SevenSegmentExtended ' + NAME + '(' + tm1637_CLK + ',' + tm1637_DIO + ');';
+ var hour = generator.valueToCode(this, 'hour', generator.ORDER_ATOMIC);
+ var minute = generator.valueToCode(this, 'minute', generator.ORDER_ATOMIC);
+ var dropdown_stat = this.getFieldValue("STAT");
+ var code = NAME + '.printTime(' + hour + ',' + minute + ',' + dropdown_stat + ');\n';
+ return code;
+};
+
+export const display_TM1637_clearDisplay = function () {
+ var stat = this.getFieldValue("STAT");
+ var NAME = this.getFieldValue('NAME') || 'display';
+ return NAME + '.' + stat + '();\n';
+};
+
+export const display_TM1637_Brightness = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'display';
+ var BRIGHTNESS = generator.valueToCode(this, 'Brightness', generator.ORDER_ATOMIC);
+ var code = NAME + '.setBacklight(' + BRIGHTNESS + ');\n';
+ return code;
+};
+
+// HT16K33点阵初始化
+export const HT16K33_Init = function (_, generator) {
+ var SDA = this.getFieldValue('SDA');
+ var SCL = this.getFieldValue('SCL');
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ generator.definitions_['include_Matrix'] = '#include ';
+ generator.definitions_['var_declare' + matrixName] = 'Matrix ' + matrixName + '(' + SDA + ',' + SCL + ');';
+ generator.setups_['setup_' + matrixName] = matrixName + '.begin(0x70);';
+ var code = matrixName + '.clear();\n';
+ return code;
+};
+
+// Max7219点阵初始化
+export const MAX7219_init = function (_, generator) {
+ var pin_cs = generator.valueToCode(this, 'PIN2', generator.ORDER_ATOMIC);
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var hDisplays = generator.valueToCode(this, 'hDisplays', generator.ORDER_ATOMIC);
+ var vDisplays = generator.valueToCode(this, 'vDisplays', generator.ORDER_ATOMIC);
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.definitions_['include_Adafruit_GFX'] = '#include ';
+ generator.definitions_['include_Max72xxPanel'] = '#include ';
+ generator.definitions_['var_declare_Max72xxPanel'] = 'Max72xxPanel ' + matrixName + ' = Max72xxPanel(' + pin_cs + ',' + hDisplays + ',' + vDisplays + ');';
+ var code = '';
+ return code;
+};
+
+// 点阵屏画点
+export const display_Matrix_DrawPixel = function (_, generator) {
+ var matrixType = this.getFieldValue('TYPE');
+ var write = this.getFieldValue('WRITE');
+ var pos_x = generator.valueToCode(this, 'XVALUE', generator.ORDER_ASSIGNMENT);
+ var pos_y = generator.valueToCode(this, 'YVALUE', generator.ORDER_ASSIGNMENT);
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var dropdown_type = generator.valueToCode(this, 'STAT', generator.ORDER_ATOMIC);
+ if (matrixType == "HT16K33") {
+ var code = matrixName + '.drawPixel(' + pos_x + ',7-' + pos_y + ',' + dropdown_type + ');\n'
+ }
+ else {
+ var code = matrixName + '.drawPixel(' + pos_x + ',' + pos_y + ',' + dropdown_type + ');\n'
+ }
+ if (write !== 'OFF') {
+ code += matrixName + '.write();\n';
+ }
+ return code;
+};
+
+// 点阵屏滚动显示文本
+export const display_Matrix_TEXT = function (_, generator) {
+ var matrixName = "myMatrix";
+ var textString = generator.valueToCode(this, 'TEXT', generator.ORDER_ASSIGNMENT);
+ var speed = generator.valueToCode(this, 'Speed', generator.ORDER_ATOMIC);
+ var code = matrixName + '.scrollMessage(' + textString + ',' + speed + ');\n'
+ return code;
+};
+
+// 点阵屏显示文本
+export const display_Matrix_print = function (_, generator) {
+ var matrixName = "myMatrix";
+ var write = this.getFieldValue('WRITE');
+ var textString = generator.valueToCode(this, 'TEXT', generator.ORDER_ASSIGNMENT);
+ var code = matrixName + '.setCursor(0, 0);\n';
+ code += matrixName + '.print(' + textString + ');\n';
+ if (write !== 'OFF') {
+ code += matrixName + '.write();\n';
+ }
+ return code;
+};
+
+// 点阵屏显示_显示图案
+export const display_Matrix_DisplayChar = function (_, generator) {
+ var matrixType = this.getFieldValue('TYPE');
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var write = this.getFieldValue('WRITE');
+ var NO = generator.valueToCode(this, 'NO', generator.ORDER_ATOMIC);
+ var dotMatrixArray = generator.valueToCode(this, 'LEDArray', generator.ORDER_ASSIGNMENT);
+ generator.definitions_['var_declare_LEDArray'] = 'uint8_t LEDArray[8];';
+ var code = '';
+ code += 'memcpy_P(&LEDArray, &' + dotMatrixArray + ', 8);\n';
+ code += 'for(int index_i=0; index_i<8; index_i++)\n';
+ code += '{\n'
+ //code+=' LEDArray[index_i]='+dotMatrixArray+'[index_i];\n';
+ code += ' for(int index_j=' + (NO) + '*8; index_j<' + (NO) + '*8+8; index_j++)\n'
+ //code+=' for(int index_j=7; index_j>=0; index_j--)\n'
+ code += ' {\n'
+ code += ' if((LEDArray[index_i]&0x01)>0)\n';
+ if (matrixType == "HT16K33") {
+ code += ' ' + matrixName + '.drawPixel(index_j, index_i,1);\n';
+ code += ' else\n ' + matrixName + '.drawPixel(index_j, index_i,0);\n';
+ }
+ else {
+ code += ' ' + matrixName + '.drawPixel(index_j, 7-index_i,1);\n';
+ code += ' else\n ' + matrixName + '.drawPixel(index_j, 7-index_i,0);\n';
+ }
+ code += ' LEDArray[index_i] = LEDArray[index_i]>>1;\n';
+ code += ' } \n';
+ code += '}\n';
+ if (write !== 'OFF') {
+ code += matrixName + '.write();\n';
+ }
+ return code;
+};
+
+// 点阵屏显示_点阵数组
+export const display_Matrix_LedArray = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var a = new Array();
+ for (var i = 1; i < 9; i++) {
+ a[i] = new Array();
+ for (var j = 1; j < 9; j++) {
+ a[i][9 - j] = (this.getFieldValue('a' + i + j) == "TRUE") ? 1 : 0;
+ }
+ }
+ var code = '{';
+ for (var i = 1; i < 9; i++) {
+ var tmp = ""
+ for (var j = 1; j < 9; j++) {
+ tmp += a[i][j];
+ }
+ tmp = (parseInt(tmp, 2)).toString(16)
+ if (tmp.length == 1) tmp = "0" + tmp;
+ code += '0x' + tmp + ((i != 8) ? ',' : '');
+ }
+ code += '};';
+ //generator.definitions_[varName] = "uint8_t " + varName + "[8]=" + code;
+ generator.definitions_[varName] = "const uint8_t " + varName + "[8] PROGMEM =" + code;
+ return [varName, generator.ORDER_ATOMIC];
+};
+
+// 点阵位图数据
+export const display_matrix_bitmap = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var a = this.getFieldValue('BITMAP');
+ var code = '{';
+ for (var i = 7; i >= 0; i--) {
+ var tmp = "";
+ for (var j = 7; j >= 0; j--) {
+ tmp += a[i][j];
+ }
+ tmp = (parseInt(tmp, 2)).toString(16);
+ if (tmp.length == 1) tmp = "0" + tmp;
+ code += '0x' + tmp + ((i !== 0) ? ',' : '');
+ }
+ code += '};';
+ generator.definitions_[varName] = "const uint8_t " + varName + "[8] PROGMEM =" + code;
+ return [varName, generator.ORDER_ATOMIC];
+};
+
+// 点阵设置亮度
+export const display_Matrix_Brightness = function (_, generator) {
+ var matrixType = this.getFieldValue('TYPE');
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var BRIGHTNESS = generator.valueToCode(this, 'Brightness', generator.ORDER_ATOMIC);
+ if (matrixType == "HT16K33") {
+ var code = matrixName + '.setBrightness(' + BRIGHTNESS + ');\n';
+ }
+ else {
+ var code = matrixName + '.setIntensity(' + BRIGHTNESS + ');\n';
+ }
+ return code;
+};
+
+// 点阵 全亮/全灭/关闭/开启
+export const display_Matrix_fillScreen = function () {
+ var write = this.getFieldValue('WRITE');
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var FILLSCREEN_TYPE = this.getFieldValue('FILLSCREEN_TYPE');
+ var code = matrixName + '.' + FILLSCREEN_TYPE + ';\n'
+ if (write !== 'OFF') {
+ code += matrixName + '.write();\n';
+ }
+ return code;
+};
+
+// 点阵屏旋转
+export const display_Max7219_Rotation = function (_, generator) {
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var dropdown_type = this.getFieldValue('Rotation_TYPE');
+ var NO = generator.valueToCode(this, 'NO', generator.ORDER_ATOMIC);
+ var code = matrixName + '.setRotation(' + NO + ',' + dropdown_type + ');\n'
+ return code;
+};
+
+// 点阵屏位置
+export const display_Max7219_setPosition = function (_, generator) {
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var NO = generator.valueToCode(this, 'NO', generator.ORDER_ATOMIC);
+ var X = generator.valueToCode(this, 'X', generator.ORDER_ATOMIC);
+ var Y = generator.valueToCode(this, 'Y', generator.ORDER_ATOMIC);
+ var code = matrixName + '.setPosition(' + NO + ',' + X + ',' + Y + ');\n'
+ return code;
+};
+
+// 点阵屏旋转
+export const display_HT16K33_Rotation = function () {
+ //var matrixName = this.getFieldValue('matrixName');
+ var matrixName = "myMatrix";
+ var dropdown_type = this.getFieldValue('Rotation_TYPE');
+ var code = matrixName + '.setRotation(4-' + dropdown_type + ');\n'
+ return code;
+};
+
+// 点阵屏 图案数组
+export const LedArray = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var a = new Array();
+ for (var i = 1; i < 9; i++) {
+ a[i] = new Array();
+ for (var j = 1; j < 9; j++) {
+ a[i][j] = (this.getFieldValue('a' + i + j) == "TRUE") ? 1 : 0;
+ }
+ }
+ var code = '{';
+ for (var i = 1; i < 9; i++) {
+ var tmp = ""
+ for (var j = 1; j < 9; j++) {
+ tmp += a[i][j];
+ }
+ tmp = (parseInt(tmp, 2)).toString(16)
+ if (tmp.length == 1) tmp = "0" + tmp;
+ code += '0x' + tmp + ((i != 8) ? ',' : '');
+ }
+ code += '};\n';
+ generator.definitions_[varName] = "byte " + varName + "[]=" + code;
+ return [varName, generator.ORDER_ATOMIC];
+};
+
+// 点阵屏预设图案
+export const Matrix_img = function (_, generator) {
+ var dropdown_img_ = this.getFieldValue('img_');
+ var code = '"' + dropdown_img_ + '"';
+ code = '{';
+ for (var i = 0; i < 15; i += 2) {
+ code += '0x' + dropdown_img_.substr(i, 2) + ((i != 14) ? ',' : '');
+ }
+ code += '};\n';
+ generator.definitions_['matrix_img_' + dropdown_img_] = "const uint8_t " + 'matrix_img_' + dropdown_img_ + "[8] PROGMEM=" + code;
+ return ['matrix_img_' + dropdown_img_, generator.ORDER_ATOMIC];
+};
+
+// 点阵屏 设置生效
+export const display_Matrix_write = function () {
+ return 'myMatrix.write();\n';
+};
+
+export const oled_init = function (_, generator) {
+ var OLED_TYPE = this.getFieldValue('OLED_TYPE');
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var ROTATION = this.getFieldValue('ROTATION');
+ var SDA = this.getFieldValue('SDA');
+ var SCL = this.getFieldValue('SCL');
+ var ADDRESS = generator.valueToCode(this, 'ADDRESS', generator.ORDER_ATOMIC) || '0x3C';
+ var board_type = JSFuncs.getPlatform();
+ //var board_type ="ESP8266";
+ generator.definitions_['include_U8g2lib'] = '#include ';
+ if (board_type.match(RegExp(/AVR/))) {
+ if (SDA == Profile.default.SDA[0][1] && SCL == Profile.default.SCL[0][1])
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_' + OLED_TYPE + '_1_HW_I2C ' + NAME + '(' + ROTATION + ', U8X8_PIN_NONE);';
+ else
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_' + OLED_TYPE + '_1_SW_I2C ' + NAME + '(' + ROTATION + ', ' + SCL + ', ' + SDA + ', U8X8_PIN_NONE);';
+ }
+ else {
+ if (SDA == Profile.default.SDA[0][1] && SCL == Profile.default.SCL[0][1])
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_' + OLED_TYPE + '_F_HW_I2C ' + NAME + '(' + ROTATION + ', U8X8_PIN_NONE);';
+ else
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_' + OLED_TYPE + '_F_SW_I2C ' + NAME + '(' + ROTATION + ', ' + SCL + ', ' + SDA + ', U8X8_PIN_NONE);';
+ }
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.setups_["setup_u8g2" + NAME] = NAME + '.setI2CAddress(' + ADDRESS + '*2);\n'
+ + ' ' + NAME + '.begin();';
+ var code = '';
+ return code;
+};
+
+export const u8g2_spi_init = function (_, generator) {
+ var U8G2_TYPE_SPI = this.getFieldValue('U8G2_TYPE_SPI');
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var ROTATION = this.getFieldValue('ROTATION');
+ var CLK = this.getFieldValue('CLK');
+ var MOSI = this.getFieldValue('MOSI');
+ var CS = this.getFieldValue('CS');
+ var DC = this.getFieldValue('DC');
+ var RST = this.getFieldValue('RST');
+ generator.definitions_['include_U8g2lib'] = '#include ';
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.setups_["setup_u8g2" + NAME] = NAME + '.begin();';
+ if (CLK == "SCK" && MOSI == "MOSI")
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_' + U8G2_TYPE_SPI + '_1_4W_HW_SPI ' + NAME + '(' + ROTATION + ', ' + CS + ', ' + DC + ', ' + RST + ');';
+ else
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_' + U8G2_TYPE_SPI + '_1_4W_SW_SPI ' + NAME + '(' + ROTATION + ', ' + CLK + ',' + MOSI + ',' + CS + ', ' + DC + ', ' + RST + ');';
+ var code = '';
+ return code;
+};
+
+export const u8g2_LCD12864_spi_init = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var ROTATION = this.getFieldValue('ROTATION');
+ var DC = this.getFieldValue('DC');
+ //var RST = this.getFieldValue('RST');
+ generator.definitions_['include_U8g2lib'] = '#include ';
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.setups_["setup_u8g2" + NAME] = NAME + '.begin();';
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_ST7920_128X64_1_HW_SPI ' + NAME + '(' + ROTATION + ', ' + DC + ', U8X8_PIN_NONE);';
+ var code = '';
+ return code;
+};
+
+export const u8g2_LCD12864_8080_init = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var ROTATION = this.getFieldValue('ROTATION');
+ var DB0 = this.getFieldValue('DB0');
+ var DB1 = this.getFieldValue('DB1');
+ var DB2 = this.getFieldValue('DB2');
+ var DB3 = this.getFieldValue('DB3');
+ var DB4 = this.getFieldValue('DB4');
+ var DB5 = this.getFieldValue('DB5');
+ var DB6 = this.getFieldValue('DB6');
+ var DB7 = this.getFieldValue('DB7');
+ var ENABLE = this.getFieldValue('ENABLE');
+ var DC = this.getFieldValue('DC');
+ //var RST = this.getFieldValue('RST');
+ generator.definitions_['include_U8g2lib'] = '#include ';
+ generator.setups_["setup_u8g2" + NAME] = NAME + '.begin();';
+ generator.definitions_['var_declare_U8G2' + NAME] = 'U8G2_ST7920_128X64_1_8080 ' + NAME + '(' + ROTATION + ', ' + DB0 + ', ' + DB1 + ', ' + DB2 + ', ' + DB3 + ', ' + DB4 + ', ' + DB5 + ', ' + DB6 + ', ' + DB7 + ', ' + ENABLE + ', U8X8_PIN_NONE, ' + DC + ');';
+ var code = '';
+ return code;
+};
+
+export const oled_clear = function () {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var code = NAME + ".clearDisplay();\n";
+ return code;
+};
+
+export const oled_face = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var POS_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var POS_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var FACE_IMAGE = this.getFieldValue('FACE_IMAGE');
+ var pos = FACE_IMAGE.indexOf(',');
+ var varName = "FACE_" + FACE_IMAGE.substring(0, pos);
+ FACE_IMAGE = FACE_IMAGE.substring(pos + 1, FACE_IMAGE.length);
+ // YANG use PROGMEM to save the RAM space
+ //generator.definitions_['var_declare' + varName] = 'static unsigned char ' + varName + '[]={' + FACE_IMAGE + ' };\n';
+ //var code="u8g2.drawXBM("+POS_x+","+POS_y+",89,64,"+varName+");\n";
+ generator.libs_[varName] = 'const static unsigned char ' + varName + '[] PROGMEM ={' + FACE_IMAGE + ' };';
+ var code = NAME + ".drawXBMP(" + POS_x + "," + POS_y + ",89,64," + varName + ");\n";
+ return code;
+};
+
+export const oled_icons = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var POS_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var POS_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var ICON_SIZE = this.getFieldValue('ICON_SIZE');
+ var ICON_IMAGE = this.getFieldValue('ICON_IMAGE');
+ var code = NAME + ".setFontPosBottom();\n" + NAME + ".setFont(u8g2_font_open_iconic_all_" + ICON_SIZE + "x_t);\n"
+ + NAME + ".drawGlyph(" + POS_x + "," + POS_y + "+" + ICON_SIZE + "*8," + ICON_IMAGE + ");\n";
+ return code;
+};
+
+export const oled_drawPixel = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var pos_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var pos_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var code = "";
+ code = code + NAME + '.drawPixel(' + pos_x + ',';
+ code += pos_y + ');\n';
+ return code;
+};
+
+export const oled_page = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var branch = generator.statementToCode(this, 'DO');
+ //branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ var code = '';
+ if (branch) {
+ code = NAME + ".firstPage();"
+ + "\ndo"
+ + "\n{"
+ + "\n" + branch
+ + "}while(" + NAME + ".nextPage());\n";
+ }
+ return code;
+};
+
+export const oled_showBitmap = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var start_x = generator.valueToCode(this, 'START_X', generator.ORDER_ATOMIC) || '0';
+ var start_y = generator.valueToCode(this, 'START_Y', generator.ORDER_ATOMIC) || '0';
+ var width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC) || '0';
+ var height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC) || '0';
+ var data_name = generator.valueToCode(this, 'bitmap_name', generator.ORDER_ATOMIC);
+ data_name = data_name.replace(/"/g, "");
+ var code = "";
+ //YANG use PROGMEM to save the RAM space
+ //code = 'u8g2.drawXBM(' + start_x + ', ';
+ code = NAME + '.drawXBMP(' + start_x + ', ';
+ code += start_y + ', ';
+ code += width + ', ';
+ code += height + ', ' + data_name + ');\n';
+ return code;
+};
+
+export const oled_define_bitmap_data = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Variables.NAME_TYPE);
+ var text = this.getFieldValue('TEXT');
+ //YANG use PROGMEM to save the RAM space
+ //generator.definitions_['var_declare' + varName] = 'static unsigned char ' + varName + '[]={' + text + ' };\n';
+ generator.libs_[varName] = 'const static unsigned char ' + varName + '[] PROGMEM ={' + text + ' };';
+ return '';
+};
+
+export const oled_drawLine = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var start_x = generator.valueToCode(this, 'START_X', generator.ORDER_ATOMIC) || '0';
+ var start_y = generator.valueToCode(this, 'START_Y', generator.ORDER_ATOMIC) || '0';
+ var end_x = generator.valueToCode(this, 'END_X', generator.ORDER_ATOMIC) || '0';
+ var end_y = generator.valueToCode(this, 'END_Y', generator.ORDER_ATOMIC) || '0';
+ var code = "";
+ code = NAME + '.drawLine(' + start_x + ',';
+ code += start_y + ',';
+ code += end_x + ',';
+ code += end_y + ');\n';
+ return code;
+};
+
+export const oled_draw_Str_Line = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var start_x = generator.valueToCode(this, 'START_X', generator.ORDER_ATOMIC) || '0';
+ var start_y = generator.valueToCode(this, 'START_Y', generator.ORDER_ATOMIC) || '0';
+ var length = generator.valueToCode(this, 'LENGTH', generator.ORDER_ATOMIC) || '0';
+ var TYPE = this.getFieldValue('TYPE');
+ var code = "";
+ code = NAME + ".draw" + TYPE + "Line(" + start_x + ',';
+ code += start_y + ',';
+ code += length + ');\n';
+ return code;
+};
+
+export const oled_drawTriangle = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var D1_x = generator.valueToCode(this, 'D1_X', generator.ORDER_ATOMIC) || '0';
+ var D1_y = generator.valueToCode(this, 'D1_Y', generator.ORDER_ATOMIC) || '0';
+ var D2_x = generator.valueToCode(this, 'D2_X', generator.ORDER_ATOMIC) || '0';
+ var D2_y = generator.valueToCode(this, 'D2_Y', generator.ORDER_ATOMIC) || '0';
+ var code = "";
+ code = NAME + '.drawTriangle(' + D0_x + ',';
+ code += D0_y + ',';
+ code += D1_x + ',';
+ code += D1_y + ',';
+ code += D2_x + ',';
+ code += D2_y + ');\n';
+ return code;
+};
+
+export const oled_drawFrame = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC) || '0';
+ var Height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var code = "";
+ code = NAME + '.' + type + '(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Width + ',';
+ code += Height + ');\n';
+ return code;
+};
+
+export const oled_drawRFrame = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC) || '0';
+ var Height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC) || '0';
+ var Rauius = generator.valueToCode(this, 'RADIUS', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var code = "";
+ code = NAME + '.' + type + '(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Width + ',';
+ code += Height + ',';
+ code += Rauius + ');\n';
+ return code;
+};
+
+export const oled_drawCircle = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Rauius = generator.valueToCode(this, 'RADIUS', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var opt = this.getFieldValue('OPT');
+ var code = "";
+ code = NAME + '.' + type + '(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Rauius + "," + opt + "); \n";
+ return code;
+};
+
+export const oled_drawEllipse = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Rauius_X = generator.valueToCode(this, 'RADIUS_X', generator.ORDER_ATOMIC) || '0';
+ var Rauius_Y = generator.valueToCode(this, 'RADIUS_Y', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var opt = this.getFieldValue('OPT');
+ var code = "";
+ code = NAME + '.' + type + '(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Rauius_X + ",";
+ code += Rauius_Y + "," + opt + "); \n";
+ return code;
+};
+
+export const oled_print = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var POS_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var POS_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var TEXT = generator.valueToCode(this, 'TEXT', generator.ORDER_ATOMIC) || '0';
+ generator.setups_["setup_enableUTF8Print" + NAME] = NAME + '.enableUTF8Print();\n';
+ var code = "";
+ code = NAME + '.setCursor(' + POS_x + ',';
+ code += POS_y + "); \n";
+ code += NAME + ".print(" + TEXT + "); \n";
+ return code;
+};
+
+export const oled_set_EN_Font = function () {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var FONT_NAME = this.getFieldValue('FONT_NAME');
+ var FONT_SIZE = this.getFieldValue('FONT_SIZE');
+ var FONT_STYLE = this.getFieldValue('FONT_STYLE');
+ var code = NAME + ".setFont(u8g2_font_" + FONT_NAME + FONT_STYLE + FONT_SIZE + "_tf);\n" + NAME + ".setFontPosTop();\n";
+ return code;
+};
+
+export const oled_set_CN_Font = function () {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var FONT_NAME = this.getFieldValue('FONT_NAME');
+ var FONT_SIZE = this.getFieldValue('FONT_SIZE');
+ var code = NAME + ".setFont(u8g2_font_" + FONT_SIZE + FONT_NAME + ");\n" + NAME + ".setFontPosTop();\n";
+ return code;
+};
+
+export const oled_set_ZH_TW_Font = function () {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+
+ var code = NAME + ".setFont(u8g2_font_unifont_t_chinese1);\n" + NAME + ".setFontPosTop();\n";
+ return code;
+};
+
+// OLED背光亮度
+export const u8g2_setContrast = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var Contrast = generator.valueToCode(this, 'Contrast', generator.ORDER_ATOMIC);
+ var code = NAME + '.setContrast(' + Contrast + ');\n';
+ return code;
+};
+
+// 返回UTF8字符串宽度
+export const get_utf8_width = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'u8g2';
+ var str = generator.valueToCode(this, 'str', generator.ORDER_ATOMIC);
+ generator.definitions_['getutf8width' + NAME] = 'int ' + NAME + '_getUTF8Width(String str) {\n const char *string_variable = str.c_str();\n return ' + NAME + '.getUTF8Width(string_variable);\n}';
+ var code = NAME + '_getUTF8Width(String(' + str + '))';
+ return [code, generator.ORDER_ATOMIC];
+};
+
+// LCD自定义图案显示
+export const lcd_display_pattern = function (_, generator) {
+ var name = this.getFieldValue('name');
+ var number = this.getFieldValue('number');
+ var row = generator.valueToCode(this, 'row', generator.ORDER_ATOMIC);
+ var column = generator.valueToCode(this, 'column', generator.ORDER_ATOMIC);
+ var pattern = generator.valueToCode(this, 'pattern', generator.ORDER_ATOMIC);
+ generator.setups_["setup_lcd_display_pattern" + number] = '' + name + '.createChar(' + number + ', ' + pattern + ');';
+ var code = '' + name + '.setCursor(' + column + '-1, ' + row + '-1);\n' + name + '.write(' + number + ');\n';
+ return code;
+};
+
+export const lcd_pattern = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var a = new Array();
+ for (var i = 1; i < 9; i++) {
+ a[i] = new Array();
+ for (var j = 1; j < 6; j++) {
+ a[i][6 - j] = (this.getFieldValue('a' + i + j) == "TRUE") ? 1 : 0;
+ }
+ }
+ var code = '{0B' + a[8][5] + '' + a[8][4] + '' + a[8][3] + '' + a[8][2] + '' + a[8][1] + ',0B' + a[7][5] + '' + a[7][4] + '' + a[7][3] + '' + a[7][2] + '' + a[7][1] + ',0B' + a[6][5] + '' + a[6][4] + '' + a[6][3] + '' + a[6][2] + '' + a[6][1] + ',0B' + a[5][5] + '' + a[5][4] + '' + a[5][3] + '' + a[5][2] + '' + a[5][1] + ',0B' + a[4][5] + '' + a[4][4] + '' + a[4][3] + '' + a[4][2] + '' + a[4][1] + ',0B' + a[3][5] + '' + a[3][4] + '' + a[3][3] + '' + a[3][2] + '' + a[3][1] + ',0B' + a[2][5] + '' + a[2][4] + '' + a[2][3] + '' + a[2][2] + '' + a[2][1] + ',0B' + a[1][5] + '' + a[1][4] + '' + a[1][3] + '' + a[1][2] + '' + a[1][1] + '};';
+ generator.definitions_[varName] = "byte " + varName + "[]=" + code;
+ return [varName, generator.ORDER_ATOMIC];
+};
+
+export const display_lcd_bitmap = function (_, generator) {
+ var varName = this.getFieldValue('VAR');
+ var bitmap = this.getFieldValue('BITMAP');
+ var code = '{';
+ var i = 0;
+ for (; i < bitmap.length - 1; i++) {
+ code += '0B' + bitmap[i].join('') + ',';
+ }
+ code += '0B' + bitmap[i].join('') + '};';
+ generator.definitions_[varName] = "byte " + varName + "[]=" + code;
+ return [varName, generator.ORDER_ATOMIC];
+};
+
+function rgb565(colour) {
+ colour = colour.substr(1);
+ var R, G, B;
+ R = colour.substr(0, 2);
+ G = colour.substr(2, 2);
+ B = colour.substr(4, 2);
+ colour = R + G + B;
+ colour = "0x" + colour;
+ var RGB565_red = (colour & 0xf80000) >> 8;
+ var RGB565_green = (colour & 0xfc00) >> 5;
+ var RGB565_blue = (colour & 0xf8) >> 3;
+ var n565Color = RGB565_red + RGB565_green + RGB565_blue;
+ return n565Color;
+}
+
+// 初始化TFT
+export const TFT_init_with_pin = function (_, generator) {
+ const PIN_CS = this.getFieldValue('CS');
+ const PIN_DC = this.getFieldValue('DC');
+ const PIN_RST = this.getFieldValue('RST');
+ const TYPE = this.getFieldValue('TYPE');
+ let icType = TYPE.split('_')[0];
+ let initParam = '';
+ if (TYPE === 'ST7735_INITR_GREENTAB') {
+ initParam = 'INITR_GREENTAB';
+ } else if (TYPE === 'ST7735_INITR_REDTAB') {
+ initParam = 'INITR_REDTAB';
+ } else if (TYPE === 'ST7735_INITR_BLACKTAB') {
+ initParam = 'INITR_BLACKTAB';
+ } else if (TYPE === 'ST7735_160×80') {
+ initParam = 'INITR_MINI160x80';
+ } else if (TYPE === 'ST7735_160×128') {
+ initParam = '128, 160';
+ } else if (TYPE === 'ST7789_240×135') {
+ initParam = '135, 240';
+ } else if (TYPE === 'ST7789_240×240') {
+ initParam = '240, 240';
+ } else if (TYPE === 'ST7789_320×240') {
+ initParam = '240, 320';
+ } else if (TYPE === 'ST7796_480×320') {
+ initParam = '';
+ }
+ generator.definitions_["include_Adafruit_GFX"] = '#include ';
+ generator.definitions_["include_Adafruit_tft"] = '#include ';
+ generator.definitions_["include_SPI"] = '#include ';
+ generator.definitions_['var_declare_Adafruit_tft'] = 'Adafruit_' + icType + ' tft = Adafruit_' + icType + '(' + PIN_CS + ', ' + PIN_DC + ', ' + PIN_RST + ');';
+ generator.setups_["setup_tft_init"] = 'tft.' + (icType === 'ST7735' ? 'initR' : 'init') + '(' + initParam + ');';
+ generator.setups_["setup_tft_fillScreen"] = 'tft.fillScreen(0x0000);';
+ generator.definitions_["include_U8g2_for_Adafruit_GFX"] = '#include ';
+ generator.definitions_['var_declare_U8G2_FOR_ADAFRUIT_GFX'] = 'U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;';
+ generator.setups_["setup_u8g2_for_adafruit_gfx"] = 'u8g2_for_adafruit_gfx.begin(tft);';
+ var code = '';
+ return code;
+};
+
+//将字符串转整数
+function myAtoi(str) {
+ str = str.replace(/(^\s*)|(\s*$)/g, "");//去掉字符串最前面的空格,中间的不用管
+ var str1 = "";
+ for (let i = 0; i < str.length; i++) {
+ if ((str.charAt(i) == "-" || str.charAt(i) == "+") && i == 0) {
+ str1 = str1.concat(str.charAt(i))
+ }//如果“+”“-”号在最前面
+ else if (/^\d+$/.test(str.charAt(i))) {
+ str1 = str1.concat(str.charAt(i))
+ }//用字符串存储值
+ else {
+ break//直接跳出for循环
+ }
+ }
+ if (str1 - 0 > 2147483647) {
+ return 2147483647
+ } //str-0 字符串化为数组最简单也是最常用的方法
+ else if (str1 - 0 < -2147483648) {
+ return -2147483648
+ }
+ if (isNaN(str1 - 0)) return 0//"+"/"-"这种情况,返回0
+ return str1 - 0
+}
+
+//将一个数字转化成16进制字符串形式
+function toHex(num) {
+ return num < 16 ? "0x0" + num.toString(16).toUpperCase() : "0x" + num.toString(16).toUpperCase();
+}
+
+//将文本或符号编码
+function encodeUnicode(str) {
+ let res = [];
+ for (let i = 0; i < str.length; i++) {
+ res[i] = ("00" + str.charCodeAt(i).toString(16)).slice(-4);
+ }
+ return "_u" + res.join("_u");
+}
+
+var canvas = document.createElement("canvas");//创建canvas
+var ctx = canvas.getContext("2d");//获得内容描述句柄
+var bitArr = new Array();
+
+//显示汉字(使用位图显示)
+export const TFT_st7735_show_hz = function (_, generator) {
+ var text_st7735_name = 'tft';
+ var checkbox_st7735_show_hz = 'TRUE';
+ var checkbox_st7735_show_hz_message = 'TRUE';
+ var checkbox_st7735_show_hz_save = this.getFieldValue('st7735_show_hz_save') == 'TRUE';
+ var dropdown_st7735_hz_sharp = this.getFieldValue('st7735_hz_sharp');
+ var text_st7735_hz_line_height = this.getFieldValue('st7735_hz_line_height');
+ var dropdown_hz_up_down = this.getFieldValue('hz_up_down');
+ var text_hz_up_down_data = this.getFieldValue('hz_up_down_data');
+ var dropdown_hz_left_right = this.getFieldValue('hz_left_right');
+ var text_hz_left_right_data = this.getFieldValue('hz_left_right_data');
+ var value_st7735_hz_data = generator.valueToCode(this, 'st7735_hz_data', generator.ORDER_ATOMIC);
+ var value_st7735_hz_x = generator.valueToCode(this, 'st7735_hz_x', generator.ORDER_ATOMIC);
+ var value_st7735_hz_y = generator.valueToCode(this, 'st7735_hz_y', generator.ORDER_ATOMIC);
+ var value_st7735_hz_height = generator.valueToCode(this, 'st7735_hz_height', generator.ORDER_ATOMIC);
+ var value_st7735_hz_width = generator.valueToCode(this, 'st7735_hz_width', generator.ORDER_ATOMIC);
+ var value_st7735_hz_color = generator.valueToCode(this, 'st7735_hz_color', generator.ORDER_ATOMIC);
+ var dropdown_st7735_hz_variant = 'normal';
+ var dropdown_st7735_hz_style = 'normal';
+ var dropdown_st7735_hz_thickness = 'normal';
+ var fontSize_width = myAtoi(value_st7735_hz_width);
+ var fontSize_height = myAtoi(value_st7735_hz_height);
+ var bs = Math.ceil(fontSize_width / 8);//每行占字节数
+
+ var move_x = 0;
+ var move_y = 0;
+ if (dropdown_hz_up_down == "hz_down") {
+ move_y = myAtoi(text_hz_up_down_data);
+ }
+ else {
+ move_y = myAtoi("-" + text_hz_up_down_data);
+ }
+
+ if (dropdown_hz_left_right == "hz_right") {
+ move_x = myAtoi(text_hz_left_right_data);
+ }
+ else {
+ move_x = myAtoi("-" + text_hz_left_right_data);
+ }
+ canvas.width = fontSize_width;
+ canvas.height = fontSize_height;
+ ctx.font = dropdown_st7735_hz_style + ' ' + dropdown_st7735_hz_variant + ' ' + dropdown_st7735_hz_thickness + ' ' + text_st7735_hz_line_height + 'px ' + dropdown_st7735_hz_sharp;
+ ctx.textAlign = "left";
+ ctx.textBaseline = "top";
+
+ var c = value_st7735_hz_data;
+ ctx.fillStyle = "#000000";
+ ctx.fillRect(0, 0, fontSize_width, fontSize_height);//涂背景
+ ctx.fillStyle = "#ffffff";
+ ctx.fillText(c, move_x, move_y);//写字
+ var data = ctx.getImageData(0, 0, fontSize_width, fontSize_height).data;//获取图像
+ var zm = new Array(bs * fontSize_height);
+ for (var i = 0; i < zm.length; i++)zm[i] = 0;//初始化字模数组
+ for (var i = 0; i < fontSize_height; i++)//读像素值组成字模数组
+ for (var j = 0; j < fontSize_width; j++)
+ if (data[i * fontSize_width * 4 + j * 4]) zm[parseInt(j / 8) + i * bs] += bitArr[j % 8];
+ var outStr = "";//将字模数组转化为十六进制形式
+ for (var i = 0; i < zm.length - 1; i++)outStr += toHex(zm[i]) + ",";
+ outStr += toHex(zm[i]);
+
+ var zm1 = new Array(bs * fontSize_height);
+ var outstr1 = "";
+ for (var i in zm) zm1[i] = zm[i].toString(2);
+ for (var i in zm1) {
+ var str = "";
+ for (var j = 0; j < 8 - zm1[i].length; j++)str += "0";
+ zm1[i] = str + zm1[i];
+ }
+ for (var i in zm1) outstr1 += zm1[i];
+
+ var HZ_image = "";
+ var num_hz = 0;
+ for (var i = 0; i < fontSize_width; i++) {
+ HZ_image += "--";
+ if (i == (fontSize_width - 1)) HZ_image += "\n|";
+ }
+
+ for (var data_hz of outstr1) {
+ num_hz++;
+ if (num_hz == outstr1.length) {
+ HZ_image += "|\n";
+ }
+ else if (num_hz % (bs * 8) < fontSize_width && num_hz % (bs * 8) > 0) {
+ if (data_hz == "0") HZ_image += " ";
+ else if (data_hz == "1") HZ_image += "0 ";
+ }
+ else if (num_hz % (bs * 8) == 0) {
+ HZ_image += "|\n|";
+ }
+ }
+ for (var i = 0; i < fontSize_width; i++) {
+ HZ_image += "--";
+ }
+ HZ_image = "/*" + "\n" + HZ_image + "\n" + "*/";
+
+ var hz_sharp = "";
+ switch (dropdown_st7735_hz_sharp) {
+ case "STHeiti":
+ hz_sharp = "华文黑体";
+ break;
+ case "STKaiti":
+ hz_sharp = "华文楷体";
+ break;
+ case "STXihei":
+ hz_sharp = "华文细黑";
+ break;
+ case "STSong":
+ hz_sharp = "华文宋体";
+ break;
+ case "STZhongsong":
+ hz_sharp = "华文中宋";
+ break;
+ case "STFangsong":
+ hz_sharp = "华文仿宋";
+ break;
+ case "STCaiyun":
+ hz_sharp = "华文彩云";
+ break;
+ case "STHupo":
+ hz_sharp = "华文琥珀";
+ break;
+ case "STLiti":
+ hz_sharp = "华文隶书";
+ break;
+ case "STXingkai":
+ hz_sharp = "华文行楷";
+ break;
+ case "STXinwei":
+ hz_sharp = "华文新魏";
+ break;
+ case "simHei":
+ hz_sharp = "黑体";
+ break;
+ case "simSun":
+ hz_sharp = "宋体";
+ break;
+ case "NSimSun":
+ hz_sharp = "新宋体";
+ break;
+ case "FangSong":
+ hz_sharp = "仿宋";
+ break;
+ case "KaiTi":
+ hz_sharp = "楷体";
+ break;
+ case "FangSong_GB2312":
+ hz_sharp = "仿宋_GB2312";
+ break;
+ case "KaiTi_GB2312":
+ hz_sharp = "楷体_GB2312";
+ break;
+ case "LiSu":
+ hz_sharp = "隶书";
+ break;
+ case "YouYuan":
+ hz_sharp = "幼圆";
+ break;
+ case "PMingLiU":
+ hz_sharp = "新细明体";
+ break;
+ case "MingLiU":
+ hz_sharp = "细明体";
+ break;
+ case "DFKai-SB":
+ hz_sharp = "标楷体";
+ break;
+ case "Microsoft JhengHei":
+ hz_sharp = "微软正黑体";
+ break;
+ case "Microsoft YaHei":
+ hz_sharp = "微软雅黑体";
+ break;
+ default:
+ hz_sharp = dropdown_st7735_hz_sharp;
+ break;
+ }
+ hz_sharp = "字体:" + hz_sharp + " 字号:" + text_st7735_hz_line_height + "px" + " 显示文字:" + value_st7735_hz_data;
+
+ if (checkbox_st7735_show_hz) {
+ generator.definitions_['var_declare_oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = HZ_image + "\n//" + hz_sharp;
+ if (checkbox_st7735_show_hz_save) {
+ generator.libs_['oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = HZ_image + "\n//" + hz_sharp + "\nstatic const unsigned char PROGMEM oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
+ }
+ else {
+ generator.libs_['oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = HZ_image + "\n//" + hz_sharp + "\nunsigned char oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
+ }
+ }
+ else {
+ if (checkbox_st7735_show_hz_message) {
+ generator.definitions_['var_declare_oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "//" + hz_sharp;
+ if (checkbox_st7735_show_hz_save) {
+ generator.libs_['oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "//" + hz_sharp + "\nstatic const unsigned char PROGMEM oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
+ }
+ else {
+ generator.libs_['oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "//" + hz_sharp + "\nunsigned char oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
+ }
+ }
+ else {
+ if (checkbox_st7735_show_hz_save) {
+ generator.libs_['oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "static const unsigned char PROGMEM oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
+ }
+ else {
+ generator.libs_['oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data)] = "unsigned char oled_st7735_" + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + "[" + (bs * fontSize_height) + "]={" + outStr + "};";
+ }
+ }
+ }
+ if (checkbox_st7735_show_hz_message) {
+ var code = '//绘制位图 ' + hz_sharp + ' X坐标:' + value_st7735_hz_x + ' Y坐标:' + value_st7735_hz_y + ' 位图宽度:' + value_st7735_hz_width + ' 位图高度:' + value_st7735_hz_height + '\n' + text_st7735_name + '.drawBitmap(' + value_st7735_hz_x + ', ' + value_st7735_hz_y + ', oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + ', ' + value_st7735_hz_width + ', ' + value_st7735_hz_height + ', ' + value_st7735_hz_color + ');\n';
+ }
+ else {
+ var code = text_st7735_name + '.drawBitmap(' + value_st7735_hz_x + ', ' + value_st7735_hz_y + ', oled_st7735_' + dropdown_st7735_hz_sharp + '_' + text_st7735_hz_line_height + 'px' + encodeUnicode(value_st7735_hz_data) + ', ' + value_st7735_hz_width + ', ' + value_st7735_hz_height + ', ' + value_st7735_hz_color + ');\n';
+ }
+ return code;
+};
+
+export const TFT_Brightness = function (_, generator) {
+ var Brightness = generator.valueToCode(this, 'BRIGHTNESS', generator.ORDER_ASSIGNMENT);
+ //generator.setups_['ledcSetup_tft_brightness'] = 'ledcSetup(0,5000,8);\n';
+ //generator.setups_['ledcAttachPin_tft_brightness'] = 'ledcAttachPin(26,0);\n ';
+ var code = 'dacWrite(26, ' + Brightness + '*4+30);\n';
+ return code;
+};
+
+export const tft_icons = function (_, generator) {
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+ var POS_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var POS_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var ICON_SIZE = this.getFieldValue('ICON_SIZE');
+ var ICON_IMAGE = this.getFieldValue('ICON_IMAGE');
+ var code = "u8g2_for_adafruit_gfx.setFont(u8g2_font_open_iconic_all_" + ICON_SIZE + "x_t);\n"
+ + "u8g2_for_adafruit_gfx.setForegroundColor(" + colour + ");\n"
+ + "u8g2_for_adafruit_gfx.setFontMode(1);\n"
+ + "u8g2_for_adafruit_gfx.drawGlyph(" + POS_x + "," + POS_y + "+" + ICON_SIZE + "*8," + ICON_IMAGE + ");\n";
+ return code;
+};
+
+export const TFT_Rotation = function () {
+ var dropdown_type = this.getFieldValue('Rotation_TYPE');
+ var code = 'tft.setRotation(' + dropdown_type + ');\n'
+ return code;
+};
+
+export const tft_setFont = function () {
+ var type = this.getFieldValue('TYPE');
+ var code = "u8g2_for_adafruit_gfx.setFont(u8g2_font_" + type + ");\nu8g2_for_adafruit_gfx.setFontMode(1);\n";
+ return code;
+};
+
+export const tft_print = function (_, generator) {
+ var POS_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var POS_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var TEXT = generator.valueToCode(this, 'TEXT', generator.ORDER_ATOMIC) || '0';
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ var code = `u8g2_for_adafruit_gfx.setCursor(${POS_x}, ${POS_y});\n`;
+ // code +='u8g2_for_adafruit_gfx.setFontMode(0);'
+ code += `u8g2_for_adafruit_gfx.setForegroundColor(${colour});\n`;
+ code += `u8g2_for_adafruit_gfx.print(${TEXT});\n`;
+ return code;
+};
+
+export const TFT_color_seclet = function (_, generator) {
+ var colour = this.getFieldValue('COLOR');
+ colour = rgb565(colour);
+ return [colour, generator.ORDER_NONE];
+};
+
+export const TFT_color_rgb = function (_, generator) {
+ var R = generator.valueToCode(this, 'R', generator.ORDER_ATOMIC);
+ var G = generator.valueToCode(this, 'G', generator.ORDER_ATOMIC);
+ var B = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC);
+ var colour = R + "*256" + "+" + G + "*8" + "+" + B + "/8";
+ return [colour, generator.ORDER_NONE];
+};
+
+export const TFT_init = function (_, generator) {
+ generator.definitions_["include_Adafruit_GFX"] = '#include ';
+ generator.definitions_["include_Adafruit_ST7735"] = '#include ';
+ generator.definitions_["include_SPI"] = '#include ';
+ generator.definitions_['var_declare_Adafruit_ST7735'] = 'Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC,-1);';
+ generator.setups_["setup_tft.initR"] = 'tft.initR(INITR_18GREENTAB);';
+ generator.setups_["setup_tft.fillScreen(ST7735_BLACK)"] = 'tft.fillScreen(ST7735_BLACK);';
+ generator.setups_['ledcSetup_tft_brightness'] = 'dacWrite(26, 255);';
+ generator.definitions_["include_U8g2_for_Adafruit_GFX"] = '#include ';
+ generator.definitions_['var_declare_U8G2_FOR_ADAFRUIT_GFX'] = 'U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;';
+ generator.setups_["setup_u8g2_for_adafruit_gfx"] = 'u8g2_for_adafruit_gfx.begin(tft);';
+ return '';
+};
+
+export const TFT_fillScreen = function (_, generator) {
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+ var code = 'tft.fillScreen' + '(' + colour + ');\n';
+ return code;
+};
+
+export const tft_drawPixel = function (_, generator) {
+ var pos_x = generator.valueToCode(this, 'POS_X', generator.ORDER_ATOMIC) || '0';
+ var pos_y = generator.valueToCode(this, 'POS_Y', generator.ORDER_ATOMIC) || '0';
+ var code = "";
+ var COLOR = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+ COLOR = COLOR.replace(/#/g, "0x");
+ COLOR = rgb565(COLOR);
+ code += 'tft.drawPixel(' + pos_x + ',';
+ code += pos_y;
+ code += ',' + COLOR + ');\n';
+ return code;
+};
+
+export const tft_drawLine = function (_, generator) {
+ var start_x = generator.valueToCode(this, 'START_X', generator.ORDER_ATOMIC) || '0';
+ var start_y = generator.valueToCode(this, 'START_Y', generator.ORDER_ATOMIC) || '0';
+ var end_x = generator.valueToCode(this, 'END_X', generator.ORDER_ATOMIC) || '0';
+ var end_y = generator.valueToCode(this, 'END_Y', generator.ORDER_ATOMIC) || '0';
+ var code = "";
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ code = 'tft.drawLine(' + start_x + ',';
+ code += start_y + ',';
+ code += end_x + ',';
+ code += end_y;
+ code += ',' + colour + ');\n';
+ return code;
+};
+
+export const tft_drawFastLine = function (_, generator) {
+ var start_x = generator.valueToCode(this, 'START_X', generator.ORDER_ATOMIC) || '0';
+ var start_y = generator.valueToCode(this, 'START_Y', generator.ORDER_ATOMIC) || '0';
+ var length = generator.valueToCode(this, 'LENGTH', generator.ORDER_ATOMIC) || '0';
+ var TYPE = this.getFieldValue('TYPE');
+ var code = "";
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ code = "tft.drawFast" + TYPE + "Line(" + start_x + ',';
+ code += start_y + ',';
+ code += length;
+ code += ',' + colour + ');\n';
+ return code;
+};
+
+export const tft_Triangle = function (_, generator) {
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var D1_x = generator.valueToCode(this, 'D1_X', generator.ORDER_ATOMIC) || '0';
+ var D1_y = generator.valueToCode(this, 'D1_Y', generator.ORDER_ATOMIC) || '0';
+ var D2_x = generator.valueToCode(this, 'D2_X', generator.ORDER_ATOMIC) || '0';
+ var D2_y = generator.valueToCode(this, 'D2_Y', generator.ORDER_ATOMIC) || '0';
+ var code = "";
+ var type = this.getFieldValue('TYPE');
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ code = 'tft.' + type + 'Triangle(' + D0_x + ',';
+ code += D0_y + ',';
+ code += D1_x + ',';
+ code += D1_y + ',';
+ code += D2_x + ',';
+ code += D2_y;
+ code += ',' + colour + ');\n';
+ return code;
+};
+
+export const tft_Rect = function (_, generator) {
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC) || '0';
+ var Height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var code = "";
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ code = 'tft.' + type + 'Rect(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Width + ',';
+ code += Height;
+ code += ',' + colour + ');\n';
+ return code;
+};
+
+export const tft_RoundRect = function (_, generator) {
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC) || '0';
+ var Height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC) || '0';
+ var Rauius = generator.valueToCode(this, 'RADIUS', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var code = "";
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ code = 'tft.' + type + 'RoundRect(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Width + ',';
+ code += Height + ',';
+ code += Rauius;
+ code += ',' + colour + ');\n';
+ return code;
+};
+
+export const tft_Circle = function (_, generator) {
+ var D0_x = generator.valueToCode(this, 'D0_X', generator.ORDER_ATOMIC) || '0';
+ var D0_y = generator.valueToCode(this, 'D0_Y', generator.ORDER_ATOMIC) || '0';
+ var Rauius = generator.valueToCode(this, 'RADIUS', generator.ORDER_ATOMIC) || '0';
+ var type = this.getFieldValue('TYPE');
+ var code = "";
+ var colour = generator.valueToCode(this, 'COLOR', generator.ORDER_ATOMIC);
+
+ code = 'tft.' + type + 'Circle(' + D0_x + ',';
+ code += D0_y + ',';
+ code += Rauius;
+ code += ',' + colour + ');\n';
+ return code;
+};
+
+export const tft_define_bitmap_data = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Variables.NAME_TYPE);
+ var text = this.getFieldValue('TEXT');
+ generator.libs_[varName] = 'const uint16_t ' + varName + '[] PROGMEM = {\n' + text + '\n};\n';
+ return '';
+};
+
+export const tft_generate_bitmap_data = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Variables.NAME_TYPE);
+ var text = this.getFieldValue('TEXT');
+ generator.libs_[varName] = 'const uint16_t ' + varName + '[] PROGMEM = {\n ' + text + '\n};\n';
+ return '';
+};
+
+export const tft_showBitmap = function (_, generator) {
+ var start_x = generator.valueToCode(this, 'START_X', generator.ORDER_ATOMIC) || '0';
+ var start_y = generator.valueToCode(this, 'START_Y', generator.ORDER_ATOMIC) || '0';
+ var Height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC) || '0';
+ var WIDTH = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC) || '0';
+ var data_name = generator.valueToCode(this, 'bitmap_name', generator.ORDER_ATOMIC);
+ data_name = data_name.replace(/"/g, "");
+ var code = "tft.drawRGBBitmap(" + start_x + ", " + start_y + ", " + data_name + ", " + WIDTH + ", " + Height + ");";
+ return code;
+};
+
+export const tft_set_EN_Font = function () {
+ var FONT_NAME = this.getFieldValue('FONT_NAME');
+ var FONT_SIZE = this.getFieldValue('FONT_SIZE');
+ var FONT_STYLE = this.getFieldValue('FONT_STYLE');
+ var code = "u8g2_for_adafruit_gfx.setFont(u8g2_font_" + FONT_NAME + FONT_STYLE + FONT_SIZE + "_tf);\n";
+ return code;
+};
+
+export const tft_set_CN_Font = function () {
+ var FONT_NAME = this.getFieldValue('FONT_NAME');
+ var FONT_SIZE = this.getFieldValue('FONT_SIZE');
+ var code = "u8g2_for_adafruit_gfx.setFont(u8g2_font_" + FONT_SIZE + FONT_NAME + ");\n";
+ return code;
+};
+
+export const display_TM1637_init_32 = function (_, generator) {
+ tm1637_CLK = this.getFieldValue('CLK');
+ tm1637_DIO = this.getFieldValue('DIO');
+ var NAME = this.getFieldValue('NAME') || 'display';
+ generator.definitions_['include_TM1637Display'] = '#include ';
+ generator.definitions_['var_declare_SevenSegmentTM1637' + NAME] = 'TM1637Display ' + NAME + '(' + tm1637_CLK + ',' + tm1637_DIO + ');';
+ generator.setups_['setup_' + NAME + '.begin()'] = NAME + '.setBrightness(7);';
+ return '';
+};
+
+export const display_TM1637_displyPrint_32 = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'display';
+ //var Speed = generator.valueToCode(this, 'Speed', generator.ORDER_ATOMIC);
+ var VALUE = generator.valueToCode(this, 'VALUE', generator.ORDER_ATOMIC);
+ var code = NAME + '.showNumberDec(String(' + VALUE + ').toInt(), false);' + '\n';
+ return code;
+};
+
+export const display_TM1637_displayTime_32 = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'display';
+ var hour = generator.valueToCode(this, 'hour', generator.ORDER_ATOMIC);
+ var minute = generator.valueToCode(this, 'minute', generator.ORDER_ATOMIC);
+ var dropdown_stat = this.getFieldValue("STAT");
+ var code = NAME + '.showNumberDecEx(((' + hour + ' * 100)+' + minute + '),' + dropdown_stat + ',1);\n';
+ return code;
+};
+
+export const display_TM1637_clearDisplay_32 = function () {
+ var stat = this.getFieldValue("STAT");
+ var NAME = this.getFieldValue('NAME') || 'display';
+ return NAME + '.' + stat + '();\n';
+};
+
+export const display_TM1637_Brightness_32 = function (_, generator) {
+ var NAME = this.getFieldValue('NAME') || 'display';
+ var BRIGHTNESS = generator.valueToCode(this, 'Brightness', generator.ORDER_ATOMIC);
+ var code = NAME + '.setBrightness(' + BRIGHTNESS + ');\n';
+ return code;
+};
+
+export const group_lcd_init = group_lcd_init2;
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/ethernet.js b/mixly/boards/default_src/arduino_avr/generators/ethernet.js
new file mode 100644
index 00000000..ea9d494e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/ethernet.js
@@ -0,0 +1,3166 @@
+import { JSFuncs } from 'mixly';
+
+export const ethernet_init_begin = function (_, generator) {
+ var Ethernet = this.getFieldValue('Ethernet');
+ generator.definitions_['include_spi'] = '#include ';
+ generator.definitions_['include_' + Ethernet] = '#include <' + Ethernet + '.h>';
+ generator.definitions_['var_declare_EthernetClient'] = 'EthernetClient client;';
+ var mac = generator.valueToCode(this, 'MAC', generator.ORDER_ATOMIC);
+ var code = "Ethernet.begin(" + mac + ")";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_mac_address = function (_, generator) {
+ var VAR1 = this.getFieldValue('VAR1');
+ var VAR2 = this.getFieldValue('VAR2');
+ var VAR3 = this.getFieldValue('VAR3');
+ var VAR4 = this.getFieldValue('VAR4');
+ var VAR5 = this.getFieldValue('VAR5');
+ var VAR6 = this.getFieldValue('VAR6');
+ generator.definitions_['var_declare_byte_mac'] = 'byte mac[] = {0x' + VAR1 + ', 0x' + VAR2 + ', 0x' + VAR3 + ', 0x' + VAR4 + ', 0x' + VAR5 + ', 0x' + VAR6 + '};';
+ var code = "mac";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_init_local_ip = function (_, generator) {
+ var code = "Ethernet.localIP()";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_client_connect_server = function (_, generator) {
+ var PORT = generator.valueToCode(this, 'PORT', generator.ORDER_ATOMIC);
+ var SERVER = generator.quote_(this.getFieldValue('SERVER'));
+ var code = 'client.connect(' + SERVER + ',' + PORT + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_client_stop = function () {
+ var code = "client.stop();\n";
+ return code;
+}
+
+export const ethernet_client_connected = function (_, generator) {
+ var code = "client.connected()";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_client_available = function (_, generator) {
+ var code = "client.available()";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_client_print = function (_, generator) {
+ var TEXT = generator.valueToCode(this, 'TEXT', generator.ORDER_ATOMIC) || '""';
+ var code = 'client.print(' + TEXT + ');\n';
+ return code;
+}
+
+export const ethernet_client_println = function (_, generator) {
+ var TEXT = generator.valueToCode(this, 'TEXT', generator.ORDER_ATOMIC) || '""';
+ var code = 'client.println(' + TEXT + ');\n';
+ return code;
+}
+
+export const ethernet_client_read = function (_, generator) {
+ var code = "(char)client.read()";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ethernet_client_get_request = function () {
+ var URL = this.getFieldValue('URL');
+ var SERVER = this.getFieldValue('SERVER');
+ var code = 'client.println("GET ' + URL + ' HTTP/1.1");\n'
+ + 'client.println(F("Host: ' + SERVER + '"));\n'
+ + 'client.println(F("Connection: close"));\n'
+ + 'client.println();\n';
+ return code;
+}
+
+export const WIFI_info = function (_, generator) {
+ var SSID = generator.valueToCode(this, 'SSID', generator.ORDER_ATOMIC);
+ var PWD = generator.valueToCode(this, 'PWD', generator.ORDER_ATOMIC);
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.setups_['setup_WiFi_begin'] = 'WiFi.begin(' + SSID + ', ' + PWD + ');\n'
+ + ' while (WiFi.status() != WL_CONNECTED) {\n'
+ + ' delay(500);\n'
+ + ' Serial.print(".");\n'
+ + ' }\n'
+ + ' Serial.println("Local IP:");\n'
+ + ' Serial.print(WiFi.localIP());\n'
+ return "";
+}
+
+export const network_wifi_connect = function (_, generator) {
+ return ["WiFi.status()", generator.ORDER_ATOMIC];
+}
+
+export const network_get_connect = function (_, generator) {
+ var board_type = JSFuncs.getPlatform();
+ var mode = this.getFieldValue('mode');
+ if (board_type.match(RegExp(/ESP8266/))) {
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ }
+ else if (board_type.match(RegExp(/ESP32/))) {
+ generator.definitions_['include_WiFi'] = '#include ';
+ }
+ if (mode == 'IP') {
+ return ["WiFi.localIP()", generator.ORDER_ATOMIC];
+ }
+ return ["WiFi.macAddress()", generator.ORDER_ATOMIC];
+}
+
+export const NTP_server = function (_, generator) {
+ var server_add = generator.valueToCode(this, 'server_add', generator.ORDER_ATOMIC);
+ var timeZone = generator.valueToCode(this, 'timeZone', generator.ORDER_ATOMIC);
+ var Interval = generator.valueToCode(this, 'Interval', generator.ORDER_ATOMIC);
+ generator.definitions_['include_TimeLib'] = '#include ';
+ generator.definitions_['include_NtpClientLib'] = '#include ';
+ generator.definitions_['var_declare_timeZone'] = 'int8_t timeZone = ' + timeZone + ';';
+ generator.definitions_['var_declare_ntpServer'] = 'const PROGMEM char *ntpServer = ' + server_add + ';';
+ generator.setups_['setup_NTP.setInterval'] = 'NTP.setInterval (' + Interval + ');';
+ generator.setups_['setup_NTP.setNTPTimeout'] = 'NTP.setNTPTimeout (1500);';
+ generator.setups_['setup_NTP.begin'] = 'NTP.begin (ntpServer, timeZone, false);';
+ return "";
+}
+
+export const NTP_server_get_time = function (_, generator) {
+ var timeType = this.getFieldValue('TIME_TYPE');
+ var code = timeType;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+var Client_ID;
+
+export const MQTT_server = function (_, generator) {
+ var server_add = generator.valueToCode(this, 'server_add', generator.ORDER_ATOMIC);
+ var server_port = generator.valueToCode(this, 'server_port', generator.ORDER_ATOMIC);
+ var IOT_ID = generator.valueToCode(this, 'IOT_ID', generator.ORDER_ATOMIC);
+ var IOT_PWD = generator.valueToCode(this, 'IOT_PWD', generator.ORDER_ATOMIC);
+ Client_ID = generator.valueToCode(this, 'Client_ID', generator.ORDER_ATOMIC);
+ if (Client_ID.length > 2) {
+ Client_ID += '/';
+ }
+ Client_ID = Client_ID.replace(/"/g, "");
+ generator.definitions_['include_Adafruit_MQTT'] = '#include "Adafruit_MQTT.h"';
+ generator.definitions_['include_Adafruit_MQTT_Client'] = '#include "Adafruit_MQTT_Client.h"';
+ generator.definitions_['include__WiFiClient'] = 'WiFiClient client;';
+ generator.definitions_['var_declare_Adafruit_MQTT_Client'] = 'Adafruit_MQTT_Client mqtt(&client, ' + server_add + ', ' + server_port + ', ' + IOT_ID + ', ' + IOT_PWD + ');';
+ var board_type = JSFuncs.getPlatform();
+ if (board_type.match(RegExp(/ESP8266/))) {
+ generator.definitions_['var_declare_ MQTT_connect();'] = 'void MQTT_connect();';
+ }
+ var funcName = 'MQTT_connect';
+ var code = 'void' + ' ' + funcName + '() {\n'
+ + ' int8_t ret;\n'
+ + ' if (mqtt.connected()) {\n'
+ + ' return;\n'
+ + ' }\n'
+ + ' Serial.print("Connecting to MQTT... ");\n'
+ + ' uint8_t retries = 3;\n'
+ + ' while ((ret = mqtt.connect()) != 0) {\n'
+ + ' Serial.println(mqtt.connectErrorString(ret));\n'
+ + ' Serial.println("Retrying MQTT connection in 5 seconds...");\n'
+ + ' mqtt.disconnect();\n'
+ + ' delay(5000);\n'
+ + ' retries--;\n'
+ + ' if (retries == 0) {\n'
+ + ' while (1);\n'
+ + ' }\n'
+ + ' }\n'
+ + ' Serial.println("MQTT Connected!");\n'
+ + '}\n';
+ generator.definitions_['var_declare_' + funcName] = code;
+ return funcName + '();\n';
+}
+
+export const MQTT_connect = function () {
+ var funcName = 'MQTT_connect';
+ // var code = 'void' + ' ' + funcName + '() {\n'
+ // + ' int8_t ret;\n'
+ // + ' if (mqtt.connected()) {\n'
+ // + ' return;\n'
+ // + ' }\n'
+ // + ' Serial.print("Connecting to MQTT... ");\n'
+ // + ' uint8_t retries = 3;\n'
+ // + ' while ((ret = mqtt.connect()) != 0) {\n'
+ // + ' Serial.println(mqtt.connectErrorString(ret));\n'
+ // + ' Serial.println("Retrying MQTT connection in 5 seconds...");\n'
+ // + ' mqtt.disconnect();\n'
+ // + ' delay(5000);\n'
+ // + ' retries--;\n'
+ // + ' if (retries == 0) {\n'
+ // + ' while (1);\n'
+ // + ' }\n'
+ // + ' }\n'
+ // + ' Serial.println("MQTT Connected!");\n'
+ // + '}\n';
+ return funcName + '();\n';
+}
+
+// 物联网-发送数据到app
+export const MQTT_publish = function (_, generator) {
+ var Topic = this.getFieldValue('Topic');
+ var data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ var Topic_var = "MQTT_Topic_" + Topic;
+ generator.definitions_['var_declare_Adafruit_MQTT_Publish' + Topic_var] = 'Adafruit_MQTT_Publish ' + Topic_var + ' = Adafruit_MQTT_Publish(&mqtt, "' + Client_ID + Topic + '");';
+ var code = Topic_var + '.publish(' + data + ');\n ';
+ return code;
+}
+
+export const MQTT_subscribe_value = function (_, generator) {
+ var Topic = this.getFieldValue('Topic_0');
+ if (Topic)
+ Topic = Topic.replace(/"/g, "");
+ var Topic_var = "MQTT_Topic_" + Topic;
+ var code = '(char *)' + Topic_var + '.lastread';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const MQTT_subscribe = function (_, generator) {
+ var n = 0;
+ var Topic = this.getFieldValue('Topic_0');
+ if (Topic)
+ Topic = Topic.replace(/"/g, "");
+ var Topic_var = "MQTT_Topic_" + Topic;
+ var branch = generator.statementToCode(this, 'DO' + n);
+ var code = 'if (subscription ==&' + Topic_var + ') {\n ' + branch.replace(new RegExp(/\n/g), "\n ") + '\n }';
+ generator.definitions_['var_declare_Adafruit_MQTT_Subscribe' + Client_ID + '/' + Topic] = 'Adafruit_MQTT_Subscribe ' + Topic_var + ' = Adafruit_MQTT_Subscribe(&mqtt,"' + Client_ID + Topic + '");';
+ generator.setups_['setup_mqtt.subscribe' + Topic] = 'mqtt.subscribe(&' + Topic_var + ');';
+ for (n = 1; n <= this.elseifCount_; n++) {
+ var Topic = this.getFieldValue('Topic_' + n);
+ if (Topic)
+ Topic = Topic.replace(/"/g, "");
+ Topic_var = "MQTT_Topic_" + Topic;
+ branch = generator.statementToCode(this, 'DO' + n);
+ generator.definitions_['var_declare_Adafruit_MQTT_Subscribe' + Client_ID + Topic] = 'Adafruit_MQTT_Subscribe ' + Topic_var + ' = Adafruit_MQTT_Subscribe(&mqtt,"' + Client_ID + Topic + '");';
+ generator.setups_['setup_mqtt.subscribe' + Topic] = 'mqtt.subscribe(&' + Topic_var + ');';
+ code += ' else if (subscription == &' + Topic_var + ') {\n ' + branch.replace(new RegExp(/\n/g), "\n ") + '\n }';
+ }
+ if (this.elseCount_) {
+ branch = generator.statementToCode(this, 'ELSE');
+ code += ' else {\n ' + branch + '\n }';
+ }
+ return 'Adafruit_MQTT_Subscribe *subscription;\nwhile ((subscription = mqtt.readSubscription(5000))) {\n ' + code + '\n}\n';
+}
+
+export const WIFI_smartConfig = function (_, generator) {
+ var MODE = this.getFieldValue('MODE');
+ // var board_type = JSFuncs.getPlatform();
+ if (MODE == 'SmartConfig') {
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ generator.definitions_['include_ESP8266WiFiMulti'] = '#include ';
+ generator.definitions_['var_declare_ESP8266WiFiMulti'] = ' ESP8266WiFiMulti wifiMulti;';
+ generator.setups_['setup_WiFi_Smartconfig'] = 'Serial.println("Wait for Smartconfig");\n'
+ + 'wifiMulti.run();\n'
+ + 'WiFi.setAutoConnect(true);\n'
+ + 'if (WiFi.status() == WL_CONNECTED) {\n'
+ + 'Serial.println("WiFi connected");\n'
+ + 'Serial.println("IP address: ");\n'
+ + 'Serial.println(WiFi.localIP());\n'
+ + ' }\n'
+ + 'else{\n'
+ + ' WiFi.mode(WIFI_STA);\n'
+ + ' WiFi.beginSmartConfig();\n'
+ + ' while(!WiFi.smartConfigDone()){\n'
+ + 'Serial.print(".");\n'
+ + 'delay(500);\n'
+ + '}\n'
+ + 'Serial.println("SmartConfig Success");\n'
+ + 'Serial.printf("SSID:%s", WiFi.SSID().c_str());\n'
+ + 'Serial.printf("PSW:%s", WiFi.psk().c_str());\n'
+ + 'wifiMulti.addAP(WiFi.SSID().c_str(),WiFi.psk().c_str());\n'
+
+ + '}\n'
+ return "";
+ }
+ generator.definitions_['include_WiFiManager'] = '#include ';
+ generator.definitions_['var_declare_WiFiServer'] = 'WiFiServer server(80);';
+ generator.setups_['setup_WiFi_mode'] = 'WiFi.mode(WIFI_STA);';
+ generator.setups_['setup_WiFiManager'] = 'WiFiManager wm;';
+ generator.setups_['setup_bool_res'] = 'bool res;';
+ generator.setups_['setup_wifiManagerautoConnect'] = 'res=wm.autoConnect();';
+ return "";
+}
+
+export const WIFI_ap_or_sta = function (_, generator) {
+ var dropdown_mode = this.getFieldValue('mode');
+ var value_SSID = generator.valueToCode(this, 'SSID', generator.ORDER_ATOMIC);
+ var value_PSK = generator.valueToCode(this, 'PSK', generator.ORDER_ATOMIC);
+ var value_IP1 = generator.valueToCode(this, 'IP1', generator.ORDER_ATOMIC);
+ var value_IP2 = generator.valueToCode(this, 'IP2', generator.ORDER_ATOMIC);
+ var value_IP = generator.valueToCode(this, 'IP', generator.ORDER_ATOMIC);
+ var value_duankou = generator.valueToCode(this, 'duankou', generator.ORDER_ATOMIC);
+ value_IP1 = value_IP1.replace(new RegExp(/\./g), ",");
+ value_IP2 = value_IP2.replace(new RegExp(/\./g), ",");
+ value_IP = value_IP.replace(new RegExp(/\./g), ",");
+ var board_type = JSFuncs.getPlatform();
+ if (board_type.match(RegExp(/ESP8266/)) != null)
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ else
+ generator.definitions_['include_WiFi'] = '#include ';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ if (dropdown_mode == 'STA') {
+ generator.definitions_['include_WiFiUdp'] = '#include ';
+ generator.definitions_['define_STASSID'] = '#define STASSID ' + value_SSID + '';
+ generator.definitions_['define_STAPSK'] = '#define STAPSK ' + value_PSK + '';
+ generator.definitions_['var_declare_ESP8266ip1'] = 'IPAddress ESP8266ip1(' + value_IP1 + ');';
+ generator.definitions_['var_declare_ESP8266ip2'] = 'IPAddress ESP8266ip2(' + value_IP2 + ');';
+ generator.definitions_['var_declare_ESP8266ip'] = 'IPAddress ESP8266ip(' + value_IP + ');';
+ generator.definitions_['var_declare_localPort'] = 'unsigned int localPort = ' + value_duankou + ';';
+ generator.definitions_['var_declare_remotePort'] = 'unsigned int remotePort = ' + value_duankou + ';';
+ generator.definitions_['var_declare_incomingPacket'] = 'char incomingPacket[537];';
+ generator.definitions_['var_declare_A'] = 'char A;';
+ generator.definitions_['var_declare_Udp'] = 'WiFiUDP Udp;';
+ generator.setups_['setup_wifi_sta'] = 'WiFi.mode(WIFI_STA);\n'
+ + ' WiFi.begin(STASSID, STAPSK);\n'
+ + ' while(WiFi.status() != WL_CONNECTED){\n'
+ + ' Serial.print(".");\n'
+ + ' delay(500);\n'
+ + ' }\n'
+ + ' delay(500);\n'
+ + ' Serial.print("Connected! IP address: ");\n'
+ + ' Serial.println(WiFi.localIP());\n'
+ + ' Serial.printf("UDP server on port ", localPort);\n'
+ + ' Udp.begin(localPort);';
+ }
+ else {
+ generator.definitions_['include_WiFiUDP'] = '#include ';
+ generator.definitions_['var_declare_AP_NameChar'] = 'const char AP_NameChar[] = ' + value_SSID + ';';
+ generator.definitions_['var_declare_WiFiAPPSK'] = 'const char WiFiAPPSK[] = ' + value_PSK + ';';
+ generator.definitions_['var_declare_ESP8266ip1'] = 'IPAddress ESP8266ip1(' + value_IP1 + ');';
+ generator.definitions_['var_declare_ESP8266ip2'] = 'IPAddress ESP8266ip2(' + value_IP2 + ');';
+ generator.definitions_['var_declare_ESP8266ip'] = 'IPAddress ESP8266ip(' + value_IP + ');';
+ generator.definitions_['var_declare_localPort'] = 'unsigned int localPort = ' + value_duankou + ';';
+ generator.definitions_['var_declare_remotePort'] = 'unsigned int remotePort = ' + value_duankou + ';';
+ generator.definitions_['var_declare_incomingPacket'] = 'char incomingPacket[537];';
+ generator.definitions_['var_declare_A'] = 'char A;';
+ generator.definitions_['var_declare_Udp'] = 'WiFiUDP Udp;';
+ generator.setups_['setup_wifi_ap'] = 'WiFi.mode(WIFI_AP);\n'
+ + ' WiFi.softAP(AP_NameChar, WiFiAPPSK);\n'
+ + ' Udp.begin(localPort);\n'
+ + ' Serial.println();\n'
+ + ' Serial.println("Started ap. Local ip: " + WiFi.localIP().toString());';
+ }
+ var code = '';
+ return code;
+}
+
+export const WIFI_ap_and_sta = function (_, generator) {
+ var value_SSID1 = generator.valueToCode(this, 'SSID1', generator.ORDER_ATOMIC);
+ var value_SSID2 = generator.valueToCode(this, 'SSID2', generator.ORDER_ATOMIC);
+ var value_PSK1 = generator.valueToCode(this, 'PSK1', generator.ORDER_ATOMIC);
+ var value_PSK2 = generator.valueToCode(this, 'PSK2', generator.ORDER_ATOMIC);
+ var value_IP1 = generator.valueToCode(this, 'IP1', generator.ORDER_ATOMIC);
+ var value_IP2 = generator.valueToCode(this, 'IP2', generator.ORDER_ATOMIC);
+ var value_IP = generator.valueToCode(this, 'IP', generator.ORDER_ATOMIC);
+ var value_duankou = generator.valueToCode(this, 'duankou', generator.ORDER_ATOMIC);
+ value_IP1 = value_IP1.replace(new RegExp(/\./g), ",");
+ value_IP2 = value_IP2.replace(new RegExp(/\./g), ",");
+ value_IP = value_IP.replace(new RegExp(/\./g), ",");
+ generator.definitions_['define_STASSID'] = '#define STASSID ' + value_SSID1;
+ generator.definitions_['define_STAPSK'] = '#define STAPSK ' + value_PSK1;
+ var board_type = JSFuncs.getPlatform();
+ if (board_type.match(RegExp(/ESP8266/)) != null)
+ generator.definitions_['include_ESP8266WiFi'] = '#include ';
+ else
+ generator.definitions_['include_WiFi'] = '#include ';
+ generator.definitions_['include_WiFiUDP'] = '#include ';
+ generator.definitions_['var_declare_AP_NameChar'] = 'const char AP_NameChar[] = ' + value_SSID2 + ';';
+ generator.definitions_['var_declare_WiFiAPPSK'] = 'const char WiFiAPPSK[] = ' + value_PSK2 + ';';
+ generator.definitions_['var_declare_ESP8266ip1'] = 'IPAddress ESP8266ip1(' + value_IP1 + ');';
+ generator.definitions_['var_declare_ESP8266ip2'] = 'IPAddress ESP8266ip2(' + value_IP2 + ');';
+ generator.definitions_['var_declare_ESP8266ip'] = 'IPAddress ESP8266ip(' + value_IP + ');';
+ generator.definitions_['var_declare_localPort'] = 'unsigned int localPort = ' + value_duankou + ';';
+ generator.definitions_['var_declare_remotePort'] = 'unsigned int remotePort = ' + value_duankou + ';';
+ generator.definitions_['var_declare_incomingPacket'] = 'char incomingPacket[537];';
+ generator.definitions_['var_declare_A'] = 'char A;';
+ generator.definitions_['var_declare_Udp'] = 'WiFiUDP Udp;';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ generator.setups_['setup_wifi_ap_and_sta'] = 'WiFi.mode(WIFI_AP_STA);\n'
+ + ' WiFi.softAP(AP_NameChar, WiFiAPPSK);\n'
+ + ' WiFi.begin(STASSID, STAPSK);\n'
+ + ' Udp.begin(localPort);\n'
+ + ' Serial.println();\n'
+ + ' Serial.println("Started ap. Local ip: " + WiFi.localIP().toString());';
+ var code = '';
+ return code;
+}
+
+export const WIFI_incomingPacket = function (_, generator) {
+ var value_input_data = generator.valueToCode(this, 'input_data', generator.ORDER_ATOMIC) || 'COM';
+ var statements_do = generator.statementToCode(this, 'do');
+ statements_do = statements_do.replace(/(^\s*)|(\s*$)/g, "");//去除两端空格
+ var code = 'int packetSize = Udp.parsePacket();\n'
+ + 'if (packetSize) {\n'
+ + ' Serial.printf("Received %d bytes from %s, port %d\\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());\n'
+ + ' int len = Udp.read(incomingPacket, 536);\n'
+ + ' if (len > 0) {\n'
+ + ' incomingPacket[len] = 0;\n'
+ + ' Serial.printf("UDP packet contents: %s\\n", incomingPacket);\n'
+ + ' String ' + value_input_data + ' = incomingPacket;\n'
+ + (statements_do != '' ? (' ' + statements_do.replace(new RegExp(/\n/g), "\n ") + '\n') : '')
+ + ' }\n'
+ + '}\n';
+ return code;
+}
+
+export const WIFI_send_data = function (_, generator) {
+ var value_data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ var code = 'Udp.beginPacket(Udp.remoteIP(),Udp.remotePort());\n'
+ + 'Udp.write(' + value_data + ');\n'
+ + 'Udp.endPacket();\n';
+ return code;
+}
+
+var WeatherCity = {
+ "北京": "101010100",
+ "海淀": "101010200",
+ "朝阳": "101010300",
+ "顺义": "101010400",
+ "怀柔": "101010500",
+ "通州": "101010600",
+ "昌平": "101010700",
+ "延庆": "101010800",
+ "丰台": "101010900",
+ "石景山": "101011000",
+ "大兴": "101011100",
+ "房山": "101011200",
+ "密云": "101011300",
+ "门头沟": "101011400",
+ "平谷": "101011500",
+ "八达岭": "101011600",
+ "佛爷顶": "101011700",
+ "汤河口": "101011800",
+ "密云上甸子": "101011900",
+ "斋堂": "101012000",
+ "霞云岭": "101012100",
+ "上海": "101020100",
+ "闵行": "101020200",
+ "宝山": "101020300",
+ "川沙": "101020400",
+ "嘉定": "101020500",
+ "南汇": "101020600",
+ "金山": "101020700",
+ "青浦": "101020800",
+ "松江": "101020900",
+ "奉贤": "101021000",
+ "崇明": "101021100",
+ "陈家镇": "101021101",
+ "引水船": "101021102",
+ "徐家汇": "101021200",
+ "浦东": "101021300",
+ "天津": "101030100",
+ "武清": "101030200",
+ "宝坻": "101030300",
+ "东丽": "101030400",
+ "西青": "101030500",
+ "北辰": "101030600",
+ "宁河": "101030700",
+ "汉沽": "101030800",
+ "静海": "101030900",
+ "津南": "101031000",
+ "塘沽": "101031100",
+ "大港": "101031200",
+ "平台": "101031300",
+ "蓟县": "101031400",
+ "重庆": "101040100",
+ "永川": "101040200",
+ "合川": "101040300",
+ "南川": "101040400",
+ "江津": "101040500",
+ "万盛": "101040600",
+ "渝北": "101040700",
+ "北碚": "101040800",
+ "巴南": "101040900",
+ "长寿": "101041000",
+ "黔江": "101041100",
+ "万州天城": "101041200",
+ "万州龙宝": "101041300",
+ "涪陵": "101041400",
+ "开县": "101041500",
+ "城口": "101041600",
+ "云阳": "101041700",
+ "巫溪": "101041800",
+ "奉节": "101041900",
+ "巫山": "101042000",
+ "潼南": "101042100",
+ "垫江": "101042200",
+ "梁平": "101042300",
+ "忠县": "101042400",
+ "石柱": "101042500",
+ "大足": "101042600",
+ "荣昌": "101042700",
+ "铜梁": "101042800",
+ "璧山": "101042900",
+ "丰都": "101043000",
+ "武隆": "101043100",
+ "彭水": "101043200",
+ "綦江": "101043300",
+ "酉阳": "101043400",
+ "金佛山": "101043500",
+ "秀山": "101043600",
+ "沙坪坝": "101043700",
+ "哈尔滨": "101050101",
+ "双城": "101050102",
+ "呼兰": "101050103",
+ "阿城": "101050104",
+ "宾县": "101050105",
+ "依兰": "101050106",
+ "巴彦": "101050107",
+ "通河": "101050108",
+ "方正": "101050109",
+ "延寿": "101050110",
+ "尚志": "101050111",
+ "五常": "101050112",
+ "木兰": "101050113",
+ "齐齐哈尔": "101050201",
+ "讷河": "101050202",
+ "龙江": "101050203",
+ "甘南": "101050204",
+ "富裕": "101050205",
+ "依安": "101050206",
+ "拜泉": "101050207",
+ "克山": "101050208",
+ "克东": "101050209",
+ "泰来": "101050210",
+ "牡丹江": "101050301",
+ "海林": "101050302",
+ "穆棱": "101050303",
+ "林口": "101050304",
+ "绥芬河": "101050305",
+ "宁安": "101050306",
+ "东宁": "101050307",
+ "佳木斯": "101050401",
+ "汤原": "101050402",
+ "抚远": "101050403",
+ "桦川": "101050404",
+ "桦南": "101050405",
+ "同江": "101050406",
+ "富锦": "101050407",
+ "绥化": "101050501",
+ "肇东": "101050502",
+ "安达": "101050503",
+ "海伦": "101050504",
+ "明水": "101050505",
+ "望奎": "101050506",
+ "兰西": "101050507",
+ "青冈": "101050508",
+ "庆安": "101050509",
+ "绥棱": "101050510",
+ "黑河": "101050601",
+ "嫩江": "101050602",
+ "孙吴": "101050603",
+ "逊克": "101050604",
+ "五大连池": "101050605",
+ "北安": "101050606",
+ "大兴安岭": "101050701",
+ "塔河": "101050702",
+ "漠河": "101050703",
+ "呼玛": "101050704",
+ "呼中": "101050705",
+ "新林": "101050706",
+ "阿木尔": "101050707",
+ "加格达奇": "101050708",
+ "伊春": "101050801",
+ "乌伊岭": "101050802",
+ "五营": "101050803",
+ "铁力": "101050804",
+ "嘉荫": "101050805",
+ "大庆": "101050901",
+ "林甸": "101050902",
+ "肇州": "101050903",
+ "肇源": "101050904",
+ "杜蒙": "101050905",
+ "七台河": "101051002",
+ "勃利": "101051003",
+ "鸡西": "101051101",
+ "虎林": "101051102",
+ "密山": "101051103",
+ "鸡东": "101051104",
+ "鹤岗": "101051201",
+ "绥滨": "101051202",
+ "萝北": "101051203",
+ "双鸭山": "101051301",
+ "集贤": "101051302",
+ "宝清": "101051303",
+ "饶河": "101051304",
+ "长春": "101060101",
+ "农安": "101060102",
+ "德惠": "101060103",
+ "九台": "101060104",
+ "榆树": "101060105",
+ "双阳": "101060106",
+ "吉林": "101060201",
+ "舒兰": "101060202",
+ "永吉": "101060203",
+ "蛟河": "101060204",
+ "磐石": "101060205",
+ "桦甸": "101060206",
+ "烟筒山": "101060207",
+ "延吉": "101060301",
+ "敦化": "101060302",
+ "安图": "101060303",
+ "汪清": "101060304",
+ "和龙": "101060305",
+ "天池": "101060306",
+ "龙井": "101060307",
+ "珲春": "101060308",
+ "图们": "101060309",
+ "罗子沟": "101060311",
+ "延边": "101060312",
+ "四平": "101060401",
+ "双辽": "101060402",
+ "梨树": "101060403",
+ "公主岭": "101060404",
+ "伊通": "101060405",
+ "孤家子": "101060406",
+ "通化": "101060501",
+ "梅河口": "101060502",
+ "柳河": "101060503",
+ "辉南": "101060504",
+ "集安": "101060505",
+ "通化县": "101060506",
+ "白城": "101060601",
+ "洮南": "101060602",
+ "大安": "101060603",
+ "镇赉": "101060604",
+ "通榆": "101060605",
+ "辽源": "101060701",
+ "东丰": "101060702",
+ "松原": "101060801",
+ "乾安": "101060802",
+ "前郭": "101060803",
+ "长岭": "101060804",
+ "扶余": "101060805",
+ "白山": "101060901",
+ "靖宇": "101060902",
+ "临江": "101060903",
+ "东岗": "101060904",
+ "长白": "101060905",
+ "沈阳": "101070101",
+ "苏家屯": "101070102",
+ "辽中": "101070103",
+ "康平": "101070104",
+ "法库": "101070105",
+ "新民": "101070106",
+ "于洪": "101070107",
+ "新城子": "101070108",
+ "大连": "101070201",
+ "瓦房店": "101070202",
+ "金州": "101070203",
+ "普兰店": "101070204",
+ "旅顺": "101070205",
+ "长海": "101070206",
+ "庄河": "101070207",
+ "皮口": "101070208",
+ "海洋岛": "101070209",
+ "鞍山": "101070301",
+ "台安": "101070302",
+ "岫岩": "101070303",
+ "海城": "101070304",
+ "抚顺": "101070401",
+ "清原": "101070403",
+ "章党": "101070404",
+ "本溪": "101070501",
+ "本溪县": "101070502",
+ "草河口": "101070503",
+ "桓仁": "101070504",
+ "丹东": "101070601",
+ "凤城": "101070602",
+ "宽甸": "101070603",
+ "东港": "101070604",
+ "东沟": "101070605",
+ "锦州": "101070701",
+ "凌海": "101070702",
+ "北宁": "101070703",
+ "义县": "101070704",
+ "黑山": "101070705",
+ "北镇": "101070706",
+ "营口": "101070801",
+ "大石桥": "101070802",
+ "盖州": "101070803",
+ "阜新": "101070901",
+ "彰武": "101070902",
+ "辽阳": "101071001",
+ "辽阳县": "101071002",
+ "灯塔": "101071003",
+ "铁岭": "101071101",
+ "开原": "101071102",
+ "昌图": "101071103",
+ "西丰": "101071104",
+ "建平": "101071202",
+ "凌源": "101071203",
+ "喀左": "101071204",
+ "北票": "101071205",
+ "羊山": "101071206",
+ "建平县": "101071207",
+ "盘锦": "101071301",
+ "大洼": "101071302",
+ "盘山": "101071303",
+ "葫芦岛": "101071401",
+ "建昌": "101071402",
+ "绥中": "101071403",
+ "兴城": "101071404",
+ "呼和浩特": "101080101",
+ "土默特左旗": "101080102",
+ "托克托": "101080103",
+ "和林格尔": "101080104",
+ "清水河": "101080105",
+ "呼和浩特市郊区": "101080106",
+ "武川": "101080107",
+ "包头": "101080201",
+ "白云鄂博": "101080202",
+ "满都拉": "101080203",
+ "土默特右旗": "101080204",
+ "固阳": "101080205",
+ "达尔罕茂明安联合旗": "101080206",
+ "石拐": "101080207",
+ "乌海": "101080301",
+ "集宁": "101080401",
+ "卓资": "101080402",
+ "化德": "101080403",
+ "商都": "101080404",
+ "希拉穆仁": "101080405",
+ "兴和": "101080406",
+ "凉城": "101080407",
+ "察哈尔右翼前旗": "101080408",
+ "察哈尔右翼中旗": "101080409",
+ "察哈尔右翼后旗": "101080410",
+ "四子王旗": "101080411",
+ "丰镇": "101080412",
+ "通辽": "101080501",
+ "舍伯吐": "101080502",
+ "科尔沁左翼中旗": "101080503",
+ "科尔沁左翼后旗": "101080504",
+ "青龙山": "101080505",
+ "开鲁": "101080506",
+ "库伦旗": "101080507",
+ "奈曼旗": "101080508",
+ "扎鲁特旗": "101080509",
+ "高力板": "101080510",
+ "巴雅尔吐胡硕": "101080511",
+ "通辽钱家店": "101080512",
+ "赤峰": "101080601",
+ "赤峰郊区站": "101080602",
+ "阿鲁科尔沁旗": "101080603",
+ "浩尔吐": "101080604",
+ "巴林左旗": "101080605",
+ "巴林右旗": "101080606",
+ "林西": "101080607",
+ "克什克腾旗": "101080608",
+ "翁牛特旗": "101080609",
+ "岗子": "101080610",
+ "喀喇沁旗": "101080611",
+ "八里罕": "101080612",
+ "宁城": "101080613",
+ "敖汉旗": "101080614",
+ "宝过图": "101080615",
+ "鄂尔多斯": "101080701",
+ "达拉特旗": "101080703",
+ "准格尔旗": "101080704",
+ "鄂托克前旗": "101080705",
+ "河南": "101080706",
+ "伊克乌素": "101080707",
+ "鄂托克旗": "101080708",
+ "杭锦旗": "101080709",
+ "乌审旗": "101080710",
+ "伊金霍洛旗": "101080711",
+ "乌审召": "101080712",
+ "东胜": "101080713",
+ "临河": "101080801",
+ "五原": "101080802",
+ "磴口": "101080803",
+ "乌拉特前旗": "101080804",
+ "大佘太": "101080805",
+ "乌拉特中旗": "101080806",
+ "乌拉特后旗": "101080807",
+ "海力素": "101080808",
+ "那仁宝力格": "101080809",
+ "杭锦后旗": "101080810",
+ "巴盟农试站": "101080811",
+ "锡林浩特": "101080901",
+ "朝克乌拉": "101080902",
+ "二连浩特": "101080903",
+ "阿巴嘎旗": "101080904",
+ "伊和郭勒": "101080905",
+ "苏尼特左旗": "101080906",
+ "苏尼特右旗": "101080907",
+ "朱日和": "101080908",
+ "东乌珠穆沁旗": "101080909",
+ "西乌珠穆沁旗": "101080910",
+ "太仆寺旗": "101080911",
+ "镶黄旗": "101080912",
+ "正镶白旗": "101080913",
+ "正兰旗": "101080914",
+ "多伦": "101080915",
+ "博克图": "101080916",
+ "乌拉盖": "101080917",
+ "白日乌拉": "101080918",
+ "那日图": "101080919",
+ "呼伦贝尔": "101081000",
+ "海拉尔": "101081001",
+ "小二沟": "101081002",
+ "阿荣旗": "101081003",
+ "莫力达瓦旗": "101081004",
+ "鄂伦春旗": "101081005",
+ "鄂温克旗": "101081006",
+ "陈巴尔虎旗": "101081007",
+ "新巴尔虎左旗": "101081008",
+ "新巴尔虎右旗": "101081009",
+ "满洲里": "101081010",
+ "牙克石": "101081011",
+ "扎兰屯": "101081012",
+ "额尔古纳": "101081014",
+ "根河": "101081015",
+ "图里河": "101081016",
+ "乌兰浩特": "101081101",
+ "阿尔山": "101081102",
+ "科尔沁右翼中旗": "101081103",
+ "胡尔勒": "101081104",
+ "扎赉特旗": "101081105",
+ "索伦": "101081106",
+ "突泉": "101081107",
+ "霍林郭勒": "101081108",
+ "阿拉善左旗": "101081201",
+ "阿拉善右旗": "101081202",
+ "额济纳旗": "101081203",
+ "拐子湖": "101081204",
+ "吉兰太": "101081205",
+ "锡林高勒": "101081206",
+ "头道湖": "101081207",
+ "中泉子": "101081208",
+ "巴彦诺尔贡": "101081209",
+ "雅布赖": "101081210",
+ "乌斯太": "101081211",
+ "孪井滩": "101081212",
+ "石家庄": "101090101",
+ "井陉": "101090102",
+ "正定": "101090103",
+ "栾城": "101090104",
+ "行唐": "101090105",
+ "灵寿": "101090106",
+ "高邑": "101090107",
+ "深泽": "101090108",
+ "赞皇": "101090109",
+ "无极": "101090110",
+ "平山": "101090111",
+ "元氏": "101090112",
+ "赵县": "101090113",
+ "辛集": "101090114",
+ "藁城": "101090115",
+ "晋洲": "101090116",
+ "新乐": "101090117",
+ "保定": "101090201",
+ "满城": "101090202",
+ "阜平": "101090203",
+ "徐水": "101090204",
+ "唐县": "101090205",
+ "高阳": "101090206",
+ "容城": "101090207",
+ "紫荆关": "101090208",
+ "涞源": "101090209",
+ "望都": "101090210",
+ "安新": "101090211",
+ "易县": "101090212",
+ "涞水": "101090213",
+ "曲阳": "101090214",
+ "蠡县": "101090215",
+ "顺平": "101090216",
+ "雄县": "101090217",
+ "涿州": "101090218",
+ "定州": "101090219",
+ "安国": "101090220",
+ "高碑店": "101090221",
+ "张家口": "101090301",
+ "宣化": "101090302",
+ "张北": "101090303",
+ "康保": "101090304",
+ "沽源": "101090305",
+ "尚义": "101090306",
+ "蔚县": "101090307",
+ "阳原": "101090308",
+ "怀安": "101090309",
+ "万全": "101090310",
+ "怀来": "101090311",
+ "涿鹿": "101090312",
+ "赤城": "101090313",
+ "崇礼": "101090314",
+ "承德": "101090402",
+ "承德县": "101090403",
+ "兴隆": "101090404",
+ "平泉": "101090405",
+ "滦平": "101090406",
+ "隆化": "101090407",
+ "丰宁": "101090408",
+ "宽城": "101090409",
+ "围场": "101090410",
+ "塞罕坎": "101090411",
+ "唐山": "101090501",
+ "丰南": "101090502",
+ "丰润": "101090503",
+ "滦县": "101090504",
+ "滦南": "101090505",
+ "乐亭": "101090506",
+ "迁西": "101090507",
+ "玉田": "101090508",
+ "唐海": "101090509",
+ "遵化": "101090510",
+ "迁安": "101090511",
+ "廊坊": "101090601",
+ "固安": "101090602",
+ "永清": "101090603",
+ "香河": "101090604",
+ "大城": "101090605",
+ "文安": "101090606",
+ "大厂": "101090607",
+ "霸州": "101090608",
+ "三河": "101090609",
+ "沧州": "101090701",
+ "青县": "101090702",
+ "东光": "101090703",
+ "海兴": "101090704",
+ "盐山": "101090705",
+ "肃宁": "101090706",
+ "南皮": "101090707",
+ "吴桥": "101090708",
+ "献县": "101090709",
+ "孟村": "101090710",
+ "泊头": "101090711",
+ "任丘": "101090712",
+ "黄骅": "101090713",
+ "河间": "101090714",
+ "曹妃甸": "101090715",
+ "衡水": "101090801",
+ "枣强": "101090802",
+ "武邑": "101090803",
+ "武强": "101090804",
+ "饶阳": "101090805",
+ "安平": "101090806",
+ "故城": "101090807",
+ "景县": "101090808",
+ "阜城": "101090809",
+ "冀州": "101090810",
+ "深州": "101090811",
+ "邢台": "101090901",
+ "临城": "101090902",
+ "邢台县浆水": "101090903",
+ "内邱": "101090904",
+ "柏乡": "101090905",
+ "隆尧": "101090906",
+ "南和": "101090907",
+ "宁晋": "101090908",
+ "巨鹿": "101090909",
+ "新河": "101090910",
+ "广宗": "101090911",
+ "平乡": "101090912",
+ "威县": "101090913",
+ "清河": "101090914",
+ "临西": "101090915",
+ "南宫": "101090916",
+ "沙河": "101090917",
+ "任县": "101090918",
+ "邯郸": "101091001",
+ "峰峰": "101091002",
+ "临漳": "101091003",
+ "成安": "101091004",
+ "大名": "101091005",
+ "涉县": "101091006",
+ "磁县": "101091007",
+ "肥乡": "101091008",
+ "永年": "101091009",
+ "邱县": "101091010",
+ "鸡泽": "101091011",
+ "广平": "101091012",
+ "馆陶": "101091013",
+ "魏县": "101091014",
+ "曲周": "101091015",
+ "武安": "101091016",
+ "秦皇岛": "101091101",
+ "青龙": "101091102",
+ "昌黎": "101091103",
+ "抚宁": "101091104",
+ "卢龙": "101091105",
+ "北戴河": "101091106",
+ "太原": "101100101",
+ "清徐": "101100102",
+ "阳曲": "101100103",
+ "娄烦": "101100104",
+ "太原古交区": "101100105",
+ "太原北郊": "101100106",
+ "太原南郊": "101100107",
+ "大同": "101100201",
+ "阳高": "101100202",
+ "大同县": "101100203",
+ "天镇": "101100204",
+ "广灵": "101100205",
+ "灵邱": "101100206",
+ "浑源": "101100207",
+ "左云": "101100208",
+ "阳泉": "101100301",
+ "盂县": "101100302",
+ "平定": "101100303",
+ "晋中": "101100401",
+ "榆次": "101100402",
+ "榆社": "101100403",
+ "左权": "101100404",
+ "和顺": "101100405",
+ "昔阳": "101100406",
+ "寿阳": "101100407",
+ "太谷": "101100408",
+ "祁县": "101100409",
+ "平遥": "101100410",
+ "灵石": "101100411",
+ "介休": "101100412",
+ "长治": "101100501",
+ "黎城": "101100502",
+ "屯留": "101100503",
+ "潞城": "101100504",
+ "襄垣": "101100505",
+ "平顺": "101100506",
+ "武乡": "101100507",
+ "沁县": "101100508",
+ "长子": "101100509",
+ "沁源": "101100510",
+ "壶关": "101100511",
+ "晋城": "101100601",
+ "沁水": "101100602",
+ "阳城": "101100603",
+ "陵川": "101100604",
+ "高平": "101100605",
+ "临汾": "101100701",
+ "曲沃": "101100702",
+ "永和": "101100703",
+ "隰县": "101100704",
+ "大宁": "101100705",
+ "吉县": "101100706",
+ "襄汾": "101100707",
+ "蒲县": "101100708",
+ "汾西": "101100709",
+ "洪洞": "101100710",
+ "霍州": "101100711",
+ "乡宁": "101100712",
+ "翼城": "101100713",
+ "侯马": "101100714",
+ "浮山": "101100715",
+ "安泽": "101100716",
+ "古县": "101100717",
+ "运城": "101100801",
+ "临猗": "101100802",
+ "稷山": "101100803",
+ "万荣": "101100804",
+ "河津": "101100805",
+ "新绛": "101100806",
+ "绛县": "101100807",
+ "闻喜": "101100808",
+ "垣曲": "101100809",
+ "永济": "101100810",
+ "芮城": "101100811",
+ "夏县": "101100812",
+ "平陆": "101100813",
+ "朔州": "101100901",
+ "平鲁": "101100902",
+ "山阴": "101100903",
+ "右玉": "101100904",
+ "应县": "101100905",
+ "怀仁": "101100906",
+ "忻州": "101101001",
+ "定襄": "101101002",
+ "五台县豆村": "101101003",
+ "河曲": "101101004",
+ "偏关": "101101005",
+ "神池": "101101006",
+ "宁武": "101101007",
+ "代县": "101101008",
+ "繁峙": "101101009",
+ "五台山": "101101010",
+ "保德": "101101011",
+ "静乐": "101101012",
+ "岢岚": "101101013",
+ "五寨": "101101014",
+ "原平": "101101015",
+ "吕梁": "101101100",
+ "离石": "101101101",
+ "临县": "101101102",
+ "兴县": "101101103",
+ "岚县": "101101104",
+ "柳林": "101101105",
+ "石楼": "101101106",
+ "方山": "101101107",
+ "交口": "101101108",
+ "中阳": "101101109",
+ "孝义": "101101110",
+ "汾阳": "101101111",
+ "文水": "101101112",
+ "交城": "101101113",
+ "西安": "101110101",
+ "长安": "101110102",
+ "临潼": "101110103",
+ "蓝田": "101110104",
+ "周至": "101110105",
+ "户县": "101110106",
+ "高陵": "101110107",
+ "杨凌": "101110108",
+ "咸阳": "101110200",
+ "三原": "101110201",
+ "礼泉": "101110202",
+ "永寿": "101110203",
+ "淳化": "101110204",
+ "泾阳": "101110205",
+ "武功": "101110206",
+ "乾县": "101110207",
+ "彬县": "101110208",
+ "长武": "101110209",
+ "旬邑": "101110210",
+ "兴平": "101110211",
+ "延安": "101110300",
+ "延长": "101110301",
+ "延川": "101110302",
+ "子长": "101110303",
+ "宜川": "101110304",
+ "富县": "101110305",
+ "志丹": "101110306",
+ "安塞": "101110307",
+ "甘泉": "101110308",
+ "洛川": "101110309",
+ "黄陵": "101110310",
+ "黄龙": "101110311",
+ "吴起": "101110312",
+ "榆林": "101110401",
+ "府谷": "101110402",
+ "神木": "101110403",
+ "佳县": "101110404",
+ "定边": "101110405",
+ "靖边": "101110406",
+ "横山": "101110407",
+ "米脂": "101110408",
+ "子洲": "101110409",
+ "绥德": "101110410",
+ "吴堡": "101110411",
+ "清涧": "101110412",
+ "渭南": "101110501",
+ "华县": "101110502",
+ "潼关": "101110503",
+ "大荔": "101110504",
+ "白水": "101110505",
+ "富平": "101110506",
+ "蒲城": "101110507",
+ "澄城": "101110508",
+ "合阳": "101110509",
+ "韩城": "101110510",
+ "华阴": "101110511",
+ "华山": "101110512",
+ "商洛": "101110601",
+ "洛南": "101110602",
+ "柞水": "101110603",
+ "镇安": "101110605",
+ "丹凤": "101110606",
+ "商南": "101110607",
+ "山阳": "101110608",
+ "安康": "101110701",
+ "紫阳": "101110702",
+ "石泉": "101110703",
+ "汉阴": "101110704",
+ "旬阳": "101110705",
+ "岚皋": "101110706",
+ "平利": "101110707",
+ "白河": "101110708",
+ "镇坪": "101110709",
+ "宁陕": "101110710",
+ "汉中": "101110801",
+ "略阳": "101110802",
+ "勉县": "101110803",
+ "留坝": "101110804",
+ "洋县": "101110805",
+ "城固": "101110806",
+ "西乡": "101110807",
+ "佛坪": "101110808",
+ "宁强": "101110809",
+ "南郑": "101110810",
+ "镇巴": "101110811",
+ "宝鸡": "101110901",
+ "宝鸡县": "101110902",
+ "千阳": "101110903",
+ "麟游": "101110904",
+ "岐山": "101110905",
+ "凤翔": "101110906",
+ "扶风": "101110907",
+ "眉县": "101110908",
+ "太白": "101110909",
+ "凤县": "101110910",
+ "陇县": "101110911",
+ "铜川": "101111001",
+ "耀县": "101111002",
+ "宜君": "101111003",
+ "济南": "101120101",
+ "长清": "101120102",
+ "商河": "101120103",
+ "章丘": "101120104",
+ "平阴": "101120105",
+ "济阳": "101120106",
+ "青岛": "101120201",
+ "崂山": "101120202",
+ "潮连岛": "101120203",
+ "即墨": "101120204",
+ "胶州": "101120205",
+ "胶南": "101120206",
+ "莱西": "101120207",
+ "平度": "101120208",
+ "淄博": "101120301",
+ "淄川": "101120302",
+ "博山": "101120303",
+ "高青": "101120304",
+ "周村": "101120305",
+ "沂源": "101120306",
+ "桓台": "101120307",
+ "临淄": "101120308",
+ "德州": "101120401",
+ "武城": "101120402",
+ "临邑": "101120403",
+ "陵县": "101120404",
+ "齐河": "101120405",
+ "乐陵": "101120406",
+ "庆云": "101120407",
+ "平原": "101120408",
+ "宁津": "101120409",
+ "夏津": "101120410",
+ "禹城": "101120411",
+ "烟台": "101120501",
+ "莱州": "101120502",
+ "长岛": "101120503",
+ "蓬莱": "101120504",
+ "龙口": "101120505",
+ "招远": "101120506",
+ "栖霞": "101120507",
+ "福山": "101120508",
+ "牟平": "101120509",
+ "莱阳": "101120510",
+ "海阳": "101120511",
+ "千里岩": "101120512",
+ "潍坊": "101120601",
+ "青州": "101120602",
+ "寿光": "101120603",
+ "临朐": "101120604",
+ "昌乐": "101120605",
+ "昌邑": "101120606",
+ "安丘": "101120607",
+ "高密": "101120608",
+ "诸城": "101120609",
+ "济宁": "101120701",
+ "嘉祥": "101120702",
+ "微山": "101120703",
+ "鱼台": "101120704",
+ "兖州": "101120705",
+ "金乡": "101120706",
+ "汶上": "101120707",
+ "泗水": "101120708",
+ "梁山": "101120709",
+ "曲阜": "101120710",
+ "邹城": "101120711",
+ "泰安": "101120801",
+ "新泰": "101120802",
+ "泰山": "101120803",
+ "肥城": "101120804",
+ "东平": "101120805",
+ "宁阳": "101120806",
+ "临沂": "101120901",
+ "莒南": "101120902",
+ "沂南": "101120903",
+ "苍山": "101120904",
+ "临沭": "101120905",
+ "郯城": "101120906",
+ "蒙阴": "101120907",
+ "平邑": "101120908",
+ "费县": "101120909",
+ "沂水": "101120910",
+ "马站": "101120911",
+ "菏泽": "101121001",
+ "鄄城": "101121002",
+ "郓城": "101121003",
+ "东明": "101121004",
+ "定陶": "101121005",
+ "巨野": "101121006",
+ "曹县": "101121007",
+ "成武": "101121008",
+ "单县": "101121009",
+ "滨州": "101121101",
+ "博兴": "101121102",
+ "无棣": "101121103",
+ "阳信": "101121104",
+ "惠民": "101121105",
+ "沾化": "101121106",
+ "邹平": "101121107",
+ "东营": "101121201",
+ "河口": "101121202",
+ "垦利": "101121203",
+ "利津": "101121204",
+ "广饶": "101121205",
+ "威海": "101121301",
+ "文登": "101121302",
+ "荣成": "101121303",
+ "乳山": "101121304",
+ "成山头": "101121305",
+ "石岛": "101121306",
+ "枣庄": "101121401",
+ "薛城": "101121402",
+ "峄城": "101121403",
+ "台儿庄": "101121404",
+ "滕州": "101121405",
+ "日照": "101121501",
+ "五莲": "101121502",
+ "莒县": "101121503",
+ "莱芜": "101121601",
+ "聊城": "101121701",
+ "冠县": "101121702",
+ "阳谷": "101121703",
+ "高唐": "101121704",
+ "茌平": "101121705",
+ "东阿": "101121706",
+ "临清": "101121707",
+ "朝城": "101121708",
+ "莘县": "101121709",
+ "乌鲁木齐": "101130101",
+ "蔡家湖": "101130102",
+ "小渠子": "101130103",
+ "巴仑台": "101130104",
+ "达坂城": "101130105",
+ "十三间房气象站": "101130106",
+ "天山大西沟": "101130107",
+ "乌鲁木齐牧试站": "101130108",
+ "白杨沟": "101130110",
+ "克拉玛依": "101130201",
+ "石河子": "101130301",
+ "炮台": "101130302",
+ "莫索湾": "101130303",
+ "乌兰乌苏": "101130304",
+ "昌吉": "101130401",
+ "呼图壁": "101130402",
+ "米泉": "101130403",
+ "阜康": "101130404",
+ "吉木萨尔": "101130405",
+ "奇台": "101130406",
+ "玛纳斯": "101130407",
+ "木垒": "101130408",
+ "北塔山": "101130409",
+ "吐鲁番": "101130501",
+ "托克逊": "101130502",
+ "吐鲁番东坎": "101130503",
+ "鄯善": "101130504",
+ "红柳河": "101130505",
+ "库尔勒": "101130601",
+ "轮台": "101130602",
+ "尉犁": "101130603",
+ "若羌": "101130604",
+ "且末": "101130605",
+ "和静": "101130606",
+ "焉耆": "101130607",
+ "和硕": "101130608",
+ "库米什": "101130609",
+ "巴音布鲁克": "101130610",
+ "铁干里克": "101130611",
+ "博湖": "101130612",
+ "塔中": "101130613",
+ "阿拉尔": "101130701",
+ "阿克苏": "101130801",
+ "乌什": "101130802",
+ "温宿": "101130803",
+ "拜城": "101130804",
+ "新和": "101130805",
+ "沙雅": "101130806",
+ "库车": "101130807",
+ "柯坪": "101130808",
+ "阿瓦提": "101130809",
+ "喀什": "101130901",
+ "英吉沙": "101130902",
+ "塔什库尔干": "101130903",
+ "麦盖提": "101130904",
+ "莎车": "101130905",
+ "叶城": "101130906",
+ "泽普": "101130907",
+ "巴楚": "101130908",
+ "岳普湖": "101130909",
+ "伽师": "101130910",
+ "伊宁": "101131001",
+ "察布查尔": "101131002",
+ "尼勒克": "101131003",
+ "伊宁县": "101131004",
+ "巩留": "101131005",
+ "新源": "101131006",
+ "昭苏": "101131007",
+ "特克斯": "101131008",
+ "霍城": "101131009",
+ "霍尔果斯": "101131010",
+ "塔城": "101131101",
+ "裕民": "101131102",
+ "额敏": "101131103",
+ "和布克赛尔": "101131104",
+ "托里": "101131105",
+ "乌苏": "101131106",
+ "沙湾": "101131107",
+ "和丰": "101131108",
+ "哈密": "101131201",
+ "沁城": "101131202",
+ "巴里坤": "101131203",
+ "伊吾": "101131204",
+ "淖毛湖": "101131205",
+ "和田": "101131301",
+ "皮山": "101131302",
+ "策勒": "101131303",
+ "墨玉": "101131304",
+ "洛浦": "101131305",
+ "民丰": "101131306",
+ "于田": "101131307",
+ "阿勒泰": "101131401",
+ "哈巴河": "101131402",
+ "一八五团": "101131403",
+ "黑山头": "101131404",
+ "吉木乃": "101131405",
+ "布尔津": "101131406",
+ "福海": "101131407",
+ "富蕴": "101131408",
+ "青河": "101131409",
+ "安德河": "101131410",
+ "阿图什": "101131501",
+ "乌恰": "101131502",
+ "阿克陶": "101131503",
+ "阿合奇": "101131504",
+ "吐尔尕特": "101131505",
+ "博乐": "101131601",
+ "温泉": "101131602",
+ "精河": "101131603",
+ "阿拉山口": "101131606",
+ "拉萨": "101140101",
+ "当雄": "101140102",
+ "尼木": "101140103",
+ "墨竹贡卡": "101140104",
+ "日喀则": "101140201",
+ "拉孜": "101140202",
+ "南木林": "101140203",
+ "聂拉木": "101140204",
+ "定日": "101140205",
+ "江孜": "101140206",
+ "帕里": "101140207",
+ "山南": "101140301",
+ "贡嘎": "101140302",
+ "琼结": "101140303",
+ "加查": "101140304",
+ "浪卡子": "101140305",
+ "错那": "101140306",
+ "隆子": "101140307",
+ "泽当": "101140308",
+ "林芝": "101140401",
+ "波密": "101140402",
+ "米林": "101140403",
+ "察隅": "101140404",
+ "昌都": "101140501",
+ "丁青": "101140502",
+ "类乌齐": "101140503",
+ "洛隆": "101140504",
+ "左贡": "101140505",
+ "芒康": "101140506",
+ "八宿": "101140507",
+ "那曲": "101140601",
+ "嘉黎": "101140603",
+ "班戈": "101140604",
+ "安多": "101140605",
+ "索县": "101140606",
+ "比如": "101140607",
+ "阿里": "101140701",
+ "改则": "101140702",
+ "申扎": "101140703",
+ "狮泉河": "101140704",
+ "普兰": "101140705",
+ "西宁": "101150101",
+ "大通": "101150102",
+ "湟源": "101150103",
+ "湟中": "101150104",
+ "铁卜加": "101150105",
+ "铁卜加寺": "101150106",
+ "中心站": "101150107",
+ "海东": "101150201",
+ "乐都": "101150202",
+ "民和": "101150203",
+ "互助": "101150204",
+ "化隆": "101150205",
+ "循化": "101150206",
+ "冷湖": "101150207",
+ "平安": "101150208",
+ "黄南": "101150301",
+ "尖扎": "101150302",
+ "泽库": "101150303",
+ "海南": "101150401",
+ "江西沟": "101150402",
+ "贵德": "101150404",
+ "河卡": "101150405",
+ "兴海": "101150406",
+ "贵南": "101150407",
+ "同德": "101150408",
+ "共和": "101150409",
+ "果洛": "101150501",
+ "班玛": "101150502",
+ "甘德": "101150503",
+ "达日": "101150504",
+ "久治": "101150505",
+ "玛多": "101150506",
+ "玛沁": "101150508",
+ "玉树": "101150601",
+ "托托河": "101150602",
+ "治多": "101150603",
+ "杂多": "101150604",
+ "囊谦": "101150605",
+ "曲麻莱": "101150606",
+ "海西": "101150701",
+ "格尔木": "101150702",
+ "察尔汉": "101150703",
+ "野牛沟": "101150704",
+ "五道梁": "101150705",
+ "小灶火": "101150706",
+ "天峻": "101150708",
+ "乌兰": "101150709",
+ "都兰": "101150710",
+ "诺木洪": "101150711",
+ "茫崖": "101150712",
+ "大柴旦": "101150713",
+ "茶卡": "101150714",
+ "香日德": "101150715",
+ "德令哈": "101150716",
+ "海北": "101150801",
+ "门源": "101150802",
+ "祁连": "101150803",
+ "海晏": "101150804",
+ "托勒": "101150805",
+ "刚察": "101150806",
+ "兰州": "101160101",
+ "皋兰": "101160102",
+ "永登": "101160103",
+ "榆中": "101160104",
+ "定西": "101160201",
+ "通渭": "101160202",
+ "陇西": "101160203",
+ "渭源": "101160204",
+ "临洮": "101160205",
+ "漳县": "101160206",
+ "岷县": "101160207",
+ "安定": "101160208",
+ "平凉": "101160301",
+ "泾川": "101160302",
+ "灵台": "101160303",
+ "崇信": "101160304",
+ "华亭": "101160305",
+ "庄浪": "101160306",
+ "静宁": "101160307",
+ "崆峒": "101160308",
+ "庆阳": "101160401",
+ "西峰": "101160402",
+ "环县": "101160403",
+ "华池": "101160404",
+ "合水": "101160405",
+ "正宁": "101160406",
+ "宁县": "101160407",
+ "镇原": "101160408",
+ "庆城": "101160409",
+ "武威": "101160501",
+ "民勤": "101160502",
+ "古浪": "101160503",
+ "乌鞘岭": "101160504",
+ "天祝": "101160505",
+ "金昌": "101160601",
+ "永昌": "101160602",
+ "张掖": "101160701",
+ "肃南": "101160702",
+ "民乐": "101160703",
+ "临泽": "101160704",
+ "高台": "101160705",
+ "山丹": "101160706",
+ "酒泉": "101160801",
+ "鼎新": "101160802",
+ "金塔": "101160803",
+ "马鬃山": "101160804",
+ "瓜州": "101160805",
+ "肃北": "101160806",
+ "玉门镇": "101160807",
+ "敦煌": "101160808",
+ "天水": "101160901",
+ "北道区": "101160902",
+ "清水": "101160903",
+ "秦安": "101160904",
+ "甘谷": "101160905",
+ "武山": "101160906",
+ "张家川": "101160907",
+ "麦积": "101160908",
+ "武都": "101161001",
+ "成县": "101161002",
+ "文县": "101161003",
+ "宕昌": "101161004",
+ "康县": "101161005",
+ "西和": "101161006",
+ "礼县": "101161007",
+ "徽县": "101161008",
+ "两当": "101161009",
+ "临夏": "101161101",
+ "康乐": "101161102",
+ "永靖": "101161103",
+ "广河": "101161104",
+ "和政": "101161105",
+ "东乡": "101161106",
+ "合作": "101161201",
+ "临潭": "101161202",
+ "卓尼": "101161203",
+ "舟曲": "101161204",
+ "迭部": "101161205",
+ "玛曲": "101161206",
+ "碌曲": "101161207",
+ "夏河": "101161208",
+ "白银": "101161301",
+ "靖远": "101161302",
+ "会宁": "101161303",
+ "华家岭": "101161304",
+ "景泰": "101161305",
+ "银川": "101170101",
+ "永宁": "101170102",
+ "灵武": "101170103",
+ "贺兰": "101170104",
+ "石嘴山": "101170201",
+ "惠农": "101170202",
+ "平罗": "101170203",
+ "陶乐": "101170204",
+ "石炭井": "101170205",
+ "大武口": "101170206",
+ "吴忠": "101170301",
+ "同心": "101170302",
+ "盐池": "101170303",
+ "韦州": "101170304",
+ "麻黄山": "101170305",
+ "青铜峡": "101170306",
+ "固原": "101170401",
+ "西吉": "101170402",
+ "隆德": "101170403",
+ "泾源": "101170404",
+ "六盘山": "101170405",
+ "彭阳": "101170406",
+ "中卫": "101170501",
+ "中宁": "101170502",
+ "兴仁堡": "101170503",
+ "海原": "101170504",
+ "郑州": "101180101",
+ "巩义": "101180102",
+ "荥阳": "101180103",
+ "登封": "101180104",
+ "新密": "101180105",
+ "新郑": "101180106",
+ "中牟": "101180107",
+ "郑州农试站": "101180108",
+ "安阳": "101180201",
+ "汤阴": "101180202",
+ "滑县": "101180203",
+ "内黄": "101180204",
+ "林州": "101180205",
+ "新乡": "101180301",
+ "获嘉": "101180302",
+ "原阳": "101180303",
+ "辉县": "101180304",
+ "卫辉": "101180305",
+ "延津": "101180306",
+ "封丘": "101180307",
+ "长垣": "101180308",
+ "许昌": "101180401",
+ "鄢陵": "101180402",
+ "襄城": "101180403",
+ "长葛": "101180404",
+ "禹州": "101180405",
+ "平顶山": "101180501",
+ "郏县": "101180502",
+ "宝丰": "101180503",
+ "汝州": "101180504",
+ "叶县": "101180505",
+ "舞钢": "101180506",
+ "鲁山": "101180507",
+ "信阳": "101180601",
+ "息县": "101180602",
+ "罗山": "101180603",
+ "光山": "101180604",
+ "新县": "101180605",
+ "淮滨": "101180606",
+ "潢川": "101180607",
+ "固始": "101180608",
+ "商城": "101180609",
+ "鸡公山": "101180610",
+ "信阳地区农试站": "101180611",
+ "南阳": "101180701",
+ "南召": "101180702",
+ "方城": "101180703",
+ "社旗": "101180704",
+ "西峡": "101180705",
+ "内乡": "101180706",
+ "镇平": "101180707",
+ "淅川": "101180708",
+ "新野": "101180709",
+ "唐河": "101180710",
+ "邓州": "101180711",
+ "桐柏": "101180712",
+ "开封": "101180801",
+ "杞县": "101180802",
+ "尉氏": "101180803",
+ "通许": "101180804",
+ "兰考": "101180805",
+ "洛阳": "101180901",
+ "新安": "101180902",
+ "孟津": "101180903",
+ "宜阳": "101180904",
+ "洛宁": "101180905",
+ "伊川": "101180906",
+ "嵩县": "101180907",
+ "偃师": "101180908",
+ "栾川": "101180909",
+ "汝阳": "101180910",
+ "商丘": "101181001",
+ "睢阳区": "101181002",
+ "睢县": "101181003",
+ "民权": "101181004",
+ "虞城": "101181005",
+ "柘城": "101181006",
+ "宁陵": "101181007",
+ "夏邑": "101181008",
+ "永城": "101181009",
+ "焦作": "101181101",
+ "修武": "101181102",
+ "武陟": "101181103",
+ "沁阳": "101181104",
+ "博爱": "101181106",
+ "温县": "101181107",
+ "孟州": "101181108",
+ "鹤壁": "101181201",
+ "浚县": "101181202",
+ "淇县": "101181203",
+ "濮阳": "101181301",
+ "台前": "101181302",
+ "南乐": "101181303",
+ "清丰": "101181304",
+ "范县": "101181305",
+ "周口": "101181401",
+ "扶沟": "101181402",
+ "太康": "101181403",
+ "淮阳": "101181404",
+ "西华": "101181405",
+ "商水": "101181406",
+ "项城": "101181407",
+ "郸城": "101181408",
+ "鹿邑": "101181409",
+ "沈丘": "101181410",
+ "黄泛区": "101181411",
+ "漯河": "101181501",
+ "临颍": "101181502",
+ "舞阳": "101181503",
+ "驻马店": "101181601",
+ "西平": "101181602",
+ "遂平": "101181603",
+ "上蔡": "101181604",
+ "汝南": "101181605",
+ "泌阳": "101181606",
+ "平舆": "101181607",
+ "新蔡": "101181608",
+ "确山": "101181609",
+ "正阳": "101181610",
+ "三门峡": "101181701",
+ "灵宝": "101181702",
+ "渑池": "101181703",
+ "卢氏": "101181704",
+ "济源": "101181801",
+ "南京": "101190101",
+ "溧水": "101190102",
+ "高淳": "101190103",
+ "江宁": "101190104",
+ "六合": "101190105",
+ "江浦": "101190106",
+ "浦口": "101190107",
+ "无锡": "101190201",
+ "江阴": "101190202",
+ "宜兴": "101190203",
+ "镇江": "101190301",
+ "丹阳": "101190302",
+ "扬中": "101190303",
+ "句容": "101190304",
+ "丹徒": "101190305",
+ "苏州": "101190401",
+ "常熟": "101190402",
+ "张家港": "101190403",
+ "昆山": "101190404",
+ "吴县东山": "101190405",
+ "吴县": "101190406",
+ "吴江": "101190407",
+ "太仓": "101190408",
+ "南通": "101190501",
+ "海安": "101190502",
+ "如皋": "101190503",
+ "如东": "101190504",
+ "吕泗": "101190505",
+ "吕泗渔场": "101190506",
+ "启东": "101190507",
+ "海门": "101190508",
+ "扬州": "101190601",
+ "宝应": "101190602",
+ "仪征": "101190603",
+ "高邮": "101190604",
+ "江都": "101190605",
+ "邗江": "101190606",
+ "盐城": "101190701",
+ "响水": "101190702",
+ "滨海": "101190703",
+ "阜宁": "101190704",
+ "射阳": "101190705",
+ "建湖": "101190706",
+ "东台": "101190707",
+ "大丰": "101190708",
+ "盐都": "101190709",
+ "徐州": "101190801",
+ "徐州农试站": "101190802",
+ "丰县": "101190803",
+ "沛县": "101190804",
+ "邳州": "101190805",
+ "睢宁": "101190806",
+ "新沂": "101190807",
+ "淮安": "101190901",
+ "金湖": "101190902",
+ "盱眙": "101190903",
+ "洪泽": "101190904",
+ "涟水": "101190905",
+ "淮阴县": "101190906",
+ "淮阴": "101190907",
+ "楚州": "101190908",
+ "连云港": "101191001",
+ "东海": "101191002",
+ "赣榆": "101191003",
+ "灌云": "101191004",
+ "灌南": "101191005",
+ "西连岛": "101191006",
+ "燕尾港": "101191007",
+ "常州": "101191101",
+ "溧阳": "101191102",
+ "金坛": "101191103",
+ "泰州": "101191201",
+ "兴化": "101191202",
+ "泰兴": "101191203",
+ "姜堰": "101191204",
+ "靖江": "101191205",
+ "宿迁": "101191301",
+ "沭阳": "101191302",
+ "泗阳": "101191303",
+ "泗洪": "101191304",
+ "武汉": "101200101",
+ "蔡甸": "101200102",
+ "黄陂": "101200103",
+ "新洲": "101200104",
+ "江夏": "101200105",
+ "襄樊": "101200201",
+ "襄阳": "101200202",
+ "保康": "101200203",
+ "南漳": "101200204",
+ "宜城": "101200205",
+ "老河口": "101200206",
+ "谷城": "101200207",
+ "枣阳": "101200208",
+ "鄂州": "101200301",
+ "孝感": "101200401",
+ "安陆": "101200402",
+ "云梦": "101200403",
+ "大悟": "101200404",
+ "应城": "101200405",
+ "汉川": "101200406",
+ "黄冈": "101200501",
+ "红安": "101200502",
+ "麻城": "101200503",
+ "罗田": "101200504",
+ "英山": "101200505",
+ "浠水": "101200506",
+ "蕲春": "101200507",
+ "黄梅": "101200508",
+ "武穴": "101200509",
+ "黄石": "101200601",
+ "大冶": "101200602",
+ "阳新": "101200603",
+ "咸宁": "101200701",
+ "赤壁": "101200702",
+ "嘉鱼": "101200703",
+ "崇阳": "101200704",
+ "通城": "101200705",
+ "通山": "101200706",
+ "荆州": "101200801",
+ "江陵": "101200802",
+ "公安": "101200803",
+ "石首": "101200804",
+ "监利": "101200805",
+ "洪湖": "101200806",
+ "松滋": "101200807",
+ "宜昌": "101200901",
+ "远安": "101200902",
+ "秭归": "101200903",
+ "兴山": "101200904",
+ "宜昌县": "101200905",
+ "五峰": "101200906",
+ "当阳": "101200907",
+ "长阳": "101200908",
+ "宜都": "101200909",
+ "枝江": "101200910",
+ "三峡": "101200911",
+ "夷陵": "101200912",
+ "恩施": "101201001",
+ "利川": "101201002",
+ "建始": "101201003",
+ "咸丰": "101201004",
+ "宣恩": "101201005",
+ "鹤峰": "101201006",
+ "来凤": "101201007",
+ "巴东": "101201008",
+ "绿葱坡": "101201009",
+ "十堰": "101201101",
+ "竹溪": "101201102",
+ "郧西": "101201103",
+ "郧县": "101201104",
+ "竹山": "101201105",
+ "房县": "101201106",
+ "丹江口": "101201107",
+ "神农架": "101201201",
+ "随州": "101201301",
+ "广水": "101201302",
+ "荆门": "101201401",
+ "钟祥": "101201402",
+ "京山": "101201403",
+ "天门": "101201501",
+ "仙桃": "101201601",
+ "潜江": "101201701",
+ "杭州": "101210101",
+ "萧山": "101210102",
+ "桐庐": "101210103",
+ "淳安": "101210104",
+ "建德": "101210105",
+ "余杭": "101210106",
+ "临安": "101210107",
+ "富阳": "101210108",
+ "湖州": "101210201",
+ "长兴": "101210202",
+ "安吉": "101210203",
+ "德清": "101210204",
+ "嘉兴": "101210301",
+ "嘉善": "101210302",
+ "海宁": "101210303",
+ "桐乡": "101210304",
+ "平湖": "101210305",
+ "海盐": "101210306",
+ "宁波": "101210401",
+ "慈溪": "101210403",
+ "余姚": "101210404",
+ "奉化": "101210405",
+ "象山": "101210406",
+ "石浦": "101210407",
+ "宁海": "101210408",
+ "鄞县": "101210409",
+ "北仑": "101210410",
+ "鄞州": "101210411",
+ "镇海": "101210412",
+ "绍兴": "101210501",
+ "诸暨": "101210502",
+ "上虞": "101210503",
+ "新昌": "101210504",
+ "嵊州": "101210505",
+ "台州": "101210601",
+ "括苍山": "101210602",
+ "玉环": "101210603",
+ "三门": "101210604",
+ "天台": "101210605",
+ "仙居": "101210606",
+ "温岭": "101210607",
+ "大陈": "101210608",
+ "洪家": "101210609",
+ "温州": "101210701",
+ "泰顺": "101210702",
+ "文成": "101210703",
+ "平阳": "101210704",
+ "瑞安": "101210705",
+ "洞头": "101210706",
+ "乐清": "101210707",
+ "永嘉": "101210708",
+ "苍南": "101210709",
+ "丽水": "101210801",
+ "遂昌": "101210802",
+ "龙泉": "101210803",
+ "缙云": "101210804",
+ "青田": "101210805",
+ "云和": "101210806",
+ "庆元": "101210807",
+ "金华": "101210901",
+ "浦江": "101210902",
+ "兰溪": "101210903",
+ "义乌": "101210904",
+ "东阳": "101210905",
+ "武义": "101210906",
+ "永康": "101210907",
+ "磐安": "101210908",
+ "衢州": "101211001",
+ "常山": "101211002",
+ "开化": "101211003",
+ "龙游": "101211004",
+ "江山": "101211005",
+ "舟山": "101211101",
+ "嵊泗": "101211102",
+ "嵊山": "101211103",
+ "岱山": "101211104",
+ "普陀": "101211105",
+ "定海": "101211106",
+ "合肥": "101220101",
+ "长丰": "101220102",
+ "肥东": "101220103",
+ "肥西": "101220104",
+ "蚌埠": "101220201",
+ "怀远": "101220202",
+ "固镇": "101220203",
+ "五河": "101220204",
+ "芜湖": "101220301",
+ "繁昌": "101220302",
+ "芜湖县": "101220303",
+ "南陵": "101220304",
+ "淮南": "101220401",
+ "凤台": "101220402",
+ "马鞍山": "101220501",
+ "当涂": "101220502",
+ "安庆": "101220601",
+ "枞阳": "101220602",
+ "太湖": "101220603",
+ "潜山": "101220604",
+ "怀宁": "101220605",
+ "宿松": "101220606",
+ "望江": "101220607",
+ "岳西": "101220608",
+ "桐城": "101220609",
+ "宿州": "101220701",
+ "砀山": "101220702",
+ "灵璧": "101220703",
+ "泗县": "101220704",
+ "萧县": "101220705",
+ "阜阳": "101220801",
+ "阜南": "101220802",
+ "颍上": "101220803",
+ "临泉": "101220804",
+ "界首": "101220805",
+ "太和": "101220806",
+ "亳州": "101220901",
+ "涡阳": "101220902",
+ "利辛": "101220903",
+ "蒙城": "101220904",
+ "黄山站": "101221001",
+ "黄山区": "101221002",
+ "屯溪": "101221003",
+ "祁门": "101221004",
+ "黟县": "101221005",
+ "歙县": "101221006",
+ "休宁": "101221007",
+ "黄山市": "101221008",
+ "滁州": "101221101",
+ "凤阳": "101221102",
+ "明光": "101221103",
+ "定远": "101221104",
+ "全椒": "101221105",
+ "来安": "101221106",
+ "天长": "101221107",
+ "淮北": "101221201",
+ "濉溪": "101221202",
+ "铜陵": "101221301",
+ "宣城": "101221401",
+ "泾县": "101221402",
+ "旌德": "101221403",
+ "宁国": "101221404",
+ "绩溪": "101221405",
+ "广德": "101221406",
+ "郎溪": "101221407",
+ "六安": "101221501",
+ "霍邱": "101221502",
+ "寿县": "101221503",
+ "南溪": "101221504",
+ "金寨": "101221505",
+ "霍山": "101221506",
+ "舒城": "101221507",
+ "巢湖": "101221601",
+ "庐江": "101221602",
+ "无为": "101221603",
+ "含山": "101221604",
+ "和县": "101221605",
+ "池州": "101221701",
+ "东至": "101221702",
+ "青阳": "101221703",
+ "九华山": "101221704",
+ "石台": "101221705",
+ "福州": "101230101",
+ "闽清": "101230102",
+ "闽侯": "101230103",
+ "罗源": "101230104",
+ "连江": "101230105",
+ "马祖": "101230106",
+ "永泰": "101230107",
+ "平潭": "101230108",
+ "福州郊区": "101230109",
+ "长乐": "101230110",
+ "福清": "101230111",
+ "平潭海峡大桥": "101230112",
+ "厦门": "101230201",
+ "同安": "101230202",
+ "宁德": "101230301",
+ "古田": "101230302",
+ "霞浦": "101230303",
+ "寿宁": "101230304",
+ "周宁": "101230305",
+ "福安": "101230306",
+ "柘荣": "101230307",
+ "福鼎": "101230308",
+ "屏南": "101230309",
+ "莆田": "101230401",
+ "仙游": "101230402",
+ "秀屿港": "101230403",
+ "泉州": "101230501",
+ "安溪": "101230502",
+ "九仙山": "101230503",
+ "永春": "101230504",
+ "德化": "101230505",
+ "南安": "101230506",
+ "崇武": "101230507",
+ "晋江": "101230509",
+ "漳州": "101230601",
+ "长泰": "101230602",
+ "南靖": "101230603",
+ "平和": "101230604",
+ "龙海": "101230605",
+ "漳浦": "101230606",
+ "诏安": "101230607",
+ "东山": "101230608",
+ "云霄": "101230609",
+ "华安": "101230610",
+ "龙岩": "101230701",
+ "长汀": "101230702",
+ "连城": "101230703",
+ "武平": "101230704",
+ "上杭": "101230705",
+ "永定": "101230706",
+ "漳平": "101230707",
+ "三明": "101230801",
+ "宁化": "101230802",
+ "清流": "101230803",
+ "泰宁": "101230804",
+ "将乐": "101230805",
+ "建宁": "101230806",
+ "明溪": "101230807",
+ "沙县": "101230808",
+ "尤溪": "101230809",
+ "永安": "101230810",
+ "大田": "101230811",
+ "南平": "101230901",
+ "顺昌": "101230902",
+ "光泽": "101230903",
+ "邵武": "101230904",
+ "武夷山": "101230905",
+ "浦城": "101230906",
+ "建阳": "101230907",
+ "松溪": "101230908",
+ "政和": "101230909",
+ "建瓯": "101230910",
+ "南昌": "101240101",
+ "新建": "101240102",
+ "南昌县": "101240103",
+ "安义": "101240104",
+ "进贤": "101240105",
+ "莲塘": "101240106",
+ "九江": "101240201",
+ "瑞昌": "101240202",
+ "庐山": "101240203",
+ "武宁": "101240204",
+ "德安": "101240205",
+ "永修": "101240206",
+ "湖口": "101240207",
+ "彭泽": "101240208",
+ "星子": "101240209",
+ "都昌": "101240210",
+ "棠荫": "101240211",
+ "修水": "101240212",
+ "上饶": "101240301",
+ "鄱阳": "101240302",
+ "婺源": "101240303",
+ "康山": "101240304",
+ "余干": "101240305",
+ "万年": "101240306",
+ "德兴": "101240307",
+ "上饶县": "101240308",
+ "弋阳": "101240309",
+ "横峰": "101240310",
+ "铅山": "101240311",
+ "玉山": "101240312",
+ "广丰": "101240313",
+ "波阳": "101240314",
+ "抚州": "101240401",
+ "广昌": "101240402",
+ "乐安": "101240403",
+ "崇仁": "101240404",
+ "金溪": "101240405",
+ "资溪": "101240406",
+ "宜黄": "101240407",
+ "南城": "101240408",
+ "南丰": "101240409",
+ "黎川": "101240410",
+ "宜春": "101240501",
+ "铜鼓": "101240502",
+ "宜丰": "101240503",
+ "万载": "101240504",
+ "上高": "101240505",
+ "靖安": "101240506",
+ "奉新": "101240507",
+ "高安": "101240508",
+ "樟树": "101240509",
+ "丰城": "101240510",
+ "吉安": "101240601",
+ "吉安县": "101240602",
+ "吉水": "101240603",
+ "新干": "101240604",
+ "峡江": "101240605",
+ "永丰": "101240606",
+ "永新": "101240607",
+ "井冈山": "101240608",
+ "万安": "101240609",
+ "遂川": "101240610",
+ "泰和": "101240611",
+ "安福": "101240612",
+ "宁冈": "101240613",
+ "赣州": "101240701",
+ "崇义": "101240702",
+ "上犹": "101240703",
+ "南康": "101240704",
+ "大余": "101240705",
+ "信丰": "101240706",
+ "宁都": "101240707",
+ "石城": "101240708",
+ "瑞金": "101240709",
+ "于都": "101240710",
+ "会昌": "101240711",
+ "安远": "101240712",
+ "全南": "101240713",
+ "龙南": "101240714",
+ "定南": "101240715",
+ "寻乌": "101240716",
+ "兴国": "101240717",
+ "景德镇": "101240801",
+ "乐平": "101240802",
+ "萍乡": "101240901",
+ "莲花": "101240902",
+ "新余": "101241001",
+ "分宜": "101241002",
+ "鹰潭": "101241101",
+ "余江": "101241102",
+ "贵溪": "101241103",
+ "长沙": "101250101",
+ "宁乡": "101250102",
+ "浏阳": "101250103",
+ "马坡岭": "101250104",
+ "湘潭": "101250201",
+ "韶山": "101250202",
+ "湘乡": "101250203",
+ "株洲": "101250301",
+ "攸县": "101250302",
+ "醴陵": "101250303",
+ "株洲县": "101250304",
+ "茶陵": "101250305",
+ "炎陵": "101250306",
+ "衡阳": "101250401",
+ "衡山": "101250402",
+ "衡东": "101250403",
+ "祁东": "101250404",
+ "衡阳县": "101250405",
+ "常宁": "101250406",
+ "衡南": "101250407",
+ "耒阳": "101250408",
+ "南岳": "101250409",
+ "郴州": "101250501",
+ "桂阳": "101250502",
+ "嘉禾": "101250503",
+ "宜章": "101250504",
+ "临武": "101250505",
+ "桥口": "101250506",
+ "资兴": "101250507",
+ "汝城": "101250508",
+ "安仁": "101250509",
+ "永兴": "101250510",
+ "桂东": "101250511",
+ "常德": "101250601",
+ "安乡": "101250602",
+ "桃源": "101250603",
+ "汉寿": "101250604",
+ "澧县": "101250605",
+ "临澧": "101250606",
+ "石门": "101250607",
+ "益阳": "101250700",
+ "赫山区": "101250701",
+ "南县": "101250702",
+ "桃江": "101250703",
+ "安化": "101250704",
+ "沅江": "101250705",
+ "娄底": "101250801",
+ "双峰": "101250802",
+ "冷水江": "101250803",
+ "冷水滩": "101250804",
+ "新化": "101250805",
+ "涟源": "101250806",
+ "邵阳": "101250901",
+ "隆回": "101250902",
+ "洞口": "101250903",
+ "新邵": "101250904",
+ "邵东": "101250905",
+ "绥宁": "101250906",
+ "新宁": "101250907",
+ "武冈": "101250908",
+ "城步": "101250909",
+ "邵阳县": "101250910",
+ "岳阳": "101251001",
+ "华容": "101251002",
+ "湘阴": "101251003",
+ "汨罗": "101251004",
+ "平江": "101251005",
+ "临湘": "101251006",
+ "张家界": "101251101",
+ "桑植": "101251102",
+ "慈利": "101251103",
+ "怀化": "101251201",
+ "鹤城区": "101251202",
+ "沅陵": "101251203",
+ "辰溪": "101251204",
+ "靖州": "101251205",
+ "会同": "101251206",
+ "通道": "101251207",
+ "麻阳": "101251208",
+ "新晃": "101251209",
+ "芷江": "101251210",
+ "溆浦": "101251211",
+ "黔阳": "101251301",
+ "洪江": "101251302",
+ "永州": "101251401",
+ "祁阳": "101251402",
+ "东安": "101251403",
+ "双牌": "101251404",
+ "道县": "101251405",
+ "宁远": "101251406",
+ "江永": "101251407",
+ "蓝山": "101251408",
+ "新田": "101251409",
+ "江华": "101251410",
+ "吉首": "101251501",
+ "保靖": "101251502",
+ "永顺": "101251503",
+ "古丈": "101251504",
+ "凤凰": "101251505",
+ "泸溪": "101251506",
+ "龙山": "101251507",
+ "花垣": "101251508",
+ "贵阳": "101260101",
+ "白云": "101260102",
+ "花溪": "101260103",
+ "乌当": "101260104",
+ "息烽": "101260105",
+ "开阳": "101260106",
+ "修文": "101260107",
+ "清镇": "101260108",
+ "遵义": "101260201",
+ "遵义县": "101260202",
+ "仁怀": "101260203",
+ "绥阳": "101260204",
+ "湄潭": "101260205",
+ "凤冈": "101260206",
+ "桐梓": "101260207",
+ "赤水": "101260208",
+ "习水": "101260209",
+ "道真": "101260210",
+ "正安": "101260211",
+ "务川": "101260212",
+ "余庆": "101260213",
+ "汇川": "101260214",
+ "安顺": "101260301",
+ "普定": "101260302",
+ "镇宁": "101260303",
+ "平坝": "101260304",
+ "紫云": "101260305",
+ "关岭": "101260306",
+ "都匀": "101260401",
+ "贵定": "101260402",
+ "瓮安": "101260403",
+ "长顺": "101260404",
+ "福泉": "101260405",
+ "惠水": "101260406",
+ "龙里": "101260407",
+ "罗甸": "101260408",
+ "平塘": "101260409",
+ "独山": "101260410",
+ "三都": "101260411",
+ "荔波": "101260412",
+ "凯里": "101260501",
+ "岑巩": "101260502",
+ "施秉": "101260503",
+ "镇远": "101260504",
+ "黄平": "101260505",
+ "黄平旧洲": "101260506",
+ "麻江": "101260507",
+ "丹寨": "101260508",
+ "三穗": "101260509",
+ "台江": "101260510",
+ "剑河": "101260511",
+ "雷山": "101260512",
+ "黎平": "101260513",
+ "天柱": "101260514",
+ "锦屏": "101260515",
+ "榕江": "101260516",
+ "从江": "101260517",
+ "炉山": "101260518",
+ "铜仁": "101260601",
+ "江口": "101260602",
+ "玉屏": "101260603",
+ "万山": "101260604",
+ "思南": "101260605",
+ "塘头": "101260606",
+ "印江": "101260607",
+ "石阡": "101260608",
+ "沿河": "101260609",
+ "德江": "101260610",
+ "松桃": "101260611",
+ "毕节": "101260701",
+ "赫章": "101260702",
+ "金沙": "101260703",
+ "威宁": "101260704",
+ "大方": "101260705",
+ "纳雍": "101260706",
+ "织金": "101260707",
+ "六盘水": "101260801",
+ "六枝": "101260802",
+ "水城": "101260803",
+ "盘县": "101260804",
+ "黔西": "101260901",
+ "晴隆": "101260902",
+ "兴仁": "101260903",
+ "贞丰": "101260904",
+ "望谟": "101260905",
+ "兴义": "101260906",
+ "安龙": "101260907",
+ "册亨": "101260908",
+ "普安": "101260909",
+ "成都": "101270101",
+ "龙泉驿": "101270102",
+ "新都": "101270103",
+ "温江": "101270104",
+ "金堂": "101270105",
+ "双流": "101270106",
+ "郫县": "101270107",
+ "大邑": "101270108",
+ "蒲江": "101270109",
+ "新津": "101270110",
+ "都江堰": "101270111",
+ "彭州": "101270112",
+ "邛崃": "101270113",
+ "崇州": "101270114",
+ "崇庆": "101270115",
+ "彭县": "101270116",
+ "攀枝花": "101270201",
+ "仁和": "101270202",
+ "米易": "101270203",
+ "盐边": "101270204",
+ "自贡": "101270301",
+ "富顺": "101270302",
+ "荣县": "101270303",
+ "绵阳": "101270401",
+ "三台": "101270402",
+ "盐亭": "101270403",
+ "安县": "101270404",
+ "梓潼": "101270405",
+ "北川": "101270406",
+ "平武": "101270407",
+ "江油": "101270408",
+ "南充": "101270501",
+ "南部": "101270502",
+ "营山": "101270503",
+ "蓬安": "101270504",
+ "仪陇": "101270505",
+ "西充": "101270506",
+ "阆中": "101270507",
+ "达州": "101270601",
+ "宣汉": "101270602",
+ "开江": "101270603",
+ "大竹": "101270604",
+ "渠县": "101270605",
+ "万源": "101270606",
+ "达川": "101270607",
+ "遂宁": "101270701",
+ "蓬溪": "101270702",
+ "射洪": "101270703",
+ "广安": "101270801",
+ "岳池": "101270802",
+ "武胜": "101270803",
+ "邻水": "101270804",
+ "华蓥山": "101270805",
+ "巴中": "101270901",
+ "通江": "101270902",
+ "南江": "101270903",
+ "平昌": "101270904",
+ "泸州": "101271001",
+ "泸县": "101271003",
+ "合江": "101271004",
+ "叙永": "101271005",
+ "古蔺": "101271006",
+ "纳溪": "101271007",
+ "宜宾": "101271101",
+ "宜宾农试站": "101271102",
+ "宜宾县": "101271103",
+ "江安": "101271105",
+ "长宁": "101271106",
+ "高县": "101271107",
+ "珙县": "101271108",
+ "筠连": "101271109",
+ "兴文": "101271110",
+ "屏山": "101271111",
+ "内江": "101271201",
+ "东兴": "101271202",
+ "威远": "101271203",
+ "资中": "101271204",
+ "隆昌": "101271205",
+ "资阳": "101271301",
+ "安岳": "101271302",
+ "乐至": "101271303",
+ "简阳": "101271304",
+ "乐山": "101271401",
+ "犍为": "101271402",
+ "井研": "101271403",
+ "夹江": "101271404",
+ "沐川": "101271405",
+ "峨边": "101271406",
+ "马边": "101271407",
+ "峨眉": "101271408",
+ "峨眉山": "101271409",
+ "眉山": "101271501",
+ "仁寿": "101271502",
+ "彭山": "101271503",
+ "洪雅": "101271504",
+ "丹棱": "101271505",
+ "青神": "101271506",
+ "凉山": "101271601",
+ "木里": "101271603",
+ "盐源": "101271604",
+ "德昌": "101271605",
+ "会理": "101271606",
+ "会东": "101271607",
+ "宁南": "101271608",
+ "普格": "101271609",
+ "西昌": "101271610",
+ "金阳": "101271611",
+ "昭觉": "101271612",
+ "喜德": "101271613",
+ "冕宁": "101271614",
+ "越西": "101271615",
+ "甘洛": "101271616",
+ "雷波": "101271617",
+ "美姑": "101271618",
+ "布拖": "101271619",
+ "雅安": "101271701",
+ "名山": "101271702",
+ "荣经": "101271703",
+ "汉源": "101271704",
+ "石棉": "101271705",
+ "天全": "101271706",
+ "芦山": "101271707",
+ "宝兴": "101271708",
+ "甘孜": "101271801",
+ "康定": "101271802",
+ "泸定": "101271803",
+ "丹巴": "101271804",
+ "九龙": "101271805",
+ "雅江": "101271806",
+ "道孚": "101271807",
+ "炉霍": "101271808",
+ "新龙": "101271809",
+ "德格": "101271810",
+ "白玉": "101271811",
+ "石渠": "101271812",
+ "色达": "101271813",
+ "理塘": "101271814",
+ "巴塘": "101271815",
+ "乡城": "101271816",
+ "稻城": "101271817",
+ "得荣": "101271818",
+ "阿坝": "101271901",
+ "汶川": "101271902",
+ "理县": "101271903",
+ "茂县": "101271904",
+ "松潘": "101271905",
+ "九寨沟": "101271906",
+ "金川": "101271907",
+ "小金": "101271908",
+ "黑水": "101271909",
+ "马尔康": "101271910",
+ "壤塘": "101271911",
+ "若尔盖": "101271912",
+ "红原": "101271913",
+ "南坪": "101271914",
+ "德阳": "101272001",
+ "中江": "101272002",
+ "广汉": "101272003",
+ "什邡": "101272004",
+ "绵竹": "101272005",
+ "罗江": "101272006",
+ "广元": "101272101",
+ "旺苍": "101272102",
+ "青川": "101272103",
+ "剑阁": "101272104",
+ "苍溪": "101272105",
+ "广州": "101280101",
+ "番禺": "101280102",
+ "从化": "101280103",
+ "增城": "101280104",
+ "花都": "101280105",
+ "天河": "101280106",
+ "韶关": "101280201",
+ "乳源": "101280202",
+ "始兴": "101280203",
+ "翁源": "101280204",
+ "乐昌": "101280205",
+ "仁化": "101280206",
+ "南雄": "101280207",
+ "新丰": "101280208",
+ "曲江": "101280209",
+ "惠州": "101280301",
+ "博罗": "101280302",
+ "惠阳": "101280303",
+ "惠东": "101280304",
+ "龙门": "101280305",
+ "梅州": "101280401",
+ "兴宁": "101280402",
+ "蕉岭": "101280403",
+ "大埔": "101280404",
+ "丰顺": "101280406",
+ "平远": "101280407",
+ "五华": "101280408",
+ "梅县": "101280409",
+ "汕头": "101280501",
+ "潮阳": "101280502",
+ "澄海": "101280503",
+ "南澳": "101280504",
+ "云澳": "101280505",
+ "南澎岛": "101280506",
+ "深圳": "101280601",
+ "珠海": "101280701",
+ "斗门": "101280702",
+ "黄茅洲": "101280703",
+ "佛山": "101280800",
+ "顺德": "101280801",
+ "三水": "101280802",
+ "南海": "101280803",
+ "肇庆": "101280901",
+ "广宁": "101280902",
+ "四会": "101280903",
+ "德庆": "101280905",
+ "怀集": "101280906",
+ "封开": "101280907",
+ "高要": "101280908",
+ "湛江": "101281001",
+ "吴川": "101281002",
+ "雷州": "101281003",
+ "徐闻": "101281004",
+ "廉江": "101281005",
+ "硇洲": "101281006",
+ "遂溪": "101281007",
+ "江门": "101281101",
+ "开平": "101281103",
+ "新会": "101281104",
+ "恩平": "101281105",
+ "台山": "101281106",
+ "上川岛": "101281107",
+ "鹤山": "101281108",
+ "河源": "101281201",
+ "紫金": "101281202",
+ "连平": "101281203",
+ "和平": "101281204",
+ "龙川": "101281205",
+ "清远": "101281301",
+ "连南": "101281302",
+ "连州": "101281303",
+ "连山": "101281304",
+ "阳山": "101281305",
+ "佛冈": "101281306",
+ "英德": "101281307",
+ "云浮": "101281401",
+ "罗定": "101281402",
+ "新兴": "101281403",
+ "郁南": "101281404",
+ "潮州": "101281501",
+ "饶平": "101281502",
+ "东莞": "101281601",
+ "中山": "101281701",
+ "阳江": "101281801",
+ "阳春": "101281802",
+ "揭阳": "101281901",
+ "揭西": "101281902",
+ "普宁": "101281903",
+ "惠来": "101281904",
+ "茂名": "101282001",
+ "高州": "101282002",
+ "化州": "101282003",
+ "电白": "101282004",
+ "信宜": "101282005",
+ "汕尾": "101282101",
+ "海丰": "101282102",
+ "陆丰": "101282103",
+ "遮浪": "101282104",
+ "东沙岛": "101282105",
+ "昆明": "101290101",
+ "昆明农试站": "101290102",
+ "东川": "101290103",
+ "寻甸": "101290104",
+ "晋宁": "101290105",
+ "宜良": "101290106",
+ "石林": "101290107",
+ "呈贡": "101290108",
+ "富民": "101290109",
+ "嵩明": "101290110",
+ "禄劝": "101290111",
+ "安宁": "101290112",
+ "太华山": "101290113",
+ "大理": "101290201",
+ "云龙": "101290202",
+ "漾鼻": "101290203",
+ "永平": "101290204",
+ "宾川": "101290205",
+ "弥渡": "101290206",
+ "祥云": "101290207",
+ "魏山": "101290208",
+ "剑川": "101290209",
+ "洱源": "101290210",
+ "鹤庆": "101290211",
+ "南涧": "101290212",
+ "红河": "101290301",
+ "石屏": "101290302",
+ "建水": "101290303",
+ "弥勒": "101290304",
+ "元阳": "101290305",
+ "绿春": "101290306",
+ "开远": "101290307",
+ "个旧": "101290308",
+ "蒙自": "101290309",
+ "屏边": "101290310",
+ "泸西": "101290311",
+ "金平": "101290312",
+ "曲靖": "101290401",
+ "沾益": "101290402",
+ "陆良": "101290403",
+ "富源": "101290404",
+ "马龙": "101290405",
+ "师宗": "101290406",
+ "罗平": "101290407",
+ "会泽": "101290408",
+ "宣威": "101290409",
+ "保山": "101290501",
+ "富宁": "101290502",
+ "龙陵": "101290503",
+ "施甸": "101290504",
+ "昌宁": "101290505",
+ "腾冲": "101290506",
+ "文山": "101290601",
+ "西畴": "101290602",
+ "马关": "101290603",
+ "麻栗坡": "101290604",
+ "砚山": "101290605",
+ "邱北": "101290606",
+ "广南": "101290607",
+ "玉溪": "101290701",
+ "澄江": "101290702",
+ "江川": "101290703",
+ "通海": "101290704",
+ "华宁": "101290705",
+ "新平": "101290706",
+ "易门": "101290707",
+ "峨山": "101290708",
+ "元江": "101290709",
+ "楚雄": "101290801",
+ "大姚": "101290802",
+ "元谋": "101290803",
+ "姚安": "101290804",
+ "牟定": "101290805",
+ "南华": "101290806",
+ "武定": "101290807",
+ "禄丰": "101290808",
+ "双柏": "101290809",
+ "永仁": "101290810",
+ "普洱": "101290901",
+ "景谷": "101290902",
+ "景东": "101290903",
+ "澜沧": "101290904",
+ "墨江": "101290906",
+ "江城": "101290907",
+ "孟连": "101290908",
+ "西盟": "101290909",
+ "镇源": "101290910",
+ "镇沅": "101290911",
+ "宁洱": "101290912",
+ "昭通": "101291001",
+ "鲁甸": "101291002",
+ "彝良": "101291003",
+ "镇雄": "101291004",
+ "威信": "101291005",
+ "巧家": "101291006",
+ "绥江": "101291007",
+ "永善": "101291008",
+ "盐津": "101291009",
+ "大关": "101291010",
+ "临沧": "101291101",
+ "沧源": "101291102",
+ "耿马": "101291103",
+ "双江": "101291104",
+ "凤庆": "101291105",
+ "永德": "101291106",
+ "云县": "101291107",
+ "镇康": "101291108",
+ "怒江": "101291201",
+ "福贡": "101291203",
+ "兰坪": "101291204",
+ "泸水": "101291205",
+ "六库": "101291206",
+ "贡山": "101291207",
+ "香格里拉": "101291301",
+ "德钦": "101291302",
+ "维西": "101291303",
+ "中甸": "101291304",
+ "丽江": "101291401",
+ "永胜": "101291402",
+ "华坪": "101291403",
+ "宁蒗": "101291404",
+ "德宏": "101291501",
+ "潞江坝": "101291502",
+ "陇川": "101291503",
+ "盈江": "101291504",
+ "畹町镇": "101291505",
+ "瑞丽": "101291506",
+ "梁河": "101291507",
+ "潞西": "101291508",
+ "景洪": "101291601",
+ "大勐龙": "101291602",
+ "勐海": "101291603",
+ "景洪电站": "101291604",
+ "勐腊": "101291605",
+ "南宁": "101300101",
+ "南宁城区": "101300102",
+ "邕宁": "101300103",
+ "横县": "101300104",
+ "隆安": "101300105",
+ "马山": "101300106",
+ "上林": "101300107",
+ "武鸣": "101300108",
+ "宾阳": "101300109",
+ "硕龙": "101300110",
+ "崇左": "101300201",
+ "天等": "101300202",
+ "龙州": "101300203",
+ "凭祥": "101300204",
+ "大新": "101300205",
+ "扶绥": "101300206",
+ "宁明": "101300207",
+ "海渊": "101300208",
+ "柳州": "101300301",
+ "柳城": "101300302",
+ "沙塘": "101300303",
+ "鹿寨": "101300304",
+ "柳江": "101300305",
+ "融安": "101300306",
+ "融水": "101300307",
+ "三江": "101300308",
+ "来宾": "101300401",
+ "忻城": "101300402",
+ "金秀": "101300403",
+ "象州": "101300404",
+ "武宣": "101300405",
+ "桂林": "101300501",
+ "桂林农试站": "101300502",
+ "龙胜": "101300503",
+ "永福": "101300504",
+ "临桂": "101300505",
+ "兴安": "101300506",
+ "灵川": "101300507",
+ "全州": "101300508",
+ "灌阳": "101300509",
+ "阳朔": "101300510",
+ "恭城": "101300511",
+ "平乐": "101300512",
+ "荔浦": "101300513",
+ "资源": "101300514",
+ "梧州": "101300601",
+ "藤县": "101300602",
+ "太平": "101300603",
+ "苍梧": "101300604",
+ "蒙山": "101300605",
+ "岑溪": "101300606",
+ "贺州": "101300701",
+ "昭平": "101300702",
+ "富川": "101300703",
+ "钟山": "101300704",
+ "信都": "101300705",
+ "贵港": "101300801",
+ "桂平": "101300802",
+ "平南": "101300803",
+ "玉林": "101300901",
+ "博白": "101300902",
+ "北流": "101300903",
+ "容县": "101300904",
+ "陆川": "101300905",
+ "百色": "101301001",
+ "那坡": "101301002",
+ "田阳": "101301003",
+ "德保": "101301004",
+ "靖西": "101301005",
+ "田东": "101301006",
+ "平果": "101301007",
+ "隆林": "101301008",
+ "西林": "101301009",
+ "乐业": "101301010",
+ "凌云": "101301011",
+ "田林": "101301012",
+ "钦州": "101301101",
+ "浦北": "101301102",
+ "灵山": "101301103",
+ "河池": "101301201",
+ "天峨": "101301202",
+ "东兰": "101301203",
+ "巴马": "101301204",
+ "环江": "101301205",
+ "罗城": "101301206",
+ "宜州": "101301207",
+ "凤山": "101301208",
+ "南丹": "101301209",
+ "都安": "101301210",
+ "北海": "101301301",
+ "合浦": "101301302",
+ "涠洲岛": "101301303",
+ "防城港": "101301401",
+ "上思": "101301402",
+ "板栏": "101301404",
+ "防城": "101301405",
+ "海口": "101310101",
+ "琼山": "101310102",
+ "三亚": "101310201",
+ "东方": "101310202",
+ "临高": "101310203",
+ "澄迈": "101310204",
+ "儋州": "101310205",
+ "昌江": "101310206",
+ "白沙": "101310207",
+ "琼中": "101310208",
+ "定安": "101310209",
+ "屯昌": "101310210",
+ "琼海": "101310211",
+ "文昌": "101310212",
+ "清兰": "101310213",
+ "保亭": "101310214",
+ "万宁": "101310215",
+ "陵水": "101310216",
+ "西沙": "101310217",
+ "珊瑚岛": "101310218",
+ "永署礁": "101310219",
+ "南沙岛": "101310220",
+ "乐东": "101310221",
+ "五指山": "101310222",
+ "通什": "101310223",
+ "香港": "101320101",
+ "新界": "101320103",
+ "中环": "101320104",
+ "铜锣湾": "101320105",
+ "澳门": "101330101",
+ "台北县": "101340101",
+ "台北市": "101340102",
+ "高雄": "101340201",
+ "大武": "101340203",
+ "恒春": "101340204",
+ "兰屿": "101340205",
+ "台南": "101340301",
+ "台中": "101340401",
+ "桃园": "101340501",
+ "新竹县": "101340601",
+ "新竹市": "101340602",
+ "公馆": "101340603",
+ "宜兰": "101340701",
+ "马公": "101340801",
+ "东吉屿": "101340802",
+ "嘉义": "101340901",
+ "阿里山": "101340902",
+ "新港": "101340904"
+};
+
+// 天气GET
+export const WeatherGet = function (_, generator) {
+ var data = this.getFieldValue('data');
+ var CityCode = WeatherCity[data];
+ generator.definitions_['include_Weather_Forcast'] = '#include ';
+ generator.definitions_['var_declare_Weather_Forcast'] = 'Weather_Forcast Weather;';
+ if (CityCode) {
+ this.setFieldValue('ok', "check");
+ } else {
+ CityCode = 'error';
+ this.setFieldValue('error', "check");
+ }
+
+ var code = "Weather.RefreshData(\"" + CityCode + "\")";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+//获取当天天气
+export const WeatherGetToday = function (_, generator) {
+ var type = this.getFieldValue('type');
+ var code = "Weather.getToday(" + type + ")";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+//获取预报天气
+export const WeatherGetForecast = function (_, generator) {
+ var type = this.getFieldValue('type');
+ var date = generator.valueToCode(this, 'date', generator.ORDER_ATOMIC);
+ var code = "Weather.get" + type + "(" + date + ")";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const mixio_mqtt_subscribe = function (_, generator) {
+ var server = generator.valueToCode(this, 'server', generator.ORDER_ATOMIC);
+ var port = generator.valueToCode(this, 'port', generator.ORDER_ATOMIC);
+ var mqtt_username = generator.valueToCode(this, 'mqtt_username', generator.ORDER_ATOMIC);
+ var mqtt_password = generator.valueToCode(this, 'mqtt_password', generator.ORDER_ATOMIC);
+ var project = generator.valueToCode(this, 'project', generator.ORDER_ATOMIC);
+ port = port.replace(/"/g, "")
+ generator.definitions_['include_PubSubClient'] = '#include \n';
+ generator.definitions_['var_declare_PubSubClient'] = 'const char *mqtt_broker = ' + server + ';\n'
+ + 'const char *mqtt_username = ' + mqtt_username + ';\n'
+ + 'const char *mqtt_password = ' + mqtt_password + ';\n'
+ + 'const int mqtt_port = ' + port + ';\n'
+ + 'String mqtt_topic = "";\n'
+ + 'String mqtt_data = "";\n'
+ + 'boolean mqtt_status = false;\n'
+ + 'String project = ' + project + ';\n\n'
+
+ + 'WiFiClient espClient;\n'
+ + 'PubSubClient client(espClient);\n'
+
+ + 'void callback(char *topic, byte *payload, unsigned int length) {\n'
+ + ' String data = "";\n'
+ + ' for (int i = 0; i < length; i++) {\n'
+ + ' data = String(data) + String((char) payload[i]);\n'
+ + ' }\n'
+ + ' mqtt_topic = String(topic);\n'
+ + ' mqtt_data = data;\n'
+ + ' mqtt_status = true;\n'
+ + '}\n';
+ generator.setups_['setups_PubSubClient'] = 'client.setServer(mqtt_broker, mqtt_port);\n'
+ + 'client.setCallback(callback);\n'
+ + 'while (!client.connected()) {\n'
+ + ' String client_id = "esp-client-";\n'
+ + ' client_id += String(WiFi.macAddress());\n'
+ + ' Serial.printf("The client %s connects to the public mqtt broker\\n", client_id.c_str());\n'
+ + ' if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {\n'
+ + ' Serial.println("Public emqx mqtt broker connected");\n'
+ + ' client.publish(String(String(mqtt_username) +"/"+ String(project) +"/"+ String("b640a0ce465fa2a4150c36b305c1c11b")).c_str(),String(client_id).c_str());\n'
+ + ' } else {\n'
+ + ' Serial.print("failed with state ");\n'
+ + ' Serial.print(client.state());\n'
+ + ' delay(2000);\n'
+ + ' }\n'
+ + '}\n';
+ var code = 'client.loop();\n';
+ return code;
+}
+
+export const mixio_mqtt_subscribe_key = function (_, generator) {
+ var key = this.getFieldValue('key');
+ var server = this.getFieldValue('server');
+ generator.definitions_['include_PubSubClient'] = '#include \n';
+ generator.definitions_['var_declare_PubSubClient'] = 'const char *mqtt_broker = "' + server + '";\n'
+ + 'const char *mqtt_username = "MixIO_public";\n'
+ + 'const char *mqtt_password = "MixIO_public";\n'
+ + 'const int mqtt_port = 1883;\n'
+ + 'String mqtt_topic = "";\n'
+ + 'String mqtt_data = "";\n'
+ + 'boolean mqtt_status = false;\n'
+ + 'String project = "' + key + '";\n\n'
+
+ + 'WiFiClient espClient;\n'
+ + 'PubSubClient client(espClient);\n'
+
+ + 'void callback(char *topic, byte *payload, unsigned int length) {\n'
+ + ' String data = "";\n'
+ + ' for (int i = 0; i < length; i++) {\n'
+ + ' data = String(data) + String((char) payload[i]);\n'
+ + ' }\n'
+ + ' mqtt_topic = String(topic);\n'
+ + ' mqtt_data = data;\n'
+ + ' mqtt_status = true;\n'
+ + '}\n';
+ generator.setups_['setups_PubSubClient'] = 'client.setServer(mqtt_broker, mqtt_port);\n'
+ + 'client.setCallback(callback);\n'
+ + 'while (!client.connected()) {\n'
+ + ' String client_id = "esp-client-";\n'
+ + ' client_id += String(WiFi.macAddress());\n'
+ + ' Serial.printf("The client %s connects to the public mqtt broker\\n", client_id.c_str());\n'
+ + ' if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {\n'
+ + ' Serial.println("Public emqx mqtt broker connected");\n'
+ + ' client.publish(String(String(mqtt_username) +"/"+ String(project) +"/"+ String("b640a0ce465fa2a4150c36b305c1c11b")).c_str(),String(client_id).c_str());\n'
+ + ' } else {\n'
+ + ' Serial.print("failed with state ");\n'
+ + ' Serial.print(client.state());\n'
+ + ' delay(2000);\n'
+ + ' }\n'
+ + '}\n';
+ var code = 'client.loop();\n';
+ return code;
+}
+
+export const mixio_mqtt_publish = function (_, generator) {
+ var data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ var topic = generator.valueToCode(this, 'topic', generator.ORDER_ATOMIC);
+ var mode = this.getFieldValue('mode');
+ if (mode == 1) {
+ var code = 'client.publish(String(String(mqtt_username) +"/"+ String(project) +"/"+ String(' + topic + ')).c_str(),String(' + data + ').c_str());\n';
+ }
+ if (mode == 2) {
+ var code = 'client.publish(String("MixIO/"+ String(project) +"/default/"+ String(' + topic + ')).c_str(),String(' + data + ').c_str());\n';
+ }
+ return code;
+}
+
+export const mixio_mqtt_received_the_news = function (_, generator) {
+ var mode = this.getFieldValue('mode');
+ var topic = generator.valueToCode(this, 'topic', generator.ORDER_ATOMIC);
+ var branch = generator.statementToCode(this, 'function');
+ branch = branch.replace(/(^\s*)|(\s*$)/g, "");
+ if (mode == 1) {
+ generator.setups_['setups_topic_' + topic + ''] = 'client.subscribe(String(String(mqtt_username) +"/"+ String(project) +"/"+ String(' + topic + ')).c_str());'
+ var code = 'if (mqtt_status) {\n'
+ + ' if (String(mqtt_topic).equals(String(String(mqtt_username) +"/"+ String(project) +"/"+ String(' + topic + ')))) {\n'
+ + ' ' + branch + '\n'
+ + ' mqtt_status = false;\n'
+ + ' }\n'
+ + '}\n'
+ }
+ if (mode == 2) {
+ generator.setups_['setups_topic_' + topic + ''] = 'client.subscribe(String("MixIO/"+ String(project) +"/default/"+ String(' + topic + ')).c_str());'
+ var code = 'if (mqtt_status) {\n'
+ + ' if (String(mqtt_topic).equals(String("MixIO/"+ String(project) +"/default/"+ String(' + topic + ')).c_str())) {\n'
+ + ' ' + branch + '\n'
+ + ' mqtt_status = false;\n'
+ + ' }\n'
+ + '}\n'
+ }
+ return code;
+}
+
+export const asyncelegantota = function (_, generator) {
+ var board_type = JSFuncs.getPlatform();
+ if (board_type.match(RegExp(/ESP8266/))) {
+ generator.definitions_['include_ESPAsyncTCP'] = '#include ';
+ } else {
+ generator.definitions_['include_AsyncTCP'] = '#include ';
+ }
+ generator.definitions_['include_ESPAsyncWebServer'] = '#include ';
+ generator.definitions_['include_AsyncElegantOTA'] = '#include \n';
+ generator.definitions_['var_AsyncWebServer'] = 'AsyncWebServer server(80);\n';
+ generator.setups_['setups_AsyncWebServer'] = 'AsyncElegantOTA.begin(&server);\n'
+ + 'server.begin();\n';
+ var code = '';
+ return code;
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/factory.js b/mixly/boards/default_src/arduino_avr/generators/factory.js
new file mode 100644
index 00000000..7dedd472
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/factory.js
@@ -0,0 +1,117 @@
+export const factory_include = function (_, generator) {
+ var INCLUDE = this.getFieldValue('INCLUDE');
+ generator.definitions_['include_' + INCLUDE] = '#include <' + INCLUDE + '.h>';
+ return '';
+}
+
+export const factory_function_noreturn = function (_, generator) {
+ var NAME = this.getFieldValue('NAME');
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || 'NULL';
+ }
+ return NAME + '(' + code.join(', ') + ');\n';
+}
+
+export const factory_function_return = function (_, generator) {
+ var NAME = this.getFieldValue('NAME');
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || 'NULL';
+ }
+ return [NAME + '(' + code.join(', ') + ')', generator.ORDER_ATOMIC];
+}
+
+export const factory_declare = function (_, generator) {
+ var TYPE = this.getFieldValue('TYPE');
+ var NAME = this.getFieldValue('NAME');
+ generator.definitions_['var_' + TYPE + '_' + NAME] = TYPE + ' ' + NAME + ';';
+ return '';
+}
+
+export const factory_declare2 = function (_, generator) {
+ var VALUE = this.getFieldValue('VALUE');
+ generator.definitions_['var_' + VALUE] = VALUE;
+ return '';
+}
+
+export const factory_define = function (_, generator) {
+ var TYPE = this.getFieldValue('TYPE');
+ if (TYPE.substr(0, 1) == '#')
+ TYPE = TYPE.substr(1);
+ var NAME = this.getFieldValue('NAME');
+ generator.definitions_["define_" + TYPE + '_' + NAME] = '#' + TYPE + ' ' + NAME;
+ return '';
+}
+
+export const factory_static_method_noreturn = function (_, generator) {
+ var TYPE = this.getFieldValue('TYPE');
+ var NAME = this.getFieldValue('NAME');
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || 'NULL';
+ }
+ return TYPE + '::' + NAME + '(' + code.join(', ') + ');\n';
+}
+
+export const factory_static_method_return = function (_, generator) {
+ var TYPE = this.getFieldValue('TYPE');
+ var NAME = this.getFieldValue('NAME');
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || 'NULL';
+ }
+ return [TYPE + '::' + NAME + '(' + code.join(', ') + ')', generator.ORDER_ATOMIC];
+}
+
+export const factory_callMethod_noreturn = function (_, generator) {
+ var NAME = this.getFieldValue('NAME');
+ var METHOD = this.getFieldValue('METHOD');
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || 'NULL';
+ }
+ return NAME + '.' + METHOD + '(' + code.join(', ') + ');\n';
+}
+
+export const factory_callMethod_return = function (_, generator) {
+ var NAME = this.getFieldValue('NAME');
+ var METHOD = this.getFieldValue('METHOD');
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || 'NULL';
+ }
+ return [NAME + '.' + METHOD + '(' + code.join(', ') + ')', generator.ORDER_ATOMIC];
+}
+
+export const factory_block = function () {
+ var VALUE = this.getFieldValue('VALUE');
+ //if(!(VALUE.charAt(VALUE.length-1)==";")){
+ //VALUE=VALUE+';';
+ //}
+ return VALUE + '\n';
+}
+
+export const factory_block_return = function (_, generator) {
+ var VALUE = this.getFieldValue('VALUE');
+ return [VALUE, generator.ORDER_ATOMIC];
+}
+
+export const factory_block_with_textarea = function () {
+ var VALUE = this.getFieldValue('VALUE');
+ //if(!(VALUE.charAt(VALUE.length-1)==";")){
+ //VALUE=VALUE+';';
+ //}
+ return VALUE + '\n';
+}
+
+export const factory_block_return_with_textarea = function (_, generator) {
+ var VALUE = this.getFieldValue('VALUE');
+ return [VALUE, generator.ORDER_ATOMIC];
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/inout.js b/mixly/boards/default_src/arduino_avr/generators/inout.js
new file mode 100644
index 00000000..5b9c19e5
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/inout.js
@@ -0,0 +1,259 @@
+import { Profile } from 'mixly';
+
+export const inout_highlow = function (_, generator) {
+ // Boolean values HIGH and LOW.
+ var code = (this.getFieldValue('BOOL') == 'HIGH') ? 'HIGH' : 'LOW';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const inout_pinMode = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_mode = this.getFieldValue('MODE');
+ //
+ var code = 'pinMode(' + dropdown_pin + ', ' + dropdown_mode + ');\n';
+ return code;
+}
+
+export const inout_digital_write2 = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_stat = generator.valueToCode(this, 'STAT', generator.ORDER_ATOMIC);
+ var code = "";
+ var isVar = true;
+ for (var pin of Profile.default.digital) {
+ if (pin[1] === dropdown_pin) {
+ isVar = false;
+ break;
+ }
+ }
+ if (isVar) {
+ code = code + 'pinMode(' + dropdown_pin + ', OUTPUT);\n';
+ } else {
+ if (generator.setups_['setup_input_' + dropdown_pin]) {
+ delete generator.setups_['setup_input_' + dropdown_pin];
+ }
+ generator.setups_['setup_output_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ }
+ code += 'digitalWrite(' + dropdown_pin + ', ' + dropdown_stat + ');\n'
+ return code;
+}
+
+export const inout_digital_read = function (_, generator) {
+ var dropdown_pin = this.getFieldValue('PIN');
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ var code = 'digitalRead(' + dropdown_pin + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const inout_digital_read2 = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var code = 'digitalRead(' + dropdown_pin + ')';
+ var isVar = true;
+ for (var pin of Profile.default.digital) {
+ if (pin[1] === dropdown_pin) {
+ isVar = false;
+ break;
+ }
+ }
+ if (!isVar) {
+ if (!generator.setups_['setup_output_' + dropdown_pin]) {
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ }
+ if (generator.setups_['setup_setup']) { //解决pullup重复问题
+ if (generator.setups_['setup_setup'].indexOf('pinMode(' + dropdown_pin) > -1) {
+ delete generator.setups_['setup_input_' + dropdown_pin];
+ }
+ }
+ }
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const inout_analog_write = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ //var dropdown_stat = this.getFieldValue('STAT');
+ var value_num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ const { pwm } = Profile.default;
+ if (typeof pwm === 'object') {
+ for (let i of pwm)
+ if (dropdown_pin === i[1]) {
+ generator.setups_['setup_output' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', OUTPUT);';
+ break;
+ }
+ }
+ var code = 'analogWrite(' + dropdown_pin + ', ' + value_num + ');\n';
+ return code;
+}
+
+export const inout_analog_read = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ const { analog } = Profile.default;
+ if (typeof analog === 'object') {
+ for (let i of analog)
+ if (dropdown_pin === i[1]) {
+ //generator.setups_['setup_output' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ break;
+ }
+ }
+ var code = 'analogRead(' + dropdown_pin + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const inout_buildin_led = function (_, generator) {
+ var dropdown_stat = this.getFieldValue('STAT');
+ generator.setups_['setup_output_13'] = 'pinMode(13, OUTPUT);';
+ var code = 'digitalWrite(13, ' + dropdown_stat + ');\n'
+ return code;
+}
+
+export const OneButton_interrupt = function (_, generator) {
+ generator.definitions_['include_OneButton'] = '#include ';
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_mode = this.getFieldValue('mode');
+ var dropdown_stat = generator.valueToCode(this, 'STAT', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_button' + dropdown_pin] = 'OneButton button' + dropdown_pin + '(' + dropdown_pin + ', ' + ((dropdown_stat == 'HIGH') ? 'false' : 'true') + ');';
+ generator.setups_['setup_onebutton_' + dropdown_pin + dropdown_mode] = 'button' + dropdown_pin + '.' + dropdown_mode + '(' + dropdown_mode + dropdown_pin + ');';
+ var code = 'button' + dropdown_pin + '.tick();';
+ var funcName = dropdown_mode + dropdown_pin;
+ var branch = generator.statementToCode(this, 'DO');
+ var code2 = 'void' + ' ' + funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code2;
+ return code;
+}
+
+export const controls_attachInterrupt = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_mode = this.getFieldValue('mode');
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT_PULLUP);';
+ //var interrupt_pin=digitalPinToInterrupt(dropdown_pin).toString();
+ var interrupt_pin = 'digitalPinToInterrupt(' + dropdown_pin + ')';
+ var code = 'attachInterrupt' + '(' + interrupt_pin + ',' + 'attachInterrupt_fun_' + dropdown_mode + '_' + dropdown_pin + ', ' + dropdown_mode + ');\n'
+ var funcName = 'attachInterrupt_fun_' + dropdown_mode + '_' + dropdown_pin;
+ var branch = generator.statementToCode(this, 'DO');
+ var code2 = 'void' + ' ' + funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code2;
+ return code;
+}
+
+export const controls_detachInterrupt = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ //var interrupt_pin=digitalPinToInterrupt(dropdown_pin).toString();
+ var interrupt_pin = 'digitalPinToInterrupt(' + dropdown_pin + ')';
+ var code = 'detachInterrupt' + '(' + interrupt_pin + ');\n'
+ return code;
+}
+
+export const controls_attachPinInterrupt = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_mode = this.getFieldValue('mode');
+ generator.definitions_['include_PinChangeInterrupt'] = '#include ';
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ //var interrupt_pin=digitalPinToInterrupt(dropdown_pin).toString();
+ var code = 'attachPCINT(digitalPinToPCINT(' + dropdown_pin + '),' + 'attachPinInterrupt_fun_' + dropdown_mode + '_' + dropdown_pin + ', ' + dropdown_mode + ');\n'
+ var funcName = 'attachPinInterrupt_fun_' + dropdown_mode + '_' + dropdown_pin;
+ var branch = generator.statementToCode(this, 'DO');
+ var code2 = 'void' + ' ' + funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code2;
+ return code;
+}
+
+export const controls_detachPinInterrupt = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ //var interrupt_pin=digitalPinToInterrupt(dropdown_pin).toString();
+ var code = 'detachPCINT(digitalPinToPCINT(' + dropdown_pin + '));\n'
+ return code;
+}
+
+
+export const inout_pulseIn = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_stat = this.getFieldValue('STAT');
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ var code = 'pulseIn(' + dropdown_pin + ', ' + dropdown_stat + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const inout_pulseIn2 = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_stat = this.getFieldValue('STAT');
+ var timeout = generator.valueToCode(this, 'TIMEOUT', generator.ORDER_ATOMIC) || '0';
+ generator.setups_['setup_input_' + dropdown_pin] = 'pinMode(' + dropdown_pin + ', INPUT);';
+ var code = 'pulseIn(' + dropdown_pin + ', ' + dropdown_stat + ', ' + timeout + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const inout_shiftout = function (_, generator) {
+ var dropdown_pin1 = generator.valueToCode(this, 'PIN1', generator.ORDER_ATOMIC);
+ var dropdown_pin2 = generator.valueToCode(this, 'PIN2', generator.ORDER_ATOMIC);
+ var dropdown_order = this.getFieldValue('ORDER');
+ var value = generator.valueToCode(this, 'DATA', generator.ORDER_ATOMIC) || '0';
+ generator.setups_['setup_output_' + dropdown_pin1] = 'pinMode(' + dropdown_pin1 + ', OUTPUT);';
+ generator.setups_['setup_output_' + dropdown_pin2] = 'pinMode(' + dropdown_pin2 + ', OUTPUT);';
+ var code = 'shiftOut(' + dropdown_pin1 + ', ' + dropdown_pin2 + ', ' + dropdown_order + ', ' + value + ');\n'
+ return code;
+}
+
+export const ESP32touchButton = function (_, generator) {
+ generator.definitions_['include_ESP32touchButton'] = '#include ';
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var dropdown_mode = this.getFieldValue('mode');
+ generator.definitions_['var_declare_button' + dropdown_pin] = 'ESP32touchButton button' + dropdown_pin + '(' + dropdown_pin + ', true);';
+ generator.setups_['setup_onebutton_' + dropdown_pin + dropdown_mode] = 'button' + dropdown_pin + '.' + dropdown_mode + '(' + dropdown_mode + dropdown_pin + ');';
+ var code = 'button' + dropdown_pin + '.tick();';
+ var funcName = dropdown_mode + dropdown_pin;
+ var branch = generator.statementToCode(this, 'DO');
+ var code2 = 'void' + ' ' + funcName + '() {\n' + branch + '}\n';
+ generator.definitions_[funcName] = code2;
+ return code;
+}
+
+export const inout_soft_analog_write = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var value_num = generator.valueToCode(this, 'NUM', generator.ORDER_ATOMIC);
+ generator.definitions_['include_SoftPWM'] = '#include ';
+ generator.setups_['setup_soft_analog_write'] = 'SoftPWMBegin();';
+ var code = 'SoftPWMSet(' + dropdown_pin + ', ' + value_num + ');\n';
+ return code;
+}
+
+export const inout_cancel_soft_analog_write = function (_, generator) {
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ generator.definitions_['include_SoftPWM'] = '#include ';
+ generator.setups_['setup_soft_analog_write'] = 'SoftPWMBegin();';
+ var code = 'SoftPWMEnd(' + dropdown_pin + ');\n';
+ return code;
+}
+
+// ADS1015模数转换模块 设置范围以及精度
+export const ADS1015_setGain = function (_, generator) {
+ var GAIN = this.getFieldValue('ADS1015_setGain');
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_Adafruit_ADS1015'] = '#include ';
+ generator.definitions_['var_declare_Adafruit_ADS1015_ads'] = 'Adafruit_ADS1015 ads;\n';
+ generator.setups_['setup_ads.begin()'] = 'ads.begin();\n';
+ generator.setups_['setup_ads.setGain'] = 'ads.setGain(' + GAIN + ');';
+ var code = '';
+ return code;
+}
+
+// ADS1015模数转换模块 采集数值
+export const ADS1015_Get_Value = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_Adafruit_ADS1015'] = '#include ';
+ generator.definitions_['var_declare_Adafruit_ADS1015_ads'] = 'Adafruit_ADS1015 ads;\n';
+ generator.setups_['setup_ads.begin()'] = 'ads.begin();';
+ var dropdown_type = this.getFieldValue('ADS1015_AIN');
+ var code = dropdown_type;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// PCF8591T模数转换模块 采集数值
+export const PCF8591T = function (_, generator) {
+ //generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_PCF8591_h'] = '#include ';
+ generator.definitions_['var_declare_PCF8591'] = 'PCF8591 pcf8591(0x48);';
+ generator.setups_['setup_pcf8591.begin()'] = 'pcf8591.begin();\n';
+ var dropdown_type = this.getFieldValue('PCF8591T_AIN');
+ var code = dropdown_type;
+ return [code, generator.ORDER_ATOMIC];
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/lists.js b/mixly/boards/default_src/arduino_avr/generators/lists.js
new file mode 100644
index 00000000..f4e9ead8
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/lists.js
@@ -0,0 +1,283 @@
+import { Variables } from 'blockly/core';
+
+export const lists_create_with = function (_, generator) {
+ // Create a list with any number of elements of any type.
+ var dropdown_type = this.getFieldValue('TYPE');
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var size = window.parseFloat(this.getFieldValue('SIZE'));
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || '0';
+ }
+ generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + '[' + size + ']' + '=' + '{' + code.join(', ') + '};\n';
+ return '';
+}
+
+export const lists_create_with_text = function (_, generator) {
+ var dropdown_type = this.getFieldValue('TYPE');
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var size = window.parseFloat(this.getFieldValue('SIZE'));
+ var text = this.getFieldValue('TEXT');
+ generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + '[' + size + ']' + '=' + '{' + text + '};\n';
+ return '';
+}
+
+export const lists_create_with2 = function (_, generator) {
+ // Create a list with any number of elements of any type.
+ var dropdown_type = this.getFieldValue('TYPE');
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ //var size=window.parseFloat(this.getFieldValue('SIZE'));
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || '0';
+ }
+ generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + '[]' + '=' + '{' + code.join(', ') + '};\n';
+ return '';
+}
+
+export const lists_create_with_text2 = function (_, generator) {
+ var dropdown_type = this.getFieldValue('TYPE');
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var size = window.parseFloat(this.getFieldValue('SIZE')) || '';
+ var text = this.getFieldValue('TEXT');
+ generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + '[' + size + ']' + '=' + '{' + text + '};\n';
+ return '';
+}
+
+export const lists_getIndex = function (_, generator) {
+ // Indexing into a list is the same as indexing into a string.
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var argument0 = generator.valueToCode(this, 'AT',
+ generator.ORDER_ADDITIVE) || '1';
+ if (argument0.match(/^\d+$/)) {
+ // If the index is a naked number, decrement it right now.
+ argument0 = parseInt(argument0, 10) - 1;
+ } else {
+ // If the index is dynamic, decrement it in code.
+ argument0 += ' - 1';
+ }
+ var code = varName + '[(int)(' + argument0 + ')]';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const lists_setIndex = function (_, generator) {
+ // Set element at index.
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var argument0 = generator.valueToCode(this, 'AT',
+ generator.ORDER_ADDITIVE) || '1';
+ var argument2 = generator.valueToCode(this, 'TO',
+ generator.ORDER_ASSIGNMENT) || '0';
+ // Blockly uses one-based indicies.
+ if (argument0.match(/^\d+$/)) {
+ // If the index is a naked number, decrement it right now.
+ argument0 = parseInt(argument0, 10) - 1;
+ } else {
+ // If the index is dynamic, decrement it in code.
+ argument0 += ' - 1';
+ }
+ return varName + '[(int)(' + argument0 + ')] = ' + argument2 + ';\n';
+}
+
+export const listsGetValueByIndex = function (_, generator) {
+ // Indexing into a list is the same as indexing into a string.
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var argument0 = generator.valueToCode(this, 'AT',
+ generator.ORDER_ADDITIVE) || '0';
+ var code = varName + '[' + argument0 + ']';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const listsSetValueByIndex = function (_, generator) {
+ // Set element at index.
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var argument0 = generator.valueToCode(this, 'AT',
+ generator.ORDER_ADDITIVE) || '0';
+ var argument2 = generator.valueToCode(this, 'TO',
+ generator.ORDER_ASSIGNMENT) || '0';
+ return varName + '[' + argument0 + '] = ' + argument2 + ';\n';
+}
+
+export const lists_length = function (_, generator) {
+ var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
+ Variables.NAME_TYPE);
+ var code = 'sizeof(' + varName + ')/sizeof(' + varName + '[0])';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 创建二维数组
+export const create_array2_with_text = function (_, generator) {
+ var TYPE = this.getFieldValue('TYPE');
+ var line = generator.valueToCode(this, 'line', generator.ORDER_ATOMIC);
+ var list = generator.valueToCode(this, 'list', generator.ORDER_ATOMIC);
+ var name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ var String = generator.valueToCode(this, 'String', generator.ORDER_ATOMIC);
+ generator.definitions_['var_declare_array' + name] = '' + TYPE + ' ' + name + '[' + line + '][' + list + ']={' + String + '};\n ';
+ return '';
+}
+
+// 二维数组赋值
+export const array2_assignment = function (_, generator) {
+ var line = generator.valueToCode(this, 'line', generator.ORDER_ATOMIC);
+ var list = generator.valueToCode(this, 'list', generator.ORDER_ATOMIC);
+ var name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ var assignment = generator.valueToCode(this, 'assignment', generator.ORDER_ATOMIC);
+ var code = '' + name + '[' + line + '-1][' + list + '-1]=' + assignment + ';\n'
+ return code;
+}
+
+// 获取二维数组值
+export const get_array2_value = function (_, generator) {
+ var line = generator.valueToCode(this, 'line', generator.ORDER_ATOMIC);
+ var list = generator.valueToCode(this, 'list', generator.ORDER_ATOMIC);
+ var name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ var code = '' + name + '[' + line + '-1][' + list + '-1]'
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 二维数组赋值
+export const lists2SetValueByIndex = function (_, generator) {
+ var line = generator.valueToCode(this, 'line', generator.ORDER_ATOMIC);
+ var list = generator.valueToCode(this, 'list', generator.ORDER_ATOMIC);
+ var name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ var assignment = generator.valueToCode(this, 'assignment', generator.ORDER_ATOMIC);
+ var code = name + '[' + line + '][' + list + '] = ' + assignment + ';\n'
+ return code;
+}
+
+// 二维数组取值
+export const lists2GetValueByIndex = function (_, generator) {
+ var line = generator.valueToCode(this, 'line', generator.ORDER_ATOMIC);
+ var list = generator.valueToCode(this, 'list', generator.ORDER_ATOMIC);
+ var name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ var code = name + '[' + line + '][' + list + ']';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const lists_array2_setup = function (_, generator) {
+ var dropdown_lists_create_type = this.getFieldValue('lists_create_type');
+ var text_lists_create_name = this.getFieldValue('lists_create_name');
+ var statements_lists_with_2_1_data = generator.statementToCode(this, 'lists_with_2_1_data');
+
+ if (statements_lists_with_2_1_data) {
+ var num_x = 0;
+ var num_y_data = '';
+ var num_y = 0;
+ var data = '';
+ var choice = false;
+ var statements_lists_with_2_1_data1 = '';
+ statements_lists_with_2_1_data = statements_lists_with_2_1_data.substring(2, statements_lists_with_2_1_data.length - 1);
+ for (var i of statements_lists_with_2_1_data) {
+ if (i == '→') {
+ statements_lists_with_2_1_data1 += '\n ';
+ choice = true;
+ continue;
+ }
+ if (choice) {
+ if (i == '{') {
+ if (num_y < num_y_data - 0)
+ num_y = num_y_data - 0;
+ num_y_data = '';
+ choice = false;
+ }
+ else {
+ num_y_data = num_y_data + i;
+ continue;
+ }
+ }
+ data = data + i;
+ if (data == '},{')
+ num_x++;
+ if (data.length == 3) {
+ data = data.substring(1, 2) + i;
+ }
+ statements_lists_with_2_1_data1 = statements_lists_with_2_1_data1 + i;
+ }
+ num_x++;
+ generator.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[' + num_x + '][' + num_y + '] = {' + statements_lists_with_2_1_data1 + '\n};';
+ }
+ else {
+ if (dropdown_lists_create_type == 'String')
+ generator.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{"0","0"},{"0","0"}};';
+ else
+ generator.definitions_['var_declare' + text_lists_create_name] = dropdown_lists_create_type + ' ' + text_lists_create_name + '[2][2] = {{0,0},{0,0}};';
+ }
+
+ var code = '';
+ return code;
+}
+
+export const lists_array2_setup_get_data = function (_, generator) {
+ // Create a list with any number of elements of any type.
+ var code = new Array(this.itemCount_);
+ for (var n = 0; n < this.itemCount_; n++) {
+ code[n] = generator.valueToCode(this, 'ADD' + n,
+ generator.ORDER_NONE) || '0';
+ }
+ var code1 = '';
+ var surround_parent = this.getSurroundParent();
+ if (surround_parent && surround_parent.type == 'lists_array2_setup') {
+ for (var n = 0; n < this.itemCount_; n++) {
+ code1 = code1 + ', ' + code[n];
+ }
+ code1 = code1.substring(2);
+ code1 = '→' + this.itemCount_ + '{' + code1 + '},';
+ }
+ else if (surround_parent && surround_parent.type == 'part_lists_create_with_2_1') {
+ for (var n = 0; n < this.itemCount_; n++) {
+ code1 = code1 + ', ' + code[n];
+ }
+ code1 = code1.substring(2);
+ code1 = '→' + this.itemCount_ + '{' + code1 + '},';
+ }
+ else if (surround_parent && surround_parent.type == 'lists_create_with_2_1_new_2019_10_18') {
+ for (var n = 0; n < this.itemCount_; n++) {
+ code1 = code1 + ', ' + code[n];
+ }
+ code1 = code1.substring(2);
+ code1 = '→' + this.itemCount_ + '{' + code1 + '},';
+ }
+ else if (surround_parent && surround_parent.type == 'part_lists_create_with_2_1_new_2019_10_18') {
+ for (var n = 0; n < this.itemCount_; n++) {
+ code1 = code1 + ', ' + code[n];
+ }
+ code1 = code1.substring(2);
+ code1 = '→' + this.itemCount_ + '{' + code1 + '},';
+ }
+ else {
+ code1 = '';
+ }
+ return code1;
+}
+
+import FUNC_ARRAY_ROTATE_LOOP_TEMPLATE from '../templates/func-array-rotate-loop.c';
+
+// 一维数组循环
+export const loop_array = function (_, generator) {
+ var mode = this.getFieldValue('mode');
+ var name = generator.valueToCode(this, 'name', generator.ORDER_ATOMIC);
+ generator.definitions_['function_array_rotate_loop'] = FUNC_ARRAY_ROTATE_LOOP_TEMPLATE;
+ var code = `array_rotate_loop(${name}, sizeof(${name}[0]), sizeof(${name}) / sizeof(${name}[0]), ${mode});\n`;
+ return code;
+}
+
+// 获取二维数组的行数与列数
+export const lists_array2_get_length = function (_, generator) {
+ var text_list_name = this.getFieldValue('list_name');
+ var dropdown_type = this.getFieldValue('type');
+ var code = '';
+ if (dropdown_type == 'col')
+ code = '(sizeof(' + text_list_name + '[0]) / sizeof(' + text_list_name + '[0][0]))';
+ else
+ code = '(sizeof(' + text_list_name + ') / sizeof(' + text_list_name + '[0]))';
+ return [code, generator.ORDER_ATOMIC];
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/logic.js b/mixly/boards/default_src/arduino_avr/generators/logic.js
new file mode 100644
index 00000000..bbefc2ff
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/logic.js
@@ -0,0 +1,58 @@
+export const logic_compare = function (_, generator) {
+ // Comparison operator.
+ var mode = this.getFieldValue('OP');
+ var operator = logic_compare.OPERATORS[mode];
+ var order = (operator == '==' || operator == '!=') ?
+ generator.ORDER_EQUALITY : generator.ORDER_RELATIONAL;
+ var argument0 = generator.valueToCode(this, 'A', order) || '0';
+ var argument1 = generator.valueToCode(this, 'B', order) || '0';
+ var code = argument0 + ' ' + operator + ' ' + argument1;
+ return [code, order];
+}
+
+logic_compare.OPERATORS = {
+ EQ: '==',
+ NEQ: '!=',
+ LT: '<',
+ LTE: '<=',
+ GT: '>',
+ GTE: '>='
+};
+
+export const logic_operation = function (_, generator) {
+ // Operations 'and', 'or'.
+ var operator = (this.getFieldValue('OP') == 'AND') ? '&&' : '||';
+ var order = (operator == '&&') ? generator.ORDER_LOGICAL_AND :
+ generator.ORDER_LOGICAL_OR;
+ var argument0 = generator.valueToCode(this, 'A', order) || 'false';
+ var argument1 = generator.valueToCode(this, 'B', order) || 'false';
+ var code = argument0 + ' ' + operator + ' ' + argument1;
+ return [code, order];
+}
+
+export const logic_negate = function (_, generator) {
+ // Negation.
+ var order = generator.ORDER_UNARY_PREFIX;
+ var argument0 = generator.valueToCode(this, 'BOOL', order) || 'false';
+ var code = '!' + argument0;
+ return [code, order];
+}
+
+export const logic_boolean = function (_, generator) {
+ // Boolean values true and false.
+ var code = (this.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const logic_null = function (_, generator) {
+ var code = 'NULL';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const logic_true_or_false = function (_, generator) {
+ var a = generator.valueToCode(this, 'A', generator.ORDER_ATOMIC) || 'false';
+ var b = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC) || 'false';
+ var c = generator.valueToCode(this, 'C', generator.ORDER_ATOMIC) || 'false';
+ var code = '(' + a + '?' + b + ':' + c + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/math.js b/mixly/boards/default_src/arduino_avr/generators/math.js
new file mode 100644
index 00000000..e8de8607
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/math.js
@@ -0,0 +1,239 @@
+export const math_number = function (_, generator) {
+ // Numeric value.
+ var code = (this.getFieldValue('NUM'));
+ // -4.abs() returns -4 in Dart due to strange order of operation choices.
+ // -4 is actually an operator and a number. Reflect this in the order.
+ var order = code < 0 ?
+ generator.ORDER_UNARY_PREFIX : generator.ORDER_ATOMIC;
+ return [code, order];
+}
+
+export const math_arithmetic = function (_, generator) {
+ // Basic arithmetic operators, and power.
+ const OPERATORS = {
+ ADD: [' + ', generator.ORDER_ADDITIVE],
+ MINUS: [' - ', generator.ORDER_ADDITIVE],
+ MULTIPLY: [' * ', generator.ORDER_MULTIPLICATIVE],
+ DIVIDE: [' / ', generator.ORDER_MULTIPLICATIVE],
+ QUYU: [' % ', generator.ORDER_MULTIPLICATIVE],//增加取余操作
+ POWER: [null, generator.ORDER_NONE] // Handle power separately.
+ };
+ var mode = this.getFieldValue('OP');
+ var tuple = OPERATORS[mode];
+ var operator = tuple[0];
+ var order = tuple[1];
+ var argument0 = generator.valueToCode(this, 'A', order) || '0';
+ var argument1 = generator.valueToCode(this, 'B', order) || '0';
+ var code;
+ if (!operator) {
+ code = 'pow(' + argument0 + ', ' + argument1 + ')';
+ return [code, generator.ORDER_UNARY_POSTFIX];
+ }
+ if (operator == ' % ') {
+ //取余必须是整数
+ argument0 = '(long) (' + argument0 + ')';
+ argument1 = '(long) (' + argument1 + ')';
+ }
+ code = argument0 + operator + argument1;
+ return [code, order];
+}
+
+export const math_bit = function (_, generator) {
+ var operator = this.getFieldValue('OP');
+ var order = generator.ORDER_ATOMIC;
+ var argument0 = generator.valueToCode(this, 'A', order) || '0';
+ var argument1 = generator.valueToCode(this, 'B', order) || '0';
+ var code = '(' + argument0 + operator + argument1 + ')';
+ return [code, order];
+}
+
+export const math_single = function (_, generator) {
+ // Math operators with single operand.
+ var operator = this.getFieldValue('OP');
+ var code;
+ var arg;
+ if (operator == 'NEG') {
+ // Negation is a special case given its different operator precedents.
+ arg = generator.valueToCode(this, 'NUM',
+ generator.ORDER_UNARY_PREFIX) || '0';
+ if (arg[0] == '-') {
+ // --3 is not legal in Dart.
+ arg = ' ' + arg;
+ }
+ code = '-' + arg;
+ return [code, generator.ORDER_UNARY_PREFIX];
+ }
+ if (operator == 'ABS' || operator.substring(0, 5) == 'ROUND') {
+ arg = generator.valueToCode(this, 'NUM',
+ generator.ORDER_UNARY_POSTFIX) || '0';
+ } else if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
+ arg = generator.valueToCode(this, 'NUM',
+ generator.ORDER_MULTIPLICATIVE) || '0';
+ } else {
+ arg = generator.valueToCode(this, 'NUM',
+ generator.ORDER_NONE) || '0';
+ }
+ // First, handle cases which generate values that don't need parentheses.
+ switch (operator) {
+ case 'ABS':
+ code = arg + '.abs()';
+ break;
+ case 'ROOT':
+ code = 'sqrt(' + arg + ')';
+ break;
+ case 'LN':
+ code = 'log(' + arg + ')';
+ break;
+ case 'EXP':
+ code = 'exp(' + arg + ')';
+ break;
+ case 'POW10':
+ code = 'pow(10,' + arg + ')';
+ break;
+ case '++':
+ code = '(++' + arg + ')';
+ break;
+ case '--':
+ code = '(--' + arg + ')';
+ break;
+ case '~':
+ code = '~(' + arg + ')';
+ break;
+ case 'ROUND':
+ code = arg + '.round()';
+ break;
+ case 'ROUNDUP':
+ code = arg + '.ceil()';
+ break;
+ case 'ROUNDDOWN':
+ code = arg + '.floor()';
+ break;
+ case 'SIN':
+ code = 'sin(' + arg + ' / 180.0 * 3.14159)';
+ break;
+ case 'COS':
+ code = 'cos(' + arg + ' / 180.0 * 3.14159)';
+ break;
+ case 'TAN':
+ code = 'tan(' + arg + ' / 180.0 * 3.14159)';
+ break;
+ }
+ if (code) {
+ return [code, generator.ORDER_UNARY_POSTFIX];
+ }
+ // Second, handle cases which generate values that may need parentheses.
+ switch (operator) {
+ case 'LOG10':
+ code = 'log(' + arg + ') / log(10)';
+ break;
+ case 'ASIN':
+ code = 'asin(' + arg + ') / 3.14159 * 180';
+ break;
+ case 'ACOS':
+ code = 'acos(' + arg + ') / 3.14159 * 180';
+ break;
+ case 'ATAN':
+ code = 'atan(' + arg + ') / 3.14159 * 180';
+ break;
+ default:
+ throw 'Unknown math operator: ' + operator;
+ }
+ return [code, generator.ORDER_MULTIPLICATIVE];
+}
+
+export const math_trig = math_single;
+
+export const math_to_int = function (_, generator) {
+ var argument0 = generator.valueToCode(this, 'A', generator.ORDER_NONE) || '0';
+ var operator = this.getFieldValue('OP');
+ var code = operator + '(' + argument0 + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 变量定义
+export const arduino_variate_type = function (_, generator) {
+ var dropdown_variate_type = this.getFieldValue('variate_type');
+ var code = dropdown_variate_type;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 获取某个变量在内存中所占用的字节数
+export const math_SizeOf = function (_, generator) {
+ this.setTooltip("以字节形式返回某个操作数的储存大小");
+ var value_data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ var code = 'sizeof(' + value_data + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const math_max_min = function (_, generator) {
+ var a = generator.valueToCode(this, 'A', generator.ORDER_NONE) || '0';
+ var b = generator.valueToCode(this, 'B', generator.ORDER_NONE) || '0';
+ var operator = this.getFieldValue('OP');
+ var code = operator + '(' + a + ', ' + b + ')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const math_random_seed = function (_, generator) {
+ // Random integer between [X] and [Y].
+ var a = generator.valueToCode(this, 'NUM', generator.ORDER_NONE) || '0';
+ //generator.setups_['setup_randomSeed'] ='randomSeed(' + a + ');'+'\n';
+ return 'randomSeed(' + a + ');' + '\n';
+}
+
+export const math_random_int = function (_, generator) {
+ // Random integer between [X] and [Y].
+ var argument0 = generator.valueToCode(this, 'FROM',
+ generator.ORDER_NONE) || '0';
+ var argument1 = generator.valueToCode(this, 'TO',
+ generator.ORDER_NONE) || '0';
+ var code = 'random(' + argument0 + ', ' + argument1 + ')';
+ return [code, generator.ORDER_UNARY_POSTFIX];
+}
+
+export const base_map = function (_, generator) {
+ var dropdown_maptype = this.getFieldValue('maptype');
+ var value_num = generator.valueToCode(this, 'NUM', generator.ORDER_NONE);
+ var value_fl = generator.valueToCode(this, 'fromLow', generator.ORDER_ATOMIC);
+ var value_fh = generator.valueToCode(this, 'fromHigh', generator.ORDER_ATOMIC);
+ var value_tl = generator.valueToCode(this, 'toLow', generator.ORDER_ATOMIC);
+ var value_th = generator.valueToCode(this, 'toHigh', generator.ORDER_ATOMIC);
+ if (dropdown_maptype == 'map_float') {
+ generator.definitions_['function_mapfloat'] = 'float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)'
+ + '\n{'
+ + '\n return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;'
+ + '\n}';
+ var code = 'mapfloat(' + value_num + ', ' + value_fl + ', ' + value_fh + ', ' + value_tl + ', ' + value_th + ')';
+ }
+ else {
+ var code = 'map(' + value_num + ', ' + value_fl + ', ' + value_fh + ', ' + value_tl + ', ' + value_th + ')';
+ }
+ return [code, generator.ORDER_NONE];
+}
+
+export const math_constrain = function (_, generator) {
+ // Constrain a number between two limits.
+ var argument0 = generator.valueToCode(this, 'VALUE',
+ generator.ORDER_NONE) || '0';
+ var argument1 = generator.valueToCode(this, 'LOW',
+ generator.ORDER_NONE) || '0';
+ var argument2 = generator.valueToCode(this, 'HIGH',
+ generator.ORDER_NONE) || '0';
+ var code = 'constrain(' + argument0 + ', ' + argument1 + ', ' +
+ argument2 + ')';
+ return [code, generator.ORDER_UNARY_POSTFIX];
+}
+
+export const variables_operation = function (_, generator) {
+ var type = this.getFieldValue('type');
+ var variables = generator.valueToCode(this, 'variables', generator.ORDER_ATOMIC);
+ var data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
+ var code = '' + variables + ' = ' + variables + ' ' + type + ' ' + data + ';\n';
+ return code;
+}
+
+export const math_auto_add_or_minus = function (_, generator) {
+ var value_math_auto_add_minus_output = generator.valueToCode(this, 'math_auto_add_minus_output', generator.ORDER_ATOMIC);
+ var dropdown_math_auto_add_minus_type = this.getFieldValue('math_auto_add_minus_type');
+ var code = value_math_auto_add_minus_output + dropdown_math_auto_add_minus_type + ';\n';
+ return code;
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/pinout.js b/mixly/boards/default_src/arduino_avr/generators/pinout.js
new file mode 100644
index 00000000..277fe95e
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/pinout.js
@@ -0,0 +1,8 @@
+export const uno_pin = function () {
+ return '';
+}
+
+export const nano_pin = uno_pin;
+export const mega_pin = uno_pin;
+export const promini_pin = uno_pin;
+export const leonardo_pin = uno_pin;
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/pins.js b/mixly/boards/default_src/arduino_avr/generators/pins.js
new file mode 100644
index 00000000..ee8bc952
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/pins.js
@@ -0,0 +1,13 @@
+export const pins_digital = function (_, generator) {
+ var code = this.getFieldValue('PIN');
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const pins_analog = pins_digital;
+export const pins_pwm = pins_digital;
+export const pins_interrupt = pins_digital;
+export const pins_MOSI = pins_digital;
+export const pins_MISO = pins_digital;
+export const pins_SCK = pins_digital;
+export const pins_SCL = pins_digital;
+export const pins_SDA = pins_digital;
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/scoop.js b/mixly/boards/default_src/arduino_avr/generators/scoop.js
new file mode 100644
index 00000000..d8882567
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/scoop.js
@@ -0,0 +1,30 @@
+export const SCoopTask = function (_, generator) {
+ var _tasknum = this.getFieldValue('_tasknum');
+ var statements_setup = generator.statementToCode(this, 'setup');
+ var statements_loop = generator.statementToCode(this, 'loop');
+ var taskcode = 'defineTask(scoopTask' + _tasknum + ')\n'
+ + 'void scoopTask' + _tasknum + '::setup()\n'
+ + '{\n'
+ + statements_setup
+ + '}\n'
+ + 'void scoopTask' + _tasknum + '::loop()\n'
+ + '{\n'
+ + statements_loop
+ + '}\n';
+ generator.definitions_['include_Scoop'] = '#include "SCoop.h"';
+ generator.setups_['scoop_start'] = 'mySCoop.start();';
+ generator.definitions_['scoop_task' + _tasknum] = taskcode;
+ var code = "";
+ return code;
+}
+
+export const SCoop_yield = function () {
+ var code = 'yield();\n';
+ return code;
+}
+
+export const SCoop_sleep = function (_, generator) {
+ var value_sleeplength = generator.valueToCode(this, 'sleeplength', generator.ORDER_ATOMIC);
+ var code = 'sleep(' + value_sleeplength + ');\n'
+ return code;
+}
\ No newline at end of file
diff --git a/mixly/boards/default_src/arduino_avr/generators/sensor.js b/mixly/boards/default_src/arduino_avr/generators/sensor.js
new file mode 100644
index 00000000..8de571f5
--- /dev/null
+++ b/mixly/boards/default_src/arduino_avr/generators/sensor.js
@@ -0,0 +1,734 @@
+import { Profile, JSFuncs } from 'mixly';
+
+export const gps_init = function (_, generator) {
+ generator.definitions_['include_TinyGPS++'] = '#include ';
+ generator.definitions_['include_SoftwareSerial'] = '#include ';
+ var rx = generator.valueToCode(this, 'RX', generator.ORDER_ATOMIC);
+ var tx = generator.valueToCode(this, 'TX', generator.ORDER_ATOMIC);
+ var bt = generator.valueToCode(this, 'CONTENT', generator.ORDER_ATOMIC)
+ generator.definitions_['var_declare_TinyGPSPlus_gps'] = 'TinyGPSPlus gps;';
+ generator.definitions_['var_declare_SoftwareSerial_gps_ss'] = 'SoftwareSerial gps_ss(' + rx + ', ' + tx + ');';
+ generator.setups_['setup_gps_ss_begin'] = 'gps_ss.begin(' + bt + ');';
+ return '';
+}
+
+export const gps_data_available = function (_, generator) {
+ var code = 'gps_ss.available()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const gps_data_encode = function (_, generator) {
+ var code = 'gps.encode(gps_ss.read())';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const gps_xxx_isValid = function (_, generator) {
+ var WHAT = this.getFieldValue('WHAT');
+ var code = 'gps.' + WHAT + '.isValid()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const gps_getData_xxx = function (_, generator) {
+ var WHAT = this.getFieldValue('WHAT');
+ var code = 'gps.' + WHAT + '()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const chaoshengbo2 = function (_, generator) {
+ var Trig = this.getFieldValue('Trig');
+ var Echo = this.getFieldValue('Echo');
+ generator.setups_['setup_output_' + Trig] = 'pinMode(' + Trig + ', OUTPUT);';
+ generator.setups_['setup_output_' + Echo] = 'pinMode(' + Echo + ', INPUT);';
+ var funcName = 'checkdistance_' + Trig + '_' + Echo;
+ var code = 'float' + ' ' + funcName + '() {\n'
+ + ' digitalWrite(' + Trig + ', LOW);\n' + ' delayMicroseconds(2);\n'
+ + ' digitalWrite(' + Trig + ', HIGH);\n' + ' delayMicroseconds(10);\n'
+ + ' digitalWrite(' + Trig + ', LOW);\n'
+ + ' float distance = pulseIn(' + Echo + ', HIGH) / 58.00;\n'
+ + ' delay(10);\n' + ' return distance;\n'
+ + '}\n';
+ generator.definitions_[funcName] = code;
+ return [funcName + '()', generator.ORDER_ATOMIC];
+}
+
+export const DHT = function (_, generator) {
+ var sensor_type = this.getFieldValue('TYPE');
+ var dropdown_pin = this.getFieldValue('PIN');
+ var what = this.getFieldValue('WHAT');
+ generator.definitions_['include_DHT'] = '#include ';
+ generator.definitions_['var_declare_dht' + dropdown_pin] = 'DHT dht' + dropdown_pin + '(' + dropdown_pin + ', ' + sensor_type + ');'
+ generator.setups_['DHT_SETUP' + dropdown_pin] = ' dht' + dropdown_pin + '.begin();';
+ var code;
+ if (what == "temperature")
+ code = 'dht' + dropdown_pin + '.readTemperature()'
+ else
+ code = 'dht' + dropdown_pin + '.readHumidity()'
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// LM35 Temperature
+export const LM35 = function (_, generator) {
+ var board_type = JSFuncs.getPlatform();
+ var dropdown_pin = generator.valueToCode(this, 'PIN', generator.ORDER_ATOMIC);
+ var code = 'analogRead(' + dropdown_pin + ')*0.488';
+ if (board_type.match(RegExp(/ESP8266/))) {
+ var code = 'analogRead(' + dropdown_pin + ')*0.322';
+ }
+ else if (board_type.match(RegExp(/ESP32/))) {
+ var code = 'analogRead(' + dropdown_pin + ')*0.161';
+ }
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const ds18b20 = function (_, generator) {
+ var dropdown_pin = this.getFieldValue('PIN');
+ var unit = this.getFieldValue('UNIT');
+ generator.definitions_['include_OneWire'] = '#include ';
+ generator.definitions_['include_DallasTemperature'] = '#include ';
+ generator.definitions_['var_declare_OneWire_DallasTemperature_sensors_' + dropdown_pin] = 'OneWire oneWire_' + dropdown_pin + '(' + dropdown_pin + ');\nDallasTemperature sensors_' + dropdown_pin + '(&oneWire_' + dropdown_pin + ');';
+ generator.definitions_['var_declare_DeviceAddress_insideThermometer'] = 'DeviceAddress insideThermometer;';
+ generator.setups_['setup_sensors_' + dropdown_pin + '_getAddress'] = 'sensors_' + dropdown_pin + '.getAddress(insideThermometer, 0);';
+ generator.setups_['setup_sensors_' + dropdown_pin + '_setResolution'] = 'sensors_' + dropdown_pin + '.setResolution(insideThermometer, 9);';
+ var funcName = 'ds18b20_' + dropdown_pin + '_getTemp';
+ var code = 'float' + ' ' + funcName + '(int w) {\n'
+ + ' sensors_' + dropdown_pin + '.requestTemperatures();\n'
+ + ' if(w==0) {\n return sensors_' + dropdown_pin + '.getTempC(insideThermometer);\n }\n'
+ + ' else {\n return sensors_' + dropdown_pin + '.getTempF(insideThermometer);\n }\n'
+ + '}\n';
+ generator.definitions_[funcName] = code;
+ return ['ds18b20_' + dropdown_pin + '_getTemp(' + unit + ')', generator.ORDER_ATOMIC];
+}
+
+// 初始化MLX90614红外测温传感器
+export const mlx90614_init = function (_, generator) {
+ var value_mlx90614_address = generator.valueToCode(this, 'mlx90614_address', generator.ORDER_ATOMIC);
+ var text_mlx90614_name = 'MLX';
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_Adafruit_MLX90614'] = '#include ';
+ generator.definitions_['var_declare_MLX90614_' + text_mlx90614_name] = 'Adafruit_MLX90614 ' + text_mlx90614_name + ' = Adafruit_MLX90614(' + value_mlx90614_address + ');';
+ generator.setups_['setup_MLX90614_' + text_mlx90614_name] = '' + text_mlx90614_name + '.begin();';
+ var code = '';
+ return code;
+}
+
+// MLX90614获取数据
+export const mlx90614_get_data = function (_, generator) {
+ var text_mlx90614_name = 'MLX';
+ var dropdown_mlx90614_data = this.getFieldValue('mlx90614_data');
+ var code = '' + text_mlx90614_name + '.' + dropdown_mlx90614_data + '()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const weightSensor = function (_, generator) {
+ var DOUT = this.getFieldValue('DOUT');
+ var SCK = this.getFieldValue('SCK');
+ var scale = generator.valueToCode(this, 'scale', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Hx711'] = '#include ';
+ generator.definitions_['var_declare_Hx711' + DOUT + SCK] = 'Hx711 scale' + DOUT + '_' + SCK + "(" + DOUT + "," + SCK + ");";
+ generator.setups_['setup_HX711' + DOUT + SCK] = 'scale' + DOUT + '_' + SCK + '.setOffset(scale' + DOUT + '_' + SCK + '.getAverageValue(30));';
+ generator.setups_['setup_' + 'scale' + DOUT + '_' + SCK + ' .setScale'] = 'scale' + DOUT + '_' + SCK + '.setScale(' + scale + ');';
+ var code = 'scale' + DOUT + '_' + SCK + '.getWeight(10)';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// DS1302
+export const DS1302_init = function (_, generator) {
+ var dropdown_rst = generator.valueToCode(this, 'RST', generator.ORDER_ATOMIC);
+ var dropdown_dat = generator.valueToCode(this, 'DAT', generator.ORDER_ATOMIC);
+ var dropdown_clk = generator.valueToCode(this, 'CLK', generator.ORDER_ATOMIC);
+ generator.definitions_['include_ThreeWire'] = '#include ';
+ generator.definitions_['include_RtcDS1302'] = '#include ';
+ //generator.definitions_['var_declare_RtcDateTime_dt'] = 'const RtcDateTime dt;';
+ generator.definitions_['var_declare_ThreeWire'] = 'ThreeWire ' + 'myWire(' + dropdown_dat + ', ' + dropdown_clk + ', ' + dropdown_rst + ');';
+ generator.definitions_['var_declare_RtcDS1302'] = 'RtcDS1302 Rtc(myWire);';
+ generator.setups_['setup_Rtc.Begin'] = 'Rtc.Begin();\n Rtc.SetIsRunning(true);';
+ return "";
+}
+
+export const DS1307_init = function (_, generator) {
+ var SDA = generator.valueToCode(this, 'SDA', generator.ORDER_ATOMIC);
+ var SCL = generator.valueToCode(this, 'SCL', generator.ORDER_ATOMIC);
+ var RTCType = this.getFieldValue('RTCType');
+ generator.definitions_['include_' + RTCType] = '#include <' + RTCType + '.h>';
+ //generator.definitions_['var_declare_RtcDateTime_dt'] = 'const RtcDateTime dt;';
+ if (SDA != Profile.default.SDA[0][1] || SCL != Profile.default.SCL[0][1]) {
+ generator.definitions_['include_SoftwareWire'] = '#include ';
+ generator.definitions_['var_declare_SoftwareWire'] = 'SoftwareWire myWire(' + SDA + ',' + SCL + ');';
+ generator.definitions_['var_declare_' + RTCType] = RTCType + ' Rtc(myWire);';
+ } else {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['var_declare_' + RTCType] = RTCType + ' Rtc(Wire);';
+ }
+ generator.setups_['setup_Rtc.Begin'] = 'Rtc.Begin();\n Rtc.SetIsRunning(true);';
+ return "";
+}
+
+export const RTC_get_time = function (_, generator) {
+ var timeType = this.getFieldValue('TIME_TYPE');
+ var code = 'Rtc.GetDateTime().' + timeType + '()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const RTC_date = function (_, generator) {
+ var year = generator.valueToCode(this, "year", generator.ORDER_ATOMIC);
+ var month = generator.valueToCode(this, "month", generator.ORDER_ATOMIC);
+ var day = generator.valueToCode(this, "day", generator.ORDER_ATOMIC);
+
+ switch (month) {
+ case '1':
+ month = 'Jan';
+ break;
+ case '2':
+ month = 'Feb';
+ break;
+ case '3':
+ month = 'Mar';
+ break;
+ case '4':
+ month = 'Apr';
+ break;
+ case '5':
+ month = 'May';
+ break;
+ case '6':
+ month = 'Jun';
+ break;
+ case '7':
+ month = 'Jul';
+ break;
+ case '8':
+ month = 'Aug';
+ break;
+ case '9':
+ month = 'Sep';
+ break;
+ case '10':
+ month = 'Oct';
+ break;
+ case '11':
+ month = 'Nov';
+ break;
+ case '12':
+ month = 'Dec';
+ break;
+ default:
+ month = 'Jan';
+ }
+ if (day.length == 1)
+ day = '0' + day;
+ var code = '"' + month + '/' + day + '/' + year + '"';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const RTC_time = function (_, generator) {
+ var hour = generator.valueToCode(this, "hour", generator.ORDER_ATOMIC);
+ var minute = generator.valueToCode(this, "minute", generator.ORDER_ATOMIC);
+ var second = generator.valueToCode(this, "second", generator.ORDER_ATOMIC);
+ if (hour.length == 1)
+ hour = '0' + hour;
+ if (minute.length == 1)
+ minute = '0' + minute;
+ if (second.length == 1)
+ second = '0' + second;
+ var code = '"' + hour + ':' + minute + ':' + second + '"';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 设置时间
+export const RTC_set_time = function (_, generator) {
+ var value_date = generator.valueToCode(this, 'date', generator.ORDER_ATOMIC);
+ var value_time = generator.valueToCode(this, 'time', generator.ORDER_ATOMIC);
+ var code = '';
+ code = 'Rtc.SetDateTime(RtcDateTime(' + value_date + ', ' + value_time + '));\n';
+ return code;
+}
+
+// 获取烧录时间和日期
+export const get_system_date_time = function (_, generator) {
+ var dropdown_type = this.getFieldValue('type');
+ var code = '__' + dropdown_type + '__';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const RTC_set_date = function () {
+ const now = new Date();
+ const year = now.getFullYear(); // 年
+ const month = now.getMonth() + 1; // 月
+ const day = now.getDate(); // 日
+ var RTCName = "myRTC";
+ var code = RTCName + '.setDate(' + year + ',' + month + ',' + day + ');\n';
+ code += RTCName + '.setDOW(' + year + ',' + month + ',' + day + ');\n';
+ return code;
+}
+
+// 传感器_sht20
+export const SHT20 = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_DFRobot_SHT20'] = '#include ';
+ generator.definitions_['var_declare_DFRobot_SHT20'] = 'DFRobot_SHT20 sht20;\n';
+ generator.setups_['setup_sht20initSHT20'] = 'sht20.initSHT20();';
+ generator.setups_['setup_sht20.checkSHT20'] = 'sht20.checkSHT20(); \n';
+ var dropdown_type = this.getFieldValue('SHT20_TYPE');
+ var code = dropdown_type;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 传感器_重力感应块
+export const ADXL345 = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_I2Cdev'] = '#include ';
+ generator.definitions_['include_ADXL345'] = '#include ';
+ generator.definitions_['var_declare_ADXL345'] = 'ADXL345 accel;\n';
+ generator.setups_['setup_Wire.begin'] = 'Wire.begin();';
+ generator.setups_['setup_accel.begin'] = 'accel.initialize(); \n';
+ var dropdown_type = this.getFieldValue('ADXL345_PIN');
+ var code = dropdown_type;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 传感器_重力感应块
+export const LIS3DHTR = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_LIS3DHTR'] = '#include ';
+ generator.definitions_['include_define_Wire'] = '#define WIRE Wire';
+ generator.definitions_['var_declare_LIS3DHTR'] = 'LIS3DHTR LIS;\n';
+ generator.setups_['setup_LIS.begin'] = 'LIS.begin(WIRE,0x19);\n';
+ generator.setups_['setup_LIS.openTemp'] = 'LIS.openTemp();';
+ generator.setups_['setup_LIS.setFullScaleRange'] = 'LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);';
+ generator.setups_['setup_LIS.setOutputDataRate'] = 'LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);';
+ var dropdown_type = this.getFieldValue('LIS3DHTR_GETDATA');
+ var code = dropdown_type;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 传感器_重力感应块
+export const ADXL345_setOffset = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_I2Cdev'] = '#include ';
+ generator.definitions_['include_ADXL345'] = '#include ';
+ generator.definitions_['var_declare_ADXL345'] = 'ADXL345 accel;\n';
+ generator.setups_['setup_Wire.begin'] = 'Wire.begin();';
+ generator.setups_['setup_accel.begin'] = 'accel.initialize(); \n';
+
+ var dropdown_type = this.getFieldValue('MIXEPI_ADXL345_OFFSET');
+ var offset_value = generator.valueToCode(this, 'OFFSET', generator.ORDER_ATOMIC);
+ var code;
+
+ if (dropdown_type == "setOffsetX") {
+ code = 'accel.setOffsetX(round(' + offset_value + '*4/15.9));\n';
+ } else if (dropdown_type == "setOffsetY") {
+ code = 'accel.setOffsetY(round(' + offset_value + '*4/15.9));\n';
+ } else if (dropdown_type == "setOffsetZ") {
+ code = 'accel.setOffsetZ(round(' + offset_value + '*4/15.9));\n';
+ }
+
+ return code;
+}
+
+// 传感器-MPU6050-获取数据
+export const MPU6050 = function (_, generator) {
+ generator.definitions_['include_MPU6050_tockn'] = '#include ';
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['var_declare_mpu6050'] = 'MPU6050 mpu6050(Wire);';
+ generator.setups_['setup_ngyro'] = 'Wire.begin();\n mpu6050.begin();\n mpu6050.calcGyroOffsets(true);';
+ var MPU6050_TYPE = this.getFieldValue('MPU6050_TYPE');
+ var code = 'mpu6050.' + MPU6050_TYPE;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 传感器-MPU6050-更新数据
+export const MPU6050_update = function () {
+ var code = 'mpu6050.update();\n';
+ return code;
+}
+
+//旋转编码器写
+export const encoder_write = function (_, generator) {
+ var Encoder_NO = this.getFieldValue('Encoder_NO');
+ var value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC);
+ var code = 'encoder_' + Encoder_NO + '.write(' + value + ');\n ';
+ return code;
+}
+
+//旋转编码器读值
+export const encoder_read = function (_, generator) {
+ var Encoder_NO = this.getFieldValue('Encoder_NO');
+ var code = 'encoder_' + Encoder_NO + '.read()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+//旋转编码管脚定义
+export const encoder_init = function (_, generator) {
+ var CLK = this.getFieldValue('CLK');
+ var DT = this.getFieldValue('DT');
+ var Encoder_NO = this.getFieldValue('Encoder_NO');
+ generator.definitions_['include_Encoder'] = '#include \n';
+ generator.definitions_['var_declare_Encoder_' + Encoder_NO] = 'Encoder encoder_' + Encoder_NO + '(' + CLK + ',' + DT + ');\n ';
+ var code = '';
+ return code;
+}
+
+//旋转编码器写
+export const encoder_write1 = function (_, generator) {
+ var Encoder_NO = this.getFieldValue('Encoder_NO');
+ var value = generator.valueToCode(this, 'value', generator.ORDER_ATOMIC);
+ var code = 'encoder_counter_' + Encoder_NO + ' = ' + value + ';\n ';
+ return code;
+}
+
+//旋转编码器读值
+export const encoder_read1 = function (_, generator) {
+ var Encoder_NO = this.getFieldValue('Encoder_NO');
+ var code = 'encoder_counter_' + Encoder_NO + '';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+//旋转编码管脚定义
+export const encoder_init1 = function (_, generator) {
+ var CLK = this.getFieldValue('CLK');
+ var DT = this.getFieldValue('DT');
+ var Encoder_NO = this.getFieldValue('Encoder_NO');
+ generator.definitions_['var_declare_Encoder_' + Encoder_NO + ''] = 'int encoder_counter_' + Encoder_NO + ' = 0;\n'
+ + 'int encoder_aState_' + Encoder_NO + ';\n'
+ + 'int encoder_aLastState_' + Encoder_NO + ';\n'
+ generator.setups_['setups_encoder_' + Encoder_NO + ''] = ' pinMode (' + CLK + ', INPUT);\n'
+ + ' pinMode (' + DT + ', INPUT);\n'
+ + ' encoder_aLastState_' + Encoder_NO + ' = digitalRead(' + CLK + ');\n'
+ var code = ' encoder_aState_' + Encoder_NO + ' = digitalRead(' + CLK + ');\n'
+ + ' if (encoder_aState_' + Encoder_NO + ' != encoder_aLastState_' + Encoder_NO + ') {\n'
+ + ' if (digitalRead(' + DT + ') != encoder_aState_' + Encoder_NO + ') {\n'
+ + ' encoder_counter_' + Encoder_NO + ' ++;\n'
+ + ' } else {\n'
+ + ' encoder_counter_' + Encoder_NO + ' --;\n'
+ + ' }\n'
+ + ' }\n'
+ + ' encoder_aLastState_' + Encoder_NO + ' = encoder_aState_' + Encoder_NO + ';\n';
+ return code;
+}
+
+// 旋转编码器初始化
+export const sensor_encoder_init = function (_, generator) {
+ var dropdownType = this.getFieldValue('TYPE');
+ var mode = this.getFieldValue('mode');
+ var valueClk = generator.valueToCode(this, 'CLK', generator.ORDER_ATOMIC);
+ var valueDt = generator.valueToCode(this, 'DT', generator.ORDER_ATOMIC);
+ generator.definitions_['include_ESPRotary'] = '#include ';
+ generator.definitions_['var_declare_encoder' + dropdownType] = `ESPRotary encoder${dropdownType};`;
+ generator.setups_['setup_encoder' + dropdownType] = `encoder${dropdownType}.begin(${valueDt}, ${valueClk});\n encoder${dropdownType}.setStepsPerClick(${mode});`;
+ generator.loops_begin_['loop_encoder' + dropdownType] = `encoder${dropdownType}.loop();\n`;
+ return '';
+}
+
+// 旋转编码器读取
+export const sensor_encoder_get = function (_, generator) {
+ var dropdownType = this.getFieldValue('TYPE');
+ var dropdownOperateType = this.getFieldValue('OPERATE_TYPE');
+ var code = `encoder${dropdownType}.${dropdownOperateType}()`;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 旋转编码器设置
+export const sensor_encoder_set = function (_, generator) {
+ var dropdownType = this.getFieldValue('TYPE');
+ var valueData = generator.valueToCode(this, 'DATA', generator.ORDER_ATOMIC);
+ var dropdownOperateType = this.getFieldValue('OPERATE_TYPE');
+ var code = `encoder${dropdownType}.${dropdownOperateType}(${valueData});\n`;
+ return code;
+}
+
+// 旋转编码器事件
+export const sensor_encoder_handle = function (_, generator) {
+ var dropdownType = this.getFieldValue('TYPE');
+ var dropdownOperateType = this.getFieldValue('OPERATE_TYPE');
+ var statementsDo = generator.statementToCode(this, 'DO');
+ var cbFuncName = 'encoder' + dropdownType;
+ switch (dropdownOperateType) {
+ case 'setChangedHandler':
+ cbFuncName += 'OnChanged';
+ break;
+ case 'setRightRotationHandler':
+ cbFuncName += 'OnRightRotation';
+ break;
+ case 'setLeftRotationHandler':
+ cbFuncName += 'OnLeftRotation';
+ break;
+ case 'setUpperOverflowHandler':
+ cbFuncName += 'OnUpperOverflow';
+ break;
+ case 'setLowerOverflowHandler':
+ default:
+ cbFuncName += 'OnLowerOverflow';
+ }
+ generator.definitions_['function_' + cbFuncName] = `void ${cbFuncName}(ESPRotary& encoder${dropdownType}) {\n`
+ + statementsDo + `}\n`;
+ generator.setups_['setup_' + cbFuncName] = `encoder${dropdownType}.${dropdownOperateType}(${cbFuncName});`;
+ var code = '';
+ return code;
+}
+
+//BME280读取
+export const BME280_READ = function (_, generator) {
+ var TYPE = this.getFieldValue('TYPE');
+ var address = generator.valueToCode(this, 'address', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_SPI'] = '#include ';
+ generator.definitions_['include_Adafruit_Sensor'] = '#include ';
+ if (TYPE == "bme") {
+ generator.definitions_['include_Adafruit_BME280'] = '#include ';
+ generator.definitions_['var_declare_Adafruit_BME280'] = 'Adafruit_BME280 bme;';
+ }
+ else {
+ generator.definitions_['include_Adafruit_BMP280'] = '#include ';
+ generator.definitions_['var_declare_Adafruit_BMP280'] = 'Adafruit_BMP280 bmp;';
+ }
+ generator.setups_['setup_status'] = 'unsigned status;\n status = ' + TYPE + '.begin(' + address + ');';
+ generator.definitions_['include_SEALEVELPRESSURE_HPA'] = '#define SEALEVELPRESSURE_HPA (1013.25)';
+ var code = this.getFieldValue('BME_TYPE');
+ return [TYPE + "." + code, generator.ORDER_ATOMIC];
+}
+
+export const PS2_init = function (_, generator) {
+ generator.definitions_['include_PS2X_lib'] = '#include ';
+ generator.definitions_['var_declare_PS2X'] = 'PS2X ps2x;';
+ var PS2_DAT = this.getFieldValue('PS2_DAT');
+ var PS2_CMD = this.getFieldValue('PS2_CMD');
+ var PS2_SEL = this.getFieldValue('PS2_SEL');
+ var PS2_CLK = this.getFieldValue('PS2_CLK');
+ var rumble = this.getFieldValue('rumble');
+
+ generator.setups_['setup_ps2x_config_gamepad'] = 'ps2x.config_gamepad(' + PS2_CLK + ',' + PS2_CMD + ',' + PS2_SEL + ',' + PS2_DAT + ', true, ' + rumble + ');\n delay(300);\n';
+ return "";
+}
+
+export const PS2_update = function () {
+ var code = 'ps2x.read_gamepad(false, 0);\ndelay(30);\n';
+ return code;
+}
+
+export const PS2_Button = function (_, generator) {
+ var bt = this.getFieldValue('psbt');
+ var btstate = this.getFieldValue('btstate');
+ var code = "ps2x." + btstate + "(" + bt + ")";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const PS2_stk = function (_, generator) {
+ var stk = this.getFieldValue('psstk');
+ var code = "ps2x.Analog(" + stk + ")";
+ return [code, generator.ORDER_ATOMIC];
+}
+
+// 改用DF TCS34725 颜色识别传感器库
+export const TCS34725_Get_RGB = function (_, generator) {
+ generator.definitions_['include_DFRobot_TCS34725'] = '#include ';
+ generator.definitions_['var_declare_TCS34725'] = 'DFRobot_TCS34725 tcs34725;\n';
+ // generator.setups_['setup_DFRobot_TCS34725' ] = 'if (tcs34725.begin()) {\n Serial.println("Found sensor");\n} \nelse { \nSerial.println("No TCS34725 found ... check your connections");\nwhile (1);\n}';
+ generator.setups_['setup_DFRobot_TCS34725'] = 'tcs34725.begin();';
+ var RGB = this.getFieldValue('DF_TCS34725_COLOR');
+ return [RGB, generator.ORDER_ATOMIC];
+}
+
+// 初始化TCS230颜色传感器
+export const tcs230_init = function (_, generator) {
+ var value_tcs230_s0 = generator.valueToCode(this, 'tcs230_s0', generator.ORDER_ATOMIC);
+ var value_tcs230_s1 = generator.valueToCode(this, 'tcs230_s1', generator.ORDER_ATOMIC);
+ var value_tcs230_s2 = generator.valueToCode(this, 'tcs230_s2', generator.ORDER_ATOMIC);
+ var value_tcs230_s3 = generator.valueToCode(this, 'tcs230_s3', generator.ORDER_ATOMIC);
+ var value_tcs230_led = generator.valueToCode(this, 'tcs230_led', generator.ORDER_ATOMIC);
+ var value_tcs230_out = generator.valueToCode(this, 'tcs230_out', generator.ORDER_ATOMIC);
+
+ generator.definitions_['define_tcs230_pin'] = '#define tcs230_S0 ' + value_tcs230_s0 + ''
+ + '\n#define tcs230_S1 ' + value_tcs230_s1 + ''
+ + '\n#define tcs230_S2 ' + value_tcs230_s2 + ''
+ + '\n#define tcs230_S3 ' + value_tcs230_s3 + ''
+ + '\n#define tcs230_sensorOut ' + value_tcs230_out + ''
+ + '\n#define tcs230_LED ' + value_tcs230_led + '';
+
+ generator.definitions_['function_tcs230_Getcolor'] = '//TCS230颜色传感器获取RGB值'
+ + '\nint tcs230_Getcolor(char data)'
+ + '\n{'
+ + '\n int frequency = 0;'
+ + '\n switch(data)'
+ + '\n {'
+ + '\n case \'R\':'
+ + '\n {'
+ + '\n digitalWrite(tcs230_S2,LOW);'
+ + '\n digitalWrite(tcs230_S3,LOW);'
+ + '\n frequency = pulseIn(tcs230_sensorOut, LOW);'
+ + '\n frequency = map(frequency, 25, 72, 255, 0);'
+ + '\n break;'
+ + '\n }'
+ + '\n case \'G\':'
+ + '\n {'
+ + '\n digitalWrite(tcs230_S2,HIGH);'
+ + '\n digitalWrite(tcs230_S3,HIGH);'
+ + '\n frequency = pulseIn(tcs230_sensorOut, LOW);'
+ + '\n frequency = map(frequency, 30, 90, 255, 0);'
+ + '\n break;'
+ + '\n }'
+ + '\n case \'B\':'
+ + '\n {'
+ + '\n digitalWrite(tcs230_S2,LOW);'
+ + '\n digitalWrite(tcs230_S3,HIGH);'
+ + '\n frequency = pulseIn(tcs230_sensorOut, LOW);'
+ + '\n frequency = map(frequency, 25, 70, 255, 0);'
+ + '\n break;'
+ + '\n }'
+ + '\n default:'
+ + '\n return -1;'
+ + '\n }'
+ + '\n if (frequency < 0)'
+ + '\n frequency = 0;'
+ + '\n if (frequency > 255)'
+ + '\n frequency = 255;'
+ + '\n return frequency;'
+ + '\n}\n';
+
+ generator.setups_['setup_tcs230_pin'] = 'pinMode(tcs230_S0, OUTPUT);'
+ + '\n pinMode(tcs230_S1, OUTPUT);'
+ + '\n pinMode(tcs230_S2, OUTPUT);'
+ + '\n pinMode(tcs230_S3, OUTPUT);'
+ + '\n pinMode(tcs230_LED, OUTPUT);'
+ + '\n pinMode(tcs230_sensorOut, INPUT);'
+ + '\n digitalWrite(tcs230_S0,HIGH);'
+ + '\n digitalWrite(tcs230_S1,LOW);'
+ + '\n digitalWrite(tcs230_LED,HIGH);';
+ var code = '';
+ return code;
+}
+
+// TCS230颜色传感器 获取RGB值
+export const tcs230_Get_RGB = function (_, generator) {
+ var dropdown_tcs230_color = this.getFieldValue('tcs230_color');
+ var code = 'tcs230_Getcolor(\'' + dropdown_tcs230_color + '\')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const Arduino_keypad_4_4_start = function (_, generator) {
+ var text_keypad_name = this.getFieldValue('keypad_name');
+ var text_keypad_row = generator.valueToCode(this, 'keypad_row', generator.ORDER_ATOMIC);
+ var text_keypad_col = generator.valueToCode(this, 'keypad_col', generator.ORDER_ATOMIC);
+ var text_keypad_type = generator.valueToCode(this, 'keypad_type', generator.ORDER_ATOMIC);
+ generator.definitions_['include_Keypad'] = '#include ';
+ generator.definitions_['var_keypadstart1' + text_keypad_name] = 'const byte ' + text_keypad_name + '_ROWS = 4;';
+ generator.definitions_['var_keypadstart2' + text_keypad_name] = 'const byte ' + text_keypad_name + '_COLS = 4;';
+ generator.definitions_['var_keypadstart3' + text_keypad_name] = 'char ' + text_keypad_name + '_hexaKeys[' + text_keypad_name + '_ROWS][' + text_keypad_name + '_COLS] = {' + '\n' + text_keypad_type + '\n};';
+ generator.definitions_['var_keypadstart4' + text_keypad_name] = 'byte ' + text_keypad_name + '_rowPins[' + text_keypad_name + '_ROWS] = ' + text_keypad_row;
+ generator.definitions_['var_keypadstart5' + text_keypad_name] = 'byte ' + text_keypad_name + '_colPins[' + text_keypad_name + '_COLS] = ' + text_keypad_col;
+ generator.definitions_['var_keypadstart6' + text_keypad_name] = 'Keypad ' + text_keypad_name + ' = Keypad(makeKeymap(' + text_keypad_name + '_hexaKeys), ' + text_keypad_name + '_rowPins, ' + text_keypad_name + '_colPins, ' + text_keypad_name + '_ROWS, ' + text_keypad_name + '_COLS);';
+ generator.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
+ var code = '';
+ return code;
+}
+
+export const keypad_row_data = function (_, generator) {
+ var pin_keypad_row_1 = generator.valueToCode(this, 'keypad_row_1', generator.ORDER_ATOMIC);
+ var pin_keypad_row_2 = generator.valueToCode(this, 'keypad_row_2', generator.ORDER_ATOMIC);
+ var pin_keypad_row_3 = generator.valueToCode(this, 'keypad_row_3', generator.ORDER_ATOMIC);
+ var pin_keypad_row_4 = generator.valueToCode(this, 'keypad_row_4', generator.ORDER_ATOMIC);
+ var code = '{' + pin_keypad_row_1 + ', ' + pin_keypad_row_2 + ', ' + pin_keypad_row_3 + ', ' + pin_keypad_row_4 + '};';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const keypad_col_data = function (_, generator) {
+ var pin_keypad_col_1 = generator.valueToCode(this, 'keypad_col_1', generator.ORDER_ATOMIC);
+ var pin_keypad_col_2 = generator.valueToCode(this, 'keypad_col_2', generator.ORDER_ATOMIC);
+ var pin_keypad_col_3 = generator.valueToCode(this, 'keypad_col_3', generator.ORDER_ATOMIC);
+ var pin_keypad_col_4 = generator.valueToCode(this, 'keypad_col_4', generator.ORDER_ATOMIC);
+ var code = '{' + pin_keypad_col_1 + ', ' + pin_keypad_col_2 + ', ' + pin_keypad_col_3 + ', ' + pin_keypad_col_4 + '};';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const keypad_type_data = function (_, generator) {
+ var text_keypad_1_1 = this.getFieldValue('keypad_1_1');
+ var text_keypad_1_2 = this.getFieldValue('keypad_1_2');
+ var text_keypad_1_3 = this.getFieldValue('keypad_1_3');
+ var text_keypad_1_4 = this.getFieldValue('keypad_1_4');
+
+ var text_keypad_2_1 = this.getFieldValue('keypad_2_1');
+ var text_keypad_2_2 = this.getFieldValue('keypad_2_2');
+ var text_keypad_2_3 = this.getFieldValue('keypad_2_3');
+ var text_keypad_2_4 = this.getFieldValue('keypad_2_4');
+
+ var text_keypad_3_1 = this.getFieldValue('keypad_3_1');
+ var text_keypad_3_2 = this.getFieldValue('keypad_3_2');
+ var text_keypad_3_3 = this.getFieldValue('keypad_3_3');
+ var text_keypad_3_4 = this.getFieldValue('keypad_3_4');
+
+ var text_keypad_4_1 = this.getFieldValue('keypad_4_1');
+ var text_keypad_4_2 = this.getFieldValue('keypad_4_2');
+ var text_keypad_4_3 = this.getFieldValue('keypad_4_3');
+ var text_keypad_4_4 = this.getFieldValue('keypad_4_4');
+ var code =
+ ' {\'' + text_keypad_1_1 + '\',\'' + text_keypad_1_2 + '\',\'' + text_keypad_1_3 + '\',\'' + text_keypad_1_4 + '\'},' +
+ '\n {\'' + text_keypad_2_1 + '\',\'' + text_keypad_2_2 + '\',\'' + text_keypad_2_3 + '\',\'' + text_keypad_2_4 + '\'},' +
+ '\n {\'' + text_keypad_3_1 + '\',\'' + text_keypad_3_2 + '\',\'' + text_keypad_3_3 + '\',\'' + text_keypad_3_4 + '\'},' +
+ '\n {\'' + text_keypad_4_1 + '\',\'' + text_keypad_4_2 + '\',\'' + text_keypad_4_3 + '\',\'' + text_keypad_4_4 + '\'}';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const get_keypad_num = function (_, generator) {
+ var text_keypad_name = this.getFieldValue('keypad_name');
+ var code = '' + text_keypad_name + '.getKey()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const arduino_keypad_event = function (_, generator) {
+ var text_keypad_name = this.getFieldValue('keypad_name');
+ var value_keypad_event_input = generator.valueToCode(this, 'keypad_event_input', generator.ORDER_ATOMIC);
+ var text_keypad_start_event_delay = this.getFieldValue('keypad_start_event_delay');
+ var statements_keypad_event_data = generator.statementToCode(this, 'keypad_event_data');
+
+ generator.definitions_['define_variate_' + value_keypad_event_input] = 'volatile char ' + value_keypad_event_input + ';';
+ generator.definitions_['var_keypadstart7_event' + text_keypad_name] = 'void keypadEvent_' + text_keypad_name + '(KeypadEvent ' + value_keypad_event_input + ') {' +
+ '\n' + statements_keypad_event_data +
+ '\n}';
+ generator.setups_['setup_keypad_event_and_delay' + text_keypad_name] = text_keypad_name + '.addEventListener(keypadEvent_' + text_keypad_name + ');' +
+ '\n ' + text_keypad_name + '.setHoldTime(' + text_keypad_start_event_delay + ');';
+
+ var code = '';
+ return code;
+}
+
+//传感器_重力感应块_获取9轴数据
+export const mixgo_MPU9250 = function (_, generator) {
+ generator.definitions_['include_Wire'] = '#include ';
+ generator.definitions_['include_FaBo9Axis_MPU9250'] = '#include