diff --git a/recipes-app/iot2050-conf-webui/files/src/components/ExtendedModules/SM1231_8AI/SM1231with8AIConf.js b/recipes-app/iot2050-conf-webui/files/src/components/ExtendedModules/SM1231_8AI/SM1231with8AIConf.js
new file mode 100644
index 000000000..1e909dd58
--- /dev/null
+++ b/recipes-app/iot2050-conf-webui/files/src/components/ExtendedModules/SM1231_8AI/SM1231with8AIConf.js
@@ -0,0 +1,315 @@
+/* eslint-disable react/prop-types */
+import * as React from 'react';
+import Stack from '@mui/material/Stack';
+import Paper from '@mui/material/Paper';
+import FormGroup from '@mui/material/FormGroup';
+import FormControl from '@mui/material/FormControl';
+import ModuleInfo from '@/components/ModuleInfo';
+import SelectionConfig from '@/components/ConfigEntry/SelectionConfig';
+import CheckConfig from '@/components/ConfigEntry/CheckConfig';
+import ConfigGroupLabel from '@/components/ConfigEntry/ConfigGroupLabel';
+import ConfTextConverter from '@/lib/smConfig/ConfTextConverter';
+import uiString from '@/lib/uiString/SM1231_8AI.json';
+import { range } from 'lodash';
+
+const yamlUIMapping = [
+ {
+ keys: [/ch[0-7]\.type/],
+ rules: [
+ {
+ scenario: 'all',
+ mapping: [
+ { ui: uiString.TYPE_1, yaml: 1 },
+ { ui: uiString.TYPE_3, yaml: 3 }
+ ]
+ }
+ ]
+ },
+ {
+ keys: [/ch[0-7]\.range/],
+ rules: [
+ {
+ scenario: 'all',
+ mapping: [
+ { ui: uiString.RANGE_2, yaml: 2 },
+ { ui: uiString.RANGE_3, yaml: 3 },
+ { ui: uiString.RANGE_7, yaml: 7 },
+ { ui: uiString.RANGE_8, yaml: 8 },
+ { ui: uiString.RANGE_9, yaml: 9 }
+ ]
+ }
+ ]
+ },
+ {
+ keys: [/integ_time/],
+ rules: [
+ {
+ scenario: 'all',
+ mapping: [
+ { ui: uiString.INT_TIME_0, yaml: 0 },
+ { ui: uiString.INT_TIME_1, yaml: 1 },
+ { ui: uiString.INT_TIME_2, yaml: 2 },
+ { ui: uiString.INT_TIME_3, yaml: 3 }
+ ]
+ }
+ ]
+ },
+ {
+ keys: [/ch[0-7]\.smooth/],
+ rules: [
+ {
+ scenario: 'all',
+ mapping: [
+ { ui: uiString.SMOOTH_0, yaml: 0 },
+ { ui: uiString.SMOOTH_1, yaml: 1 },
+ { ui: uiString.SMOOTH_2, yaml: 2 },
+ { ui: uiString.SMOOTH_3, yaml: 3 }
+ ]
+ }
+ ]
+ }
+];
+
+const converter = new ConfTextConverter(yamlUIMapping);
+
+const rangeSelectionOfCurrent = [
+ uiString.RANGE_2,
+ uiString.RANGE_3
+];
+
+const rangeSelectionOfVoltage = [
+ uiString.RANGE_7,
+ uiString.RANGE_8,
+ uiString.RANGE_9
+];
+
+const channelConfigDefault = {
+ type: {
+ label: uiString.LABEL_TYPE,
+ selection: [
+ uiString.TYPE_1,
+ uiString.TYPE_3
+ ],
+ value: uiString.TYPE_1
+ },
+ range: {
+ label: uiString.LABEL_RANGE_VOL,
+ selection: rangeSelectionOfVoltage,
+ value: uiString.RANGE_9
+ },
+ smooth: {
+ label: uiString.LABEL_SMOOTH,
+ selection: [
+ uiString.SMOOTH_0,
+ uiString.SMOOTH_1,
+ uiString.SMOOTH_2,
+ uiString.SMOOTH_3
+ ],
+ value: uiString.SMOOTH_1
+ },
+ open_wire_alarm: {
+ label: uiString.LABEL_OPEN_WIRE_ALARM,
+ value: false
+ },
+ overflow_alarm: {
+ label: uiString.LABEL_OVER_FLOW_ALARM,
+ value: true
+ },
+ underflow_alarm: {
+ label: uiString.LABEL_UNDER_FLOW_ALARM,
+ value: true
+ }
+};
+
+export const SM1231with8AIConfDefault = {
+ mlfb: '6ES7231-4HF32-0XB0',
+ power_alarm: {
+ label: uiString.LABEL_POWER_ALARM,
+ value: true
+ },
+ integ_time: {
+ label: uiString.LABEL_INT_TIME,
+ selection: [
+ uiString.INT_TIME_0,
+ uiString.INT_TIME_1,
+ uiString.INT_TIME_2,
+ uiString.INT_TIME_3
+ ],
+ value: uiString.INT_TIME_2
+ },
+ channels: [
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault)),
+ JSON.parse(JSON.stringify(channelConfigDefault))
+ ]
+};
+
+export function convertToUIFormat (config) {
+ const ret = JSON.parse(JSON.stringify(SM1231with8AIConfDefault));
+
+ ret.power_alarm.value = config.power_alarm;
+ ret.integ_time.value = converter.yamlToUi('integ_time', config.integ_time);
+
+ for (let i = 0; i < 8; i++) {
+ ret.channels[i].type.value = converter.yamlToUi(`ch${i}.type`, config[`ch${i}`].type);
+ ret.channels[i].range.value = converter.yamlToUi(`ch${i}.range`, config[`ch${i}`].range);
+ if (ret.channels[i].type.value === uiString.TYPE_1) {
+ ret.channels[i].range.selection = rangeSelectionOfVoltage;
+ ret.channels[i].range.label = uiString.LABEL_RANGE_VOL;
+ } else {
+ ret.channels[i].range.selection = rangeSelectionOfCurrent;
+ ret.channels[i].range.label = uiString.LABEL_RANGE_CUR;
+ }
+
+ ret.channels[i].smooth.value = converter.yamlToUi(`ch${i}.smooth`, config[`ch${i}`].smooth);
+ ret.channels[i].open_wire_alarm.value = config[`ch${i}`].open_wire_alarm;
+ ret.channels[i].overflow_alarm.value = config[`ch${i}`].overflow_alarm;
+ ret.channels[i].underflow_alarm.value = config[`ch${i}`].underflow_alarm;
+ }
+ return ret;
+};
+
+export function convertToDeviceFormat (config) {
+ const ret = {
+ description: uiString.DESC_MOD,
+ mlfb: config.mlfb,
+ power_alarm: config.power_alarm.value,
+ integ_time: converter.uiToYaml('integ_time', config.integ_time.value)
+ };
+ for (let i = 0; i < 8; i++) {
+ ret['ch' + i] = {
+ type: converter.uiToYaml(`ch${i}.type`, config.channels[i].type.value),
+ range: converter.uiToYaml(`ch${i}.range`, config.channels[i].range.value),
+ smooth: converter.uiToYaml(`ch${i}.smooth`, config.channels[i].smooth.value),
+ open_wire_alarm: config.channels[i].open_wire_alarm.value,
+ overflow_alarm: config.channels[i].overflow_alarm.value,
+ underflow_alarm: config.channels[i].underflow_alarm.value
+ };
+ }
+ return ret;
+};
+
+export default function SM1231with8AIConf ({ slotNum, configData, updateConfig }) {
+ const setChannelRange = (event) => {
+ const chIndex = parseInt(event.target.name.slice(-1), 10);
+ const newType = configData.channels[chIndex].type.value;
+ let newRangeSelection;
+ let newRangeLabel;
+ let newRange;
+
+ if (newType === uiString.TYPE_1) {
+ newRangeSelection = rangeSelectionOfVoltage;
+ newRangeLabel = uiString.LABEL_RANGE_VOL;
+ newRange = uiString.RANGE_9;
+ } else {
+ newRangeSelection = rangeSelectionOfCurrent;
+ newRangeLabel = uiString.LABEL_RANGE_CUR;
+ newRange = uiString.RANGE_2;
+ }
+
+ configData.channels[chIndex].range.selection = newRangeSelection;
+ configData.channels[chIndex].range.label = newRangeLabel;
+ configData.channels[chIndex].range.value = newRange;
+ /* Set the binding channel */
+ configData.channels[chIndex + 1].type.value = newType;
+ configData.channels[chIndex + 1].range.selection = newRangeSelection;
+ configData.channels[chIndex + 1].range.label = newRangeLabel;
+ configData.channels[chIndex + 1].range.value = newRange;
+ };
+
+ const updateSlotConfig = () => {
+ updateConfig(slotNum, configData);
+ };
+
+ return (
+
+
+
+
+
+
+
+ {range(0, 8).map((index) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))
+ }
+
+ );
+}
diff --git a/recipes-app/iot2050-conf-webui/files/src/components/SlotInfo.js b/recipes-app/iot2050-conf-webui/files/src/components/SlotInfo.js
index 2300c9ff8..d369ec86e 100644
--- a/recipes-app/iot2050-conf-webui/files/src/components/SlotInfo.js
+++ b/recipes-app/iot2050-conf-webui/files/src/components/SlotInfo.js
@@ -8,6 +8,7 @@ import Typography from '@mui/material/Typography';
import SM1223Conf, { SM1223ConfDefault } from '@/components/ExtendedModules/SM1223/SM1223Conf';
import SM1231_4RTDConf, { SM1231_4RTDConfDefault } from '@/components/ExtendedModules/SM1231_RTD/SM1231_4RTDConf';
import SM1231_8RTDConf, { SM1231_8RTDConfDefault } from '@/components/ExtendedModules/SM1231_RTD/SM1231_8RTDConf';
+import SM1231with8AIConf, { SM1231with8AIConfDefault } from '@/components/ExtendedModules/SM1231_8AI/SM1231with8AIConf';
function Mod ({ modType, slotNum, config, updateConfig }) {
switch (modType) {
@@ -29,6 +30,12 @@ function Mod ({ modType, slotNum, config, updateConfig }) {
configData={config}
updateConfig={updateConfig}
/>;
+ case '6ES7231-4HF32-0XB0':
+ return ;
default:
return No module in this slot!!!;
}
@@ -46,6 +53,9 @@ export default function SlotInfo ({ slotNum, configData, updateSlot }) {
case '6ES7231-5PF32-0XB0':
updateSlot(slotNum, JSON.parse(JSON.stringify(SM1231_8RTDConfDefault)));
break;
+ case '6ES7231-4HF32-0XB0':
+ updateSlot(slotNum, JSON.parse(JSON.stringify(SM1231with8AIConfDefault)));
+ break;
default:
updateSlot(slotNum, { mlfb: 'None' });
}
@@ -56,6 +66,7 @@ export default function SlotInfo ({ slotNum, configData, updateSlot }) {
'6ES7223-1QH32-0XB0', // SM1223
'6ES7231-5PD32-0XB0', // SM1231-4RTD
'6ES7231-5PF32-0XB0', // SM1231-8RTD
+ '6ES7231-4HF32-0XB0', // SM1231-8AI
];
return (
diff --git a/recipes-app/iot2050-conf-webui/files/src/lib/smConfig/smConfig.js b/recipes-app/iot2050-conf-webui/files/src/lib/smConfig/smConfig.js
index 8b18ff81e..3aa16279b 100644
--- a/recipes-app/iot2050-conf-webui/files/src/lib/smConfig/smConfig.js
+++ b/recipes-app/iot2050-conf-webui/files/src/lib/smConfig/smConfig.js
@@ -6,6 +6,10 @@ import {
convertToDeviceFormat as convertToDeviceFmtForSM1231RTD,
convertToUIFormat as convertToUIFmtForSM1231RTD
} from '@/components/ExtendedModules/SM1231_RTD/SM1231_RTDConf';
+import {
+ convertToDeviceFormat as convertToDeviceFmtForSM1231with8AI,
+ convertToUIFormat as convertToUIFmtForSM1231with8AI
+} from '@/components/ExtendedModules/SM1231_8AI/SM1231with8AIConf';
export function exportYamlConfig (configData) {
const yamlConfig = {};
@@ -20,6 +24,9 @@ export function exportYamlConfig (configData) {
case '6ES7231-5PF32-0XB0': // SM1231-8RTD
yamlConfig['slot' + slotIndex] = convertToDeviceFmtForSM1231RTD(confSlot);
break;
+ case '6ES7231-4HF32-0XB0': // SM1231-8AI
+ yamlConfig['slot' + slotIndex] = convertToDeviceFmtForSM1231with8AI(confSlot);
+ break;
case 'None':
default:
yamlConfig['slot' + slotIndex] = {
@@ -53,6 +60,9 @@ export function importYamlConfig (configData) {
case '6ES7231-5PF32-0XB0': // SM1231-8RTD
uiConfig.config[i - 1] = convertToUIFmtForSM1231RTD(configData['slot' + i]);
break;
+ case '6ES7231-4HF32-0XB0': // SM1231-8AI
+ uiConfig.config[i - 1] = convertToUIFmtForSM1231with8AI(configData['slot' + i]);
+ break;
case 'None':
default:
break;
diff --git a/recipes-app/iot2050-conf-webui/files/src/lib/uiString/SM1231_8AI.json b/recipes-app/iot2050-conf-webui/files/src/lib/uiString/SM1231_8AI.json
new file mode 100644
index 000000000..8827c4637
--- /dev/null
+++ b/recipes-app/iot2050-conf-webui/files/src/lib/uiString/SM1231_8AI.json
@@ -0,0 +1,27 @@
+{
+ "DESC_MOD": "Analog input module AI8 x 13 bits",
+ "LABEL_POWER_ALARM": "Enable module 24V DC power supply diagnostics",
+ "LABEL_TYPE": "Measurement type:",
+ "LABEL_RANGE_VOL": "Voltage range:",
+ "LABEL_RANGE_CUR": "Current range:",
+ "LABEL_INT_TIME": "Set integration time for noise reduction:",
+ "LABEL_SMOOTH": "Smoothing:",
+ "LABEL_OPEN_WIRE_ALARM": "Enable broken wire diagnostics",
+ "LABEL_OVER_FLOW_ALARM": "Enable overflow diagnostics",
+ "LABEL_UNDER_FLOW_ALARM": "Enable underflow diagnostics",
+ "TYPE_1": "Voltage",
+ "TYPE_3": "Current",
+ "RANGE_2": "0..20mA",
+ "RANGE_3": "4..20mA",
+ "RANGE_7": "+/-2.5V",
+ "RANGE_8": "+/-5V",
+ "RANGE_9": "+/-10V",
+ "INT_TIME_0": "400 Hz (2.5ms)",
+ "INT_TIME_1": "60 Hz (16.6ms)",
+ "INT_TIME_2": "50 Hz (20ms)",
+ "INT_TIME_3": "10 Hz (100ms)",
+ "SMOOTH_0": "None (1 cycle)",
+ "SMOOTH_1": "Weak (4 cycles)",
+ "SMOOTH_2": "Medium (16 cycles)",
+ "SMOOTH_3": "Strong (32 cycles)"
+}
\ No newline at end of file