add inductance and voltage

This commit is contained in:
Bane Stojkovic
2026-11-10 10:40:34 +01:00
parent b2f99c7022
commit 025fcab11b
20 changed files with 318 additions and 202 deletions
@@ -102,8 +102,8 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final String SNAP_TO_COMPONENTS = "Components";
public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
public static final String VALUE_NOTATION_DECIMAL = "Decimal (4.7K, 0.22uF)";
public static final String VALUE_NOTATION_RKM = "RKM (4K7, 0u22)";
public static final String VALUE_NOTATION_DECIMAL = "Decimal (4.7K, 0.22uF, 6.3V)";
public static final String VALUE_NOTATION_RKM = "RKM (4K7, 0u22, 6V3)";
public static final String VALUE_NOTATION_DEFAULT = VALUE_NOTATION_DECIMAL;
public static final String SHOW_NODE_NAME_TOOLTIPS_KEY = "showNodeNameTooltips";
@@ -41,13 +41,24 @@ public class Inductance extends AbstractMeasure<InductanceUnit> {
}
public static Inductance parseCapacitance(String value) {
value = value.replace("*", "");
for (InductanceUnit unit : InductanceUnit.values()) {
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
value = value.substring(0, value.length() - unit.toString().length()).trim();
return new Inductance(parse(value), unit);
}
ValueNotation.ParsedMeasure<InductanceUnit> parsed;
try {
parsed = ValueNotation.parse(value, InductanceUnit::fromSymbol);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Could not parse inductance: " + value, e);
}
throw new IllegalArgumentException("Could not parse inductance: " + value);
if (parsed.unit() == null) {
throw new IllegalArgumentException("Could not parse inductance: " + value);
}
return new Inductance(parsed.value(), parsed.unit());
}
@Override
public String toString() {
if (ValueNotation.getCurrent() == ValueNotation.RKM && value != null && unit != null
&& unit.getRkmSymbol() != null) {
return ValueNotation.formatRkm(value, unit.getRkmSymbol());
}
return super.toString();
}
}
@@ -23,14 +23,16 @@ package org.diylc.core.measures;
public enum InductanceUnit implements Unit {
pH(1, "pH"), nH(1e3, "nH"), uH(1e6, "uH"), mH(1e9, "mH"), H(1e12, "H");
pH(1, "pH", "p"), nH(1e3, "nH", "n"), uH(1e6, "uH", "u"), mH(1e9, "mH", "m"), H(1e12, "H", "H");
double factor;
String display;
String rkmSymbol;
private InductanceUnit(double factor, String display) {
private InductanceUnit(double factor, String display, String rkmSymbol) {
this.factor = factor;
this.display = display;
this.rkmSymbol = rkmSymbol;
}
@Override
@@ -38,8 +40,50 @@ public enum InductanceUnit implements Unit {
return factor;
}
public String getRkmSymbol() {
return rkmSymbol;
}
@Override
public String toString() {
return display;
}
/**
* Resolves the unit written after an inductance value, e.g. "uH", "u", "\u00B5H" or "H".
* Case does not matter when the trailing "H" is present. Without it, "M" is rejected so that it
* is never mistaken for mega. "R" is not accepted: inductor makers print 4R7 for 4.7uH, while
* in RKM it would mean 4.7H.
*
* @param symbol unit text with no surrounding whitespace
* @return the unit, or null when the text is not an inductance unit
*/
public static InductanceUnit fromSymbol(String symbol) {
if (symbol.equalsIgnoreCase("H")) {
return H;
}
String prefix = symbol;
if (symbol.length() == 2 && (symbol.endsWith("H") || symbol.endsWith("h"))) {
prefix = symbol.substring(0, 1).toLowerCase();
} else if (symbol.equals("M")) {
return null;
}
switch (prefix) {
case "p":
case "P":
return pH;
case "n":
case "N":
return nH;
case "u":
case "U":
case "\u00B5":
case "\u03BC":
return uH;
case "m":
return mH;
default:
return null;
}
}
}
@@ -29,9 +29,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Notation used to write resistance and capacitance values: plain decimal ("4.7K", "0.22uF") or
* RKM as defined by IEC 60062, where the unit symbol takes the place of the decimal point ("4K7",
* "0u22"). Parsing accepts both regardless of the selected notation.
* Notation used to write resistance, capacitance, inductance and voltage values: plain decimal
* ("4.7K", "0.22uF", "6.3V") or RKM, where the unit symbol takes the place of the decimal point
* ("4K7", "0u22", "6V3"). IEC 60062 defines it for resistance and capacitance; inductance and
* voltage follow common practice. Parsing accepts both regardless of the selected notation.
*
* @author Branislav Stojkovic
*/
@@ -41,14 +41,16 @@ public class Voltage extends AbstractMeasure<VoltageUnit> {
}
public static Voltage parseVoltage(String value) {
value = value.replace("*", "");
for (VoltageUnit unit : VoltageUnit.values()) {
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
value = value.substring(0, value.length() - unit.toString().length()).trim();
return new Voltage(parse(value), unit);
}
ValueNotation.ParsedMeasure<VoltageUnit> parsed;
try {
parsed = ValueNotation.parse(value, VoltageUnit::fromSymbol);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Could not parse voltage: " + value, e);
}
throw new IllegalArgumentException("Could not parse voltage: " + value);
if (parsed.unit() == null) {
throw new IllegalArgumentException("Could not parse voltage: " + value);
}
return new Voltage(parsed.value(), parsed.unit());
}
public Double getNormalizedValue() {
@@ -56,4 +58,13 @@ public class Voltage extends AbstractMeasure<VoltageUnit> {
return null;
return value * unit.getFactor();
}
@Override
public String toString() {
if (ValueNotation.getCurrent() == ValueNotation.RKM && value != null && unit != null
&& unit.getRkmSymbol() != null) {
return ValueNotation.formatRkm(value, unit.getRkmSymbol());
}
return super.toString();
}
}
@@ -23,14 +23,17 @@ package org.diylc.core.measures;
public enum VoltageUnit implements Unit {
MV(1e-3, "mV"), V(1, "V"), KV(1e3, "KV");
// only volts have an RKM form (6V3, 3V3); 1m5 or 1k5 would not say that the value is a voltage
MV(1e-3, "mV", null), V(1, "V", "V"), KV(1e3, "KV", null);
double factor;
String display;
String rkmSymbol;
private VoltageUnit(double factor, String display) {
private VoltageUnit(double factor, String display, String rkmSymbol) {
this.factor = factor;
this.display = display;
this.rkmSymbol = rkmSymbol;
}
@Override
@@ -38,8 +41,31 @@ public enum VoltageUnit implements Unit {
return factor;
}
public String getRkmSymbol() {
return rkmSymbol;
}
@Override
public String toString() {
return display;
}
/**
* Resolves the unit written after a voltage value: "V", "mV" or "kV", case-insensitive.
*
* @param symbol unit text with no surrounding whitespace
* @return the unit, or null when the text is not a voltage unit
*/
public static VoltageUnit fromSymbol(String symbol) {
switch (symbol.toLowerCase()) {
case "v":
return V;
case "mv":
return MV;
case "kv":
return KV;
default:
return null;
}
}
}
@@ -631,7 +631,7 @@
<changes>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added 'Value Notation' to the Config menu to show resistance and capacitance values in RKM notation, e.g. 4K7, 0R22, 2n2 or 0u22, instead of decimal; values can be typed in either notation, and typing the unit together with the value, e.g. 4K7 or 2.2nF, sets the unit at the same time</description>
<description>Added 'Value Notation' to the Config menu to show resistance, capacitance, inductance and voltage values in RKM notation, e.g. 4K7, 0R22, 2n2, 4u7 or 6V3, instead of decimal; values can be typed in either notation, and typing the unit together with the value, e.g. 4K7 or 2.2nF, sets the unit at the same time</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>BUG_FIX</changeType>
@@ -138,6 +138,62 @@ public class ValueNotationTest {
assertCapacitance(4.7, CapacitanceUnit.pF, "4p7");
}
@Test
public void rkmInductance() {
ValueNotation.setCurrent(ValueNotation.RKM);
assertEquals("4u7", new Inductance(4.7, InductanceUnit.uH).toString());
assertEquals("2n2", new Inductance(2.2, InductanceUnit.nH).toString());
assertEquals("10m", new Inductance(10d, InductanceUnit.mH).toString());
assertEquals("1H", new Inductance(1d, InductanceUnit.H).toString());
}
@Test
public void rkmVoltage() {
ValueNotation.setCurrent(ValueNotation.RKM);
assertEquals("6V3", new Voltage(6.3, VoltageUnit.V).toString());
assertEquals("3V3", new Voltage(3.3, VoltageUnit.V).toString());
assertEquals("400V", new Voltage(400d, VoltageUnit.V).toString());
assertEquals("500mV", new Voltage(500d, VoltageUnit.MV).toString());
assertEquals("1.5KV", new Voltage(1.5, VoltageUnit.KV).toString());
}
@Test
public void parsesInductance() {
assertInductance(4.7, InductanceUnit.uH, "4.7uH");
assertInductance(4.7, InductanceUnit.uH, "4u7");
assertInductance(4.7, InductanceUnit.uH, "4u7H");
assertInductance(4.7, InductanceUnit.uH, "4\u00B57");
assertInductance(2.2, InductanceUnit.nH, "2n2");
assertInductance(10, InductanceUnit.mH, "10mH");
assertInductance(10, InductanceUnit.mH, "10MH");
assertInductance(10, InductanceUnit.mH, "10m");
assertInductance(1, InductanceUnit.H, "1H");
assertInductance(100, InductanceUnit.pH, "100pH");
}
@Test
public void parsesVoltage() {
assertVoltage(6.3, VoltageUnit.V, "6.3V");
assertVoltage(6.3, VoltageUnit.V, "6V3");
assertVoltage(3.3, VoltageUnit.V, "3v3");
assertVoltage(0.8, VoltageUnit.V, "0V8");
assertVoltage(400, VoltageUnit.V, "400 V");
assertVoltage(500, VoltageUnit.MV, "500mV");
assertVoltage(1.5, VoltageUnit.KV, "1.5KV");
assertVoltage(1.5, VoltageUnit.KV, "1.5kV");
assertVoltage(1.5, VoltageUnit.KV, "1k5V");
}
@Test
public void rejectsInvalidInductanceAndVoltage() {
assertInductanceRejected("4R7");
assertInductanceRejected("4M7");
assertInductanceRejected("10");
assertVoltageRejected("4K7");
assertVoltageRejected("1k5");
assertVoltageRejected("16");
}
@Test
public void bareNumberHasNoUnit() {
ValueNotation.ParsedMeasure<ResistanceUnit> parsed =
@@ -172,6 +228,14 @@ public class ValueNotationTest {
Capacitance capacitance = new Capacitance(value, unit);
assertEquals(capacitance, Capacitance.parseCapacitance(capacitance.toString()));
}
for (InductanceUnit unit : InductanceUnit.values()) {
Inductance inductance = new Inductance(value, unit);
assertEquals(inductance, Inductance.parseCapacitance(inductance.toString()));
}
for (VoltageUnit unit : VoltageUnit.values()) {
Voltage voltage = new Voltage(value, unit);
assertEquals(voltage, Voltage.parseVoltage(voltage.toString()));
}
}
}
}
@@ -188,6 +252,36 @@ public class ValueNotationTest {
assertEquals(text, unit, parsed.getUnit());
}
private static void assertInductance(double value, InductanceUnit unit, String text) {
Inductance parsed = Inductance.parseCapacitance(text);
assertEquals(text, value, parsed.getValue(), DELTA);
assertEquals(text, unit, parsed.getUnit());
}
private static void assertVoltage(double value, VoltageUnit unit, String text) {
Voltage parsed = Voltage.parseVoltage(text);
assertEquals(text, value, parsed.getValue(), DELTA);
assertEquals(text, unit, parsed.getUnit());
}
private static void assertInductanceRejected(String text) {
try {
Inductance.parseCapacitance(text);
fail("Expected " + text + " to be rejected");
} catch (IllegalArgumentException e) {
// expected
}
}
private static void assertVoltageRejected(String text) {
try {
Voltage.parseVoltage(text);
fail("Expected " + text + " to be rejected");
} catch (IllegalArgumentException e) {
// expected
}
}
private static void assertRejected(String text, Class<?> unitType) {
try {
if (unitType == ResistanceUnit.class) {