@@ -31,16 +31,16 @@ Entry.smartCodingHouse = {
31
31
32
32
// 핀 매핑 (참고용)
33
33
analogPin : {
34
- ULTRASONIC_TRIG : 0 ,
35
- ULTRASONIC_ECHO : 1 ,
36
- TEMP_HUM : 2 ,
37
- IR_SENSOR : 3 ,
38
- LIGHT_SENSOR : 4 ,
39
- RAIN_SENSOR : 5 ,
34
+ ULTRASONIC_TRIG : 0 , // 초음파센서 trig
35
+ ULTRASONIC_ECHO : 1 , // 초음파센서 echo
36
+ TEMP_HUM : 2 , // 온습도센서
37
+ IR_SENSOR : 3 , // 적외선센서
38
+ LIGHT_SENSOR : 4 , // 조도센서
39
+ RAIN_SENSOR : 5 , // 레인센서서
40
40
} ,
41
41
digitalPin : {
42
- SERVO_MOTOR : 2 , // 서보모터 제어 (D2)
43
- DC_MOTOR : 3 , // DC모터 (D3) – 방향과 속도를 하나의 값으로 결합
42
+ SERVO_MOTOR : 2 , // 서보모터
43
+ DC_MOTOR : 3 , // DC모터 – 방향과 속도를 하나의 값으로 결합
44
44
OUTDOOR1_LED_RED : 5 , // 1층 실외 빨강 LED
45
45
OUTDOOR1_LED_GREEN : 6 , // 1층 실외 초록 LED
46
46
OUTDOOR1_LED_BLUE : 7 , // 1층 실외 파란 LED
@@ -122,91 +122,93 @@ function hexToRgb(hex) {
122
122
let num = parseInt ( hex , 16 ) ;
123
123
return { r : ( num >> 16 ) & 255 , g : ( num >> 8 ) & 255 , b : num & 255 } ;
124
124
}
125
+
125
126
// RGB를 HSV로 변환하는 함수
126
127
function rgbToHsv ( r , g , b ) {
127
128
// 0~255 범위의 값을 0~1 범위로 정규화
128
129
r /= 255 ;
129
130
g /= 255 ;
130
131
b /= 255 ;
131
-
132
+
132
133
// 최대값과 최소값 찾기
133
134
let max = Math . max ( r , g , b ) ;
134
135
let min = Math . min ( r , g , b ) ;
135
136
let h ,
136
- s ,
137
- v = max ;
137
+ s ,
138
+ v = max ;
138
139
let d = max - min ;
139
-
140
+
140
141
// 채도(saturation) 계산: 최대값이 0이면 0, 아니면 (최대-최소)/최대
141
142
s = max === 0 ? 0 : d / max ;
142
-
143
+
143
144
// 색조(hue) 계산
144
145
if ( max === min ) {
145
- // 무채색인 경우(hue는 정의할 수 없음; 0으로 지정)
146
- h = 0 ;
146
+ // 무채색인 경우(hue는 정의할 수 없음; 0으로 지정)
147
+ h = 0 ;
147
148
} else {
148
- if ( max === r ) {
149
- h = ( g - b ) / d + ( g < b ? 6 : 0 ) ;
150
- } else if ( max === g ) {
151
- h = ( b - r ) / d + 2 ;
152
- } else {
153
- h = ( r - g ) / d + 4 ;
154
- }
155
- h /= 6 ; // 0~1 사이의 값으로 정규화
149
+ if ( max === r ) {
150
+ h = ( g - b ) / d + ( g < b ? 6 : 0 ) ;
151
+ } else if ( max === g ) {
152
+ h = ( b - r ) / d + 2 ;
153
+ } else {
154
+ h = ( r - g ) / d + 4 ;
155
+ }
156
+ h /= 6 ; // 0~1 사이의 값으로 정규화
156
157
}
157
-
158
+
158
159
// 결과 객체 반환: h는 0~1, s는 0~1, v는 0~1
159
160
return { h : h , s : s , v : v } ;
160
- }
161
-
162
- // HSV 값을 RGB로 변환하는 함수
163
- function hsvToRgb ( h , s , v ) {
161
+ }
162
+
163
+ // HSV 값을 RGB로 변환하는 함수
164
+ function hsvToRgb ( h , s , v ) {
164
165
let r , g , b ;
165
166
const i = Math . floor ( h * 6 ) ;
166
167
const f = h * 6 - i ;
167
168
const p = v * ( 1 - s ) ;
168
169
const q = v * ( 1 - f * s ) ;
169
170
const t = v * ( 1 - ( 1 - f ) * s ) ;
170
171
switch ( i % 6 ) {
171
- case 0 :
172
- ( r = v ) , ( g = t ) , ( b = p ) ;
173
- break ;
174
- case 1 :
175
- ( r = q ) , ( g = v ) , ( b = p ) ;
176
- break ;
177
- case 2 :
178
- ( r = p ) , ( g = v ) , ( b = t ) ;
179
- break ;
180
- case 3 :
181
- ( r = p ) , ( g = q ) , ( b = v ) ;
182
- break ;
183
- case 4 :
184
- ( r = t ) , ( g = p ) , ( b = v ) ;
185
- break ;
186
- case 5 :
187
- ( r = v ) , ( g = p ) , ( b = q ) ;
188
- break ;
172
+ case 0 :
173
+ ( r = v ) , ( g = t ) , ( b = p ) ;
174
+ break ;
175
+ case 1 :
176
+ ( r = q ) , ( g = v ) , ( b = p ) ;
177
+ break ;
178
+ case 2 :
179
+ ( r = p ) , ( g = v ) , ( b = t ) ;
180
+ break ;
181
+ case 3 :
182
+ ( r = p ) , ( g = q ) , ( b = v ) ;
183
+ break ;
184
+ case 4 :
185
+ ( r = t ) , ( g = p ) , ( b = v ) ;
186
+ break ;
187
+ case 5 :
188
+ ( r = v ) , ( g = p ) , ( b = q ) ;
189
+ break ;
189
190
}
190
191
return {
191
- r : Math . round ( r * 255 ) ,
192
- g : Math . round ( g * 255 ) ,
193
- b : Math . round ( b * 255 ) ,
192
+ r : Math . round ( r * 255 ) ,
193
+ g : Math . round ( g * 255 ) ,
194
+ b : Math . round ( b * 255 ) ,
194
195
} ;
195
- }
196
+ }
196
197
197
198
// 블록이 아니라, 일반 함수로 선언
198
- Entry . smartCodingHouse . modeDoor = function ( ) {
199
+ Entry . smartCodingHouse . modeDoor = function ( ) {
199
200
let port = Entry . smartCodingHouse . digitalPin . SERVO_MOTOR ;
200
201
// 서보모터를 90도로 설정
201
202
Entry . hw . sendQueue [ port ] = 4 ;
202
203
Entry . hw . update && Entry . hw . update ( ) ;
203
-
204
+
204
205
setTimeout ( ( ) => {
205
206
Entry . hw . sendQueue [ port ] = 0 ;
206
207
Entry . hw . update && Entry . hw . update ( ) ;
207
208
} , 26 ) ;
208
209
} ;
209
210
211
+
210
212
Entry . smartCodingHouse . getBlocks = function ( ) {
211
213
return {
212
214
set_ultrasonic_input : {
@@ -234,22 +236,27 @@ Entry.smartCodingHouse.getBlocks = function () {
234
236
paramsKeyMap : { EXPECTED : 0 , THRESHOLD : 1 } ,
235
237
def : {
236
238
type : 'set_ultrasonic_input' ,
237
- params : [ null , { type : 'number' , params : [ '3 ' ] } ] ,
239
+ params : [ null , { type : 'number' , params : [ '20 ' ] } ] ,
238
240
} ,
239
241
class : 'SmartCodingHouseSensor' ,
240
242
isNotFor : [ 'smartCodingHouse' ] ,
241
243
func : function ( sprite , script ) {
242
244
var expected = script . getField ( 'EXPECTED' , script ) ; // "near" 또는 "far"
243
- var threshold = script . getNumberValue ( 'THRESHOLD' , script ) ; // 임계값 (기본 3 )
245
+ var threshold = script . getNumberValue ( 'THRESHOLD' , script ) ; // 임계값 (기본 20cm )
244
246
var distance = Number ( Entry . hw . portData . ultrasonic ) ;
245
- if ( isNaN ( distance ) ) return false ;
247
+
248
+ if ( isNaN ( distance ) ) {
249
+ // 만약 ultrasonic이 NaN이면, a1 값을 대신 사용
250
+ distance = Number ( Entry . hw . portData . a1 ) ;
251
+ }
252
+ // console.log('[DEBUG] Ultrasonic sensor reading: ' + distance + ' cm');
253
+
246
254
// 센서 값이 임계값보다 작으면 "near", 이상이면 "far"
247
255
var actual = distance < threshold ? 'near' : 'far' ;
248
256
return actual === expected ;
249
257
} ,
250
258
} ,
251
259
252
- // ── 온습도 센서 블록 ─────────────────────────────
253
260
set_temp_hum_input : {
254
261
color : EntryStatic . colorSet . block . default . HARDWARE ,
255
262
outerLine : EntryStatic . colorSet . block . default . HARDWARE ,
@@ -286,24 +293,36 @@ Entry.smartCodingHouse.getBlocks = function () {
286
293
func : function ( sprite , script ) {
287
294
var sensorType = script . getField ( 'TYPE' , script ) ; // "temperature" 또는 "humidity"
288
295
var expected = script . getField ( 'EXPECTED' , script ) ;
296
+ // a2 채널에서 수신한 결합된 값을 가져옴
297
+ var combined = Number ( Entry . hw . portData . a2 ) ;
298
+ // Arduino에서 보낸 값은 (온도×100 + 습도)를 5로 나눈 값이므로,
299
+ // 원래 값을 복원하려면 5를 곱해줌
300
+ var value = combined * 5 ;
301
+ // 온도는 몫, 습도는 나머지로 분리 (예: 25°C, 50% → 25×100+50 = 2550)
302
+ var temp = Math . floor ( value / 100 ) ;
303
+ var humi = value % 100 ;
304
+
305
+ console . log ( '[DEBUG] combined: ' + combined ) ;
306
+ console . log ( '[DEBUG] temp: ' + temp ) ;
307
+ console . log ( '[DEBUG] humi: ' + humi ) ;
308
+
309
+ if ( isNaN ( combined ) ) {
310
+ combined = Number ( Entry . hw . portData . a2 ) ;
311
+ }
312
+
289
313
if ( sensorType === 'temperature' ) {
290
- var temp = Number ( Entry . hw . portData . temperature ) ;
291
- if ( isNaN ( temp ) ) return false ;
292
- // 25℃를 기준으로 온도가 높으면 "hot", 낮으면 "cold"
293
314
var actual = temp > 25 ? 'hot' : 'cold' ;
294
- // 예상 결과가 온도 관련 옵션이 아니면 false 반환
295
315
if ( expected !== 'hot' && expected !== 'cold' ) return false ;
296
316
return actual === expected ;
297
317
} else {
298
- var humi = Number ( Entry . hw . portData . humidity ) ;
299
- if ( isNaN ( humi ) ) return false ;
300
- // 50%를 기준으로 습도가 높으면 "wet", 낮으면 "dry"
301
318
var actual = humi > 50 ? 'wet' : 'dry' ;
302
319
if ( expected !== 'wet' && expected !== 'dry' ) return false ;
303
320
return actual === expected ;
304
321
}
322
+
305
323
} ,
306
324
} ,
325
+
307
326
308
327
set_light_input : {
309
328
color : EntryStatic . colorSet . block . default . HARDWARE ,
@@ -543,6 +562,7 @@ Entry.smartCodingHouse.getBlocks = function () {
543
562
Entry . smartCodingHouse . modeDoor ( ) ;
544
563
break ;
545
564
default :
565
+ console . log ( 'Unknown mode: ' + mode ) ;
546
566
}
547
567
return script . callReturn ( ) ;
548
568
} ,
@@ -692,14 +712,10 @@ Entry.smartCodingHouse.getBlocks = function () {
692
712
let location = script . getField ( 'LOCATION' , script ) ;
693
713
let color = script . getStringField ( 'COLOR' , script ) ;
694
714
if ( ! location ) {
715
+ console . error ( 'Error: LOCATION 값이 undefined!' ) ;
695
716
return script . callReturn ( ) ;
696
717
}
697
718
let rgb = hexToRgb ( color ) ;
698
- let hsv = rgbToHsv ( rgb . r , rgb . g , rgb . b ) ; // RGB → HSV
699
- hsv . s = 1.0 ; // 채도 100%
700
- hsv . v = 1.0 ; // 밝기 100%
701
- rgb = hsvToRgb ( hsv . h , hsv . s , hsv . v ) ; // HSV → RGB
702
-
703
719
let pinR , pinG , pinB ;
704
720
if ( location === 'OUTDOOR1' ) {
705
721
pinR = Entry . smartCodingHouse . digitalPin . OUTDOOR1_LED_RED ;
@@ -714,6 +730,10 @@ Entry.smartCodingHouse.getBlocks = function () {
714
730
pinG = Entry . smartCodingHouse . digitalPin . TERRACE2_LED_GREEN ;
715
731
pinB = Entry . smartCodingHouse . digitalPin . TERRACE2_LED_BLUE ;
716
732
}
733
+ // 콘솔 로그로 선택된 포트 번호 확인
734
+ // console.log('LED OFF - Location:', location);
735
+ // console.log('Port Red:', pinR, 'Port Green:', pinG, 'Port Blue:', pinB);
736
+
717
737
// LED 출력: 하드웨어 업데이트 전에 값 할당
718
738
Entry . hw . sendQueue [ pinR ] = rgb . r ;
719
739
Entry . hw . sendQueue [ pinG ] = rgb . g ;
@@ -734,7 +754,7 @@ Entry.smartCodingHouse.getBlocks = function () {
734
754
{
735
755
type : 'Dropdown' ,
736
756
options : [
737
- [ '1층 실내' , 'INDOOR' ] ,
757
+ [ '실내' , 'INDOOR' ] ,
738
758
[ '1층 실외' , 'OUTDOOR1' ] ,
739
759
[ '2층 테라스' , 'TERRACE2' ] ,
740
760
] ,
0 commit comments