Răsfoiți Sursa

dev control

shjung 2 ani în urmă
părinte
comite
62e9e4de38

+ 29 - 2
src/main/java/com/its/cctv/api/controller/CctvControlController.java

@@ -1,5 +1,6 @@
 package com.its.cctv.api.controller;
 
+import com.its.cctv.api.dto.CctvParamControlDto;
 import com.its.cctv.api.dto.CctvPresetControlDto;
 import com.its.cctv.api.dto.CctvPtzControlDto;
 import com.its.cctv.api.dto.CctvStatusDto;
@@ -15,7 +16,7 @@ import org.springframework.web.bind.annotation.*;
 import javax.validation.Valid;
 
 @Slf4j
-@Api(tags = "11.CCTV-0.제어")
+@Api(tags = "1.CCTV-0.제어")
 @Validated
 @RestController
 @RequiredArgsConstructor
@@ -24,7 +25,33 @@ public class CctvControlController {
 
     private final CctvControlService service;
 
-    @ApiOperation(value = "CCTV PTZ 제어", response = CctvStatusDto.CctvStatusDtoRes.class)
+    @ApiOperation(value = "TEST", response = CctvStatusDto.CctvStatusNotifyDtoRes.class)
+    @GetMapping(value = "/status/notify/{id}", produces = {"application/json; charset=utf8"})
+    public CctvStatusDto.CctvStatusNotifyDtoRes notifyStatus(
+            @ApiParam(name = "id", value = "제어기번호", example = "1001", required = true)
+            @PathVariable("id") Long id) {
+        return this.service.notifyStatus(id);
+    }
+
+    @ApiOperation(value = "CCTV 환경 파라미터 조회", response = CctvParamControlDto.CctvParamValueRes.class)
+    @GetMapping(value = "/param-qry/{id}", produces = {"application/json; charset=utf8"})
+    public CctvParamControlDto.CctvParamValueRes requestParam(
+            @ApiParam(name = "id", value = "제어기번호", example = "1001", required = true)
+            @PathVariable("id") Long id) {
+        return this.service.requestParam(id);
+    }
+
+    @ApiOperation(value = "CCTV 환경 파라미터 설정", response = CctvParamControlDto.CctvParamControlRes.class)
+    @PostMapping(value = "/param-set/{id}", produces = {"application/json; charset=utf8"})
+    public CctvParamControlDto.CctvParamControlRes controlParam(
+            @ApiParam(name = "id", value = "제어기번호", example = "1001", required = true)
+            @PathVariable("id") Long id,
+            @ApiParam(name = "req", value = "CCTV PARAMETER 설정 정보", example = "[ADMIN]", required = true)
+            @RequestBody @Valid final CctvParamControlDto.CctvParamControlReq req) {
+        return this.service.controlParam(id, req);
+    }
+
+    @ApiOperation(value = "CCTV 상태 조회", response = CctvStatusDto.CctvStatusDtoRes.class)
     @GetMapping(value = "/status/{id}", produces = {"application/json; charset=utf8"})
     public CctvStatusDto.CctvStatusDtoRes requestStatus(
             @ApiParam(name = "id", value = "제어기번호", example = "1001", required = true)

+ 144 - 0
src/main/java/com/its/cctv/api/dto/CctvParamControlDto.java

@@ -0,0 +1,144 @@
+package com.its.cctv.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import javax.validation.constraints.PositiveOrZero;
+import java.io.Serializable;
+
+/**
+ * CCTV 제어기 프리셋제어 DTO Class
+ */
+@Data
+@Builder
+@ApiModel("CctvParamControlDto(CCTV 프리셋제어 정보")
+public class CctvParamControlDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModel("CctvParamControlReq(CCTV 프리셋제어 정보)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor//(access = AccessLevel.PROTECTED)
+    public static class CctvParamControlReq {
+
+        @ApiModelProperty("FAN ON 설정 온도")
+        @JsonProperty("fanOnTmpr")
+        @PositiveOrZero
+        private Integer fanOnTmpr;
+
+        @ApiModelProperty("FAN OFF 설정 온도")
+        @JsonProperty("fanOffTmpr")
+        @PositiveOrZero
+        private Integer fanOffTmpr;
+
+        @ApiModelProperty("Heater ON 설정 온도")
+        @JsonProperty("zoom")
+        @PositiveOrZero
+        private Integer hetrOnTmpr;
+
+        @ApiModelProperty("Heater OFF 설정 온도")
+        @JsonProperty("hetrOffTmpr")
+        @PositiveOrZero
+        private Integer hetrOffTmpr;
+
+        @ApiModelProperty("로그인 사용자 ID")
+        @JsonProperty("user_id")
+        private String userId;
+
+        @Builder
+        public CctvParamControlReq(Integer fanOnTmpr, Integer fanOffTmpr, Integer hetrOnTmpr, Integer hetrOffTmpr, String user_id) {
+            this.fanOnTmpr = fanOnTmpr;
+            this.fanOffTmpr = fanOffTmpr;
+            this.hetrOnTmpr = hetrOnTmpr;
+            this.hetrOffTmpr = hetrOffTmpr;
+            this.userId = user_id;
+        }
+    }
+
+    @ApiModel("CctvParamControlRes(CCTV 프리셋제어 응답)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor//(access = AccessLevel.PROTECTED)
+    public static class CctvParamControlRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+        @Builder
+        public CctvParamControlRes(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+    }
+
+    @ApiModel("CctvParamValueRes(CCTV 프리셋 상태 정보)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor//(access = AccessLevel.PROTECTED)
+    public static class CctvParamValueRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        @ApiModelProperty("FAN ON 설정 온도")
+        @JsonProperty("fanOnTmpr")
+        @PositiveOrZero
+        private Integer fanOnTmpr;
+
+        @ApiModelProperty("FAN OFF 설정 온도")
+        @JsonProperty("fanOffTmpr")
+        @PositiveOrZero
+        private Integer fanOffTmpr;
+
+        @ApiModelProperty("Heater ON 설정 온도")
+        @JsonProperty("zoom")
+        @PositiveOrZero
+        private Integer hetrOnTmpr;
+
+        @ApiModelProperty("Heater OFF 설정 온도")
+        @JsonProperty("hetrOffTmpr")
+        @PositiveOrZero
+        private Integer hetrOffTmpr;
+
+        public CctvParamValueRes(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+            this.fanOnTmpr = 0;
+            this.fanOffTmpr = 0;
+            this.hetrOnTmpr = 0;
+            this.hetrOffTmpr = 0;
+        }
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+
+        public void setValue(Integer fanOnTmpr, Integer fanOffTmpr, Integer hetrOnTmpr, Integer hetrOffTmpr) {
+            this.fanOnTmpr = fanOnTmpr;
+            this.fanOffTmpr = fanOffTmpr;
+            this.hetrOnTmpr = hetrOnTmpr;
+            this.hetrOffTmpr = hetrOffTmpr;
+        }
+    }
+
+}

+ 5 - 5
src/main/java/com/its/cctv/api/dto/CctvPresetControlDto.java

@@ -102,22 +102,22 @@ public class CctvPresetControlDto implements Serializable {
         @ApiModelProperty("Pan Preset Value")
         @JsonProperty("pan")
         @PositiveOrZero
-        private Integer pan;
+        private Short pan;
 
         @ApiModelProperty("Tilt Preset Value")
         @JsonProperty("tilt")
         @PositiveOrZero
-        private Integer tilt;
+        private Short tilt;
 
         @ApiModelProperty("Zoom Preset Value")
         @JsonProperty("zoom")
         @PositiveOrZero
-        private Integer zoom;
+        private Short zoom;
 
         @ApiModelProperty("Focus Preset Value")
         @JsonProperty("focus")
         @PositiveOrZero
-        private Integer focus;
+        private Short focus;
 
         public CctvPresetValueRes(Integer error, String message) {
             this.error = error;
@@ -133,7 +133,7 @@ public class CctvPresetControlDto implements Serializable {
             this.message = message;
         }
 
-        public void setValue(Integer pan, Integer tilt, Integer zoom, Integer focus) {
+        public void setValue(Short pan, Short tilt, Short zoom, Short focus) {
             this.pan = pan;
             this.tilt = tilt;
             this.zoom = zoom;

+ 27 - 0
src/main/java/com/its/cctv/api/dto/CctvStatusDto.java

@@ -46,4 +46,31 @@ public class CctvStatusDto implements Serializable {
             this.stts = stts;
         }
     }
+
+    @ApiModel("CctvStatusNotifyDtoRes(CCTV 상태 Notify 응답)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor//(access = AccessLevel.PROTECTED)
+    public static class CctvStatusNotifyDtoRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+
+        @Builder
+        public CctvStatusNotifyDtoRes(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+    }
 }

+ 109 - 13
src/main/java/com/its/cctv/api/service/CctvControlService.java

@@ -1,12 +1,14 @@
 package com.its.cctv.api.service;
 
 import com.its.app.utils.ByteUtils;
+import com.its.cctv.api.dto.CctvParamControlDto;
 import com.its.cctv.api.dto.CctvPresetControlDto;
 import com.its.cctv.api.dto.CctvPtzControlDto;
 import com.its.cctv.api.dto.CctvStatusDto;
 import com.its.cctv.domain.NET;
 import com.its.cctv.entity.TbCctvCtlr;
 import com.its.cctv.global.AppRepository;
+import com.its.cctv.xnettcp.cctv.protocol.CctvReqParamSet;
 import com.its.cctv.xnettcp.cctv.protocol.CctvReqPresetMove;
 import com.its.cctv.xnettcp.cctv.protocol.CctvReqPresetQry;
 import com.its.cctv.xnettcp.cctv.protocol.CctvReqPtzCtrl;
@@ -101,7 +103,7 @@ public class CctvControlService {
      * @return
      */
     public CctvPtzControlDto.CctvPtzControlRes controlPtz(Long id, CctvPtzControlDto.CctvControlPtzReq req) {
-        log.info("{}", req);
+        log.info("controlPtz: {}", req);
         TbCctvCtlr cctv = this.requireOne(id);
         if (cctv == null) {
             return new CctvPtzControlDto.CctvPtzControlRes(req.getCommand(), req.getAction(), 1, "알수없는 CCTV 관리번호 입니다.");
@@ -158,10 +160,10 @@ public class CctvControlService {
      * @return
      */
     public CctvPresetControlDto.CctvPresetControlRes controlPreset(Long id, CctvPresetControlDto.CctvPresetControlReq req) {
-        log.info("{}", req);
+        log.info("controlPreset: {}", req);
         TbCctvCtlr cctv = this.requireOne(id);
         if (cctv == null) {
-            return new CctvPresetControlDto.CctvPresetControlRes(1, "unknown cctv type");
+            return new CctvPresetControlDto.CctvPresetControlRes(1, "CCTV 제어기 정보를 찾을 수 없습니다.");
         }
         if (cctv.getNetState() != NET.LOGINED) {
             return new CctvPresetControlDto.CctvPresetControlRes(2, "CCTV 통신연결이 되어 있지 않습니다.");
@@ -179,26 +181,120 @@ public class CctvControlService {
         }
         return result;
     }
+    
+    public CctvParamControlDto.CctvParamControlRes controlParam(Long id, CctvParamControlDto.CctvParamControlReq req) {
+        log.info("controlParam: {}", id);
+        TbCctvCtlr cctv = this.requireOne(id);
+        if (cctv == null) {
+            return new CctvParamControlDto.CctvParamControlRes(1, "CCTV 제어기 정보를 찾을 수 없습니다.");
+        }
+        if (cctv.getNetState() != NET.LOGINED) {
+            return new CctvParamControlDto.CctvParamControlRes(2, "CCTV 통신연결이 되어 있지 않습니다.");
+        }
+
+        CctvParamControlDto.CctvParamControlRes result = new CctvParamControlDto.CctvParamControlRes(0, "success");
+        CctvReqParamSet pkt = new CctvReqParamSet(cctv.getAddress());
+        pkt.setValue(req.getFanOnTmpr().byteValue(), req.getFanOffTmpr().byteValue(), req.getHetrOnTmpr().byteValue(), req.getHetrOffTmpr().byteValue());
+        ByteBuffer sendBuffer = pkt.getByteBuffer();
+        if (cctv.sendData(sendBuffer, 0, "cctv_ParamSet")) {
+            log.info("PARAMETER SET send success.");
+        } else {
+            result.setResult(4, "CCTV PARAMETER 명령 전송이 실패하였습니다.");
+            log.error("PARAMETER SET send failed.");
+        }
+        return result;
+    }
+
+    public CctvParamControlDto.CctvParamValueRes requestParam(Long id) {
+        log.info("requestParam: {}", id);
+        TbCctvCtlr cctv = this.requireOne(id);
+        if (cctv == null) {
+            return new CctvParamControlDto.CctvParamValueRes(1, "CCTV 제어기 정보를 찾을 수 없습니다.");
+        }
+        if (cctv.getNetState() != NET.LOGINED) {
+            return new CctvParamControlDto.CctvParamValueRes(2, "CCTV 통신연결이 되어 있지 않습니다.");
+        }
+
+        CctvParamControlDto.CctvParamValueRes result = new CctvParamControlDto.CctvParamValueRes(0, "success");
+
+        synchronized (cctv.getParamVal()) {
+            try {
+                cctv.getParamVal().setCompleted(false);
+                ByteBuffer sendBuffer = cctv.getReqParam().getByteBuffer();
+                if (cctv.sendData(sendBuffer, 0, "cctv_ParamReq")) {
+                    log.info("PARAMETER QRY send success.");
+                    cctv.getParamVal().wait(5000);
+                    if (cctv.getParamVal().isCompleted()) {
+                        result.setValue(cctv.getParamVal().getFanOnTmpr(), cctv.getParamVal().getFanOffTmpr(), cctv.getParamVal().getHetrOnTmpr(), cctv.getParamVal().getHetrOffTmpr());
+                    } else {
+                        result.setResult(5, "CCTV PARAMETER 값조회 명령 중 타임아웃이 발생하였습니다.");
+                    }
+                } else {
+                    result.setResult(4, "CCTV PARAMETER 값조회 명령 전송이 실패하였습니다.");
+                    log.error("PARAMETER QRY send failed.");
+                }
+            } catch (InterruptedException e) {
+                result.setResult(9, "CCTV PARAMETER 값조회 명령 전송 중 오류가 발생하였습니다.");
+            }
+        }
+        return result;
+    }
 
     public CctvPresetControlDto.CctvPresetValueRes requestPresetValue(Long id) {
-        log.info("{}", id);
+        log.info("requestPresetValue: {}", id);
         TbCctvCtlr cctv = this.requireOne(id);
         if (cctv == null) {
-            return new CctvPresetControlDto.CctvPresetValueRes(1, "unknown cctv type");
+            return new CctvPresetControlDto.CctvPresetValueRes(1, "CCTV 제어기 정보를 찾을 수 없습니다.");
         }
         if (cctv.getNetState() != NET.LOGINED) {
             return new CctvPresetControlDto.CctvPresetValueRes(2, "CCTV 통신연결이 되어 있지 않습니다.");
         }
 
         CctvPresetControlDto.CctvPresetValueRes result = new CctvPresetControlDto.CctvPresetValueRes(0, "success");
-        CctvReqPresetQry pkt = new CctvReqPresetQry(cctv.getAddress());
-        pkt.setValue((byte)0x00);
-        ByteBuffer sendBuffer = pkt.getByteBuffer();
-        if (cctv.sendData(sendBuffer, 0, "cctv_PresetQry")) {
-            log.info("PRESET QRY send success.");
-        } else {
-            result.setResult(4, "CCTV PRESET 값조회 명령 전송이 실패하였습니다.");
-            log.error("PRESET QRY send failed.");
+
+        synchronized (cctv.getPsetVal()) {
+            try {
+                cctv.getPsetVal().setCompleted(false);
+                CctvReqPresetQry pkt = new CctvReqPresetQry(cctv.getAddress());
+                pkt.setValue((byte)0x00);
+                ByteBuffer sendBuffer = pkt.getByteBuffer();
+                if (cctv.sendData(sendBuffer, 0, "cctv_PresetQry")) {
+                    log.info("PRESET QRY send success.");
+                    cctv.getPsetVal().wait(5000);
+                    if (cctv.getPsetVal().isCompleted()) {
+                        result.setValue(cctv.getPsetVal().getPan(), cctv.getPsetVal().getTilt(), cctv.getPsetVal().getZoom(), cctv.getPsetVal().getFocus());
+                    } else {
+                        result.setResult(5, "CCTV PRESET 값조회 명령 중 타임아웃이 발생하였습니다.");
+                    }
+                } else {
+                    result.setResult(4, "CCTV PRESET 값조회 명령 전송이 실패하였습니다.");
+                    log.error("PRESET QRY send failed.");
+                }
+            } catch (InterruptedException e) {
+                result.setResult(9, "CCTV PRESET 값조회 명령 전송 중 오류가 발생하였습니다.");
+            }
+        }
+        return result;
+    }
+
+    public CctvStatusDto.CctvStatusNotifyDtoRes notifyStatus(Long id) {
+        log.info("notifyStatus: {}", id);
+        TbCctvCtlr cctv = this.requireOne(id);
+        if (cctv == null) {
+            return new CctvStatusDto.CctvStatusNotifyDtoRes(1, "CCTV 제어기 정보를 찾을 수 없습니다.");
+        }
+        if (cctv.getNetState() != NET.LOGINED) {
+            return new CctvStatusDto.CctvStatusNotifyDtoRes(2, "CCTV 통신연결이 되어 있지 않습니다.");
+        }
+
+        CctvStatusDto.CctvStatusNotifyDtoRes result = new CctvStatusDto.CctvStatusNotifyDtoRes(0, "success");
+        synchronized (cctv.getPsetVal()) {
+            try {
+                cctv.getPsetVal().notifyAll();
+            }
+            catch(Exception e) {
+                log.error("{}, {}", cctv.getPsetVal(), e.getMessage());
+            }
         }
         return result;
     }

+ 37 - 0
src/main/java/com/its/cctv/entity/CctvParamValue.java

@@ -0,0 +1,37 @@
+package com.its.cctv.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.Serializable;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+public class CctvParamValue implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private boolean isCompleted = false;
+    private Integer fanOnTmpr;
+    private Integer fanOffTmpr;
+    private Integer hetrOnTmpr;
+    private Integer hetrOffTmpr;
+
+    public void init() {
+        this.fanOnTmpr = 0;
+        this.fanOffTmpr = 0;
+        this.hetrOnTmpr = 0;
+        this.hetrOffTmpr = 0;
+    }
+
+    public void setValue(Integer fanOnTmpr, Integer fanOffTmpr, Integer hetrOnTmpr, Integer hetrOffTmpr) {
+        this.fanOnTmpr = fanOnTmpr;
+        this.fanOffTmpr = fanOffTmpr;
+        this.hetrOnTmpr = hetrOnTmpr;
+        this.hetrOffTmpr = hetrOffTmpr;
+    }
+
+}

+ 1 - 0
src/main/java/com/its/cctv/entity/CctvPresetValue.java

@@ -14,6 +14,7 @@ import java.io.Serializable;
 public class CctvPresetValue implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    private boolean isCompleted = false;
     private Short pan;
     private Short tilt;
     private Short zoom;

+ 3 - 0
src/main/java/com/its/cctv/entity/TbCctvCtlr.java

@@ -44,6 +44,7 @@ public class TbCctvCtlr {
 	private String            dstIpAddr;
 	private TbCctvCtlrStts    stts;
 	private CctvPresetValue   psetVal;
+	private CctvParamValue    paramVal;
 	private Channel           channel;
 	private Channel           dupChannel;
 	private long              syncTime;
@@ -66,7 +67,9 @@ public class TbCctvCtlr {
 	public TbCctvCtlr() {
 		this.stts = new TbCctvCtlrStts();
 		this.psetVal = new CctvPresetValue();
+		this.paramVal = new CctvParamValue();
 		this.psetVal.init();
+		this.paramVal.init();
 
 		this.connectCount = 0;
 		this.connectTm = "";

+ 8 - 0
src/main/java/com/its/cctv/xnettcp/cctv/process/Job_ParamRes.java

@@ -73,6 +73,14 @@ public class Job_ParamRes implements JobProtocol {
 
 		if (this.packet.getOpCode() == CctvProtocol.cctv_ParamSet) {
 			// 파라미터 설정 응답
+			synchronized (obj.getParamVal()) {
+				try {
+					obj.getParamVal().setValue(FAN_ON_TMPR, FAN_OFF_TMPR, HETR_ON_TMPR, HETR_OFF_TMPR);
+					obj.getParamVal().setCompleted(true);
+					obj.getParamVal().notifyAll();
+				} catch(Exception ignored) {
+				}
+			}
 		}
 
 		MainUI mainUI = MainUI.getInstance();

+ 8 - 2
src/main/java/com/its/cctv/xnettcp/cctv/process/Job_PresetQryRes.java

@@ -34,8 +34,14 @@ public class Job_PresetQryRes implements JobProtocol {
 		short tilt = buffer.getShort();
 		short zoom  = buffer.getShort();
 		short focus = buffer.getShort();
-		obj.getPsetVal().setValue(pan, tilt, zoom, focus);
-		obj.getPsetVal().notifyAll();
+		synchronized (obj.getPsetVal()) {
+			try {
+				obj.getPsetVal().setValue(pan, tilt, zoom, focus);
+				obj.getPsetVal().setCompleted(true);
+				obj.getPsetVal().notifyAll();
+			} catch(Exception ignored) {
+			}
+		}
 
 		MainUI mainUI = MainUI.getInstance();
 		if (mainUI != null) {

+ 0 - 7
src/main/java/com/its/cctv/xnettcp/cctv/protocol/CctvReqParam.java

@@ -9,11 +9,4 @@ public class CctvReqParam extends CctvReqFramePacket {
         super(address, CctvProtocol.cctv_ParamReq);
         this.body = new byte[4];
     }
-
-    public void setParam(byte fanOnTmpr, byte fanOffTmpr, byte hetrOnTmpr, byte hetrOffTmpr) {
-        this.body[0] = fanOnTmpr;
-        this.body[1] = fanOffTmpr;
-        this.body[2] = hetrOnTmpr;
-        this.body[3] = hetrOffTmpr;
-    }
 }

+ 7 - 0
src/main/java/com/its/cctv/xnettcp/cctv/protocol/CctvReqParamSet.java

@@ -9,4 +9,11 @@ public class CctvReqParamSet extends CctvReqFramePacket {
         super(address, CctvProtocol.cctv_ParamSet);
     }
 
+    public void setValue(byte fanOnTmpr, byte fanOffTmpr, byte hetrOnTmpr, byte hetrOffTmpr) {
+        this.body[0] = fanOnTmpr;
+        this.body[1] = fanOffTmpr;
+        this.body[2] = hetrOnTmpr;
+        this.body[3] = hetrOffTmpr;
+    }
+
 }