Commit 5e447316566699474bf5bfa8cc275477377511ab

Authored by Imanol-Mikel Barba Sabariego
1 parent 19dba459

--no commit message

DUREX Vendor Control/Base.lproj/Localizable.strings
... ... @@ -101,4 +101,8 @@
101 101 "Product name change returned error" = "Product name change returned error";
102 102 "Error occurred while reading answer from device" = "Error occurred while reading answer from device";
103 103 "Error occurred while sending command to device" = "Error occurred while sending command to device";
104   -"Connection lost" = "Connection lost";
105 104 \ No newline at end of file
  105 +"Connection lost" = "Connection lost";
  106 +"Device answer timeout occurred" = "Device answer timeout occurred";
  107 +"Incident log" = "Incident log";
  108 +"Error Code" = "Error Code";
  109 +"Error Value" = "Error Value";
106 110 \ No newline at end of file
... ...
DUREX Vendor Control/CommunicationProtocol.h
... ... @@ -21,6 +21,7 @@
21 21 #define CHANGE_NUM_UNITS ((int)2)
22 22 #define MAX_PRODUCTS ((int)16)
23 23 #define SALE_STRING_LENGTH ((int)36)
  24 +#define INCIDENT_STRING_LENGTH ((int)20)
24 25 #define REPORT_SERVER_URL @"http://seneca.upc.es:8090/machine"
25 26  
26 27 @protocol CommunicationProtocolDelegate <NSObject>
... ... @@ -41,6 +42,7 @@
41 42 -(void) updateProductName: (uint8_t) channel : (uint8_t) product : (NSString*) name;
42 43 -(void) readSensorData;
43 44 -(void) readSalesLog: (NSDateComponents*) start : (NSDateComponents*) end;
  45 +-(void) readIncidentLog: (NSDateComponents*) start : (NSDateComponents*) end;
44 46 +(id) sharedProtocol;
45 47  
46 48 @end
... ...
DUREX Vendor Control/CommunicationProtocol.m
... ... @@ -321,4 +321,38 @@
321 321 //NSMutableString *answer = [[NSMutableString alloc]initWithString:@"P21408161036000001000000110450000001P21409012216000100000000220900000100P21409032307000000010502330800000000P21409070540000000020000440350000001P2P2"];
322 322 }
323 323  
  324 +-(void) readIncidentLog:(NSDateComponents *)start :(NSDateComponents *)end
  325 +{
  326 + NSMutableString *startDate = [NSMutableString stringWithString:@""];
  327 + NSMutableString *endDate = [NSMutableString stringWithString:@""];
  328 + NSMutableString *command = [NSMutableString stringWithString:@"A3"];
  329 + if(start == nil)
  330 + {
  331 + [startDate setString:@""];
  332 + }
  333 + else
  334 + {
  335 + NSInteger year = [start year];
  336 + year = year - (year/100)*100;
  337 + [startDate appendString:[NSString stringWithFormat:@"%02ld",(long)year]];
  338 + [startDate appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld",(long)[start month],(long)[start day],(long)[start hour],(long)[start minute]]];
  339 + }
  340 + if(end == nil)
  341 + {
  342 + [endDate setString:@""];
  343 + }
  344 + else
  345 + {
  346 + NSInteger year = [end year];
  347 + year = year - (year/100)*100;
  348 + [endDate appendString:[NSString stringWithFormat:@"%02ld",(long)year]];
  349 + [endDate appendString:[NSString stringWithFormat:@"%02ld%02ld%02ld%02ld",(long)[end month],(long)[end day],(long)[end hour],(long)[end minute]]];
  350 + }
  351 + [command appendString:startDate];
  352 + [command appendString:@"-"];
  353 + [command appendString:endDate];
  354 + [self writeMessage:command];
  355 +}
  356 +
  357 +
324 358 @end
... ...
DUREX Vendor Control/DUREX Vendor Control.xcodeproj/project.pbxproj
... ... @@ -44,6 +44,8 @@
44 44 F989B60219BCE28C00657DD9 /* SalesLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F989B60119BCE28C00657DD9 /* SalesLog.m */; };
45 45 F996591219CC7F3D00667BEC /* DateRangePickerViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = F996591419CC7F3D00667BEC /* DateRangePickerViewController_iPad.xib */; };
46 46 F9A8EF7C192FE201009E7532 /* Stack.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A8EF7B192FE201009E7532 /* Stack.m */; };
  47 + F9B9100919E59773006D4D06 /* IncidentLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F9B9100819E59773006D4D06 /* IncidentLog.m */; };
  48 + F9B9100C19E5A0A1006D4D06 /* Incident.m in Sources */ = {isa = PBXBuildFile; fileRef = F9B9100B19E5A0A1006D4D06 /* Incident.m */; };
47 49 F9C77F50192CDE30002DBE8A /* system.json in Resources */ = {isa = PBXBuildFile; fileRef = F9C77F4F192CDE30002DBE8A /* system.json */; };
48 50 F9CED59A19BE086E008F3764 /* UIView+Toast.m in Sources */ = {isa = PBXBuildFile; fileRef = F9CED59919BE086E008F3764 /* UIView+Toast.m */; };
49 51 F9E4D8FD19B8FD32009A7359 /* EMConnectingView_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = F9E4D8FF19B8FD32009A7359 /* EMConnectingView_iPad.xib */; };
... ... @@ -142,6 +144,10 @@
142 144 F996591819CC7F4500667BEC /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/DateRangePickerViewController_iPad.strings; sourceTree = "<group>"; };
143 145 F9A8EF7A192FE201009E7532 /* Stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stack.h; sourceTree = SOURCE_ROOT; };
144 146 F9A8EF7B192FE201009E7532 /* Stack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Stack.m; sourceTree = SOURCE_ROOT; };
  147 + F9B9100719E59773006D4D06 /* IncidentLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncidentLog.h; sourceTree = SOURCE_ROOT; };
  148 + F9B9100819E59773006D4D06 /* IncidentLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IncidentLog.m; sourceTree = SOURCE_ROOT; };
  149 + F9B9100A19E5A0A1006D4D06 /* Incident.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Incident.h; sourceTree = SOURCE_ROOT; };
  150 + F9B9100B19E5A0A1006D4D06 /* Incident.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Incident.m; sourceTree = SOURCE_ROOT; };
145 151 F9C77F4F192CDE30002DBE8A /* system.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = system.json; sourceTree = SOURCE_ROOT; };
146 152 F9CED59819BE086E008F3764 /* UIView+Toast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Toast.h"; sourceTree = SOURCE_ROOT; };
147 153 F9CED59919BE086E008F3764 /* UIView+Toast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Toast.m"; sourceTree = SOURCE_ROOT; };
... ... @@ -218,6 +224,8 @@
218 224 F98446EF19B9EAE9005C4992 /* Sensors.m */,
219 225 F989B5FE19BCD7A100657DD9 /* Sale.m */,
220 226 F989B60119BCE28C00657DD9 /* SalesLog.m */,
  227 + F9B9100B19E5A0A1006D4D06 /* Incident.m */,
  228 + F9B9100819E59773006D4D06 /* IncidentLog.m */,
221 229 );
222 230 name = "DUREX Vendor Control";
223 231 path = TestAppExample;
... ... @@ -324,6 +332,8 @@
324 332 F98446EE19B9EAE9005C4992 /* Sensors.h */,
325 333 F989B5FD19BCD7A100657DD9 /* Sale.h */,
326 334 F989B60019BCE28C00657DD9 /* SalesLog.h */,
  335 + F9B9100A19E5A0A1006D4D06 /* Incident.h */,
  336 + F9B9100719E59773006D4D06 /* IncidentLog.h */,
327 337 );
328 338 name = Headers;
329 339 sourceTree = "<group>";
... ... @@ -431,9 +441,11 @@
431 441 F933F80419B6819400521B90 /* DatePickerViewController.m in Sources */,
432 442 F989B5FF19BCD7A100657DD9 /* Sale.m in Sources */,
433 443 F98356D6192E835F00EA6821 /* InitialViewController.m in Sources */,
  444 + F9B9100C19E5A0A1006D4D06 /* Incident.m in Sources */,
434 445 F9CED59A19BE086E008F3764 /* UIView+Toast.m in Sources */,
435 446 F9A8EF7C192FE201009E7532 /* Stack.m in Sources */,
436 447 34AAB885189804FF0019860D /* EMDevicePickerViewController.m in Sources */,
  448 + F9B9100919E59773006D4D06 /* IncidentLog.m in Sources */,
437 449 F989B60219BCE28C00657DD9 /* SalesLog.m in Sources */,
438 450 F92F567919B75F5E00A1EACA /* PriceChangerViewController.m in Sources */,
439 451 34AAB883189804FF0019860D /* DUREXAppDelegate.m in Sources */,
... ...
DUREX Vendor Control/DUREX Vendor Control.xcodeproj/project.xcworkspace/xcuserdata/imanol.xcuserdatad/UserInterfaceState.xcuserstate
No preview for this file type
DUREX Vendor Control/DUREX Vendor Control.xcodeproj/xcuserdata/imanol.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
... ... @@ -31,7 +31,7 @@
31 31 endingColumnNumber = "9223372036854775807"
32 32 startingLineNumber = "776"
33 33 endingLineNumber = "776"
34   - landmarkName = "-tableView:cellForRowAtIndexPath:"
  34 + landmarkName = "-numberOfSectionsInTableView:"
35 35 landmarkType = "5">
36 36 </BreakpointContent>
37 37 </BreakpointProxy>
... ... @@ -47,8 +47,8 @@
47 47 endingColumnNumber = "9223372036854775807"
48 48 startingLineNumber = "718"
49 49 endingLineNumber = "718"
50   - landmarkName = "@implementation MenuTableViewController"
51   - landmarkType = "3">
  50 + landmarkName = "-tableView:didSelectRowAtIndexPath:"
  51 + landmarkType = "5">
52 52 </BreakpointContent>
53 53 </BreakpointProxy>
54 54 <BreakpointProxy
... ... @@ -78,7 +78,9 @@
78 78 startingColumnNumber = "9223372036854775807"
79 79 endingColumnNumber = "9223372036854775807"
80 80 startingLineNumber = "337"
81   - endingLineNumber = "337">
  81 + endingLineNumber = "337"
  82 + landmarkName = "-readIncidentLog::"
  83 + landmarkType = "5">
82 84 </BreakpointContent>
83 85 </BreakpointProxy>
84 86 <BreakpointProxy
... ... @@ -92,7 +94,9 @@
92 94 startingColumnNumber = "9223372036854775807"
93 95 endingColumnNumber = "9223372036854775807"
94 96 startingLineNumber = "336"
95   - endingLineNumber = "336">
  97 + endingLineNumber = "336"
  98 + landmarkName = "-readIncidentLog::"
  99 + landmarkType = "5">
96 100 </BreakpointContent>
97 101 </BreakpointProxy>
98 102 <BreakpointProxy
... ... @@ -106,7 +110,9 @@
106 110 startingColumnNumber = "9223372036854775807"
107 111 endingColumnNumber = "9223372036854775807"
108 112 startingLineNumber = "349"
109   - endingLineNumber = "349">
  113 + endingLineNumber = "349"
  114 + landmarkName = "-readIncidentLog::"
  115 + landmarkType = "5">
110 116 </BreakpointContent>
111 117 </BreakpointProxy>
112 118 <BreakpointProxy
... ... @@ -281,7 +287,7 @@
281 287 endingColumnNumber = "9223372036854775807"
282 288 startingLineNumber = "723"
283 289 endingLineNumber = "723"
284   - landmarkName = "-tableView:indentationLevelForRowAtIndexPath:"
  290 + landmarkName = "-tableView:didSelectRowAtIndexPath:"
285 291 landmarkType = "5">
286 292 </BreakpointContent>
287 293 </BreakpointProxy>
... ... @@ -441,7 +447,7 @@
441 447 endingColumnNumber = "9223372036854775807"
442 448 startingLineNumber = "767"
443 449 endingLineNumber = "767"
444   - landmarkName = "-tableView:cellForRowAtIndexPath:"
  450 + landmarkName = "-tableView:indentationLevelForRowAtIndexPath:"
445 451 landmarkType = "5">
446 452 </BreakpointContent>
447 453 </BreakpointProxy>
... ... @@ -521,7 +527,7 @@
521 527 endingColumnNumber = "9223372036854775807"
522 528 startingLineNumber = "1237"
523 529 endingLineNumber = "1237"
524   - landmarkName = "-passDateRangeViewController:didFinishEnteringItem::"
  530 + landmarkName = "-passPriceViewController:didFinishEnteringItem:"
525 531 landmarkType = "5">
526 532 </BreakpointContent>
527 533 </BreakpointProxy>
... ... @@ -537,7 +543,7 @@
537 543 endingColumnNumber = "9223372036854775807"
538 544 startingLineNumber = "1222"
539 545 endingLineNumber = "1222"
540   - landmarkName = "-passNameViewController:didFinishEnteringItem:"
  546 + landmarkName = "-passPriceViewController:didFinishEnteringItem:"
541 547 landmarkType = "5">
542 548 </BreakpointContent>
543 549 </BreakpointProxy>
... ...
DUREX Vendor Control/Incident.h 0 → 100644
  1 +//
  2 +// Incident.h
  3 +// DUREX Vendor Control
  4 +//
  5 +// Created by Imanol Barba on 10/8/14.
  6 +// Copyright (c) 2014 Emmoco. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "CommunicationProtocol.h"
  11 +
  12 +@interface Incident : NSObject
  13 +
  14 +@property NSString *errorCode;
  15 +@property NSString *errorValue;
  16 +@property NSDate *incidentTime;
  17 +
  18 +@end
0 19 \ No newline at end of file
... ...
DUREX Vendor Control/Incident.m 0 → 100644
  1 +//
  2 +// Incident.m
  3 +// DUREX Vendor Control
  4 +//
  5 +// Created by Imanol Barba on 10/8/14.
  6 +// Copyright (c) 2014 Emmoco. All rights reserved.
  7 +//
  8 +
  9 +#import "Incident.h"
  10 +
  11 +@implementation Incident
  12 +
  13 +@end
0 14 \ No newline at end of file
... ...
DUREX Vendor Control/IncidentLog.h 0 → 100644
  1 +//
  2 +// IncidentLog.h
  3 +// DUREX Vendor Control
  4 +//
  5 +// Created by Imanol Barba on 10/8/14.
  6 +// Copyright (c) 2014 Emmoco. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "CommunicationProtocol.h"
  11 +#import "Incident.h"
  12 +
  13 +@interface IncidentLog : NSObject
  14 +
  15 +@property (strong,nonatomic) NSString *response;
  16 +@property (strong,nonatomic) NSMutableArray *incidents;
  17 +
  18 +- (id) init;
  19 +- (void) setResponseValue:(NSString *)response;
  20 +
  21 +@end
... ...
DUREX Vendor Control/IncidentLog.m 0 → 100644
  1 +//
  2 +// IncidentLog.m
  3 +// DUREX Vendor Control
  4 +//
  5 +// Created by Imanol Barba on 10/8/14.
  6 +// Copyright (c) 2014 Emmoco. All rights reserved.
  7 +//
  8 +
  9 +#import "IncidentLog.h"
  10 +
  11 +@implementation IncidentLog
  12 +
  13 +- (id) init
  14 +{
  15 + [self setIncidents:[[NSMutableArray alloc] init]];
  16 + return self;
  17 +}
  18 +
  19 +- (void) setResponseValue:(NSString *)response
  20 +{
  21 + [self setResponse: response];
  22 + [self parseResponse];
  23 +}
  24 +
  25 +- (void) parseResponse
  26 +{
  27 + NSInteger currentIncident = 0;
  28 + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
  29 + NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
  30 + NSDateComponents *incidentDate = [[NSDateComponents alloc] init];
  31 + NSInteger currentYear = [[calendar components:units fromDate:[NSDate date]] year];
  32 + currentYear = (currentYear/100)*100;
  33 + while(![[[self response] substringWithRange:NSMakeRange((currentIncident*INCIDENT_STRING_LENGTH), 4)] isEqualToString:@"P3P3"])
  34 + {
  35 + Incident *incident = [[Incident alloc] init];
  36 + [incidentDate setYear:(currentYear + [[[self response] substringWithRange:NSMakeRange(2 + currentIncident*SALE_STRING_LENGTH, 2)] intValue])];
  37 + [incidentDate setMonth:[[[self response] substringWithRange:NSMakeRange(4 + currentIncident*SALE_STRING_LENGTH, 2)] intValue]];
  38 + [incidentDate setDay:[[[self response] substringWithRange:NSMakeRange(6 + currentIncident*SALE_STRING_LENGTH, 2)] intValue]];
  39 + [incidentDate setHour:[[[self response] substringWithRange:NSMakeRange(8 + currentIncident*SALE_STRING_LENGTH, 2)] intValue]];
  40 + [incidentDate setMinute:[[[self response] substringWithRange:NSMakeRange(10 + currentIncident*SALE_STRING_LENGTH, 2)] intValue]];
  41 + [incidentDate setMinute:[[[self response] substringWithRange:NSMakeRange(12 + currentIncident*SALE_STRING_LENGTH, 2)] intValue]];
  42 + [incident setIncidentTime:[calendar dateFromComponents:incidentDate]];
  43 + NSLog(@"date: %@",[calendar dateFromComponents:incidentDate]);
  44 + [incident setErrorCode:[[self response] substringWithRange:NSMakeRange(14 + currentIncident*SALE_STRING_LENGTH, 2)]];
  45 + NSLog(@"errorCode: %@",[incident errorCode]);
  46 + [incident setErrorValue:[[self response] substringWithRange:NSMakeRange(16 + currentIncident*SALE_STRING_LENGTH, 4)]];
  47 + NSLog(@"errorValue: %@",[incident errorValue]);
  48 + [[self incidents] insertObject:incident atIndex:currentIncident];
  49 + currentIncident++;
  50 + }
  51 + NSLog(@"%@",[self incidents]);
  52 +}
  53 +
  54 +@end
  55 +
... ...
DUREX Vendor Control/MenuTableViewController.h
... ... @@ -16,6 +16,7 @@
16 16 #import "DateRangePickerViewController.h"
17 17 #import "Sensors.h"
18 18 #import "SalesLog.h"
  19 +#import "IncidentLog.h"
19 20 #import "UIView+Toast.h"
20 21  
21 22 #define num(x) [NSNumber numberWithUnsignedInt:x]
... ... @@ -41,6 +42,10 @@
41 42 #define SALE_CELLS_PER_SECTION num(5)
42 43 #define SALE_HEADERS nil
43 44  
  45 +#define INCIDENT_ELEMENTS @">[5000]Error Code",@"[5001]Error Value"
  46 +#define INCIDENT_CELLS_PER_SECTION num(2)
  47 +#define INCIDENT_HEADERS nil
  48 +
44 49 #define CONFIGURATION_ELEMENTS @"[4000]Update Date & Time",@"[4001]Update product price",@"[4002]Update product name"
45 50 #define CONFIGURATION_CELLS_PER_SECTION num(3)
46 51 #define CONFIGURATION_HEADERS nil
... ... @@ -52,6 +57,8 @@ enum {
52 57 MAINTENANCE,
53 58 SALE_LIST,
54 59 SALE,
  60 + INCIDENT_LIST,
  61 + INCIDENT,
55 62 BASIC_CONFIGURATION,
56 63 REPORT,
57 64 } navigationLevel;
... ... @@ -64,6 +71,8 @@ enum {
64 71 A5,
65 72 A6,
66 73 A7,
  74 + INVALID_COMMAND,
  75 + NONE,
67 76 } commandTypes;
68 77  
69 78 enum {
... ...
DUREX Vendor Control/MenuTableViewController.m
... ... @@ -31,6 +31,14 @@
31 31 @property (nonatomic,strong) const NSMutableArray *saleStructure;
32 32 @property (nonatomic,strong) const NSMutableArray *saleHeaders;
33 33  
  34 +@property (nonatomic,strong) const NSMutableArray *incidentListElements;
  35 +@property (nonatomic,strong) const NSMutableArray *incidentListStructure;
  36 +@property (nonatomic,strong) const NSMutableArray *incidentListHeaders;
  37 +
  38 +@property (nonatomic,strong) const NSMutableArray *incidentElements;
  39 +@property (nonatomic,strong) const NSMutableArray *incidentStructure;
  40 +@property (nonatomic,strong) const NSMutableArray *incidentHeaders;
  41 +
34 42 @property (nonatomic,strong) const NSMutableArray *configElements;
35 43 @property (nonatomic,strong) const NSMutableArray *configStructure;
36 44 @property (nonatomic,strong) const NSMutableArray *configHeaders;
... ... @@ -41,10 +49,13 @@
41 49 @property (nonatomic,strong) CommunicationProtocol* protocol;
42 50 @property (strong,nonatomic) NSString *machineMACAddr;
43 51 @property (strong,nonatomic) Stack *parentLayout;
  52 +@property (strong,nonatomic) NSTimer *timeoutTimer;
44 53  
45 54 @property (strong,nonatomic) Sensors *sensorStatus;
46 55 @property (strong,nonatomic) SalesLog *salesLog;
47 56 @property (strong,nonatomic) Sale *currentSale;
  57 +@property (strong,nonatomic) IncidentLog *incidentLog;
  58 +@property (strong,nonatomic) Incident *currentIncident;
48 59 @property uint8_t requestedLog;
49 60 @property uint8_t sentCommand;
50 61  
... ... @@ -137,6 +148,38 @@
137 148 return TRUE;
138 149 }
139 150  
  151 +- (void) generateIncidentListNavLevel
  152 +{
  153 + NSMutableArray *dateArray = [[NSMutableArray alloc] init];
  154 + for(int i = 0; i < [[[self incidentLog] incidents]count]; i++)
  155 + {
  156 + Incident *currentIncident = [[[self incidentLog] incidents]objectAtIndex:i];
  157 + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
  158 + NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
  159 + NSDateComponents *components = [calendar components:units fromDate:[currentIncident incidentTime]];
  160 + [dateArray insertObject:[NSString stringWithFormat:@"[%d%d%d%d%d]%02d/%02d/%d %02d:%02d",[components day],[components month],[components year],[components hour],[components minute],[components day],[components month],[components year],[components hour],[components minute]] atIndex:i];
  161 + }
  162 + [self setIncidentListElements:[[NSMutableArray alloc] initWithArray:dateArray]];
  163 + [self setIncidentListStructure:[[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:[dateArray count]], nil]];
  164 + [self setIncidentListHeaders:nil];
  165 +}
  166 +
  167 +- (Boolean) generateIncidentNavLevel : (NSInteger) numIncident
  168 +{
  169 + [self setIncidentElements:[[NSMutableArray alloc] initWithObjects:INCIDENT_ELEMENTS, nil]];
  170 + [self setIncidentStructure:[[NSMutableArray alloc] initWithObjects:INCIDENT_CELLS_PER_SECTION, nil]];
  171 + if([[self incidentStructure] count] > 1)
  172 + {
  173 + [self setIncidentHeaders:[[NSMutableArray alloc] initWithObjects:INCIDENT_HEADERS, nil]];
  174 + }
  175 + else
  176 + {
  177 + [self setIncidentHeaders:nil];
  178 + }
  179 + [self setCurrentIncident:[[[self incidentLog]incidents]objectAtIndex:numIncident]];
  180 + return TRUE;
  181 +}
  182 +
140 183 - (void) changeNavLevel: (uint8_t) level : (BOOL) push
141 184 {
142 185 NSLog(@"[MenuTableViewController.m]: navLevel is %d",level);
... ... @@ -178,6 +221,23 @@
178 221 [self setCurrentStructure:[self saleStructure]];
179 222 [self setCurrentHeaders:[self saleHeaders]];
180 223 }
  224 + else if([self currentNavLevel] == INCIDENT_LIST)
  225 + {
  226 + [[self navigationItem] setTitle:NSLocalizedString(@"Incident log", nil)];
  227 + [self setCurrentElements:[self incidentListElements]];
  228 + [self setCurrentStructure:[self incidentListStructure]];
  229 + [self setCurrentHeaders:[self incidentListHeaders]];
  230 + }
  231 + else if([self currentNavLevel] == INCIDENT)
  232 + {
  233 + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
  234 + NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
  235 + NSDateComponents *components = [calendar components:units fromDate:[[self currentIncident] incidentTime]];
  236 + [[self navigationItem] setTitle:[NSString stringWithFormat:@"%@ %02d/%02d/%d %02d:%02d",NSLocalizedString(@"Incident on", nil),[components day],[components month],[components year],[components hour],[components minute]]];
  237 + [self setCurrentElements:[self incidentElements]];
  238 + [self setCurrentStructure:[self incidentStructure]];
  239 + [self setCurrentHeaders:[self incidentHeaders]];
  240 + }
181 241 else if([self currentNavLevel] == BASIC_CONFIGURATION)
182 242 {
183 243 [[self navigationItem] setTitle:NSLocalizedString(@"Basic Configuration", nil)];
... ... @@ -263,6 +323,7 @@
263 323 - (void)processMessage:(CommunicationProtocol*)protocol didFinishEnteringItem:(NSString*) response
264 324 {
265 325 NSLog(@"[MenuTableViewController.m]: Answer received: %@",response);
  326 + [self.timeoutTimer invalidate];
266 327 if(self.sentCommand == HELLO)
267 328 {
268 329 if([response isEqualToString:@"Hello"])
... ... @@ -289,7 +350,11 @@
289 350 }
290 351 else if(self.sentCommand == A3 && [[response substringToIndex:2]isEqualToString:@"P3"])
291 352 {
292   -
  353 + NSLog(@"[MenuTableViewController.m]: Received A3 answer");
  354 + [self setIncidentLog:[[IncidentLog alloc]init]];
  355 + [[self incidentLog] setResponseValue:response];
  356 + [self generateIncidentListNavLevel];
  357 + [self changeNavLevel:INCIDENT_LIST:TRUE];
293 358 }
294 359 else if(self.sentCommand == A4 && [[response substringToIndex:2]isEqualToString:@"P4"])
295 360 {
... ... @@ -342,6 +407,29 @@
342 407 {
343 408 NSLog(@"[MenuTableViewController]: Unknown response received. Data discarded.");
344 409 }
  410 + [self setSentCommand:NONE];
  411 +}
  412 +
  413 +- (void) startTimeoutTimer
  414 +{
  415 + self.timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:10
  416 + target:self
  417 + selector:@selector(commandDidTimeout:)
  418 + userInfo:nil
  419 + repeats:NO];
  420 +}
  421 +
  422 +- (void) commandDidTimeout:(NSTimer *) timer
  423 +{
  424 + if(self.currentNavLevel == 255)
  425 + {
  426 + [self processMessage:nil didFinishEnteringItem:@"ERROR"];
  427 + }
  428 + else
  429 + {
  430 + [self setSentCommand:INVALID_COMMAND];
  431 + [self.view makeToast:NSLocalizedString(@"Device answer timeout occurred", nil) duration:3 position:[NSValue valueWithCGPoint:CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2)] title:NSLocalizedString(@"Error", nil) image:[UIImage imageNamed:@"icon_delete"]];
  432 + }
345 433 }
346 434  
347 435 - (void)viewDidLoad
... ... @@ -375,6 +463,7 @@
375 463 self.currentNavLevel = 255;
376 464 [_protocol establishConnection];
377 465 [self setSentCommand:HELLO];
  466 + [self startTimeoutTimer];
378 467 }
379 468  
380 469 -(void)didReceiveNotification:(NSNotification*) notification
... ... @@ -591,9 +680,13 @@
591 680 {
592 681 if([cellName isEqualToString:NSLocalizedString(@"Maintenance", nil)])
593 682 {
594   - NSLog(@"[MenuTableViewController.m]: Changing to navLevel: MAINTENANCE");
595   - [[self protocol] readSensorData];
596   - [self setSentCommand:A4];
  683 + if(self.sentCommand == NONE)
  684 + {
  685 + NSLog(@"[MenuTableViewController.m]: Changing to navLevel: MAINTENANCE");
  686 + [[self protocol] readSensorData];
  687 + [self setSentCommand:A4];
  688 + [self startTimeoutTimer];
  689 + }
597 690 }
598 691 else if([cellName isEqualToString:NSLocalizedString(@"Basic Configuration", nil)])
599 692 {
... ... @@ -602,7 +695,13 @@
602 695 }
603 696 else if([cellName isEqualToString:NSLocalizedString(@"Sending a Report", nil)])
604 697 {
605   -
  698 + //TEST TIMEOUT
  699 + if(self.sentCommand == NONE)
  700 + {
  701 + [_protocol writeMessage:@"A9"];
  702 + [self setSentCommand:INVALID_COMMAND];
  703 + [self startTimeoutTimer];
  704 + }
606 705 }
607 706 }
608 707 //Cells in MAINTENANCE
... ... @@ -620,20 +719,41 @@
620 719 }
621 720 else if([cellName isEqualToString:NSLocalizedString(@"Sales log", nil)])
622 721 {
623   - [self setRequestedLog:SALES_LOG];
624   - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  722 + if(self.sentCommand == NONE)
625 723 {
626   - self.dateRangePickerViewController = [[DateRangePickerViewController alloc] initWithNibName:@"DateRangePickerViewController_iPad" bundle:nil];
627   - self.dateRangePickerViewController.delegate = self;
628   - [self.dateRangePickerViewController showInView:self.navigationController.view animated:YES];
  724 + [self setRequestedLog:SALES_LOG];
  725 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  726 + {
  727 + self.dateRangePickerViewController = [[DateRangePickerViewController alloc] initWithNibName:@"DateRangePickerViewController_iPad" bundle:nil];
  728 + self.dateRangePickerViewController.delegate = self;
  729 + [self.dateRangePickerViewController showInView:self.navigationController.view animated:YES];
  730 + }
  731 + else
  732 + {
  733 + self.dateRangePickerViewController = [[DateRangePickerViewController alloc] initWithNibName:@"DateRangePickerViewController" bundle:nil];
  734 + self.dateRangePickerViewController.delegate = self;
  735 + [self.dateRangePickerViewController showInView:self.navigationController.view animated:YES];
  736 + }
629 737 }
630   - else
  738 + }
  739 + else if([cellName isEqualToString:NSLocalizedString(@"Incident log", nil)])
  740 + {
  741 + if(self.sentCommand == NONE)
631 742 {
632   - self.dateRangePickerViewController = [[DateRangePickerViewController alloc] initWithNibName:@"DateRangePickerViewController" bundle:nil];
633   - self.dateRangePickerViewController.delegate = self;
634   - [self.dateRangePickerViewController showInView:self.navigationController.view animated:YES];
  743 + [self setRequestedLog:INCIDENT_LOG];
  744 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  745 + {
  746 + self.dateRangePickerViewController = [[DateRangePickerViewController alloc] initWithNibName:@"DateRangePickerViewController_iPad" bundle:nil];
  747 + self.dateRangePickerViewController.delegate = self;
  748 + [self.dateRangePickerViewController showInView:self.navigationController.view animated:YES];
  749 + }
  750 + else
  751 + {
  752 + self.dateRangePickerViewController = [[DateRangePickerViewController alloc] initWithNibName:@"DateRangePickerViewController" bundle:nil];
  753 + self.dateRangePickerViewController.delegate = self;
  754 + [self.dateRangePickerViewController showInView:self.navigationController.view animated:YES];
  755 + }
635 756 }
636   -
637 757 }
638 758 else if([cellName isEqualToString:NSLocalizedString(@"Send report", nil)])
639 759 {
... ... @@ -650,49 +770,58 @@
650 770 //Update Date & Time command
651 771 if([cellName isEqualToString:NSLocalizedString(@"Update Date & Time", nil)])
652 772 {
653   - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  773 + if(self.sentCommand == NONE)
654 774 {
655   - self.datePickerViewController = [[DatePickerViewController alloc] initWithNibName:@"DatePickerViewController_iPad" bundle:nil];
656   - self.datePickerViewController.delegate = self;
657   - [self.datePickerViewController showInView:self.navigationController.view animated:YES];
658   - }
659   - else
660   - {
661   - self.datePickerViewController = [[DatePickerViewController alloc] initWithNibName:@"DatePickerViewController" bundle:nil];
662   - self.datePickerViewController.delegate = self;
663   - [self.datePickerViewController showInView:self.navigationController.view animated:YES];
  775 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  776 + {
  777 + self.datePickerViewController = [[DatePickerViewController alloc] initWithNibName:@"DatePickerViewController_iPad" bundle:nil];
  778 + self.datePickerViewController.delegate = self;
  779 + [self.datePickerViewController showInView:self.navigationController.view animated:YES];
  780 + }
  781 + else
  782 + {
  783 + self.datePickerViewController = [[DatePickerViewController alloc] initWithNibName:@"DatePickerViewController" bundle:nil];
  784 + self.datePickerViewController.delegate = self;
  785 + [self.datePickerViewController showInView:self.navigationController.view animated:YES];
  786 + }
664 787 }
665 788 }
666 789 //Update Product Price command
667 790 else if([cellName isEqualToString:NSLocalizedString(@"Update product price", nil)])
668 791 {
669   - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  792 + if(self.sentCommand == NONE)
670 793 {
671   - self.priceChangerViewController = [[PriceChangerViewController alloc] initWithNibName:@"PriceChangerViewController_iPad" bundle:nil];
672   - self.priceChangerViewController.delegate = self;
673   - [self.priceChangerViewController showInView:self.navigationController.view animated:YES];
674   - }
675   - else
676   - {
677   - self.priceChangerViewController = [[PriceChangerViewController alloc] initWithNibName:@"PriceChangerViewController" bundle:nil];
678   - self.priceChangerViewController.delegate = self;
679   - [self.priceChangerViewController showInView:self.navigationController.view animated:YES];
  794 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  795 + {
  796 + self.priceChangerViewController = [[PriceChangerViewController alloc] initWithNibName:@"PriceChangerViewController_iPad" bundle:nil];
  797 + self.priceChangerViewController.delegate = self;
  798 + [self.priceChangerViewController showInView:self.navigationController.view animated:YES];
  799 + }
  800 + else
  801 + {
  802 + self.priceChangerViewController = [[PriceChangerViewController alloc] initWithNibName:@"PriceChangerViewController" bundle:nil];
  803 + self.priceChangerViewController.delegate = self;
  804 + [self.priceChangerViewController showInView:self.navigationController.view animated:YES];
  805 + }
680 806 }
681 807 }
682 808 //Update Product Name command
683 809 else if([cellName isEqualToString:NSLocalizedString(@"Update product name", nil)])
684 810 {
685   - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
686   - {
687   - self.nameChangerViewController = [[NameChangerViewController alloc] initWithNibName:@"NameChangerViewController_iPad" bundle:nil];
688   - self.nameChangerViewController.delegate = self;
689   - [self.nameChangerViewController showInView:self.navigationController.view animated:YES];
690   - }
691   - else
  811 + if(self.sentCommand == NONE)
692 812 {
693   - self.nameChangerViewController = [[NameChangerViewController alloc] initWithNibName:@"NameChangerViewController" bundle:nil];
694   - self.nameChangerViewController.delegate = self;
695   - [self.nameChangerViewController showInView:self.navigationController.view animated:YES];
  813 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  814 + {
  815 + self.nameChangerViewController = [[NameChangerViewController alloc] initWithNibName:@"NameChangerViewController_iPad" bundle:nil];
  816 + self.nameChangerViewController.delegate = self;
  817 + [self.nameChangerViewController showInView:self.navigationController.view animated:YES];
  818 + }
  819 + else
  820 + {
  821 + self.nameChangerViewController = [[NameChangerViewController alloc] initWithNibName:@"NameChangerViewController" bundle:nil];
  822 + self.nameChangerViewController.delegate = self;
  823 + [self.nameChangerViewController showInView:self.navigationController.view animated:YES];
  824 + }
696 825 }
697 826 }
698 827 }
... ... @@ -712,6 +841,13 @@
712 841 }
713 842  
714 843 }
  844 + else if([self currentNavLevel] == INCIDENT_LIST)
  845 + {
  846 + if([self generateIncidentNavLevel: [indexPath row]])
  847 + {
  848 + [self changeNavLevel:INCIDENT:TRUE];
  849 + }
  850 + }
715 851 }
716 852  
717 853 #pragma mark - Table view data source
... ... @@ -1140,6 +1276,23 @@
1140 1276 }
1141 1277 }
1142 1278 }
  1279 + else if([self currentNavLevel] == INCIDENT)
  1280 + {
  1281 + [[[cell contentView] viewWithTag:CELL_CARAT_TAG] removeFromSuperview];
  1282 + [[cell detailTextLabel] setText:@""];
  1283 + [cell setAccessoryView:nil];
  1284 + [cell setAccessoryType:UITableViewCellAccessoryNone];
  1285 + if([[[cell textLabel] text] isEqualToString:NSLocalizedString(@"Error Code",nil)])
  1286 + {
  1287 + [[cell detailTextLabel] setText:[self.currentIncident errorCode]];
  1288 + [cell setAccessoryView:nil];
  1289 + }
  1290 + else if([[[cell textLabel] text] isEqualToString:NSLocalizedString(@"Error Value",nil)])
  1291 + {
  1292 + [[cell detailTextLabel] setText:[self.currentIncident errorCode]];
  1293 + [cell setAccessoryView:nil];
  1294 + }
  1295 + }
1143 1296 return cell;
1144 1297 }
1145 1298  
... ... @@ -1152,6 +1305,7 @@
1152 1305 NSLog(@"[MenuTableViewController.m]: %@", components);
1153 1306 [_protocol updateTime: components];
1154 1307 [self setSentCommand:A5];
  1308 + [self startTimeoutTimer];
1155 1309 }
1156 1310  
1157 1311 - (void)passPriceViewController:(PriceChangerViewController *)controller didFinishEnteringItem:(NSArray *)data
... ... @@ -1193,6 +1347,7 @@
1193 1347 NSArray *price = [priceString componentsSeparatedByString:@"."];
1194 1348 [_protocol updatePrice:channel :code :[[price objectAtIndex:0] intValue] :[[price objectAtIndex:1] intValue]];
1195 1349 [self setSentCommand:A6];
  1350 + [self startTimeoutTimer];
1196 1351 }
1197 1352 }
1198 1353  
... ... @@ -1229,6 +1384,7 @@
1229 1384 int code = [codeString intValue];
1230 1385 [_protocol updateProductName:channel :code :name];
1231 1386 [self setSentCommand:A7];
  1387 + [self startTimeoutTimer];
1232 1388 }
1233 1389 }
1234 1390  
... ... @@ -1252,10 +1408,28 @@
1252 1408 componentsTo = [calendar components:units fromDate:to];
1253 1409 }
1254 1410 [_protocol readSalesLog: componentsFrom : componentsTo];
  1411 + [self setSentCommand:A2];
  1412 + [self startTimeoutTimer];
1255 1413 }
1256 1414 else if([self requestedLog] == INCIDENT_LOG)
1257 1415 {
  1416 + NSLog(@"[MenuTableViewController.m]: Changing to navLevel: INCIDENT_LIST");
1258 1417  
  1418 + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
  1419 + NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
  1420 + NSDateComponents *componentsFrom = nil;
  1421 + NSDateComponents *componentsTo = nil;
  1422 + if(from != nil)
  1423 + {
  1424 + componentsFrom = [calendar components:units fromDate:from];
  1425 + }
  1426 + if(to != nil)
  1427 + {
  1428 + componentsTo = [calendar components:units fromDate:to];
  1429 + }
  1430 + [_protocol readIncidentLog: componentsFrom : componentsTo];
  1431 + [self setSentCommand:A3];
  1432 + [self startTimeoutTimer];
1259 1433 }
1260 1434 }
1261 1435  
... ...
DUREX Vendor Control/en.lproj/Localizable.strings
... ... @@ -101,4 +101,8 @@
101 101 "Product name change returned error" = "Product name change returned error";
102 102 "Error occurred while reading answer from device" = "Error occurred while reading answer from device";
103 103 "Error occurred while sending command to device" = "Error occurred while sending command to device";
104   -"Connection lost" = "Connection lost";
105 104 \ No newline at end of file
  105 +"Connection lost" = "Connection lost";
  106 +"Device answer timeout occurred" = "Device answer timeout occurred";
  107 +"Incident log" = "Incident log";
  108 +"Error Code" = "Error Code";
  109 +"Error Value" = "Error Value";
106 110 \ No newline at end of file
... ...
DUREX Vendor Control/es.lproj/Localizable.strings
... ... @@ -101,4 +101,8 @@
101 101 "Product name change returned error" = "Error al cambiar el nombre del producto";
102 102 "Error occurred while reading answer from device" = "Error al leer la respuesta del dispositivo";
103 103 "Error occurred while sending command to device" = "Error al mandar el comando al dispositivo";
104   -"Connection lost" = "Conexión perdida";
105 104 \ No newline at end of file
  105 +"Connection lost" = "Conexión perdida";
  106 +"Device answer timeout occurred" = "El tiempo de espera de respuesta del dispositivo ha expirado";
  107 +"Incident log" = "Registro de incidencias";
  108 +"Error Code" = "Código de error";
  109 +"Error Value" = "Valor del error";
106 110 \ No newline at end of file
... ...
1 1 TESTS:
2 2 - Multiple fragments
3   -
  3 +- Timeout
  4 +- A3 command
  5 +- A2 command
  6 +- Prevent multiple commands sending
  7 +
4 8 BUGS:
5 9 - On date change, response is overwritten by previous query, trimming needed according to numBytes
6 10  
7 11 TODO:
8   -- Incident class
9   -- Incident parser
10   -- A3 command
11 12 - Channels and codes to 2 ciphers
12 13 - Add landscape layout and inverted layout
13 14 - Month/Year headers on sale list
... ...