CommandClassControlDetailView.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. //
  2. // CommandClassControlDetailView.m
  3. // kneet
  4. //
  5. // Created by Jason Lee on 3/16/15.
  6. // Copyright (c) 2015 ntels. All rights reserved.
  7. //
  8. #import "JDObject.h"
  9. #import "RequestHandler.h"
  10. #import "JDJSONModel.h"
  11. #import "DeviceModel.h"
  12. #import "CustomLabel.h"
  13. #import "CommonUtil.h"
  14. #import "CustomButton.h"
  15. #import "CustomRadioGroup.h"
  16. #import "UIImageView+WebCache.h"
  17. #import "CommandClassControlDetailView.h"
  18. #import "CommandClassControlView.h"
  19. #import "CustomImageView.h"
  20. #define GRAPH_ANI_DUR 0.5f
  21. #define DEGREES(radians)((radians) * 180 / M_PI)
  22. #define RADIANS(degree)((degree) * M_PI / 180)
  23. typedef void(^NodeCommandCompletionBlock)(id result);
  24. typedef void(^NodeCommandFailureBlock)(id error);
  25. @implementation CommandClassControlDetailView
  26. + (CommandClassControlView *)viewForCommandClass:(CmdClsType)cmdClsType
  27. {
  28. CommandClassControlView *controlView = nil;
  29. for (UIView *view in [CommonUtil nibViews:@"CommandClassControlDetailView"]) {
  30. if (view.tag == cmdClsType) {
  31. controlView = (CommandClassControlView *)view;
  32. break;
  33. }
  34. }
  35. if (!controlView) {//상위 부모에서 가져옴.
  36. controlView = [CommandClassControlView viewForCommandClass:cmdClsType];
  37. }
  38. return controlView;
  39. }
  40. @end
  41. @implementation CommandClassSwitchDetailView
  42. @end
  43. @interface CommandClassThermostatModeDetailView () <CustomRadioGroupDelegate> {
  44. CustomRadioGroup *_rgroup;
  45. }
  46. @end
  47. @implementation CommandClassThermostatModeDetailView
  48. - (void)willMoveToSuperview:(UIView *)newSuperview {
  49. if (!newSuperview)
  50. return;
  51. [self initControl];
  52. }
  53. - (void)initControl {
  54. _rgroup = [[CustomRadioGroup alloc] init];
  55. _rgroup.delegate = self;
  56. [self setLayoutUI];
  57. }
  58. - (CustomBgRadioButton *)getModeButton:(CmdClsValueModel *)mode {
  59. UIImage *nimage = [UIImage imageNamed:@"tp_01_img_control_bg_black"];
  60. UIImage *himage = [UIImage imageNamed:@"tp_01_img_control_bg_active"];
  61. CustomBgRadioButton *rdoMode = [[CustomBgRadioButton alloc] initWithFrame:CGRectMake(0, 0, kfControlDefaultWidth, kfControlDefaultHeight) bgNormalImage:nimage bgHighlightImage:himage rectForCapBg:CGRectMake(40, 0, 40, 0)];
  62. rdoMode.value = mode;
  63. rdoMode.titleLabel.font = [UIFont boldSystemFontOfSize:kUIFontSize02];
  64. [rdoMode setTitleColor:kUITextColor01 forState:UIControlStateNormal];
  65. [rdoMode setTitle:mode.cmdclsValueMsg forState:UIControlStateNormal];
  66. rdoMode.titleColorNormal = kUITextColor01;
  67. rdoMode.titleColorHighlight = kUITextColor04;
  68. return rdoMode;
  69. }
  70. - (void)setLayoutUI {
  71. _modeArray = [_node cmdclsValueList];
  72. NSString *mode;
  73. NSUInteger highest = 0, i = 0;
  74. for (CmdClsValueModel *tmpCmdclsValue in _modeArray) {
  75. if (tmpCmdclsValue.cmdclsValueMsg.length > highest) {
  76. highest = tmpCmdclsValue.cmdclsValueMsg.length;
  77. mode = tmpCmdclsValue.cmdclsValueMsg;
  78. }
  79. }
  80. CGFloat width = [CommonUtil getSizeFromString:mode font:[UIFont boldSystemFontOfSize:kUIFontSize02] width:FLT_MAX].width + kfSwitchLabelPadding;
  81. CGFloat eWidth = width + kfCommandClassSwitchLeftPadding + kfCommandClassSwitchRightPadding;
  82. eWidth = eWidth < kfControlDefaultWidth ? kfControlDefaultWidth : eWidth;
  83. CustomBgRadioButton *_prevRadio, *_selectedRadio;
  84. for (CmdClsValueModel *tmpCmdclsValue in _modeArray) {
  85. CustomBgRadioButton *rdoMode = [self getModeButton:tmpCmdclsValue];
  86. [self addSubview:rdoMode];
  87. // rdoMode.checked = i == 0;
  88. [_rgroup addRadioButton:rdoMode];
  89. [rdoMode mas_makeConstraints:^(MASConstraintMaker *make) {
  90. if (i == 0) {
  91. make.top.mas_equalTo(10);
  92. } else {
  93. make.top.equalTo(_prevRadio.mas_bottom).offset(5); //adjust padding 5px
  94. }
  95. make.left.equalTo(self);
  96. make.width.mas_equalTo(eWidth);
  97. make.height.mas_equalTo(kfControlDefaultHeight);
  98. }];
  99. if ([_device.contentValue isEqualToString:tmpCmdclsValue.cmdclsValue]) {
  100. _selectedRadio = rdoMode;
  101. }
  102. _prevRadio = rdoMode;
  103. i++;
  104. }
  105. if (!_selectedRadio) {
  106. _selectedRadio = _rgroup.rdoBtns.firstObject;
  107. }
  108. [_rgroup someRadioButtonTouched:_selectedRadio]; //리스트에도 수정.
  109. CGRect sr = self.frame;
  110. sr.size.width = eWidth;
  111. sr.size.height = (kfControlDefaultHeight + 5.0f) * _modeArray.count;
  112. self.frame = sr;
  113. }
  114. - (CGSize)sizeForIntrinsic {
  115. CGFloat height = (kfControlDefaultHeight + 5.0f) * [_node cmdclsValueList].count;
  116. return CGSizeMake(kfControlMaxWidth, height);
  117. }
  118. - (CGSize)sizeForIntrinsicForItemCount:(NSInteger)count {
  119. CGFloat height = (kfControlDefaultHeight + 5.0f) * count;
  120. return CGSizeMake(kfControlMaxWidth, height);
  121. }
  122. - (void)didSomeRadioButtonTouched:(id)sender {
  123. if (_isConditionMode) //룰, 씬일 경우, 제어를 하지 않음
  124. return;
  125. CustomBgRadioButton *rdoMode = (CustomBgRadioButton *)sender;
  126. CmdClsValueModel *cmdclsValue = rdoMode.value;
  127. [self updateThingsViewContoller];
  128. NSString *requestValue = cmdclsValue.cmdclsValue;
  129. [CommandClassControlView requestNodeCommand:self.parameterForNodeCommand requestValue:requestValue completionHandler:nil failureHandler:nil];
  130. }
  131. @end
  132. @implementation CommandClassThermostatFanModeDetailView
  133. @end
  134. @implementation CommandClassThermostatSetPointDetailView
  135. @end
  136. @implementation CommandClassLockDetailView
  137. @end
  138. @implementation CommandClassAVPlaybackDetailView
  139. @end
  140. #pragma mark - Sensors View
  141. @implementation CommandClassSensorBinaryDetailView
  142. @end
  143. @implementation CommandClassSensorMultiLevelDetailView
  144. @end
  145. @implementation CommandClassMeterCurrentOfDAWONView
  146. - (void)willMoveToSuperview:(UIView *)newSuperview {
  147. if (!newSuperview)
  148. return;
  149. [self initControl];
  150. }
  151. - (void)initControl {
  152. [self setLayoutUI];
  153. }
  154. - (void)setLayoutUI {
  155. _device = _device ? _device : _node;
  156. NSString *contentValue = (!_device.contentValue || [_device.contentValue isEmptyString] ||[_device.contentValue isEqualToString:@"none"]) ? @"-" : _device.contentValue;
  157. if ([contentValue isEqualToString:@"-"]) {
  158. contentValue = @"1000";
  159. }
  160. NSString *unit = _device.unit && ![_device.unit isEmptyString] ? _device.unit : ksEmptyString;
  161. unit = [contentValue isEqualToString:@"-"] ? ksEmptyString : unit;
  162. if (_node) {//디바이스 상세일 경우,
  163. self.lblMeter.text = [NSString stringWithFormat:@"%@ %@", contentValue, unit];
  164. self.lblMeter.font = [UIFont systemFontOfSize:kUIFontSize07];
  165. }
  166. CGFloat percent = [contentValue floatValue] / [_node.controlMaxValue floatValue];
  167. [self drawDonutChart:percent];
  168. CGRect sr = self.frame;
  169. sr.size = CGSizeMake(200, 200);
  170. self.frame = sr;
  171. }
  172. - (CGSize)sizeForIntrinsic {
  173. return CGSizeMake(200, 200);
  174. }
  175. - (void)drawDonutChart:(CGFloat)percent {
  176. UIImage *gradientImage = [UIImage imageNamed:@"dawon_meter_graph_over"];
  177. //draw chart
  178. CGRect bgGradient = (CGRect){.origin={10, 10}, .size = gradientImage.size};
  179. _gradientLayer = [CAShapeLayer layer];
  180. _gradientLayer.contents = (id)[gradientImage CGImage];
  181. _gradientLayer.frame = bgGradient;
  182. [self.layer addSublayer:_gradientLayer];
  183. CGFloat angle = percent * 360;
  184. [self drawMask:85 angle:angle]; //FIXME : constant
  185. //x = 10 / 360
  186. //270 + atan2(x)
  187. // int value = -_currentAngle < 90 ? (-_currentAngle + 225) : (-_currentAngle - 134);
  188. // self.percent = @((value) / 270.0f);
  189. }
  190. - (void)drawMask:(CGFloat)radius angle:(CGFloat)angle {
  191. CGContextRef ctx = UIGraphicsGetCurrentContext();
  192. //Make sure the remove the anti-alias effect from circle
  193. CGContextSetAllowsAntialiasing(ctx, true);
  194. CGContextSetShouldAntialias(ctx, true);
  195. UIColor *color = [UIColor redColor];
  196. //10 : 360 = x : 100
  197. //x : 100 = 10 : 360
  198. //차트 생성 및 애니메이션
  199. CGFloat start = RADIANS(270);
  200. CGFloat max = RADIANS(270 + angle);
  201. // CGFloat end = 1.0 * RADIANS(269);//percent * RADIANS(180);
  202. CGPoint center = CGPointMake(_gradientLayer.frame.size.width/2, _gradientLayer.frame.size.height/2);
  203. UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:start endAngle:max clockwise:YES];
  204. CAShapeLayer *maskLayer = [CAShapeLayer layer];
  205. maskLayer.path = [path CGPath];
  206. maskLayer.strokeColor = [color CGColor];
  207. maskLayer.fillColor = nil;
  208. maskLayer.lineWidth = 10;
  209. maskLayer.lineJoin = kCALineJoinRound;
  210. _gradientLayer.mask = maskLayer;
  211. CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  212. pathAnimation.duration = GRAPH_ANI_DUR;
  213. pathAnimation.fromValue = @(0.0f);
  214. pathAnimation.toValue = @(1.0f);
  215. // [pathAnimation animationDidStop:pathAnimation2 finished:NO];
  216. [maskLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
  217. }
  218. @end
  219. @implementation CommandClassMeterTotalOfDAWONView
  220. - (void)willMoveToSuperview:(UIView *)newSuperview {
  221. if (!newSuperview)
  222. return;
  223. [self initControl];
  224. }
  225. - (void)initControl {
  226. self.lblMeter.textColor = kUITextColor01;
  227. [self setLayoutUI];
  228. }
  229. - (void)setLayoutUI {
  230. _device = _device ? _device : _node;
  231. NSString *contentValue = (!_device.contentValue || [_device.contentValue isEmptyString] ||[_device.contentValue isEqualToString:@"none"]) ? @"-" : _device.contentValue;
  232. NSString *unit = _device.unit && ![_device.unit isEmptyString] ? _device.unit : ksEmptyString;
  233. unit = [contentValue isEqualToString:@"-"] ? ksEmptyString : unit;
  234. if (_node) {//디바이스 상세일 경우,
  235. self.lblMeter.text = [NSString stringWithFormat:@"%@ %@", contentValue, unit];
  236. self.lblMeter.font = [UIFont systemFontOfSize:kUIFontSize07];
  237. if ([_node.nodeId isEqualToString:@"3"]) {//누적 전력량
  238. [_imgvIcon setImage:[UIImage imageNamed:@"dawon_command_icon_total_power"]];
  239. } else if ([_node.nodeId isEqualToString:@"4"]) {//CO2 발생량
  240. [_imgvIcon setImage:[UIImage imageNamed:@"dawon_command_icon_co2"]];
  241. } else if ([_node.nodeId isEqualToString:@"5"]) {//예상금액 아이콘
  242. [_imgvIcon setImage:[UIImage imageNamed:@"dawon_command_icon_price"]];
  243. }
  244. }
  245. CGRect sr = self.frame;
  246. sr.size = CGSizeMake(200, 50);
  247. self.frame = sr;
  248. }
  249. - (CGSize)sizeForIntrinsic {
  250. return CGSizeMake(200, 50);
  251. }
  252. @end
  253. @interface CommandClassSpeedControlDetailView () <CustomRadioGroupDelegate> {
  254. CustomRadioGroup *_rgroup;
  255. }
  256. @end
  257. @implementation CommandClassSpeedControlDetailView
  258. - (void)willMoveToSuperview:(UIView *)newSuperview {
  259. if (!newSuperview)
  260. return;
  261. [self initControl];
  262. }
  263. - (void)initControl {
  264. _rgroup = [[CustomRadioGroup alloc] init];
  265. _rgroup.delegate = self;
  266. [self setLayoutUI];
  267. }
  268. - (CustomBgRadioButton *)getModeButton:(CmdClsValueModel *)mode {
  269. UIImage *nimage = [UIImage imageNamed:@"tp_01_img_control_bg_black"];
  270. UIImage *himage = [UIImage imageNamed:@"tp_01_img_control_bg_active"];
  271. CustomBgRadioButton *rdoMode = [[CustomBgRadioButton alloc] initWithFrame:CGRectMake(0, 0, kfControlDefaultWidth, kfControlDefaultHeight) bgNormalImage:nimage bgHighlightImage:himage rectForCapBg:CGRectMake(40, 0, 40, 0)];
  272. rdoMode.value = mode;
  273. rdoMode.titleLabel.font = [UIFont boldSystemFontOfSize:kUIFontSize02];
  274. [rdoMode setTitleColor:kUITextColor01 forState:UIControlStateNormal];
  275. [rdoMode setTitle:mode.cmdclsValueMsg forState:UIControlStateNormal];
  276. rdoMode.titleColorNormal = kUITextColor01;
  277. rdoMode.titleColorHighlight = kUITextColor04;
  278. return rdoMode;
  279. }
  280. - (void)setLayoutUI {
  281. _modeArray = [_node cmdclsValueList];
  282. NSString *mode;
  283. NSUInteger highest = 0, i = 0;
  284. for (CmdClsValueModel *tmpCmdclsValue in _modeArray) {
  285. if (tmpCmdclsValue.cmdclsValueMsg.length > highest) {
  286. highest = tmpCmdclsValue.cmdclsValueMsg.length;
  287. mode = tmpCmdclsValue.cmdclsValueMsg;
  288. }
  289. }
  290. CGFloat width = [CommonUtil getSizeFromString:mode font:[UIFont boldSystemFontOfSize:kUIFontSize02] width:FLT_MAX].width + kfSwitchLabelPadding;
  291. CGFloat eWidth = width + kfCommandClassSwitchLeftPadding + kfCommandClassSwitchRightPadding;
  292. eWidth = eWidth < kfControlDefaultWidth ? kfControlDefaultWidth : eWidth;
  293. CustomBgRadioButton *_prevRadio, *_selectedRadio;
  294. for (CmdClsValueModel *tmpCmdclsValue in _modeArray) {
  295. CustomBgRadioButton *rdoMode = [self getModeButton:tmpCmdclsValue];
  296. [self addSubview:rdoMode];
  297. // rdoMode.checked = i == 0;
  298. [_rgroup addRadioButton:rdoMode];
  299. [rdoMode mas_makeConstraints:^(MASConstraintMaker *make) {
  300. if (i == 0) {
  301. make.top.mas_equalTo(0);
  302. } else {
  303. make.top.equalTo(_prevRadio.mas_bottom).offset(5); //adjust padding 5px
  304. }
  305. make.left.equalTo(self);
  306. make.width.mas_equalTo(eWidth);
  307. make.height.mas_equalTo(kfControlDefaultHeight);
  308. }];
  309. if ([_device.contentValue isEqualToString:tmpCmdclsValue.cmdclsValue]) {
  310. _selectedRadio = rdoMode;
  311. }
  312. _prevRadio = rdoMode;
  313. i++;
  314. }
  315. if (!_selectedRadio) {
  316. _selectedRadio = _rgroup.rdoBtns.firstObject;
  317. }
  318. [_rgroup someRadioButtonTouched:_selectedRadio];
  319. CGRect sr = self.frame;
  320. sr.size.width = eWidth;
  321. sr.size.height = (kfControlDefaultHeight + 5.0f) * _modeArray.count;
  322. self.frame = sr;
  323. }
  324. - (CGSize)sizeForIntrinsic {
  325. CGFloat height = (kfControlDefaultHeight + 5.0f) * [_node cmdclsValueList].count;
  326. return CGSizeMake(kfControlMaxWidth, height);
  327. }
  328. - (CGSize)sizeForIntrinsicForItemCount:(NSInteger)count {
  329. CGFloat height = (kfControlDefaultHeight + 5.0f) * count;
  330. return CGSizeMake(kfControlMaxWidth, height);
  331. }
  332. - (void)didSomeRadioButtonTouched:(id)sender {
  333. if (_isConditionMode) //룰, 씬일 경우, 제어를 하지 않음
  334. return;
  335. CustomBgRadioButton *rdoMode = (CustomBgRadioButton *)sender;
  336. CmdClsValueModel *cmdclsValue = rdoMode.value;
  337. [self updateThingsViewContoller];
  338. NSString *requestValue = cmdclsValue.cmdclsValue;
  339. [CommandClassControlView requestNodeCommand:self.parameterForNodeCommand requestValue:requestValue completionHandler:nil failureHandler:nil];
  340. }
  341. @end