
// component images
var moisture = require('../../images/components/101020008-moisture.png');
var ultrasonicRanger = require('../../images/components/101020010-ultrasonicRanger.png');
var temperatureHumidity = require('../../images/components/101020011-temperatureHumidity.png');
var pirSensor = require('../../images/components/101020020-pirSensor.png');
var lightSensor = require('../../images/components/101020022-lightSensor.png');
var touch = require('../../images/components/101020037-touch.png');
var axisDigitalAccelerometer = require('../../images/components/101020054-axisDigitalAccelerometer.png');
var loudnessSensor = require('../../images/components/101020063-loudnessSensor.png');
var digitDisplay = require('../../images/components/104030003-digitDisplay.png');
var chanbalelednb = require('../../images/components/104030006-chanbalelednb.png');
var buzzer = require('../../images/components/107020000-buzzer.png');
var servo = require('../../images/components/316010005-servo.png');
var groveFan = require('../../images/components/811005001-groveFan.png');
var speaker = require('../../images/components/107020001-speaker.png');
var infraedReceiver = require('../../images/components/101020016-infraedReceiver.png');

export default function *() {
	// group: analog, digital, I2C, UART, input, output
	// color: red darken-1, light-blue lighten-1, light-green, amber
	// border: border-red, border-blue, border-green, border-yellow
	// Get current store from state or else set a default if it exists

	function restorePinName(pinNum) {
		var usedPorts = [];
		for (var pinName in store.digitalPinTable) {
			if (store.digitalPinTable[pinName] == pinNum) {
				usedPorts.push(pinName);
			}
		}

		return usedPorts;
	};

	var store = this.getState('WorkBoard', {
		connected: {},
		pinTable: { 
			D2: 2,
			D3: 3,
			D4: 4,
			D5: 5,
			D6: 6,
			D7: 7,
			D8: 8,
			A0: 'A0',
			A1: 'A1',
			A2: 'A2',
			A3: 'A3',
			A4: 'A4',
			I2C1: 1,
			I2C2: 2,
			I2C3: 3,
			I2C4: 4
		},
		digitalPinTable: {
			D2: 2,
			D3: 3,
			D4: 4,
			D5: 5,
			D6: 6,
			D7: 7,
			D8: 8
		},
		I2CPinTable: {
			I2C1: 1,
			I2C2: 2,
			I2C3: 3,
			I2C4: 4
		},
		pinDef: {
			A0: [ 'analog' ],
			A1: [ 'analog' ],
			A2: [ 'analog' ],
			A3: [ 'analog' ],
			A4: [ 'analog' ],
			D0: [ 'digital' ],
			D1: [ 'digital' ],
			D2: [ 'digital' ],
			D3: [ 'digital', 'pwm' ],
			D4: [ 'digital' ],
			D5: [ 'digital', 'pwm' ],
			D6: [ 'digital', 'pwm' ],
			D7: [ 'digital' ],
			D8: [ 'digital' ],
			I2C1: [ 'i2c' ],
			I2C2: [ 'i2c' ],
			I2C3: [ 'i2c' ],
			I2C4: [ 'i2c' ]
		},
		testCode: null,
		testResults: {},
		displayModules: {},
		blockPins: {
			D2: false,
			D3: false,
			D4: false,
			D5: false,
			D6: false,
			D7: false,
			D8: false,
			A0: false,
			A1: false,
			A2: false,
			A3: false,
			A4: false,
			I2C1: false,
			I2C2: false,
			I2C3: false,
			I2C4: false
		},
		modules: {
			sensors: [
				{
					'type': 'moisture',
					'sku': 101020008,
					'image': moisture,
					'name': '土壤湿度传感器',
					'color': 'red darken-1',
					'border': 'border-red',
					'pins': ['A0', 'A1', 'A2', 'A3', 'A4'],
					'group': ['analog', 'input'],
					'input': true,
					'tips': '名称：土壤湿度传感器 (输入模块)。用途：测量土壤的实际含水量。数值使用：返回值为数值，最小值是 0；最大值是 950。如果是干土壤，数值约为 0~300 之间；如果是湿土壤，数值约为 300~700 之间，如果是水，数值约为 700~950 之間。接口：模拟接口。',
					'io': '输入I',
					'samples': [
						{
							'modules': [
								{'sku': 101020008, 'pin': 'A0'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="318" x="250" y="-590"><field name="VAR">water</field><comment pinned="false" h="64" w="444">此范例为读取土壤湿度传感器的土壤含水量后，判断如果含水量小于 300 时蜂鸣器发出声响，否则蜂鸣器不发出声响</comment><value name="VALUE"><block type="genuino_101020008_A0_input" id="309"><field name="PIN">A0</field></block></value><next><block type="controls_if" id="327"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="336"><field name="OP">LT</field><value name="A"><block type="variables_get" id="341"><field name="VAR">water</field></block></value><value name="B"><block type="math_number" id="350"><field name="NUM">300</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="353"><field name="PIN">3</field><field name="STAT">1</field><next><block type="base_delay" id="363"><value name="DELAY_TIME"><block type="math_number" id="364"><field name="NUM">1000</field></block></value></block></next></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="354"><field name="PIN">3</field><field name="STAT">0</field><next><block type="base_delay" id="365"><value name="DELAY_TIME"><block type="math_number" id="366"><field name="NUM">1000</field></block></value></block></next></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'temperatureHumidity',
					'sku': 101020011,
					'image': temperatureHumidity,
					'name': '温湿度传感器',
					'color': 'red darken-1',
					'border': 'border-red',
					'pins': ['A0', 'A1', 'A2', 'A3', 'A4'],
					'group': ['analog', 'input'],
					'headers': [
						'SeeedDHT.h'
					],
					'definitions': [
						'DHT dht%s;'
					],
					'methods': [
						{
							'title': '读取温湿度传感器',
							'name': 'TemperatureHumidityRead',
							'desc': '读取温湿度传感器',
							'defBlock': {
								'message0': '读取温湿度传感器 %1 PIN# %2 %3',
								'args0': [
									{ 'type': 'field_image', 'src': temperatureHumidity, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'field_dropdown', 'name': 'Mode', 'options': [ [ '温度', 'T' ], [ '湿度', 'H' ] ] }
								],
								'colour': 190,
								'output': 'Number'
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var mode = this.getFieldValue('Mode');
								return [ 'dht' + pin + '.TemperatureHumidityRead(' + pin + ', \'' + mode + '\')', Blockly.Arduino.ORDER_ATOMIC ];
							}
						}
					],
					'tips': '名称：温湿度传感器 (输入模块)。用途：测量温度及相对湿度。数值使用：返回值为数值，温度在 0°C 到 50°C 之间，相对湿度在 20% 到 90% 之间。接口：模拟接口。',
					'io': '输入I',
					'tests': [
						{
							'name': 'Temperature',
							'output': true, 
							'codeGen': function(pin) {
								return 'dht' + pin + '.TemperatureHumidityRead(' + pin + ', \'T\')';
							}
						},
						{
							'name': 'Humidity',
							'output': true, 
							'codeGen': function(pin) {
								return 'dht' + pin + '.TemperatureHumidityRead(' + pin + ', \'H\')';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 101020011, 'pin': 'A0'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="198" x="110" y="-530"><field name="VAR">Temp</field><comment pinned="false" h="73" w="402">此范例为读取温湿度传感器的温度后，判断温度如果大于 30 度时蜂鸣器发出声响，否则蜂鸣器不发出声响</comment><value name="VALUE"><block type="genuino_101020011_A0_TemperatureHumidityRead" id="201"><field name="PIN">A0</field><field name="Mode">T</field></block></value><next><block type="controls_if" id="221"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="230"><field name="OP">GT</field><value name="A"><block type="variables_get" id="252"><field name="VAR">Temp</field></block></value><value name="B"><block type="math_number" id="239"><field name="NUM">30</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="265"><field name="PIN">3</field><field name="STAT">1</field><next><block type="base_delay" id="277"><value name="DELAY_TIME"><block type="math_number" id="278"><field name="NUM">1000</field></block></value></block></next></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="268"><field name="PIN">3</field><field name="STAT">0</field><next><block type="base_delay" id="279"><value name="DELAY_TIME"><block type="math_number" id="280"><field name="NUM">1000</field></block></value></block></next></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'loudnessSensor',
					'sku': 101020063,
					'image': loudnessSensor,
					'name': '声音传感器',
					'color': 'red darken-1',
					'border': 'border-red',
					'pins': ['A0', 'A1', 'A2', 'A3', 'A4'],
					'group': ['analog', 'input'],
					'input': true,
					'tips': '名称：声音传感器 (输入模块)。用途：检测环境声音的强度，可以获取声音大小的數值。数值使用：返回值为数值，最小值是 0；最大值是 1023。接口：模拟接口。',
					'io': '输入I',
					'samples': [
						{
							'modules': [
								{'sku': 101020063, 'pin': 'A0'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="91" x="170" y="-550"><field name="VAR">项目</field><comment pinned="true" h="66" w="481">此范例为获取声音大小的数值，判断如果声音大小的数值大于 50 时，蜂鸣器发出声响，否则蜂鸣器不发出声响。</comment><value name="VALUE"><block type="genuino_101020063_A0_input" id="94"><field name="PIN">A0</field></block></value><next><block type="controls_if" id="132"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="150"><field name="OP">GT</field><value name="A"><block type="variables_get" id="141"><field name="VAR">项目</field></block></value><value name="B"><block type="math_number" id="159"><field name="NUM">50</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="162"><field name="PIN">3</field><field name="STAT">1</field></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="165"><field name="PIN">3</field><field name="STAT">0</field></block></statement></block></next></block></xml>'
						}
					]
				},
/*
				{
					'moduleId': 14,
					'type': 'infraedReceiver',
					'sku': 101020016,
					'image': infraedReceiver,
					'name': '红外线接收器',
					'color': 'red darken-1',
					'border': 'border-red',
					'pins': ['A0', 'A1', 'A2', 'A3', 'A4'],
					'group': ['analog', 'input'],
					'tips': '红外线接收器,可接收家中红外线摇控器信号,此为模块使用模拟引脚,所以请接在 A0-A4 脚位',
					'headers': [
						'IRSendRev.h'
					],
					'init': function(pin) {
						return 'IR.Init(' + pin + ');';
					},
					'methods': [
						{
							'title': '读取红外线接收器',
							'name': 'SpeakerWrite',
							'desc': '读取红外线接收器',
							'defBlock': {
								'message0': '读取红外线接收器 %1 PIN# %2 %3',
								'args0': [
									{ 'type': 'field_image', 'src': infraedReceiver, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'field_variable', 'name': 'VAR', 'variable': 'data' }
								],
								'colour': 190,
								'previousStatement': null,
								'nextStatement': null
							},
							'isVariable': true,
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var num = this.getFieldValue('Number');
								return 'IR.Recv();\n';
							}
						}
					]
				},
*/
				{
					'type': 'axisDigitalAccelerometer',
					'sku': 101020054,
					'image': axisDigitalAccelerometer,
					'name': '三轴数字加速度传感器',
					'color': 'light-green',
					'border': 'border-green',
					'pins': ['I2C1', 'I2C2', 'I2C3', 'I2C4'],
					'group': ['I2C', 'input'],
					'headers': [
						'Wire.h',
						'ADXL345.h'
					],
					'definitions': [
						'ADXL345 adxl%s;'
					],
					'init': function(pin) {
						return 'adxl.init();';
					},
					'methods': [
						{
							'title': '读取三轴数字加速度传感器',
							'name': 'AxisDigitalAccelerometerRead',
							'desc': '读取三轴数字加速度值',
							'defBlock': {
								'message0': '读取三轴数字加速度传感器 %1 PIN# %2 %3',
								'args0': [
									{ 'type': 'field_image', 'src': axisDigitalAccelerometer, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'field_dropdown', 'name': 'AXIS', 'options': [ [ 'X 轴', 'X' ], [ 'Y 轴', 'Y' ], [ 'Z 轴', 'Z' ] ] }
								],
								'colour': 190,
								'output': 'Number'
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var axis = this.getFieldValue('AXIS');
								return [ 'adxl' + pin + '.AxisDigitalAccelerometerRead(' + pin + ', \'' + axis + '\')', Blockly.Arduino.ORDER_ATOMIC ];
							}
						}
					],
					'tips': '名称：三轴数字加速度传感器 (输入模块)。用途：测量在三个轴 (X、Y、Z)方向上的加速度值，能够全面准确反映物体的运动性质，适合用于运动检测，手势坚持及机器人领域。数值使用：返回值为数值，为读取自三个轴 (X、Y、Z)的加速度值。接口：I2C 接口。',
					'io': '输入I',
					'tests': [
						{
							'name': 'X',
							'output': true, 
							'codeGen': function(pin) {
								return 'adxl' + pin + '.AxisDigitalAccelerometerRead(' + pin + ', \'X\')';
							}
						},
						{
							'name': 'Y',
							'output': true, 
							'codeGen': function(pin) {
								return 'adxl' + pin + '.AxisDigitalAccelerometerRead(' + pin + ', \'Y\')';
							}
						},
						{
							'name': 'Z',
							'output': true, 
							'codeGen': function(pin) {
								return 'adxl' + pin + '.AxisDigitalAccelerometerRead(' + pin + ', \'Z\')';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 101020037, 'pin': 'D2'},
								{'sku': 104030006, 'pin': 'D4'},
								{'sku': 101020054, 'pin': 'I2C3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="91" x="170" y="-550"><field name="VAR">BUTTON</field><comment pinned="true" h="48" w="505">当触摸住开关，转动奖杯的方向位置，灯光会随着改变成七彩的状态。</comment><value name="VALUE"><block type="genuino_101020037_D2_input" id="181"><field name="PIN">2</field></block></value><next><block type="controls_if" id="239"><value name="IF0"><block type="logic_compare" id="248"><field name="OP">EQ</field><value name="A"><block type="variables_get" id="257"><field name="VAR">BUTTON</field></block></value><value name="B"><block type="high_low" id="266"><field name="Mode">1</field></block></value></block></value><statement name="DO0"><block type="variables_set" id="275"><field name="VAR">ACC_X</field><value name="VALUE"><block type="math_arithmetic" id="450"><field name="OP">MULTIPLY</field><value name="A"><block type="math_single" id="431"><field name="OP">ABS</field><value name="NUM"><block type="genuino_101020054_I2C3_AxisDigitalAccelerometerRead" id="282"><field name="PIN">3</field><field name="AXIS">X</field></block></value></block></value><value name="B"><block type="math_number" id="459"><field name="NUM">100</field></block></value></block></value><next><block type="variables_set" id="460"><field name="VAR">ACC_Y</field><value name="VALUE"><block type="math_arithmetic" id="461"><field name="OP">MULTIPLY</field><value name="A"><block type="math_single" id="462"><field name="OP">ABS</field><value name="NUM"><block type="genuino_101020054_I2C3_AxisDigitalAccelerometerRead" id="463"><field name="PIN">3</field><field name="AXIS">Y</field></block></value></block></value><value name="B"><block type="math_number" id="464"><field name="NUM">100</field></block></value></block></value><next><block type="variables_set" id="465"><field name="VAR">ACC_Z</field><value name="VALUE"><block type="math_arithmetic" id="466"><field name="OP">MULTIPLY</field><value name="A"><block type="math_single" id="467"><field name="OP">ABS</field><value name="NUM"><block type="genuino_101020054_I2C3_AxisDigitalAccelerometerRead" id="468"><field name="PIN">3</field><field name="AXIS">Z</field></block></value></block></value><value name="B"><block type="math_number" id="469"><field name="NUM">100</field></block></value></block></value><next><block type="genuino_104030006_D4_" id="476"><field name="PIN">4</field><value name="RED"><block type="variables_get" id="517"><field name="VAR">ACC_X</field></block></value><value name="GREEN"><block type="variables_get" id="518"><field name="VAR">ACC_Y</field></block></value><value name="BLUE"><block type="variables_get" id="519"><field name="VAR">ACC_Z</field></block></value><next><block type="base_delay" id="581"><value name="DELAY_TIME"><block type="math_number" id="582"><field name="NUM">1000</field></block></value></block></next></block></next></block></next></block></next></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'ultrasonicRanger',
					'sku': 101020010,
					'image': ultrasonicRanger,
					'name': '超声测距传感器',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'input'],
					'headers': [
						'Ultrasonic.h'
					],
					'definitions': [
						'Ultrasonic ultrasonic%s;'
					],
					'methods': [
						{
							'title': '读取超声测距传感器',
							'name': 'UltrasonicRangerRead',
							'desc': '读取距离 (cm)',
							'defBlock': {
								'message0': '读取超声测距传感器 %1 PIN# %2',
								'args0': [
									{ 'type': 'field_image', 'src': ultrasonicRanger, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] }
								],
								'colour': 190,
								'output': 'Number'
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								return [ 'ultrasonic' + pin + '.UltrasonicRangerRead(' + pin + ')', Blockly.Arduino.ORDER_ATOMIC ];
							}
						}
					],
					'tips': '名称：超声测距传感器 (输入模块)。用途：测量超声测距传感器碰触到物品之间的距离。数值使用：返回值为数值，单位：公分。接口：数字接口。',
					'io': '输入I',
					'tests': [
						{
							'name': 'Read',
							'output': true, 
							'codeGen': function(pin) {
								return 'ultrasonic' + pin + '.UltrasonicRangerRead(' + pin + ')';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 101020010, 'pin': 'D2'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="491" x="90" y="-530"><field name="VAR">项目</field><comment pinned="false" h="69" w="568">此范例为测量超声测距传感器碰触到物品之间的距离，判断如果超声测距传感器与物品之间的距离小于 5 公分时蜂鸣器发出声响，否则蜂鸣器不发出声响</comment><value name="VALUE"><block type="genuino_101020010_D2_UltrasonicRangerRead" id="545"><field name="PIN">2</field></block></value><next><block type="controls_if" id="500"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="509"><field name="OP">LT</field><value name="A"><block type="variables_get" id="528"><field name="VAR">项目</field></block></value><value name="B"><block type="math_number" id="554"><field name="NUM">5</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="479"><field name="PIN">3</field><field name="STAT">1</field><next><block type="base_delay" id="539"><value name="DELAY_TIME"><block type="math_number" id="540"><field name="NUM">1000</field></block></value></block></next></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="519"><field name="PIN">3</field><field name="STAT">0</field><next><block type="base_delay" id="541"><value name="DELAY_TIME"><block type="math_number" id="542"><field name="NUM">1000</field></block></value></block></next></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'pirSensor',
					'sku': 101020020,
					'image': pirSensor,
					'name': '运动检测传感器',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'input'],
					'input': true,
					'tips': '名称：运动检测传感器 (输入模块)。用途：测量是否有运动中的红外源。数值使用：当有人走入它的探测范围时，返回值为高电平；没有时，返回值为低电平。接口：数字接口。',
					'io': '输入I',
					'samples': [
						{	
							'modules': [
								{'sku': 101020020, 'pin': 'D2'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="401" x="150" y="-590"><field name="VAR">项目</field><comment pinned="false" h="77" w="431">此范例为测量是否有运动中的红外源，判断如果有人走入它的探测范围时蜂鸣器发出声响，否则蜂鸣器不发出声响</comment><value name="VALUE"><block type="genuino_101020020_D2_input" id="404"><field name="PIN">2</field></block></value><next><block type="controls_if" id="413"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="422"><field name="OP">EQ</field><value name="A"><block type="variables_get" id="476"><field name="VAR">项目</field></block></value><value name="B"><block type="high_low" id="467"><field name="Mode">1</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="425"><field name="PIN">3</field><field name="STAT">1</field><next><block type="base_delay" id="437"><value name="DELAY_TIME"><block type="math_number" id="438"><field name="NUM">1000</field></block></value></block></next></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="428"><field name="PIN">3</field><field name="STAT">0</field><next><block type="base_delay" id="455"><value name="DELAY_TIME"><block type="math_number" id="456"><field name="NUM">1000</field></block></value></block></next></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'lightSensor',
					'sku': 101020022,
					'image': lightSensor,
					'name': '光线传感器',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'input'],
					'input': true,
					'tips': '名称：光敏传感器 (输入模块)。用途：检测是否有光源。数值使用：检测到有光源时，返回值为高电平；没有光源时，返回值为低电平。接口：数字接口。',
					'io': '输入I',
					'samples': [
						{
							'modules': [
								{'sku': 101020022, 'pin': 'D2'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="491" x="90" y="-530"><field name="VAR">项目</field><comment pinned="false" h="70" w="370">此范例为测量是否有光源，判断如果有光源时蜂鸣器发出声响，否则蜂鸣器不发出声响</comment><value name="VALUE"><block type="genuino_101020022_D2_input" id="482"><field name="PIN">2</field></block></value><next><block type="controls_if" id="500"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="509"><field name="OP">EQ</field><value name="A"><block type="variables_get" id="528"><field name="VAR">项目</field></block></value><value name="B"><block type="high_low" id="518"><field name="Mode">1</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="479"><field name="PIN">3</field><field name="STAT">1</field><next><block type="base_delay" id="539"><value name="DELAY_TIME"><block type="math_number" id="540"><field name="NUM">1000</field></block></value></block></next></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="519"><field name="PIN">3</field><field name="STAT">0</field><next><block type="base_delay" id="541"><value name="DELAY_TIME"><block type="math_number" id="542"><field name="NUM">1000</field></block></value></block></next></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'touch',
					'sku': 101020037,
					'image': touch,
					'name': '触摸传感器',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'input'],
					'input': true,
					'tips': '名称：触摸传感器 (输入模块)。用途：检测是否有碰触。数值使用：碰触到传感器时，返回值为高电平；没有碰触时，返回值为低电平。接口：数字接口。',
					'io': '输入I',
					'samples': [
						{
							'modules': [
								{'sku': 101020037, 'pin': 'D2'},
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="variables_set" id="3" x="210" y="-570"><field name="VAR">项目</field><comment pinned="true" h="66" w="357">此范例为检测是否有碰触，判断如果碰触到传感器时蜂鸣器发出声响，否则蜂鸣器不发出声响。</comment><value name="VALUE"><block type="genuino_101020037_D2_input" id="6"><field name="PIN">2</field></block></value><next><block type="controls_if" id="26"><mutation else="1"></mutation><value name="IF0"><block type="logic_compare" id="58"><field name="OP">EQ</field><value name="A"><block type="variables_get" id="29"><field name="VAR">项目</field></block></value><value name="B"><block type="high_low" id="67"><field name="Mode">1</field></block></value></block></value><statement name="DO0"><block type="genuino_107020000_D3_output" id="9"><field name="PIN">3</field><field name="STAT">1</field></block></statement><statement name="ELSE"><block type="genuino_107020000_D3_output" id="70"><field name="PIN">3</field><field name="STAT">0</field></block></statement></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'digitDisplay',
					'sku': 104030003,
					'image': digitDisplay,
					'name': '4位数码管',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'output'],
					'usePorts': function(pin) {
						var pinNum = store.digitalPinTable[pin] + 1;

						return restorePinName(pinNum);
					},
					'headers': [
						'TM1637.h'
					],
					'definitions': [
						'TM1637 led%s;'
					],
					'methods': [
						{
							'title': '设定4位数码管',
							'name': 'DigitDisplayWrite',
							'desc': '设定4位数码管',
							'defBlock': {
								'message0': '设定4位数码管 %1 PIN# %2 %3',
								'args0': [
									{ 'type': 'field_image', 'src': digitDisplay, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'input_value', 'name': 'NUMBER', 'check': 'Number' }
								],
								'colour': 190,
								'previousStatement': null,
								'nextStatement': null
							},
							'values': {
								'NUMBER': {
									'type': 'math_number',
									'defValue': 9999
								},
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var num = Blockly.Arduino.valueToCode(this, 'NUMBER', Blockly.Arduino.ORDER_ATOMIC) || 0;
								return 'led' + pin + '.DigitDisplayWrite(' + pin + ', ' + (parseInt(pin) + 1) + ', ' + num+ ');\n';
							}
						}
					],
					'tips': '名称：4位数码管 (输出模块)。用途：显示4个红色数字。数值使用：可设定显示的数字为 0~9999 之间。接口：数字接口。',
					'io': '输出O',
					'tests': [
						{
							'name': 'Write',
							'input': true, 
							'codeGen': function(pin) {
								return 'led' + pin + '.DigitDisplayWrite(' + pin + ', ' + (parseInt(pin) + 1) + ', 1911);';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 104030003, 'pin': 'D2'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="controls_for" id="590" x="130" y="-497"><field name="VAR">i</field><comment pinned="false" h="91" w="446">此范例为 4 位数码管显示从 1 开始显示间隔 1 秒后加1 至 9999 ，如此一直循环( 執行迴圈設定4 位数码管顯示為變量 i ，變量 i  從 1~9999，每次累加 1 ）</comment><value name="FROM"><block type="math_number" id="591"><field name="NUM">1</field></block></value><value name="TO"><block type="math_number" id="592"><field name="NUM">9999</field></block></value><value name="BY"><block type="math_number" id="593"><field name="NUM">1</field></block></value><statement name="DO"><block type="genuino_104030003_D2_DigitDisplayWrite" id="557"><field name="PIN">2</field><value name="NUMBER"><block type="variables_get" id="598"><field name="VAR">i</field></block></value><next><block type="base_delay" id="615"><value name="DELAY_TIME"><block type="math_number" id="616"><field name="NUM">1000</field></block></value></block></next></block></statement></block></xml>'
						}
					]
				},
				{
					'type': 'chanbalelednb',
					'sku': 104030006,
					'image': chanbalelednb,
					'name': '变色 LED 灯',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'output'],
					'usePorts': function(pin) {
						var pinNum = store.digitalPinTable[pin] + 1;

						return restorePinName(pinNum);
					},
					'headers': [
						'ChainableLED.h'
					],
					'definitions': [
						'ChainableLED leds%s;'
					],
					'methods': [
						{
							'title': '设定变色 LED 灯',
							'name': '',
							'desc': '设定变色 LED 灯',
							'defBlock': {
								'message0': '设定变色 LED 灯 %1 PIN# %2',
								'args0': [
									{ 'type': 'field_image', 'src': chanbalelednb, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] }
								],
								'message1': '红 %1',
								'args1': [
									{ 'type': 'input_value', 'name': 'RED', 'align': 'RIGHT', 'check': 'Number' }
								],
								'message2': '绿 %1',
								'args2': [
									{ 'type': 'input_value', 'name': 'GREEN', 'align': 'RIGHT', 'check': 'Number' }
								],
								'message3': '蓝 %1',
								'args3': [
									{ 'type': 'input_value', 'name': 'BLUE', 'align': 'RIGHT', 'check': 'Number' }
								],
								'colour': 190,
								'previousStatement': null,
								'nextStatement': null
							},
							'values': {
								'RED': {
									'type': 'math_number',
									'defValue': 255
								},
								'GREEN': {
									'type': 'math_number',
									'defValue': 255
								},
								'BLUE': {
									'type': 'math_number',
									'defValue': 255
								}
							},
							'codeGen': function(Blockly) {
								var red = Blockly.Arduino.valueToCode(this, 'RED', Blockly.Arduino.ORDER_ATOMIC) || 255;
								var green = Blockly.Arduino.valueToCode(this, 'GREEN', Blockly.Arduino.ORDER_ATOMIC) || 255;
								var blue = Blockly.Arduino.valueToCode(this, 'BLUE', Blockly.Arduino.ORDER_ATOMIC) || 255;
								var pin = this.getFieldValue('PIN');
								var num = this.getFieldValue('Number');
								return 'leds' + pin + '.ChainableRGBLEDWrite(' + pin + ', ' + (parseInt(pin) + 1) + ', 1, ' + red + ', ' + green + ', ' + blue + ');';
							}
						}
					],
					'tips': '名称：多彩LED灯 (输出模块)。用途：以三原色共同交集成灯光。数值使用：设定红、绿、蓝三色的数值，可设定的值为 0~255 之间。接口：数字接口。',
					'io': '输出O',
					'tests': [
						{
							'name': 'Write',
							'input': true, 
							'codeGen': function(pin) {
								return 'leds' + pin + '.ChainableRGBLEDWrite(' + pin + ', ' + (parseInt(pin) + 1) + ', 1, 0, 255, 0);';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 104030006, 'pin': 'D2'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="genuino_104030006_D2_" id="371" x="170" y="-590"><field name="PIN">2</field><comment pinned="false" h="75" w="484">此范例 LED 灯为白光 1 秒后改为由红色 100 、绿色 50 、蓝色 20 所集结成的灯光 1 秒，如此一直循环</comment><value name="RED"><block type="math_number" id="372"><field name="NUM">255</field></block></value><value name="GREEN"><block type="math_number" id="373"><field name="NUM">255</field></block></value><value name="BLUE"><block type="math_number" id="374"><field name="NUM">255</field></block></value><next><block type="base_delay" id="383"><value name="DELAY_TIME"><block type="math_number" id="384"><field name="NUM">1000</field></block></value><next><block type="genuino_104030006_D2_" id="385"><field name="PIN">2</field><value name="RED"><block type="math_number" id="386"><field name="NUM">100</field></block></value><value name="GREEN"><block type="math_number" id="387"><field name="NUM">50</field></block></value><value name="BLUE"><block type="math_number" id="388"><field name="NUM">20</field></block></value><next><block type="base_delay" id="389"><value name="DELAY_TIME"><block type="math_number" id="390"><field name="NUM">1000</field></block></value></block></next></block></next></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'buzzer',
					'sku': 107020000,
					'image': buzzer,
					'name': '蜂鸣器',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'output'],
					'output': true,
					'tips': '名称：蜂鸣器 (输出模块)。用途：发出声响。数值使用：设定为高电平时，发出声响；设定为低电平时，不发出声响。接口：数字接口。',
					'io': '输出O',
					'tests': [
						{
							'name': 'Write',
							'input': true, 
							'codeGen': function(pin) {
								return 'digitalWrite(' + pin + ', 1);\ndelay(5000);\ndigitalWrite(' + pin + ', 0);\ndelay(5000);';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 107020000, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="genuino_107020000_D3_output" x="269" y="-470"><field name="PIN">3</field><field name="STAT">1</field><comment pinned="true" h="79" w="402">此范例为蜂鸣器响 1 秒后停止不响 1 秒，如此一直循环</comment><next><block type="base_delay"><value name="DELAY_TIME"><block type="math_number"><field name="NUM">1000</field></block></value><next><block type="genuino_107020000_D3_output"><field name="PIN">3</field><field name="STAT">0</field><next><block type="base_delay"><value name="DELAY_TIME"><block type="math_number"><field name="NUM">1000</field></block></value></block></next></block></next></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'servo',
					'sku': 316010005,
					'image': servo,
					'name': '舵机',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'pwm', 'output'],
					'tips': '名称：舵机 (输出模块)。用途：也叫伺服电机，最早用于船舶上实现其转向功能。数值使用：设定舵机偏转角度，可设定的值为 0~180 之间，即为0度~180度。接口：数字接口。',
					'io': '输出O',
					'headers': [
						'Servo.h'
					],
					'definitions': [
						'Servo myservo%s;'
					],
					'init': function(pin) {
						return 'myservo' + pin + '.attach(' + pin + ');';
					},
					'methods': [
						{
							'title': '设定舵机',
							'name': 'Servo',
							'desc': '设定舵机',
							'defBlock': {
								'message0': '设定舵机 %1 PIN# %2 角度(0 ~ 180) %3',
								'args0': [
									{ 'type': 'field_image', 'src': servo, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'input_value', 'name': 'NUMBER', 'check': 'Number' }
								],
								'colour': 190,
								'previousStatement': null,
								'nextStatement': null
							},
							'values': {
								'NUMBER': {
									'type': 'math_number',
									'defValue': 45
								},
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var num = Blockly.Arduino.valueToCode(this, 'NUMBER', Blockly.Arduino.ORDER_ATOMIC) || 0;
								return 'myservo' + pin + '.write(' + num+ ');\n';
							}
						}
					],
					'tests': [
						{
							'name': 'Write',
							'input': true, 
							'codeGen': function(pin) {
								return 'myservo' + pin + '.write(45);';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 316010005, 'pin': 'D2'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="genuino_316010005_D2_Servo" id="68" x="81" y="-550"><field name="PIN">2</field><comment pinned="true" h="68" w="293">此范例为舵机偏转至 180 度后停止 1 秒再偏转回 0 度停止 1 秒，如此一直循环</comment><value name="NUMBER"><block type="math_number" id="69"><field name="NUM">180</field></block></value><next><block type="base_delay" id="78"><value name="DELAY_TIME"><block type="math_number" id="79"><field name="NUM">1000</field></block></value><next><block type="genuino_316010005_D2_Servo" id="82"><field name="PIN">2</field><value name="NUMBER"><block type="math_number" id="83"><field name="NUM">0</field></block></value><next><block type="base_delay" id="84"><value name="DELAY_TIME"><block type="math_number" id="85"><field name="NUM">1000</field></block></value></block></next></block></next></block></next></block></xml>'
						}
					]
				},
				{
					'type': 'groveFan',
					'sku': 811005001,
					'image': groveFan,
					'name': '直流电机',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'pwm', 'output'],
					'tips': '名称：直流电机 (输出模块)。用途：可驱动风扇、遥控车等。数值使用：设定为高电平时，马达转动；设定为低电平时，马达不动。接口：数字接口。',
					'io': '输出O',
					'init': function(pin) {
						return 'pinMode(' + pin + ', OUTPUT);';
					},
					'methods': [
						{
							'title': '设定直流电机', // It sucks so disable PWM. only support HIGH and LOW.
							'name': 'TemperatureHumidityRead',
							'desc': '设定直流电机',
							'defBlock': {
								'message0': '设定直流电机 %1 PIN# %2 %3',
								'args0': [
									{ 'type': 'field_image', 'src': groveFan, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'field_dropdown', 'name': 'Mode', 'options': [ [ '高电平', '1' ], [ '低电平', '0' ] ] }
								],
								'colour': 190,
								'previousStatement': null,
								'nextStatement': null
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var mode = this.getFieldValue('Mode');
								return 'digitalWrite(' + pin + ', ' + mode + ');\n';
							}
						}
					],
					'tests': [
						{
							'name': 'Write',
							'input': true, 
							'codeGen': function(pin) {
								return 'digitalWrite(' + pin + ', 1);\ndelay(5000);\ndigitalWrite(' + pin + ', 0);';
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 811005001, 'pin': 'D3'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="genuino_811005001_D3_TemperatureHumidityRead" id="290" x="210" y="-530"><field name="PIN">3</field><field name="Mode">1</field><comment pinned="false" h="75" w="301">此范例为风扇旋转 1 秒后停止不动 1 秒，如此一直循环</comment><next><block type="base_delay" id="301"><value name="DELAY_TIME"><block type="math_number" id="302"><field name="NUM">1000</field></block></value><next><block type="genuino_811005001_D3_TemperatureHumidityRead" id="305"><field name="PIN">3</field><field name="Mode">0</field><next><block type="base_delay" id="306"><value name="DELAY_TIME"><block type="math_number" id="307"><field name="NUM">1000</field></block></value></block></next></block></next></block></next></block></xml>'
						}
					]
				},
				{
					'moduleId': 13,
					'type': 'speaker',
					'sku': 107020001,
					'image': speaker,
					'name': '扬声器',
					'color': 'light-blue lighten-1',
					'border': 'border-blue',
					'pins': ['D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'],
					'group': ['digital', 'output'],
					'tips': '名称：扬声器 (输出模块)。用途：可发出 Do, Re, Mi, Fa, Sol, La, Si, Do 等音符。数值使用：可设定的值为 0~8 之间。0 为不发出声响，1~8 为 Do, Re, Mi, Fa, Sol, La, Si, Do。接口：数字接口。',
					'io': '输出O',
					'headers': [
						'Speaker.h'
					],
					'definitions': [
						'grove_speaker_g speaker%s;'
					],
					'methods': [
						{
							'title': '设定扬声器',
							'name': 'SpeakerWrite',
							'desc': '设定扬声器',
							'defBlock': {
								'message0': '设定扬声器 %1 PIN# %2 音符(1~8，0 停止声响) %3',
								'args0': [
									{ 'type': 'field_image', 'src': speaker, 'width': 64, 'height': 64 },
									{ 'type': 'field_dropdown', 'name': 'PIN', 'options': [] },
									{ 'type': 'input_value', 'name': 'NUMBER', 'check': 'Number' }
								],
								'colour': 190,
								'previousStatement': null,
								'nextStatement': null
							},
							'values': {
								'NUMBER': {
									'type': 'math_number',
									'defValue': 1
								},
							},
							'codeGen': function(Blockly) {
								var pin = this.getFieldValue('PIN');
								var num = Blockly.Arduino.valueToCode(this, 'NUMBER', Blockly.Arduino.ORDER_ATOMIC) || 0;
								return 'speaker' + pin + '.SpeakerWrite(' + pin + ', ' + num+ ');\n';
							}
						}
					],
					'tests': [
						{
							'name': 'Level',
							'input': true, 
							'codeGen': function(pin) {
								return [
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 1);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 2);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 3);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 4);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 5);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 6);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 7);',
									'delay(400);',
									'speaker' + pin + '.SpeakerWrite(' + pin + ', 8);',
									'delay(400);'
								].join('\n');
							}
						}
					],
					'samples': [
						{
							'modules': [
								{'sku': 107020001, 'pin': 'D4'}
							],
							'code': '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="controls_for" id="101" x="190" y="-490"><field name="VAR">i</field><comment pinned="true" h="86" w="526">此范例为掦声器先发出 Do, Re, Mi, Fa, Sol, La, Si, Do 等音符后，停止发出声响一秒，如此一直循环 ( 執行迴圈設定揚聲器音符為變量 i ，變量 i  從 1~8 ，每次累加 1 ）</comment><value name="FROM"><block type="math_number" id="102"><field name="NUM">1</field></block></value><value name="TO"><block type="math_number" id="103"><field name="NUM">8</field></block></value><value name="BY"><block type="math_number" id="104"><field name="NUM">1</field></block></value><statement name="DO"><block type="genuino_107020001_D4_SpeakerWrite" id="107"><field name="PIN">4</field><value name="NUMBER"><block type="variables_get" id="161"><field name="VAR">i</field></block></value><next><block type="base_delay" id="122"><value name="DELAY_TIME"><block type="math_number" id="123"><field name="NUM">1000</field></block></value></block></next></block></statement><next><block type="genuino_107020001_D4_SpeakerWrite" id="126"><field name="PIN">4</field><value name="NUMBER"><block type="math_number" id="127"><field name="NUM">0</field></block></value><next><block type="base_delay" id="175"><value name="DELAY_TIME"><block type="math_number" id="176"><field name="NUM">1000</field></block></value></block></next></block></next></block></xml>'
						}
					]
				}
			]
		}
	});

	this.on('store.WorkBoard.displayModule', function *(moduleId, isHide) {
		var store = this.getState('WorkBoard');
		store.displayModules[moduleId] = isHide;

		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.addBlockPin', function *(blockedPins) {
		var store = this.getState('WorkBoard');

		blockedPins.forEach(function(pinName) {
			store.blockPins[pinName] = true;
		});

		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.removeBlockPin', function *(blockedPins) {
		var store = this.getState('WorkBoard');

		blockedPins.forEach(function(pinName) {
			store.blockPins[pinName] = false;
		});
		
		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.connectModule', function *(moduleId, pin) {
		var store = this.getState('WorkBoard');
		store.connected[pin] = moduleId;

		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.resetAndConnectModules', function *(modules) {
		var store = this.getState('WorkBoard');

		// Reset
		store.connected = {};

		for (var pinName in store.blockPins)
			store.blockPins[pinName] = false;

		// Connect modules
		for (var index in modules) {
			var module = modules[index];
			store.connected[module.pin] = module.sku;
		}

		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.disconnectModule', function *(moduleId, pin) {
		delete store.connected[pin];

		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.disconnectAllModules', function *() {
		store.connected = {};

		for (var pinName in store.blockPins)
			store.blockPins[pinName] = false;

		// Notify view that time to update
		this.dispatch('store.WorkBoard', 'change');
	});

	this.on('store.WorkBoard.updateResults', function *(results) {
		var store = this.getState('WorkBoard');

		for (var pin in results) {
			store.testResults[pin] = results[pin];
		}

		this.dispatch('store.WorkBoard', 'change');
	});
};
