Skip to content

Commit 92121b0

Browse files
Enable Display and Input in Hex format for modbus Addresses (#14)
* Enable Display and Input in Hex format for modbus Addresses --------- Co-authored-by: volkmarnissen <[email protected]>
1 parent 69cf77f commit 92121b0

File tree

10 files changed

+218
-89
lines changed

10 files changed

+218
-89
lines changed

CHANGELOG.md

Lines changed: 44 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,92 @@
11
# Changelog for angular
22

3-
## [v0.12.22](https://github.com/modbus2mqtt/angular/tree/v0.12.22) (2025-09-03)
3+
## [v0.12.19](https://github.com/volkmarnissen/angular/tree/v0.12.19) (2025-01-16)
44

5-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.21...v0.12.22)
5+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.18...v0.12.19)
66

7-
## [v0.12.21](https://github.com/modbus2mqtt/angular/tree/v0.12.21) (2025-09-03)
7+
## [v0.12.18](https://github.com/volkmarnissen/angular/tree/v0.12.18) (2025-01-15)
88

9-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.20...v0.12.21)
9+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.17...v0.12.18)
1010

11-
**Merged pull requests:**
11+
## [v0.12.17](https://github.com/volkmarnissen/angular/tree/v0.12.17) (2025-01-02)
1212

13-
- \[Feature\] Add number of processed calls to Modbus Status [\#12](https://github.com/modbus2mqtt/angular/pull/12) ([volkmarnissen](https://github.com/volkmarnissen))
14-
- \[Feature\] Add number of processed calls to Modbus Status [\#11](https://github.com/modbus2mqtt/angular/pull/11) ([volkmarnissen](https://github.com/volkmarnissen))
15-
- Update Changelog [\#10](https://github.com/modbus2mqtt/angular/pull/10) ([volkmarnissen](https://github.com/volkmarnissen))
16-
- \[bug\]Modbus Error Handling, Slave Specification Detection, TCP RTU bridge, Fixes [\#9](https://github.com/modbus2mqtt/angular/pull/9) ([volkmarnissen](https://github.com/volkmarnissen))
17-
- \[bug\]Modbus Error Handling, Slave Specification Detection, TCP RTU bridge, Fixes [\#8](https://github.com/modbus2mqtt/angular/pull/8) ([volkmarnissen](https://github.com/volkmarnissen))
18-
- Angular TcpBridge Fix [\#7](https://github.com/modbus2mqtt/angular/pull/7) ([volkmarnissen](https://github.com/volkmarnissen))
19-
- \[bug\]Modbus Error Handling, Slave Specification Detection, TCP RTU bridge, Fixes [\#6](https://github.com/modbus2mqtt/angular/pull/6) ([volkmarnissen](https://github.com/volkmarnissen))
20-
- Modbus Error Handling and Monitoring [\#5](https://github.com/modbus2mqtt/angular/pull/5) ([volkmarnissen](https://github.com/volkmarnissen))
13+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.16...v0.12.17)
2114

22-
## [v0.12.20](https://github.com/modbus2mqtt/angular/tree/v0.12.20) (2025-04-14)
15+
## [v0.12.16](https://github.com/volkmarnissen/angular/tree/v0.12.16) (2024-12-31)
2316

24-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.19...v0.12.20)
17+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.15...v0.12.16)
2518

26-
**Merged pull requests:**
19+
## [v0.12.15](https://github.com/volkmarnissen/angular/tree/v0.12.15) (2024-12-30)
2720

28-
- Please update me [\#4](https://github.com/modbus2mqtt/angular/pull/4) ([volkmarnissen](https://github.com/volkmarnissen))
29-
- Fixed package-lock.json [\#3](https://github.com/modbus2mqtt/angular/pull/3) ([volkmarnissen](https://github.com/volkmarnissen))
30-
- Adding support for discrete inputs [\#2](https://github.com/modbus2mqtt/angular/pull/2) ([arturmietek](https://github.com/arturmietek))
21+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.14...v0.12.15)
3122

32-
## [v0.12.19](https://github.com/modbus2mqtt/angular/tree/v0.12.19) (2025-01-16)
23+
## [v0.12.14](https://github.com/volkmarnissen/angular/tree/v0.12.14) (2024-12-30)
3324

34-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.18...v0.12.19)
25+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/0.12.14...v0.12.14)
3526

36-
## [v0.12.18](https://github.com/modbus2mqtt/angular/tree/v0.12.18) (2025-01-15)
27+
## [0.12.14](https://github.com/volkmarnissen/angular/tree/0.12.14) (2024-12-13)
3728

38-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.17...v0.12.18)
29+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.13...0.12.14)
3930

40-
## [v0.12.17](https://github.com/modbus2mqtt/angular/tree/v0.12.17) (2025-01-02)
31+
## [v0.12.13](https://github.com/volkmarnissen/angular/tree/v0.12.13) (2024-12-13)
4132

42-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.16...v0.12.17)
33+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.12...v0.12.13)
4334

44-
**Merged pull requests:**
35+
## [v0.12.12](https://github.com/volkmarnissen/angular/tree/v0.12.12) (2024-12-11)
4536

46-
- Adding signed int 32 and unsigned int 32 options to number format [\#1](https://github.com/modbus2mqtt/angular/pull/1) ([arturmietek](https://github.com/arturmietek))
37+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.11...v0.12.12)
4738

48-
## [v0.12.16](https://github.com/modbus2mqtt/angular/tree/v0.12.16) (2024-12-31)
39+
## [v0.12.11](https://github.com/volkmarnissen/angular/tree/v0.12.11) (2024-11-22)
4940

50-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.15...v0.12.16)
41+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.10...v0.12.11)
5142

52-
## [v0.12.15](https://github.com/modbus2mqtt/angular/tree/v0.12.15) (2024-12-30)
43+
## [v0.12.10](https://github.com/volkmarnissen/angular/tree/v0.12.10) (2024-11-19)
5344

54-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.14...v0.12.15)
45+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.9...v0.12.10)
5546

56-
## [v0.12.14](https://github.com/modbus2mqtt/angular/tree/v0.12.14) (2024-12-30)
47+
## [v0.12.9](https://github.com/volkmarnissen/angular/tree/v0.12.9) (2024-11-16)
5748

58-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/0.12.14...v0.12.14)
49+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.8...v0.12.9)
5950

60-
## [0.12.14](https://github.com/modbus2mqtt/angular/tree/0.12.14) (2024-12-13)
51+
## [v0.12.8](https://github.com/volkmarnissen/angular/tree/v0.12.8) (2024-11-14)
6152

62-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.13...0.12.14)
53+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.7...v0.12.8)
6354

64-
## [v0.12.13](https://github.com/modbus2mqtt/angular/tree/v0.12.13) (2024-12-13)
55+
## [v0.12.7](https://github.com/volkmarnissen/angular/tree/v0.12.7) (2024-10-23)
6556

66-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.12...v0.12.13)
57+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.6...v0.12.7)
6758

68-
## [v0.12.12](https://github.com/modbus2mqtt/angular/tree/v0.12.12) (2024-12-11)
59+
## [v0.12.6](https://github.com/volkmarnissen/angular/tree/v0.12.6) (2024-10-16)
6960

70-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.11...v0.12.12)
61+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.5...v0.12.6)
7162

72-
## [v0.12.11](https://github.com/modbus2mqtt/angular/tree/v0.12.11) (2024-11-22)
63+
## [v0.12.5](https://github.com/volkmarnissen/angular/tree/v0.12.5) (2024-09-24)
7364

74-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.10...v0.12.11)
65+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.4...v0.12.5)
7566

76-
## [v0.12.10](https://github.com/modbus2mqtt/angular/tree/v0.12.10) (2024-11-19)
67+
## [v0.12.4](https://github.com/volkmarnissen/angular/tree/v0.12.4) (2024-09-16)
7768

78-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.9...v0.12.10)
69+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.3...v0.12.4)
7970

80-
## [v0.12.9](https://github.com/modbus2mqtt/angular/tree/v0.12.9) (2024-11-16)
71+
## [v0.12.3](https://github.com/volkmarnissen/angular/tree/v0.12.3) (2024-09-06)
8172

82-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.8...v0.12.9)
73+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.2...v0.12.3)
8374

84-
## [v0.12.8](https://github.com/modbus2mqtt/angular/tree/v0.12.8) (2024-11-14)
75+
## [v0.12.2](https://github.com/volkmarnissen/angular/tree/v0.12.2) (2024-08-27)
8576

86-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.7...v0.12.8)
77+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.12.0...v0.12.2)
8778

88-
## [v0.12.7](https://github.com/modbus2mqtt/angular/tree/v0.12.7) (2024-10-23)
79+
## [v0.12.0](https://github.com/volkmarnissen/angular/tree/v0.12.0) (2024-08-16)
8980

90-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.6...v0.12.7)
81+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.11.0...v0.12.0)
9182

92-
## [v0.12.6](https://github.com/modbus2mqtt/angular/tree/v0.12.6) (2024-10-16)
83+
## [v0.11.0](https://github.com/volkmarnissen/angular/tree/v0.11.0) (2024-08-05)
9384

94-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.5...v0.12.6)
85+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/v0.10.1...v0.11.0)
9586

96-
## [v0.12.5](https://github.com/modbus2mqtt/angular/tree/v0.12.5) (2024-09-24)
87+
## [v0.10.1](https://github.com/volkmarnissen/angular/tree/v0.10.1) (2024-08-05)
9788

98-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.4...v0.12.5)
99-
100-
## [v0.12.4](https://github.com/modbus2mqtt/angular/tree/v0.12.4) (2024-09-16)
101-
102-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.3...v0.12.4)
103-
104-
## [v0.12.3](https://github.com/modbus2mqtt/angular/tree/v0.12.3) (2024-09-06)
105-
106-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.2...v0.12.3)
107-
108-
## [v0.12.2](https://github.com/modbus2mqtt/angular/tree/v0.12.2) (2024-08-27)
109-
110-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.12.0...v0.12.2)
111-
112-
## [v0.12.0](https://github.com/modbus2mqtt/angular/tree/v0.12.0) (2024-08-16)
113-
114-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.11.0...v0.12.0)
115-
116-
## [v0.11.0](https://github.com/modbus2mqtt/angular/tree/v0.11.0) (2024-08-05)
117-
118-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/v0.10.1...v0.11.0)
119-
120-
## [v0.10.1](https://github.com/modbus2mqtt/angular/tree/v0.10.1) (2024-08-05)
121-
122-
[Full Changelog](https://github.com/modbus2mqtt/angular/compare/0b2169b1bceece9fa4c2c6940ef33dafe96ae43b...v0.10.1)
89+
[Full Changelog](https://github.com/volkmarnissen/angular/compare/0b2169b1bceece9fa4c2c6940ef33dafe96ae43b...v0.10.1)
12390

12491

12592

cypress/hexinputfield.cy.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
import { HexinputfieldComponent } from "angular/src/app/specification/hexinputfield/hexinputfield.test.component";
3+
4+
function mount(startValue:number, displayHex:boolean) {
5+
cy.mount(HexinputfieldComponent, {
6+
autoDetectChanges: true,
7+
componentProperties: {
8+
displayHex: displayHex,
9+
startValue: startValue,
10+
},
11+
});
12+
}
13+
const inputField='input[formControlName="testHex"]'
14+
describe("Hexinputfield Component tests", () => {
15+
it("Show decimal", () => {
16+
mount(0x1234,false);
17+
cy.get(inputField).should('have.value', '4660');;
18+
cy.get(inputField).clear().type('1234').should('have.value', '1234');
19+
cy.get(inputField).clear().type('0x1234').blur().should('have.value', '4660');
20+
});
21+
it("Show Hex", () => {
22+
mount(0x1234,true);
23+
cy.get(inputField).should('have.value', '0x1234');;
24+
cy.get(inputField).clear().type('4660').blur().should('have.value', '0x1234');;
25+
cy.get(inputField).clear().type('0x1234').blur().should('have.value', '0x1234');;
26+
});
27+
});

cypress/specification-entity.cy.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ImodbusEntityWithName } from "angular/src/app/services/specificationInt
22
import {
33
afterEachEntityHelper,
44
beforeEachHelper as beforeEachEntityHelper,
5+
mountEntityComponent,
56
setOnEntityNameOrVariableFieldsChangeFunc,
67
} from "./support/entityHelper";
78

@@ -64,3 +65,16 @@ describe("Entity Component tests", () => {
6465
// "not.be.null");
6566
});
6667
});
68+
describe("Test for Modbus Address", () => {
69+
beforeEach(()=>{mountEntityComponent(true)}); // mounts entity and opens all expansion panels
70+
afterEach(afterEachEntityHelper);
71+
it("Modbus address in hex", () => {
72+
const inputField='input[formControlName="modbusAddress"]'
73+
const matField='mat-form-field input[formControlName="modbusAddress"]'
74+
cy.get(inputField).should('have.value', '0x4');
75+
cy.get(inputField).clear().type('1234').blur().should('have.value', '0x4d2');
76+
cy.get(inputField).clear().type('0X12s32').blur().should('have.value', '0x1232');
77+
cy.get(inputField).clear().type('0xx7')
78+
cy.get(inputField).parent().get( "mat-error").should('contain', 'dec or hex')
79+
})
80+
});

cypress/support/entityHelper.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ let selectEntity: ImodbusEntity = {
8888
*
8989
* If other initial values are required, a new test file is required
9090
*/
91-
export function beforeEachHelper() {
91+
export function mountEntityComponent(displayHex:boolean) {
9292
cy.intercept("GET", "**/converters", {
9393
fixture: "converters.json",
9494
});
@@ -105,9 +105,15 @@ export function beforeEachHelper() {
105105
specificationMethods: specificationMethods,
106106
entity: selectEntity,
107107
disabled: false,
108+
displayHex:displayHex
108109
},
109110
});
110111
cy.openAllExpansionPanels();
112+
113+
}
114+
115+
export function beforeEachHelper() {
116+
mountEntityComponent(false);
111117
}
112118
/**
113119
* resets the function set by setOnEntityNameOrVariableFieldsChangeFunc

src/app/specification/entity/entity.component.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,21 @@
7878
<div class="flexrows">
7979
<mat-form-field class="width100pt smallfield">
8080
<mat-label>Modbus Addr.</mat-label>
81-
<input #entityModbusAddress matInput type="number" formControlName="modbusAddress"
82-
[errorStateMatcher]="errorStateMatcher" (change)="onModbusAddressChange()">
81+
<input #entityModbusAddress matInput hexFormater [displayHex] ="displayHex" type="text" formControlName="modbusAddress"
82+
matTooltip="Please enter decimal (0-65536) or hexadecimal (0x123a) number"
83+
[errorStateMatcher]="errorStateMatcher" (change)="onModbusAddressChange()"
84+
(keypress)="onModbusAddressKeyPress($event)" >
8385
<mat-error *ngIf="entityFormGroup.get('modbusAddress')!.hasError('required')">
8486
This field is required
8587
</mat-error>
8688
<mat-error
8789
*ngIf="entityFormGroup.get('modbusAddress')!.hasError('min')|| entityFormGroup.get('modbusAddress')!.hasError('max')">
8890
Range is 1-65536
8991
</mat-error>
92+
<mat-error
93+
*ngIf="entityFormGroup.get('modbusAddress')!.hasError('pattern')">
94+
dec or hex
95+
</mat-error>
9096
</mat-form-field>
9197
<mat-form-field class="smallfield">
9298
<mat-label>Register</mat-label>

src/app/specification/entity/entity.component.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
} from "@angular/core";
99

1010
import { ApiService } from "../../services/api-service";
11+
import {HexFormaterDirective, HexFormaterPipe} from '../hexinputfield/hexinputfield'
12+
1113
import {
1214
AbstractControl,
1315
FormBuilder,
@@ -104,6 +106,7 @@ const newEntity: ImodbusEntityWithName = {
104106
styleUrl: "./entity.component.css",
105107
standalone: true,
106108
imports: [
109+
HexFormaterDirective,
107110
MatCard,
108111
MatCardHeader,
109112
MatCardTitle,
@@ -170,6 +173,8 @@ export class EntityComponent
170173
backupEntity: ImodbusEntityWithName | null;
171174
@Input()
172175
disabled: boolean = true;
176+
@Input()
177+
displayHex: boolean = false;
173178
entityCategories: string[] = ["", "config", "diagnostic"];
174179

175180
mqttValues: HTMLElement;
@@ -229,6 +234,7 @@ export class EntityComponent
229234
Validators.required,
230235
Validators.min(0),
231236
Validators.max(65536),
237+
Validators.pattern("^0[xX][0-9a-fA-F]+$|^[0-9]+$")
232238
]),
233239
],
234240
registerType: [null as IRegisterType | null, Validators.required],
@@ -442,7 +448,7 @@ export class EntityComponent
442448
this.entityFormGroup.get("registerType")!.setValue( { registerType: entity.registerType, name: "unknown"});
443449
converterFormControl.setValue(entity.converter);
444450
modbusAddressFormControl.setValue(
445-
entity.modbusAddress != undefined ? entity.modbusAddress : null,
451+
entity.modbusAddress != undefined ? HexFormaterDirective.convertNumberToInput(entity.modbusAddress,this.displayHex) : null,
446452
);
447453

448454
if (
@@ -454,7 +460,7 @@ export class EntityComponent
454460
);
455461
modbusAddressFormControl.setValue(
456462
entity.modbusAddress && entity.modbusAddress != -1
457-
? entity.modbusAddress
463+
? HexFormaterDirective.convertNumberToInput(entity.modbusAddress,this.displayHex)!
458464
: null,
459465
);
460466
}
@@ -664,6 +670,10 @@ export class EntityComponent
664670
this.specificationMethods.copy2Translation(this.entity);
665671
}
666672
}
673+
onModbusAddressKeyPress(event:KeyboardEvent){
674+
const allowed="0123456789xXABCDEFabcdef"
675+
return allowed.indexOf( event.key) >=0
676+
}
667677
onModbusAddressChange() {
668678
if (!this.entity) return;
669679
this.specificationMethods.setEntitiesTouched();
@@ -676,10 +686,8 @@ export class EntityComponent
676686
(converterFormControl.value != null &&
677687
converterFormControl.value !== this.entity.converter)
678688
) {
679-
this.entity.modbusAddress =
680-
modbusAddressFormControl.value != null
681-
? modbusAddressFormControl.value
682-
: undefined;
689+
if(modbusAddressFormControl.value != null)
690+
this.entity.modbusAddress = HexFormaterDirective.convertHexInput(modbusAddressFormControl.value)!
683691
if (converterFormControl.value !== null) {
684692
this.entity.converter = converterFormControl.value as Converters;
685693
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Component, Input, OnInit, } from '@angular/core';
2+
import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
3+
import {HexFormaterDirective} from './hexinputfield'
4+
@Component({
5+
selector: 'app-hexinputfield',
6+
imports: [
7+
FormsModule,
8+
ReactiveFormsModule,
9+
HexFormaterDirective
10+
],
11+
template: `
12+
<div [formGroup]="formGroup">
13+
<input hexFormater [displayHex] ="displayHex" type="text" formControlName="testHex">
14+
</div>
15+
`,
16+
styles: ``
17+
})
18+
export class HexinputfieldComponent implements OnInit{
19+
@Input() startValue:number = 0x1234;
20+
@Input() displayHex:boolean = false;
21+
formGroup:FormGroup;
22+
constructor( private fb: FormBuilder){}
23+
ngOnInit(): void {
24+
this.formGroup = this.fb.group({
25+
testHex: [HexFormaterDirective.convertNumberToInput(this.startValue,this.displayHex) ],
26+
});
27+
}
28+
}

0 commit comments

Comments
 (0)