mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
Merge pull request #1381 from MichaelDvP/dev2
Dev2: relais, fix exhausttemp, fix RC20 remote
This commit is contained in:
@@ -29,7 +29,7 @@
|
|||||||
"@types/imagemin": "^8.0.3",
|
"@types/imagemin": "^8.0.3",
|
||||||
"@types/lodash-es": "^4.17.10",
|
"@types/lodash-es": "^4.17.10",
|
||||||
"@types/node": "^20.8.10",
|
"@types/node": "^20.8.10",
|
||||||
"@types/react": "^18.2.33",
|
"@types/react": "^18.2.34",
|
||||||
"@types/react-dom": "^18.2.14",
|
"@types/react-dom": "^18.2.14",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"alova": "^2.13.1",
|
"alova": "^2.13.1",
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"eslint-import-resolver-typescript": "^3.6.1",
|
"eslint-import-resolver-typescript": "^3.6.1",
|
||||||
"eslint-plugin-autofix": "^1.1.0",
|
"eslint-plugin-autofix": "^1.1.0",
|
||||||
"eslint-plugin-import": "^2.29.0",
|
"eslint-plugin-import": "^2.29.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||||
"eslint-plugin-prettier": "alpha",
|
"eslint-plugin-prettier": "alpha",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const de: Translation = {
|
|||||||
WRITEABLE: 'Schreibbar',
|
WRITEABLE: 'Schreibbar',
|
||||||
SHOWING: 'Anzeigen von',
|
SHOWING: 'Anzeigen von',
|
||||||
SEARCH: 'Suche',
|
SEARCH: 'Suche',
|
||||||
CERT: 'TLS Zertifikat (Freilassen um TLS zu deaktivieren)'
|
CERT: 'TLS Zertifikat (Freilassen um TLS zu deaktivieren)',
|
||||||
|
ON: 'An',
|
||||||
|
OFF: 'Aus',
|
||||||
|
POLARITY: 'Polarität',
|
||||||
|
ACTIVEHIGH: 'Aktiv Positiv',
|
||||||
|
ACTIVELOW: 'Aktiv Negativ',
|
||||||
|
UNCHANGED: 'Unverändert',
|
||||||
|
ALWAYS: 'Immer'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default de;
|
export default de;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const en: Translation = {
|
|||||||
WRITEABLE: 'Writeable',
|
WRITEABLE: 'Writeable',
|
||||||
SHOWING: 'Showing',
|
SHOWING: 'Showing',
|
||||||
SEARCH: 'Search',
|
SEARCH: 'Search',
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)'
|
CERT: 'TLS root certificate (leave blank to disable TLS)',
|
||||||
|
ON: 'On',
|
||||||
|
OFF: 'Off',
|
||||||
|
POLARITY: 'Polarity',
|
||||||
|
ACTIVEHIGH: 'Active High',
|
||||||
|
ACTIVELOW: 'Active Low',
|
||||||
|
UNCHANGED: 'Unchanged',
|
||||||
|
ALWAYS: 'Always'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const fr: Translation = {
|
|||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Writeable', // TODO translate
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Showing', // TODO translate
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Search', // TODO translate
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)' // TODO translate
|
CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default fr;
|
export default fr;
|
||||||
|
|||||||
@@ -325,7 +325,14 @@ const it: Translation = {
|
|||||||
WRITEABLE: 'Scrivibile',
|
WRITEABLE: 'Scrivibile',
|
||||||
SHOWING: 'Visualizza',
|
SHOWING: 'Visualizza',
|
||||||
SEARCH: 'Ricerca',
|
SEARCH: 'Ricerca',
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)' // TODO translate
|
CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default it;
|
export default it;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const nl: Translation = {
|
|||||||
WRITEABLE: 'Beschrijfbare',
|
WRITEABLE: 'Beschrijfbare',
|
||||||
SHOWING: 'Tonen',
|
SHOWING: 'Tonen',
|
||||||
SEARCH: 'Zoek',
|
SEARCH: 'Zoek',
|
||||||
CERT: 'TLS rootcertificaat (laat leeg om TLS uit te schakelen)'
|
CERT: 'TLS rootcertificaat (laat leeg om TLS uit te schakelen)',
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nl;
|
export default nl;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const no: Translation = {
|
|||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Writeable', // TODO translate
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Showing', // TODO translate
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Search', // TODO translate
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)' // TODO translate
|
CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default no;
|
export default no;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const pl: BaseTranslation = {
|
|||||||
WRITEABLE: 'zapisywalna',
|
WRITEABLE: 'zapisywalna',
|
||||||
SHOWING: 'Wyświetlane',
|
SHOWING: 'Wyświetlane',
|
||||||
SEARCH: 'Szukaj',
|
SEARCH: 'Szukaj',
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)' // TODO translate
|
CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default pl;
|
export default pl;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const sv: Translation = {
|
|||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Writeable', // TODO translate
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Showing', // TODO translate
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Search', // TODO translate
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)' // TODO translate
|
CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sv;
|
export default sv;
|
||||||
|
|||||||
@@ -323,7 +323,14 @@ const tr: Translation = {
|
|||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Writeable', // TODO translate
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Showing', // TODO translate
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Search', // TODO translate
|
||||||
CERT: 'TLS root certificate (leave blank to disable TLS)' // TODO translate
|
CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate
|
||||||
|
ON: 'On', // TODO translate
|
||||||
|
OFF: 'Off', // TODO translate
|
||||||
|
POLARITY: 'Polarity', // TODO translate
|
||||||
|
ACTIVEHIGH: 'Active High', // TODO translate
|
||||||
|
ACTIVELOW: 'Active Low', // TODO translate
|
||||||
|
UNCHANGED: 'Unchanged', // TODO translate
|
||||||
|
ALWAYS: 'Always' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default tr;
|
export default tr;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import DashboardSensorsAnalogDialog from './DashboardSensorsAnalogDialog';
|
|||||||
import DashboardSensorsTemperatureDialog from './DashboardSensorsTemperatureDialog';
|
import DashboardSensorsTemperatureDialog from './DashboardSensorsTemperatureDialog';
|
||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
|
|
||||||
import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames } from './types';
|
import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames, AnalogType } from './types';
|
||||||
import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators';
|
import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators';
|
||||||
import type { TemperatureSensor, AnalogSensor } from './types';
|
import type { TemperatureSensor, AnalogSensor } from './types';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
@@ -38,7 +38,8 @@ const DashboardSensors: FC = () => {
|
|||||||
initialData: {
|
initialData: {
|
||||||
ts: [],
|
ts: [],
|
||||||
as: [],
|
as: [],
|
||||||
analog_enabled: false
|
analog_enabled: false,
|
||||||
|
platform: 'ESP32'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -391,7 +392,11 @@ const DashboardSensors: FC = () => {
|
|||||||
<Cell stiff>{a.g}</Cell>
|
<Cell stiff>{a.g}</Cell>
|
||||||
<Cell>{a.n}</Cell>
|
<Cell>{a.n}</Cell>
|
||||||
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
|
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
|
||||||
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
{a.t === AnalogType.DIGITAL_OUT || a.t === AnalogType.DIGITAL_IN ? (
|
||||||
|
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
|
||||||
|
) : (
|
||||||
|
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
||||||
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
))}
|
))}
|
||||||
</Body>
|
</Body>
|
||||||
@@ -402,18 +407,22 @@ const DashboardSensors: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContent title={LL.SENSOR_DATA()} titleGutter>
|
<SectionContent title={LL.SENSOR_DATA()} titleGutter>
|
||||||
<Typography sx={{ pt: 2, pb: 1 }} variant="h6" color="secondary">
|
{sensorData.ts.length > 0 && (
|
||||||
{LL.TEMP_SENSORS()}
|
<>
|
||||||
</Typography>
|
<Typography sx={{ pt: 2, pb: 1 }} variant="h6" color="secondary">
|
||||||
<RenderTemperatureSensors />
|
{LL.TEMP_SENSORS()}
|
||||||
{selectedTemperatureSensor && (
|
</Typography>
|
||||||
<DashboardSensorsTemperatureDialog
|
<RenderTemperatureSensors />
|
||||||
open={temperatureDialogOpen}
|
{selectedTemperatureSensor && (
|
||||||
onClose={onTemperatureDialogClose}
|
<DashboardSensorsTemperatureDialog
|
||||||
onSave={onTemperatureDialogSave}
|
open={temperatureDialogOpen}
|
||||||
selectedItem={selectedTemperatureSensor}
|
onClose={onTemperatureDialogClose}
|
||||||
validator={temperatureSensorItemValidation()}
|
onSave={onTemperatureDialogSave}
|
||||||
/>
|
selectedItem={selectedTemperatureSensor}
|
||||||
|
validator={temperatureSensorItemValidation()}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{sensorData?.analog_enabled === true && (
|
{sensorData?.analog_enabled === true && (
|
||||||
@@ -429,7 +438,7 @@ const DashboardSensors: FC = () => {
|
|||||||
onSave={onAnalogDialogSave}
|
onSave={onAnalogDialogSave}
|
||||||
creating={creating}
|
creating={creating}
|
||||||
selectedItem={selectedAnalogSensor}
|
selectedItem={selectedAnalogSensor}
|
||||||
validator={analogSensorItemValidation(sensorData.as, creating)}
|
validator={analogSensorItemValidation(sensorData.as, creating, sensorData.platform)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@@ -442,14 +451,16 @@ const DashboardSensors: FC = () => {
|
|||||||
{LL.REFRESH()}
|
{LL.REFRESH()}
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
<Button
|
{sensorData?.analog_enabled === true && (
|
||||||
variant="outlined"
|
<Button
|
||||||
color="primary"
|
variant="outlined"
|
||||||
startIcon={<AddCircleOutlineOutlinedIcon />}
|
color="primary"
|
||||||
onClick={addAnalogSensor}
|
startIcon={<AddCircleOutlineOutlinedIcon />}
|
||||||
>
|
onClick={addAnalogSensor}
|
||||||
{LL.ADD(0) + ' ' + LL.ANALOG_SENSOR(1)}
|
>
|
||||||
</Button>
|
{LL.ADD(0) + ' ' + LL.ANALOG_SENSOR(1)}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</ButtonRow>
|
</ButtonRow>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ const DashboardSensorsAnalogDialog = ({
|
|||||||
fieldErrors={fieldErrors}
|
fieldErrors={fieldErrors}
|
||||||
name="g"
|
name="g"
|
||||||
label="GPIO"
|
label="GPIO"
|
||||||
disabled={!creating}
|
|
||||||
value={numberValue(editItem.g)}
|
value={numberValue(editItem.g)}
|
||||||
type="number"
|
type="number"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@@ -124,66 +123,66 @@ const DashboardSensorsAnalogDialog = ({
|
|||||||
</TextField>
|
</TextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
|
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
|
||||||
<>
|
<Grid item xs={4}>
|
||||||
<Grid item xs={4}>
|
<TextField name="u" label={LL.UNIT()} value={editItem.u} fullWidth select onChange={updateFormValue}>
|
||||||
<TextField name="u" label={LL.UNIT()} value={editItem.u} fullWidth select onChange={updateFormValue}>
|
{DeviceValueUOM_s.map((val, i) => (
|
||||||
{DeviceValueUOM_s.map((val, i) => (
|
<MenuItem key={i} value={i}>
|
||||||
<MenuItem key={i} value={i}>
|
{val}
|
||||||
{val}
|
</MenuItem>
|
||||||
</MenuItem>
|
))}
|
||||||
))}
|
</TextField>
|
||||||
</TextField>
|
</Grid>
|
||||||
</Grid>
|
)}
|
||||||
{editItem.t === AnalogType.ADC && (
|
{editItem.t === AnalogType.ADC && (
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<TextField
|
<TextField
|
||||||
name="o"
|
name="o"
|
||||||
label={LL.OFFSET()}
|
label={LL.OFFSET()}
|
||||||
value={numberValue(editItem.o)}
|
value={numberValue(editItem.o)}
|
||||||
fullWidth
|
fullWidth
|
||||||
type="number"
|
type="number"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
inputProps={{ min: '0', max: '3300', step: '1' }}
|
inputProps={{ min: '0', max: '3300', step: '1' }}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: <InputAdornment position="start">mV</InputAdornment>
|
startAdornment: <InputAdornment position="start">mV</InputAdornment>
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
{editItem.t === AnalogType.COUNTER && (
|
{editItem.t === AnalogType.COUNTER && (
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<TextField
|
<TextField
|
||||||
name="o"
|
name="o"
|
||||||
label={LL.STARTVALUE()}
|
label={LL.STARTVALUE()}
|
||||||
value={numberValue(editItem.o)}
|
value={numberValue(editItem.o)}
|
||||||
fullWidth
|
fullWidth
|
||||||
type="number"
|
type="number"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
inputProps={{ step: '0.001' }}
|
inputProps={{ step: '0.001' }}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
<Grid item xs={4}>
|
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
|
||||||
<TextField
|
<Grid item xs={4}>
|
||||||
name="f"
|
<TextField
|
||||||
label={LL.FACTOR()}
|
name="f"
|
||||||
value={numberValue(editItem.f)}
|
label={LL.FACTOR()}
|
||||||
fullWidth
|
value={numberValue(editItem.f)}
|
||||||
type="number"
|
fullWidth
|
||||||
variant="outlined"
|
type="number"
|
||||||
onChange={updateFormValue}
|
variant="outlined"
|
||||||
inputProps={{ step: '0.001' }}
|
onChange={updateFormValue}
|
||||||
/>
|
inputProps={{ step: '0.001' }}
|
||||||
</Grid>
|
/>
|
||||||
</>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
{editItem.t === AnalogType.DIGITAL_OUT && (editItem.g === 25 || editItem.g === 26) && (
|
{editItem.t === AnalogType.DIGITAL_OUT && (editItem.g === 25 || editItem.g === 26) && (
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<TextField
|
<TextField
|
||||||
name="o"
|
name="o"
|
||||||
label={LL.VALUE(1)}
|
label={LL.VALUE(0)}
|
||||||
value={numberValue(editItem.o)}
|
value={numberValue(editItem.o)}
|
||||||
fullWidth
|
fullWidth
|
||||||
type="number"
|
type="number"
|
||||||
@@ -194,20 +193,55 @@ const DashboardSensorsAnalogDialog = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
{editItem.t === AnalogType.DIGITAL_OUT && editItem.g !== 25 && editItem.g !== 26 && (
|
{editItem.t === AnalogType.DIGITAL_OUT && editItem.g !== 25 && editItem.g !== 26 && (
|
||||||
<Grid item xs={4}>
|
<>
|
||||||
<TextField
|
<Grid item xs={4}>
|
||||||
name="o"
|
<TextField
|
||||||
label={LL.VALUE(1)}
|
name="o"
|
||||||
value={numberValue(editItem.o)}
|
label={LL.VALUE(0)}
|
||||||
fullWidth
|
value={numberValue(editItem.o)}
|
||||||
type="number"
|
fullWidth
|
||||||
variant="outlined"
|
select
|
||||||
onChange={updateFormValue}
|
variant="outlined"
|
||||||
inputProps={{ min: '0', max: '1', step: '1' }}
|
onChange={updateFormValue}
|
||||||
/>
|
>
|
||||||
</Grid>
|
<MenuItem value={0}>{LL.OFF()}</MenuItem>
|
||||||
|
<MenuItem value={1}>{LL.ON()}</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<TextField
|
||||||
|
name="f"
|
||||||
|
label={LL.POLARITY()}
|
||||||
|
value={editItem.f}
|
||||||
|
fullWidth
|
||||||
|
select
|
||||||
|
onChange={updateFormValue}
|
||||||
|
>
|
||||||
|
<MenuItem value={1}>{LL.ACTIVEHIGH()}</MenuItem>
|
||||||
|
<MenuItem value={-1}>{LL.ACTIVELOW()}</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<TextField
|
||||||
|
name="u"
|
||||||
|
label={LL.STARTVALUE()}
|
||||||
|
value={editItem.u}
|
||||||
|
fullWidth
|
||||||
|
select
|
||||||
|
onChange={updateFormValue}
|
||||||
|
>
|
||||||
|
<MenuItem value={0}>{LL.UNCHANGED()}</MenuItem>
|
||||||
|
<MenuItem value={1}>
|
||||||
|
{LL.ALWAYS()} {LL.OFF()}
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem value={2}>
|
||||||
|
{LL.ALWAYS()} {LL.ON()}
|
||||||
|
</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{editItem.t >= AnalogType.PWM_0 && (
|
{(editItem.t === AnalogType.PWM_0 || editItem.t === AnalogType.PWM_1 || editItem.t === AnalogType.PWM_2) && (
|
||||||
<>
|
<>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<TextField
|
<TextField
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ export interface SensorData {
|
|||||||
ts: TemperatureSensor[];
|
ts: TemperatureSensor[];
|
||||||
as: AnalogSensor[];
|
as: AnalogSensor[];
|
||||||
analog_enabled: boolean;
|
analog_enabled: boolean;
|
||||||
|
platform: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CoreData {
|
export interface CoreData {
|
||||||
|
|||||||
@@ -188,12 +188,12 @@ export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const analogSensorItemValidation = (sensors: AnalogSensor[], creating: boolean) =>
|
export const analogSensorItemValidation = (sensors: AnalogSensor[], creating: boolean, platform: string) =>
|
||||||
new Schema({
|
new Schema({
|
||||||
n: [{ required: true, message: 'Name is required' }],
|
n: [{ required: true, message: 'Name is required' }],
|
||||||
g: [
|
g: [
|
||||||
{ required: true, message: 'GPIO is required' },
|
{ required: true, message: 'GPIO is required' },
|
||||||
GPIO_VALIDATOR,
|
platform === 'ESP32-S3' ? GPIO_VALIDATORS3 : platform === 'ESP32-C3' ? GPIO_VALIDATORC3 : GPIO_VALIDATOR,
|
||||||
...(creating ? [isGPIOUniqueValidator(sensors)] : [])
|
...(creating ? [isGPIOUniqueValidator(sensors)] : [])
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7":
|
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7":
|
||||||
version: 7.23.2
|
version: 7.23.2
|
||||||
resolution: "@babel/runtime@npm:7.23.2"
|
resolution: "@babel/runtime@npm:7.23.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1359,7 +1359,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/react@npm:*, @types/react@npm:^18.2.33":
|
"@types/react@npm:*":
|
||||||
version: 18.2.33
|
version: 18.2.33
|
||||||
resolution: "@types/react@npm:18.2.33"
|
resolution: "@types/react@npm:18.2.33"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1370,6 +1370,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/react@npm:^18.2.34":
|
||||||
|
version: 18.2.34
|
||||||
|
resolution: "@types/react@npm:18.2.34"
|
||||||
|
dependencies:
|
||||||
|
"@types/prop-types": "npm:*"
|
||||||
|
"@types/scheduler": "npm:*"
|
||||||
|
csstype: "npm:^3.0.2"
|
||||||
|
checksum: 6d16f86b384e829edc3710b1dd9ec4eb1d6b26bc079c5cf605bd0cbf77ae6224f15c76949afadb7f53df4544cfe4025c1111fbe36732cd7f660a320fbc2e5866
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/responselike@npm:^1.0.0":
|
"@types/responselike@npm:^1.0.0":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "@types/responselike@npm:1.0.2"
|
resolution: "@types/responselike@npm:1.0.2"
|
||||||
@@ -1547,7 +1558,7 @@ __metadata:
|
|||||||
"@types/imagemin": "npm:^8.0.3"
|
"@types/imagemin": "npm:^8.0.3"
|
||||||
"@types/lodash-es": "npm:^4.17.10"
|
"@types/lodash-es": "npm:^4.17.10"
|
||||||
"@types/node": "npm:^20.8.10"
|
"@types/node": "npm:^20.8.10"
|
||||||
"@types/react": "npm:^18.2.33"
|
"@types/react": "npm:^18.2.34"
|
||||||
"@types/react-dom": "npm:^18.2.14"
|
"@types/react-dom": "npm:^18.2.14"
|
||||||
"@types/react-router-dom": "npm:^5.3.3"
|
"@types/react-router-dom": "npm:^5.3.3"
|
||||||
"@typescript-eslint/eslint-plugin": "npm:^6.9.1"
|
"@typescript-eslint/eslint-plugin": "npm:^6.9.1"
|
||||||
@@ -1562,7 +1573,7 @@ __metadata:
|
|||||||
eslint-import-resolver-typescript: "npm:^3.6.1"
|
eslint-import-resolver-typescript: "npm:^3.6.1"
|
||||||
eslint-plugin-autofix: "npm:^1.1.0"
|
eslint-plugin-autofix: "npm:^1.1.0"
|
||||||
eslint-plugin-import: "npm:^2.29.0"
|
eslint-plugin-import: "npm:^2.29.0"
|
||||||
eslint-plugin-jsx-a11y: "npm:^6.7.1"
|
eslint-plugin-jsx-a11y: "npm:^6.8.0"
|
||||||
eslint-plugin-prettier: "npm:alpha"
|
eslint-plugin-prettier: "npm:alpha"
|
||||||
eslint-plugin-react: "npm:^7.33.2"
|
eslint-plugin-react: "npm:^7.33.2"
|
||||||
eslint-plugin-react-hooks: "npm:^4.6.0"
|
eslint-plugin-react-hooks: "npm:^4.6.0"
|
||||||
@@ -1754,7 +1765,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"aria-query@npm:^5.1.3":
|
"aria-query@npm:^5.3.0":
|
||||||
version: 5.3.0
|
version: 5.3.0
|
||||||
resolution: "aria-query@npm:5.3.0"
|
resolution: "aria-query@npm:5.3.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1865,10 +1876,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ast-types-flow@npm:^0.0.7":
|
"ast-types-flow@npm:^0.0.8":
|
||||||
version: 0.0.7
|
version: 0.0.8
|
||||||
resolution: "ast-types-flow@npm:0.0.7"
|
resolution: "ast-types-flow@npm:0.0.8"
|
||||||
checksum: 663b90e99b56ee2d7f736a6b6fff8b3c5404f28fa1860bb8d83ee5a9bff9e687520d0d6d9db6edff5a34fd4d3c0c11a3beb1cf75e43c9a880cca04371cc99808
|
checksum: 85a1c24af4707871c27cfe456bd2ff7fcbe678f3d1c878ac968c9557735a171a17bdcc8c8f903ceab3fc3c49d5b3da2194e6ab0a6be7fec0e133fa028f21ba1b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1902,14 +1913,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"axe-core@npm:^4.6.2":
|
"axe-core@npm:=4.7.0":
|
||||||
version: 4.8.2
|
version: 4.7.0
|
||||||
resolution: "axe-core@npm:4.8.2"
|
resolution: "axe-core@npm:4.7.0"
|
||||||
checksum: 3e8dbf264a57767713daa77fe04bbabd71a956b08b99c2eb0ec61b75852f21190653f557d2da623dea9e0a7555460deaac71d9f6a9125c0b52576f8581bfbe52
|
checksum: 615c0f7722c3c9fcf353dbd70b00e2ceae234d4c17cbc839dd85c01d16797c4e4da45f8d27c6118e9e6b033fb06efd196106e13651a1b2f3a10e0f11c7b2f660
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"axobject-query@npm:^3.1.1":
|
"axobject-query@npm:^3.2.1":
|
||||||
version: 3.2.1
|
version: 3.2.1
|
||||||
resolution: "axobject-query@npm:3.2.1"
|
resolution: "axobject-query@npm:3.2.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3034,7 +3045,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"es-iterator-helpers@npm:^1.0.12":
|
"es-iterator-helpers@npm:^1.0.12, es-iterator-helpers@npm:^1.0.15":
|
||||||
version: 1.0.15
|
version: 1.0.15
|
||||||
resolution: "es-iterator-helpers@npm:1.0.15"
|
resolution: "es-iterator-helpers@npm:1.0.15"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3539,29 +3550,29 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"eslint-plugin-jsx-a11y@npm:^6.7.1":
|
"eslint-plugin-jsx-a11y@npm:^6.8.0":
|
||||||
version: 6.7.1
|
version: 6.8.0
|
||||||
resolution: "eslint-plugin-jsx-a11y@npm:6.7.1"
|
resolution: "eslint-plugin-jsx-a11y@npm:6.8.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": "npm:^7.20.7"
|
"@babel/runtime": "npm:^7.23.2"
|
||||||
aria-query: "npm:^5.1.3"
|
aria-query: "npm:^5.3.0"
|
||||||
array-includes: "npm:^3.1.6"
|
array-includes: "npm:^3.1.7"
|
||||||
array.prototype.flatmap: "npm:^1.3.1"
|
array.prototype.flatmap: "npm:^1.3.2"
|
||||||
ast-types-flow: "npm:^0.0.7"
|
ast-types-flow: "npm:^0.0.8"
|
||||||
axe-core: "npm:^4.6.2"
|
axe-core: "npm:=4.7.0"
|
||||||
axobject-query: "npm:^3.1.1"
|
axobject-query: "npm:^3.2.1"
|
||||||
damerau-levenshtein: "npm:^1.0.8"
|
damerau-levenshtein: "npm:^1.0.8"
|
||||||
emoji-regex: "npm:^9.2.2"
|
emoji-regex: "npm:^9.2.2"
|
||||||
has: "npm:^1.0.3"
|
es-iterator-helpers: "npm:^1.0.15"
|
||||||
jsx-ast-utils: "npm:^3.3.3"
|
hasown: "npm:^2.0.0"
|
||||||
language-tags: "npm:=1.0.5"
|
jsx-ast-utils: "npm:^3.3.5"
|
||||||
|
language-tags: "npm:^1.0.9"
|
||||||
minimatch: "npm:^3.1.2"
|
minimatch: "npm:^3.1.2"
|
||||||
object.entries: "npm:^1.1.6"
|
object.entries: "npm:^1.1.7"
|
||||||
object.fromentries: "npm:^2.0.6"
|
object.fromentries: "npm:^2.0.7"
|
||||||
semver: "npm:^6.3.0"
|
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
|
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
|
||||||
checksum: b7eb451304dc27c9552649a716be1de3b5d577f39e53f6da6a2dac084b84b349b0224be3020439f99c2b3bf417a13c5591326f1ce6af8d74f1cb5d5d95c4222b
|
checksum: 7a8e4498531a43d988ce2f12502a3f5ce96eacfec13f956cf927f24bb041b724fb7fc0f0306ea19d143bfc79e138bf25e25acca0822847206ac6bf5ce095e846
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -4625,13 +4636,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"has@npm:^1.0.3":
|
|
||||||
version: 1.0.4
|
|
||||||
resolution: "has@npm:1.0.4"
|
|
||||||
checksum: c245f332fe78c7b6b8753857240ac12b3286f995f656a33c77e0f5baab7d0157e6ddb1c34940ffd2bffc51f75ede50cd8b29ff65c13e336376aca8cf3df58043
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"hasown@npm:^2.0.0":
|
"hasown@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "hasown@npm:2.0.0"
|
resolution: "hasown@npm:2.0.0"
|
||||||
@@ -5493,7 +5497,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.3":
|
"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5":
|
||||||
version: 3.3.5
|
version: 3.3.5
|
||||||
resolution: "jsx-ast-utils@npm:3.3.5"
|
resolution: "jsx-ast-utils@npm:3.3.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5544,19 +5548,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"language-subtag-registry@npm:~0.3.2":
|
"language-subtag-registry@npm:^0.3.20":
|
||||||
version: 0.3.22
|
version: 0.3.22
|
||||||
resolution: "language-subtag-registry@npm:0.3.22"
|
resolution: "language-subtag-registry@npm:0.3.22"
|
||||||
checksum: 5591f4abd775d1ab5945355a5ba894327d2d94c900607bdb69aac1bc5bb921dbeeeb5f616df95e8c0ae875501d19c1cfa0e852ece822121e95048deb34f2b4d2
|
checksum: 5591f4abd775d1ab5945355a5ba894327d2d94c900607bdb69aac1bc5bb921dbeeeb5f616df95e8c0ae875501d19c1cfa0e852ece822121e95048deb34f2b4d2
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"language-tags@npm:=1.0.5":
|
"language-tags@npm:^1.0.9":
|
||||||
version: 1.0.5
|
version: 1.0.9
|
||||||
resolution: "language-tags@npm:1.0.5"
|
resolution: "language-tags@npm:1.0.9"
|
||||||
dependencies:
|
dependencies:
|
||||||
language-subtag-registry: "npm:~0.3.2"
|
language-subtag-registry: "npm:^0.3.20"
|
||||||
checksum: 2161292ddae73ff2f5a15fd2d753b21096b81324337dff4ad78d702c63210d5beb18892cd53a3455ee6e88065807c8e285e82c40503678951d2071d101a473b4
|
checksum: d3a7c14b694e67f519153d6df6cb200681648d38d623c3bfa9d6a66a5ec5493628acb88e9df5aceef3cf1902ab263a205e7d59ee4cf1d6bb67e707b83538bd6d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -6196,7 +6200,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"object.entries@npm:^1.1.5, object.entries@npm:^1.1.6":
|
"object.entries@npm:^1.1.5, object.entries@npm:^1.1.6, object.entries@npm:^1.1.7":
|
||||||
version: 1.1.7
|
version: 1.1.7
|
||||||
resolution: "object.entries@npm:1.1.7"
|
resolution: "object.entries@npm:1.1.7"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -14,12 +14,8 @@ using espMqttClientTypes::DisconnectReason;
|
|||||||
using espMqttClientTypes::Error;
|
using espMqttClientTypes::Error;
|
||||||
|
|
||||||
MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint8_t priority, uint8_t core)
|
MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint8_t priority, uint8_t core)
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
: _useInternalTask(useInternalTask)
|
: _useInternalTask(useInternalTask)
|
||||||
, _transport(nullptr)
|
, _transport(nullptr)
|
||||||
#else
|
|
||||||
: _transport(nullptr)
|
|
||||||
#endif
|
|
||||||
, _onConnectCallback(nullptr)
|
, _onConnectCallback(nullptr)
|
||||||
, _onDisconnectCallback(nullptr)
|
, _onDisconnectCallback(nullptr)
|
||||||
, _onSubscribeCallback(nullptr)
|
, _onSubscribeCallback(nullptr)
|
||||||
@@ -153,8 +149,8 @@ uint16_t MqttClient::publish(const char * topic, uint8_t qos, bool retain, const
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
|
||||||
EMC_SEMAPHORE_TAKE();
|
EMC_SEMAPHORE_TAKE();
|
||||||
|
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
||||||
if (!_addPacket(packetId, topic, payload, length, qos, retain)) {
|
if (!_addPacket(packetId, topic, payload, length, qos, retain)) {
|
||||||
emc_log_e("Could not create PUBLISH packet");
|
emc_log_e("Could not create PUBLISH packet");
|
||||||
_onError(packetId, Error::OUT_OF_MEMORY);
|
_onError(packetId, Error::OUT_OF_MEMORY);
|
||||||
@@ -177,8 +173,8 @@ uint16_t MqttClient::publish(const char * topic, uint8_t qos, bool retain, espMq
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
|
||||||
EMC_SEMAPHORE_TAKE();
|
EMC_SEMAPHORE_TAKE();
|
||||||
|
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
||||||
if (!_addPacket(packetId, topic, callback, length, qos, retain)) {
|
if (!_addPacket(packetId, topic, callback, length, qos, retain)) {
|
||||||
emc_log_e("Could not create PUBLISH packet");
|
emc_log_e("Could not create PUBLISH packet");
|
||||||
_onError(packetId, Error::OUT_OF_MEMORY);
|
_onError(packetId, Error::OUT_OF_MEMORY);
|
||||||
@@ -320,12 +316,9 @@ void MqttClient::_loop(MqttClient * c) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t MqttClient::_getNextPacketId() {
|
uint16_t MqttClient::_getNextPacketId() {
|
||||||
uint16_t packetId = 0;
|
++_packetId;
|
||||||
EMC_SEMAPHORE_TAKE();
|
if (_packetId == 0) ++_packetId;
|
||||||
// cppcheck-suppress knownConditionTrueFalse
|
return _packetId;
|
||||||
packetId = (++_packetId == 0) ? ++_packetId : _packetId;
|
|
||||||
EMC_SEMAPHORE_GIVE();
|
|
||||||
return packetId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttClient::_checkOutbox() {
|
void MqttClient::_checkOutbox() {
|
||||||
@@ -340,10 +333,9 @@ int MqttClient::_sendPacket() {
|
|||||||
EMC_SEMAPHORE_TAKE();
|
EMC_SEMAPHORE_TAKE();
|
||||||
OutgoingPacket * packet = _outbox.getCurrent();
|
OutgoingPacket * packet = _outbox.getCurrent();
|
||||||
|
|
||||||
size_t wantToWrite = 0;
|
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
if (packet && (wantToWrite == written)) {
|
if (packet) {
|
||||||
wantToWrite = packet->packet.available(_bytesSent);
|
size_t wantToWrite = packet->packet.available(_bytesSent);
|
||||||
if (wantToWrite == 0) {
|
if (wantToWrite == 0) {
|
||||||
EMC_SEMAPHORE_GIVE();
|
EMC_SEMAPHORE_GIVE();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ bool ClientPosix::connect(IPAddress ip, uint16_t port) {
|
|||||||
_host.sin_addr.s_addr = htonl(uint32_t(ip));
|
_host.sin_addr.s_addr = htonl(uint32_t(ip));
|
||||||
_host.sin_port = htons(port); // modified by proddy for EMS-ESP compiling standalone
|
_host.sin_port = htons(port); // modified by proddy for EMS-ESP compiling standalone
|
||||||
|
|
||||||
int ret = ::connect(_sockfd, (struct sockaddr *)&_host, sizeof(_host));
|
int ret = ::connect(_sockfd, reinterpret_cast<sockaddr*>(&_host), sizeof(_host));
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
emc_log_e("Error connecting: %d - (%d) %s", ret, errno, strerror(errno));
|
emc_log_e("Error connecting: %d - (%d) %s", ret, errno, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class ClientPosix : public Transport {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _sockfd;
|
int _sockfd;
|
||||||
struct sockaddr_in _host;
|
sockaddr_in _host;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace espMqttClientInternals
|
} // namespace espMqttClientInternals
|
||||||
|
|||||||
@@ -127,7 +127,9 @@ extends = espressi32_base_tasmota
|
|||||||
board = lolin_c3_mini
|
board = lolin_c3_mini
|
||||||
board_upload.flash_size = 4MB
|
board_upload.flash_size = 4MB
|
||||||
board_build.partitions = esp32_partition_4M.csv
|
board_build.partitions = esp32_partition_4M.csv
|
||||||
build_flags = ${common.build_flags}
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
-DEMSESP_DEFAULT_BOARD_PROFILE = "C3MINI"
|
||||||
|
|
||||||
; lolin C3 mini v1 needs special wifi init.
|
; lolin C3 mini v1 needs special wifi init.
|
||||||
; https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
|
; https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
|
||||||
@@ -139,13 +141,16 @@ board_build.partitions = esp32_partition_4M.csv
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
-DBOARD_C3_MINI_V1
|
-DBOARD_C3_MINI_V1
|
||||||
|
-DEMSESP_DEFAULT_BOARD_PROFILE = "C3MINI"
|
||||||
|
|
||||||
[env:lolin_s2_mini]
|
[env:lolin_s2_mini]
|
||||||
extends = espressi32_base_tasmota
|
extends = espressi32_base_tasmota
|
||||||
board = lolin_s2_mini
|
board = lolin_s2_mini
|
||||||
board_upload.flash_size = 4MB
|
board_upload.flash_size = 4MB
|
||||||
board_build.partitions = esp32_partition_4M.csv
|
board_build.partitions = esp32_partition_4M.csv
|
||||||
build_flags = ${common.build_flags}
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
-DEMSESP_DEFAULT_BOARD_PROFILE = "S2MINI"
|
||||||
|
|
||||||
[env:lolin_s3]
|
[env:lolin_s3]
|
||||||
extends = espressi32_base
|
extends = espressi32_base
|
||||||
@@ -158,6 +163,7 @@ board_upload.wait_for_upload_port = false
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
-O2
|
-O2
|
||||||
|
-DEMSESP_DEFAULT_BOARD_PROFILE = "S32S3"
|
||||||
|
|
||||||
; to build and run: pio run -e standalone -t exec
|
; to build and run: pio run -e standalone -t exec
|
||||||
[env:standalone]
|
[env:standalone]
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ void AnalogSensor::start() {
|
|||||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
||||||
FL_(commands_cmd));
|
FL_(commands_cmd));
|
||||||
|
|
||||||
Mqtt::subscribe(EMSdevice::DeviceType::ANALOGSENSOR, "analogsensor/#", nullptr); // use empty function callback
|
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
|
snprintf(topic, sizeof(topic), "%s/#", F_(analogsensor));
|
||||||
|
Mqtt::subscribe(EMSdevice::DeviceType::ANALOGSENSOR, topic, nullptr); // use empty function callback
|
||||||
}
|
}
|
||||||
|
|
||||||
// load settings from the customization file, sorts them and initializes the GPIOs
|
// load settings from the customization file, sorts them and initializes the GPIOs
|
||||||
@@ -142,12 +144,12 @@ void AnalogSensor::reload() {
|
|||||||
for (auto & sensor : sensors_) {
|
for (auto & sensor : sensors_) {
|
||||||
sensor.ha_registered = false; // force HA configs to be re-created
|
sensor.ha_registered = false; // force HA configs to be re-created
|
||||||
if (sensor.type() == AnalogType::ADC) {
|
if (sensor.type() == AnalogType::ADC) {
|
||||||
LOG_DEBUG("Adding analog ADC sensor on GPIO %02d", sensor.gpio());
|
LOG_DEBUG("ADC Sensor on GPIO %02d", sensor.gpio());
|
||||||
// analogSetPinAttenuation does not work with analogReadMilliVolts
|
// analogSetPinAttenuation does not work with analogReadMilliVolts
|
||||||
sensor.analog_ = 0; // initialize
|
sensor.analog_ = 0; // initialize
|
||||||
sensor.last_reading_ = 0;
|
sensor.last_reading_ = 0;
|
||||||
} else if (sensor.type() == AnalogType::COUNTER) {
|
} else if (sensor.type() == AnalogType::COUNTER) {
|
||||||
LOG_DEBUG("Adding analog I/O Counter sensor on GPIO %02d", sensor.gpio());
|
LOG_DEBUG("I/O Counter on GPIO %02d", sensor.gpio());
|
||||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
||||||
@@ -165,7 +167,7 @@ void AnalogSensor::reload() {
|
|||||||
}
|
}
|
||||||
publish_sensor(sensor);
|
publish_sensor(sensor);
|
||||||
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
|
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
|
||||||
LOG_DEBUG("Adding analog Timer/Rate sensor on GPIO %02d", sensor.gpio());
|
LOG_DEBUG("Timer/Rate on GPIO %02d", sensor.gpio());
|
||||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||||
sensor.polltime_ = uuid::get_uptime();
|
sensor.polltime_ = uuid::get_uptime();
|
||||||
sensor.last_polltime_ = uuid::get_uptime();
|
sensor.last_polltime_ = uuid::get_uptime();
|
||||||
@@ -174,7 +176,7 @@ void AnalogSensor::reload() {
|
|||||||
sensor.set_value(0);
|
sensor.set_value(0);
|
||||||
publish_sensor(sensor);
|
publish_sensor(sensor);
|
||||||
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
|
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
|
||||||
LOG_DEBUG("Adding analog Read sensor on GPIO %02d", sensor.gpio());
|
LOG_DEBUG("Digital Read on GPIO %02d", sensor.gpio());
|
||||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||||
sensor.set_value(digitalRead(sensor.gpio())); // initial value
|
sensor.set_value(digitalRead(sensor.gpio())); // initial value
|
||||||
sensor.set_uom(0); // no uom, just for safe measures
|
sensor.set_uom(0); // no uom, just for safe measures
|
||||||
@@ -182,7 +184,7 @@ void AnalogSensor::reload() {
|
|||||||
sensor.poll_ = digitalRead(sensor.gpio());
|
sensor.poll_ = digitalRead(sensor.gpio());
|
||||||
publish_sensor(sensor);
|
publish_sensor(sensor);
|
||||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||||
LOG_DEBUG("Adding analog Write sensor on GPIO %02d", sensor.gpio());
|
LOG_DEBUG("Digital Write on GPIO %02d", sensor.gpio());
|
||||||
pinMode(sensor.gpio(), OUTPUT);
|
pinMode(sensor.gpio(), OUTPUT);
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
||||||
@@ -206,13 +208,12 @@ void AnalogSensor::reload() {
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
digitalWrite(sensor.gpio(), sensor.offset() > 0 ? 1 : 0);
|
digitalWrite(sensor.gpio(), sensor.offset() * sensor.factor() > 0 ? 1 : 0);
|
||||||
sensor.set_value(digitalRead(sensor.gpio()));
|
sensor.set_value(sensor.offset());
|
||||||
}
|
}
|
||||||
sensor.set_uom(0); // no uom, just for safe measures
|
|
||||||
publish_sensor(sensor);
|
publish_sensor(sensor);
|
||||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
|
||||||
LOG_DEBUG("Adding PWM output sensor on GPIO %02d", sensor.gpio());
|
LOG_DEBUG("PWM output on GPIO %02d", sensor.gpio());
|
||||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
ledcAttach(sensor.gpio(), sensor.factor(), 13);
|
ledcAttach(sensor.gpio(), sensor.factor(), 13);
|
||||||
#else
|
#else
|
||||||
@@ -239,10 +240,10 @@ void AnalogSensor::reload() {
|
|||||||
|
|
||||||
// measure input sensors and moving average adc
|
// measure input sensors and moving average adc
|
||||||
void AnalogSensor::measure() {
|
void AnalogSensor::measure() {
|
||||||
static uint32_t measure_last_ = 0;
|
static uint32_t measure_last_ = uuid::get_uptime() - MEASURE_ANALOG_INTERVAL;
|
||||||
|
|
||||||
// measure interval 500ms for adc sensors
|
// measure interval 500ms for adc sensors
|
||||||
if (!measure_last_ || (uuid::get_uptime() - measure_last_) >= MEASURE_ANALOG_INTERVAL) {
|
if ((uuid::get_uptime() - measure_last_) >= MEASURE_ANALOG_INTERVAL) {
|
||||||
measure_last_ = uuid::get_uptime();
|
measure_last_ = uuid::get_uptime();
|
||||||
// go through the list of adc sensors
|
// go through the list of adc sensors
|
||||||
for (auto & sensor : sensors_) {
|
for (auto & sensor : sensors_) {
|
||||||
@@ -434,15 +435,15 @@ void AnalogSensor::remove_ha_topic(const int8_t type, const uint8_t gpio) const
|
|||||||
#else
|
#else
|
||||||
if (type == AnalogType::DIGITAL_OUT) {
|
if (type == AnalogType::DIGITAL_OUT) {
|
||||||
#endif
|
#endif
|
||||||
snprintf(topic, sizeof(topic), "switch/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
snprintf(topic, sizeof(topic), "switch/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||||
} else if (type == AnalogType::DIGITAL_OUT) { // DAC
|
} else if (type == AnalogType::DIGITAL_OUT) { // DAC
|
||||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||||
} else if (type >= AnalogType::PWM_0) {
|
} else if (type >= AnalogType::PWM_0) {
|
||||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||||
} else if (type == AnalogType::DIGITAL_IN) {
|
} else if (type == AnalogType::DIGITAL_IN) {
|
||||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||||
} else {
|
} else {
|
||||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||||
}
|
}
|
||||||
Mqtt::queue_remove_topic(topic);
|
Mqtt::queue_remove_topic(topic);
|
||||||
}
|
}
|
||||||
@@ -514,7 +515,7 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
|
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
|
||||||
|
|
||||||
char stat_t[50];
|
char stat_t[50];
|
||||||
snprintf(stat_t, sizeof(stat_t), "%s/analogsensor_data", Mqtt::basename().c_str()); // use basename
|
snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::basename().c_str(), F_(analogsensor)); // use base path
|
||||||
config["stat_t"] = stat_t;
|
config["stat_t"] = stat_t;
|
||||||
|
|
||||||
char val_obj[50];
|
char val_obj[50];
|
||||||
@@ -534,9 +535,9 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
|
|
||||||
char uniq_s[70];
|
char uniq_s[70];
|
||||||
if (Mqtt::entity_format() == Mqtt::entityFormat::MULTI_SHORT) {
|
if (Mqtt::entity_format() == Mqtt::entityFormat::MULTI_SHORT) {
|
||||||
snprintf(uniq_s, sizeof(uniq_s), "%s_analogsensor_%02d", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(uniq_s, sizeof(uniq_s), "%s_%s_%02d", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
} else {
|
} else {
|
||||||
snprintf(uniq_s, sizeof(uniq_s), "analogsensor_%02d", sensor.gpio());
|
snprintf(uniq_s, sizeof(uniq_s), "%s_%02d", F_(analogsensor), sensor.gpio());
|
||||||
}
|
}
|
||||||
|
|
||||||
config["obj_id"] = uniq_s;
|
config["obj_id"] = uniq_s;
|
||||||
@@ -559,8 +560,8 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
#else
|
#else
|
||||||
if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||||
#endif
|
#endif
|
||||||
snprintf(topic, sizeof(topic), "switch/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(topic, sizeof(topic), "switch/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||||
config["cmd_t"] = command_topic;
|
config["cmd_t"] = command_topic;
|
||||||
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||||
config["pl_on"] = true;
|
config["pl_on"] = true;
|
||||||
@@ -574,30 +575,30 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
config["pl_off"] = Helpers::render_boolean(result, false);
|
config["pl_off"] = Helpers::render_boolean(result, false);
|
||||||
}
|
}
|
||||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) { // DAC
|
} else if (sensor.type() == AnalogType::DIGITAL_OUT) { // DAC
|
||||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||||
config["cmd_t"] = command_topic;
|
config["cmd_t"] = command_topic;
|
||||||
config["min"] = 0;
|
config["min"] = 0;
|
||||||
config["max"] = 255;
|
config["max"] = 255;
|
||||||
config["mode"] = "box"; // auto, slider or box
|
config["mode"] = "box"; // auto, slider or box
|
||||||
config["step"] = 1;
|
config["step"] = 1;
|
||||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
|
||||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||||
config["cmd_t"] = command_topic;
|
config["cmd_t"] = command_topic;
|
||||||
config["min"] = 0;
|
config["min"] = 0;
|
||||||
config["max"] = 100;
|
config["max"] = 100;
|
||||||
config["mode"] = "box"; // auto, slider or box
|
config["mode"] = "box"; // auto, slider or box
|
||||||
config["step"] = 0.1;
|
config["step"] = 0.1;
|
||||||
} else if (sensor.type() == AnalogType::COUNTER) {
|
} else if (sensor.type() == AnalogType::COUNTER) {
|
||||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||||
config["cmd_t"] = command_topic;
|
config["cmd_t"] = command_topic;
|
||||||
config["stat_cla"] = "total_increasing";
|
config["stat_cla"] = "total_increasing";
|
||||||
// config["mode"] = "box"; // auto, slider or box
|
// config["mode"] = "box"; // auto, slider or box
|
||||||
// config["step"] = sensor.factor();
|
// config["step"] = sensor.factor();
|
||||||
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
|
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
|
||||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||||
config["pl_on"] = true;
|
config["pl_on"] = true;
|
||||||
config["pl_off"] = false;
|
config["pl_off"] = false;
|
||||||
@@ -610,7 +611,7 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
config["pl_off"] = Helpers::render_boolean(result, false);
|
config["pl_off"] = Helpers::render_boolean(result, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||||
config["stat_cla"] = "measurement";
|
config["stat_cla"] = "measurement";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +627,9 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mqtt::queue_publish("analogsensor_data", doc.as<JsonObject>());
|
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
|
snprintf(topic, sizeof(topic), "%s_data", F_(analogsensor));
|
||||||
|
Mqtt::queue_publish(topic, doc.as<JsonObject>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from emsesp.cpp, similar to the emsdevice->get_value_info
|
// called from emsesp.cpp, similar to the emsdevice->get_value_info
|
||||||
@@ -657,7 +660,7 @@ bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const i
|
|||||||
output["offset"] = sensor.offset();
|
output["offset"] = sensor.offset();
|
||||||
output["factor"] = sensor.factor();
|
output["factor"] = sensor.factor();
|
||||||
output["value"] = sensor.value();
|
output["value"] = sensor.value();
|
||||||
output["writeable"] = sensor.type() == AnalogType::COUNTER || sensor.type() >= AnalogType::DIGITAL_OUT;
|
output["writeable"] = sensor.type() == AnalogType::COUNTER || (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2);
|
||||||
// min/max for writeable analogs
|
// min/max for writeable analogs
|
||||||
if (sensor.type() == AnalogType::COUNTER) {
|
if (sensor.type() == AnalogType::COUNTER) {
|
||||||
output["min"] = 0;
|
output["min"] = 0;
|
||||||
@@ -665,7 +668,7 @@ bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const i
|
|||||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||||
output["min"] = 0;
|
output["min"] = 0;
|
||||||
output["max"] = sensor.gpio() == 25 || sensor.gpio() == 26 ? 255 : 1;
|
output["max"] = sensor.gpio() == 25 || sensor.gpio() == 26 ? 255 : 1;
|
||||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
|
||||||
output["min"] = 0;
|
output["min"] = 0;
|
||||||
output["max"] = 100;
|
output["max"] = 100;
|
||||||
}
|
}
|
||||||
@@ -702,6 +705,7 @@ bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject
|
|||||||
JsonObject dataSensor = output.createNestedObject(sensor.name());
|
JsonObject dataSensor = output.createNestedObject(sensor.name());
|
||||||
dataSensor["gpio"] = sensor.gpio();
|
dataSensor["gpio"] = sensor.gpio();
|
||||||
dataSensor["type"] = F_(number);
|
dataSensor["type"] = F_(number);
|
||||||
|
dataSensor["value"] = sensor.value();
|
||||||
dataSensor["analog"] = FL_(list_sensortype)[sensor.type()];
|
dataSensor["analog"] = FL_(list_sensortype)[sensor.type()];
|
||||||
if (sensor.type() == AnalogType::ADC) {
|
if (sensor.type() == AnalogType::ADC) {
|
||||||
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
|
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
|
||||||
@@ -713,11 +717,10 @@ bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject
|
|||||||
dataSensor["factor"] = sensor.factor();
|
dataSensor["factor"] = sensor.factor();
|
||||||
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
|
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
|
||||||
dataSensor["factor"] = sensor.factor();
|
dataSensor["factor"] = sensor.factor();
|
||||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
|
||||||
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
|
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
|
||||||
dataSensor["frequency"] = sensor.factor();
|
dataSensor["frequency"] = sensor.factor();
|
||||||
}
|
}
|
||||||
dataSensor["value"] = sensor.value();
|
|
||||||
} else if (id == 0) { // output values command
|
} else if (id == 0) { // output values command
|
||||||
output[sensor.name()] = sensor.value();
|
output[sensor.name()] = sensor.value();
|
||||||
} else { // if someone wants gpio numbers
|
} else { // if someone wants gpio numbers
|
||||||
@@ -763,6 +766,7 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
|||||||
}
|
}
|
||||||
for (auto & sensor : sensors_) {
|
for (auto & sensor : sensors_) {
|
||||||
if (sensor.gpio() == gpio) {
|
if (sensor.gpio() == gpio) {
|
||||||
|
double oldoffset = sensor.offset();
|
||||||
if (sensor.type() == AnalogType::COUNTER) {
|
if (sensor.type() == AnalogType::COUNTER) {
|
||||||
if (val < 0 || value[0] == '+') { // sign corrects values
|
if (val < 0 || value[0] == '+') { // sign corrects values
|
||||||
sensor.set_offset(sensor.value() + val);
|
sensor.set_offset(sensor.value() + val);
|
||||||
@@ -771,11 +775,11 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
|||||||
sensor.set_offset(val);
|
sensor.set_offset(val);
|
||||||
sensor.set_value(val);
|
sensor.set_value(val);
|
||||||
}
|
}
|
||||||
publish_sensor(sensor);
|
if (oldoffset != sensor.offset() && sensor.offset() != EMSESP::nvs_.getDouble(sensor.name().c_str())) {
|
||||||
return true;
|
EMSESP::nvs_.putDouble(sensor.name().c_str(), sensor.value());
|
||||||
|
}
|
||||||
} else if (sensor.type() == AnalogType::ADC) {
|
} else if (sensor.type() == AnalogType::ADC) {
|
||||||
sensor.set_offset(val);
|
sensor.set_offset(val);
|
||||||
return true;
|
|
||||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||||
uint8_t v = val;
|
uint8_t v = val;
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
@@ -784,8 +788,6 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
|||||||
sensor.set_value(v);
|
sensor.set_value(v);
|
||||||
pinMode(sensor.gpio(), OUTPUT);
|
pinMode(sensor.gpio(), OUTPUT);
|
||||||
dacWrite(sensor.gpio(), sensor.offset());
|
dacWrite(sensor.gpio(), sensor.offset());
|
||||||
publish_sensor(sensor);
|
|
||||||
return true;
|
|
||||||
} else
|
} else
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
if ((sensor.gpio() == 23 || sensor.gpio() == 24) && v <= 255) {
|
if ((sensor.gpio() == 23 || sensor.gpio() == 24) && v <= 255) {
|
||||||
@@ -801,11 +803,9 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
|||||||
sensor.set_offset(v);
|
sensor.set_offset(v);
|
||||||
sensor.set_value(v);
|
sensor.set_value(v);
|
||||||
pinMode(sensor.gpio(), OUTPUT);
|
pinMode(sensor.gpio(), OUTPUT);
|
||||||
digitalWrite(sensor.gpio(), sensor.offset() > 0 ? 1 : 0);
|
digitalWrite(sensor.gpio(), sensor.offset() * sensor.factor() > 0 ? 1 : 0);
|
||||||
publish_sensor(sensor);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
|
||||||
if (val > 100) {
|
if (val > 100) {
|
||||||
val = 100;
|
val = 100;
|
||||||
} else if (val < 0) {
|
} else if (val < 0) {
|
||||||
@@ -819,9 +819,28 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
|||||||
uint8_t channel = sensor.type() - AnalogType::PWM_0;
|
uint8_t channel = sensor.type() - AnalogType::PWM_0;
|
||||||
ledcWrite(channel, (uint32_t)(val * 8191 / 100));
|
ledcWrite(channel, (uint32_t)(val * 8191 / 100));
|
||||||
#endif
|
#endif
|
||||||
publish_sensor(sensor);
|
} else {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (oldoffset != sensor.offset()) {
|
||||||
|
EMSESP::webCustomizationService.update(
|
||||||
|
[&](WebCustomization & settings) {
|
||||||
|
for (auto & AnalogCustomization : settings.analogCustomizations) {
|
||||||
|
if (AnalogCustomization.gpio == sensor.gpio() && AnalogCustomization.type == sensor.type()) {
|
||||||
|
AnalogCustomization.offset = sensor.offset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sensor.type() == AnalogType::COUNTER || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.uom() > 0)) {
|
||||||
|
return StateUpdateResult::UNCHANGED; // temporary change
|
||||||
|
} else {
|
||||||
|
return StateUpdateResult::CHANGED; // persist the change
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"local");
|
||||||
|
publish_sensor(sensor);
|
||||||
|
changed_ = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1269,8 +1269,10 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
|
|||||||
has_update(telegram, heatblock_, 23); // see #1317
|
has_update(telegram, heatblock_, 23); // see #1317
|
||||||
has_update(telegram, headertemp_, 25); // see #1317
|
has_update(telegram, headertemp_, 25); // see #1317
|
||||||
//has_update(telegram, temperatur_, 27); // unknown temperature
|
//has_update(telegram, temperatur_, 27); // unknown temperature
|
||||||
has_update(telegram, exhaustTemp_, 31);
|
telegram->read_value(exhaustTemp1_ , 31);
|
||||||
|
if (Helpers::hasValue(exhaustTemp1_)) {
|
||||||
|
has_update(exhaustTemp_, exhaustTemp1_);
|
||||||
|
}
|
||||||
// read 3 char service code / installation status as appears on the display
|
// read 3 char service code / installation status as appears on the display
|
||||||
if ((telegram->message_length > 3) && (telegram->offset == 0)) {
|
if ((telegram->message_length > 3) && (telegram->offset == 0)) {
|
||||||
char serviceCode[4] = {0};
|
char serviceCode[4] = {0};
|
||||||
@@ -1338,7 +1340,10 @@ void Boiler::process_UBAMonitorSlowPlus(std::shared_ptr<const Telegram> telegram
|
|||||||
has_bitupdate(telegram, heatingPump_, 2, 5);
|
has_bitupdate(telegram, heatingPump_, 2, 5);
|
||||||
has_bitupdate(telegram, wwCirc_, 2, 7);
|
has_bitupdate(telegram, wwCirc_, 2, 7);
|
||||||
// temperature measurements at offset 4 unknown, see https://github.com/emsesp/EMS-ESP/issues/620
|
// temperature measurements at offset 4 unknown, see https://github.com/emsesp/EMS-ESP/issues/620
|
||||||
// exhaustTemp was offset 6, now in e4. See #1147, #1150, #1326
|
// exhaust is in E4/31, but not always published, but this goes to zero if burner stops
|
||||||
|
if (!Helpers::hasValue(exhaustTemp1_)) {
|
||||||
|
has_update(telegram, exhaustTemp_, 6);
|
||||||
|
}
|
||||||
has_update(telegram, burnStarts_, 10, 3); // force to 3 bytes
|
has_update(telegram, burnStarts_, 10, 3); // force to 3 bytes
|
||||||
has_update(telegram, burnWorkMin_, 13, 3); // force to 3 bytes
|
has_update(telegram, burnWorkMin_, 13, 3); // force to 3 bytes
|
||||||
has_update(telegram, burn2WorkMin_, 16, 3); // force to 3 bytes
|
has_update(telegram, burn2WorkMin_, 16, 3); // force to 3 bytes
|
||||||
|
|||||||
@@ -113,7 +113,8 @@ class Boiler : public EMSdevice {
|
|||||||
uint16_t switchTemp_; // Switch temperature
|
uint16_t switchTemp_; // Switch temperature
|
||||||
uint8_t sysPress_; // System pressure
|
uint8_t sysPress_; // System pressure
|
||||||
uint16_t boilTemp_; // Boiler temperature
|
uint16_t boilTemp_; // Boiler temperature
|
||||||
uint16_t exhaustTemp_; // Exhaust temperature
|
uint16_t exhaustTemp_; // Exhaust temperature published
|
||||||
|
uint16_t exhaustTemp1_; // read from E4
|
||||||
uint8_t burnGas_; // Gas on/off
|
uint8_t burnGas_; // Gas on/off
|
||||||
uint8_t burnGas2_; // Gas stage 2 on/off
|
uint8_t burnGas2_; // Gas stage 2 on/off
|
||||||
uint16_t flameCurr_; // Flame current in micro amps
|
uint16_t flameCurr_; // Flame current in micro amps
|
||||||
|
|||||||
@@ -83,27 +83,34 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
|
|
||||||
// RC20
|
// RC20
|
||||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20) {
|
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20) {
|
||||||
monitor_typeids = {0x91};
|
if (device_id == 0x17) { // master
|
||||||
set_typeids = {0xA8};
|
monitor_typeids = {0x91};
|
||||||
curve_typeids = {0x90};
|
set_typeids = {0xA8};
|
||||||
timer_typeids = {0x8F};
|
curve_typeids = {0x90};
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
timer_typeids = {0x8F};
|
||||||
register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor));
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set));
|
register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor));
|
||||||
register_telegram_type(curve_typeids[i], "RC20Temp", false, MAKE_PF_CB(process_RC20Temp));
|
register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set));
|
||||||
register_telegram_type(timer_typeids[i], "RC20Timer", false, MAKE_PF_CB(process_RC20Timer));
|
register_telegram_type(curve_typeids[i], "RC20Temp", false, MAKE_PF_CB(process_RC20Temp));
|
||||||
|
register_telegram_type(timer_typeids[i], "RC20Timer", false, MAKE_PF_CB(process_RC20Timer));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// remote thermostat uses only 0xAF
|
||||||
|
register_telegram_type(0xAF, "RC20Remote", false, MAKE_PF_CB(process_RC20Remote));
|
||||||
}
|
}
|
||||||
// remote thermostat uses only 0xAF
|
|
||||||
register_telegram_type(0xAF, "RC20Remote", false, MAKE_PF_CB(process_RC20Remote));
|
|
||||||
// RC20 newer
|
// RC20 newer
|
||||||
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) {
|
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) {
|
||||||
monitor_typeids = {0xAE};
|
if (device_id == 0x17) { // master
|
||||||
set_typeids = {0xAD};
|
monitor_typeids = {0xAE};
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
set_typeids = {0xAD};
|
||||||
register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor_2));
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set_2));
|
register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor_2));
|
||||||
|
register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set_2));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// remote thermostat uses only 0xAF
|
||||||
|
register_telegram_type(0xAF, "RC20Remote", false, MAKE_PF_CB(process_RC20Remote));
|
||||||
}
|
}
|
||||||
register_telegram_type(0xAF, "RC20Remote", false, MAKE_PF_CB(process_RC20Remote));
|
|
||||||
// RC30
|
// RC30
|
||||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
|
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
|
||||||
monitor_typeids = {0x41};
|
monitor_typeids = {0x41};
|
||||||
@@ -237,15 +244,23 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
|
|||||||
// look through the Monitor and Set arrays to see if there is a match
|
// look through the Monitor and Set arrays to see if there is a match
|
||||||
uint8_t hc_num = 0;
|
uint8_t hc_num = 0;
|
||||||
bool toggle_ = false;
|
bool toggle_ = false;
|
||||||
// search monitor message types
|
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
// search device-id types for remote thermostats first, they have only a single typeid for all hcs
|
||||||
if (monitor_typeids[i] == telegram->type_id) {
|
if (telegram->src >= 0x18 && telegram->src <= 0x1F) {
|
||||||
hc_num = i + 1;
|
hc_num = telegram->src - 0x17;
|
||||||
toggle_ = true;
|
toggle_ = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not found, search monitor message types
|
||||||
|
if (hc_num == 0) {
|
||||||
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
|
if (monitor_typeids[i] == telegram->type_id) {
|
||||||
|
hc_num = i + 1;
|
||||||
|
toggle_ = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// not found, search status message/set types
|
// not found, search status message/set types
|
||||||
if (hc_num == 0) {
|
if (hc_num == 0) {
|
||||||
for (uint8_t i = 0; i < set_typeids.size(); i++) {
|
for (uint8_t i = 0; i < set_typeids.size(); i++) {
|
||||||
@@ -335,12 +350,6 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found, search device-id types for remote thermostats
|
|
||||||
if (hc_num == 0 && telegram->src >= 0x18 && telegram->src <= 0x1F) {
|
|
||||||
hc_num = telegram->src - 0x17;
|
|
||||||
toggle_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not found, search device-id types for remote thermostats
|
// not found, search device-id types for remote thermostats
|
||||||
if (hc_num == 0 && telegram->dest >= 0x20 && telegram->dest <= 0x27) {
|
if (hc_num == 0 && telegram->dest >= 0x20 && telegram->dest <= 0x27) {
|
||||||
hc_num = telegram->dest - 0x20;
|
hc_num = telegram->dest - 0x20;
|
||||||
@@ -4223,13 +4232,8 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
|
|||||||
MAKE_CF_CB(set_tempautotemp),
|
MAKE_CF_CB(set_tempautotemp),
|
||||||
-1,
|
-1,
|
||||||
30);
|
30);
|
||||||
register_device_value(tag,
|
register_device_value(tag, &hc->remoteseltemp, DeviceValueType::INT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(remoteseltemp), DeviceValueUOM::DEGREES);
|
||||||
&hc->remoteseltemp,
|
// a command is only accepted from the remote device, not from ems-esp.
|
||||||
DeviceValueType::INT,
|
|
||||||
DeviceValueNumOp::DV_NUMOP_DIV2,
|
|
||||||
FL_(remoteseltemp),
|
|
||||||
DeviceValueUOM::DEGREES);
|
|
||||||
// a command is only accepted from the remote device, not from ems-esp.
|
|
||||||
register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup));
|
register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup));
|
||||||
register_device_value(tag,
|
register_device_value(tag,
|
||||||
&hc->switchonoptimization,
|
&hc->switchonoptimization,
|
||||||
@@ -4258,14 +4262,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
|
|||||||
MAKE_CF_CB(set_remotetemp),
|
MAKE_CF_CB(set_remotetemp),
|
||||||
-1,
|
-1,
|
||||||
101);
|
101);
|
||||||
register_device_value(tag,
|
register_device_value(tag, &hc->remotehum, DeviceValueType::UINT, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101);
|
||||||
&hc->remotehum,
|
|
||||||
DeviceValueType::UINT,
|
|
||||||
FL_(remotehum),
|
|
||||||
DeviceValueUOM::PERCENT,
|
|
||||||
MAKE_CF_CB(set_remotehum),
|
|
||||||
-1,
|
|
||||||
101);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EMS_DEVICE_FLAG_CRF:
|
case EMS_DEVICE_FLAG_CRF:
|
||||||
|
|||||||
@@ -1595,7 +1595,11 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// do not overwrite
|
||||||
|
if (json.containsKey(name)) {
|
||||||
|
EMSESP::logger().debug("double json key: %s", name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// handle Booleans
|
// handle Booleans
|
||||||
if (dv.type == DeviceValueType::BOOL && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
if (dv.type == DeviceValueType::BOOL && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
||||||
// see how to render the value depending on the setting
|
// see how to render the value depending on the setting
|
||||||
|
|||||||
@@ -601,10 +601,10 @@ void EMSESP::publish_other_values() {
|
|||||||
publish_device_values(EMSdevice::DeviceType::HEATSOURCE);
|
publish_device_values(EMSdevice::DeviceType::HEATSOURCE);
|
||||||
publish_device_values(EMSdevice::DeviceType::VENTILATION);
|
publish_device_values(EMSdevice::DeviceType::VENTILATION);
|
||||||
publish_device_values(EMSdevice::DeviceType::EXTENSION);
|
publish_device_values(EMSdevice::DeviceType::EXTENSION);
|
||||||
|
publish_device_values(EMSdevice::DeviceType::ALERT);
|
||||||
// other devices without values yet
|
// other devices without values yet
|
||||||
// publish_device_values(EMSdevice::DeviceType::GATEWAY);
|
// publish_device_values(EMSdevice::DeviceType::GATEWAY);
|
||||||
// publish_device_values(EMSdevice::DeviceType::CONNECT);
|
// publish_device_values(EMSdevice::DeviceType::CONNECT);
|
||||||
// publish_device_values(EMSdevice::DeviceType::ALERT);
|
|
||||||
// publish_device_values(EMSdevice::DeviceType::GENERIC);
|
// publish_device_values(EMSdevice::DeviceType::GENERIC);
|
||||||
webCustomEntityService.publish();
|
webCustomEntityService.publish();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -881,7 +881,6 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
break;
|
break;
|
||||||
case DeviceValueType::STRING:
|
case DeviceValueType::STRING:
|
||||||
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime
|
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime
|
||||||
set_ha_classes = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// plain old sensor
|
// plain old sensor
|
||||||
@@ -1130,7 +1129,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
|
|
||||||
// add category "diagnostic" for system entities
|
// add category "diagnostic" for system entities
|
||||||
// config for writeable entities, like switches. diagnostic for read only sensors.
|
// config for writeable entities, like switches. diagnostic for read only sensors.
|
||||||
doc["ent_cat"] = (has_cmd) ? "config" : "diagnostic";
|
doc["ent_cat"] = (has_cmd && !set_ha_classes) ? "config" : "diagnostic";
|
||||||
|
|
||||||
// add the dev json object to the end
|
// add the dev json object to the end
|
||||||
doc["dev"] = dev_json;
|
doc["dev"] = dev_json;
|
||||||
|
|||||||
@@ -1442,7 +1442,7 @@ bool System::load_board_profile(std::vector<int8_t> & data, const std::string &
|
|||||||
} else if (board_profile == "E32") {
|
} else if (board_profile == "E32") {
|
||||||
data = {2, 4, 5, 17, 33, PHY_type::PHY_TYPE_LAN8720, 16, 1, 0}; // BBQKees Gateway E32
|
data = {2, 4, 5, 17, 33, PHY_type::PHY_TYPE_LAN8720, 16, 1, 0}; // BBQKees Gateway E32
|
||||||
} else if (board_profile == "E32V2") {
|
} else if (board_profile == "E32V2") {
|
||||||
data = {2, 14, 4, 5, 12, PHY_type::PHY_TYPE_LAN8720, 15, 0, 1}; // BBQKees Gateway E32 V2
|
data = {2, 14, 4, 5, 34, PHY_type::PHY_TYPE_LAN8720, 15, 0, 1}; // BBQKees Gateway E32 V2
|
||||||
} else if (board_profile == "MH-ET") {
|
} else if (board_profile == "MH-ET") {
|
||||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // MH-ET Live D1 Mini
|
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // MH-ET Live D1 Mini
|
||||||
} else if (board_profile == "NODEMCU") {
|
} else if (board_profile == "NODEMCU") {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define EMSESP_APP_VERSION "3.6.3-dev.5a"
|
#define EMSESP_APP_VERSION "3.6.3-dev.5b"
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace emsesp {
|
|||||||
|
|
||||||
using namespace std::placeholders; // for `_1` etc
|
using namespace std::placeholders; // for `_1` etc
|
||||||
|
|
||||||
|
bool WebCustomization::_start = true;
|
||||||
|
|
||||||
WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||||
: _httpEndpoint(WebCustomization::read,
|
: _httpEndpoint(WebCustomization::read,
|
||||||
WebCustomization::update,
|
WebCustomization::update,
|
||||||
@@ -132,10 +134,13 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
|||||||
sensor.factor = analogJson["factor"];
|
sensor.factor = analogJson["factor"];
|
||||||
sensor.uom = analogJson["uom"];
|
sensor.uom = analogJson["uom"];
|
||||||
sensor.type = analogJson["type"];
|
sensor.type = analogJson["type"];
|
||||||
|
if (_start && sensor.type == EMSESP::analogsensor_.AnalogType::DIGITAL_OUT && sensor.uom > DeviceValue::DeviceValueUOM::NONE) {
|
||||||
|
sensor.offset = sensor.uom - 1;
|
||||||
|
}
|
||||||
customizations.analogCustomizations.push_back(sensor); // add to list
|
customizations.analogCustomizations.push_back(sensor); // add to list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_start = false;
|
||||||
// load array of entities id's with masks, building up the object class
|
// load array of entities id's with masks, building up the object class
|
||||||
customizations.entityCustomizations.clear();
|
customizations.entityCustomizations.clear();
|
||||||
if (root["masked_entities"].is<JsonArray>()) {
|
if (root["masked_entities"].is<JsonArray>()) {
|
||||||
@@ -203,7 +208,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
|
|||||||
size_t buffer = EMSESP_JSON_SIZE_XXXXLARGE;
|
size_t buffer = EMSESP_JSON_SIZE_XXXXLARGE;
|
||||||
auto * response = new MsgpackAsyncJsonResponse(true, buffer);
|
auto * response = new MsgpackAsyncJsonResponse(true, buffer);
|
||||||
|
|
||||||
while (!response->getSize()) {
|
while (!response) {
|
||||||
delete response;
|
delete response;
|
||||||
buffer -= 1024;
|
buffer -= 1024;
|
||||||
response = new MsgpackAsyncJsonResponse(true, buffer);
|
response = new MsgpackAsyncJsonResponse(true, buffer);
|
||||||
@@ -259,7 +264,7 @@ void WebCustomizationService::customization_entities(AsyncWebServerRequest * req
|
|||||||
// emsesp::EMSESP::logger().info(id.as<const char *>());
|
// emsesp::EMSESP::logger().info(id.as<const char *>());
|
||||||
}
|
}
|
||||||
// add deleted entities from file
|
// add deleted entities from file
|
||||||
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
|
read([&](WebCustomization & settings) {
|
||||||
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
|
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
|
||||||
if (entityCustomization.device_id == device_id) {
|
if (entityCustomization.device_id == device_id) {
|
||||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||||
@@ -288,7 +293,7 @@ void WebCustomizationService::customization_entities(AsyncWebServerRequest * req
|
|||||||
emsdevice->getCustomizationEntities(entity_ids);
|
emsdevice->getCustomizationEntities(entity_ids);
|
||||||
|
|
||||||
// Save the list to the customization file
|
// Save the list to the customization file
|
||||||
EMSESP::webCustomizationService.update(
|
update(
|
||||||
[&](WebCustomization & settings) {
|
[&](WebCustomization & settings) {
|
||||||
// see if we already have a mask list for this device, if so remove it
|
// see if we already have a mask list for this device, if so remove it
|
||||||
for (auto it = settings.entityCustomizations.begin(); it != settings.entityCustomizations.end();) {
|
for (auto it = settings.entityCustomizations.begin(); it != settings.entityCustomizations.end();) {
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ class WebCustomization {
|
|||||||
std::list<EntityCustomization> entityCustomizations; // for a list of entities that have a special mask set
|
std::list<EntityCustomization> entityCustomizations; // for a list of entities that have a special mask set
|
||||||
static void read(WebCustomization & customizations, JsonObject & root);
|
static void read(WebCustomization & customizations, JsonObject & root);
|
||||||
static StateUpdateResult update(JsonObject & root, WebCustomization & customizations);
|
static StateUpdateResult update(JsonObject & root, WebCustomization & customizations);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _start;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebCustomizationService : public StatefulService<WebCustomization> {
|
class WebCustomizationService : public StatefulService<WebCustomization> {
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add any custom entities
|
// add any custom entities
|
||||||
if (EMSESP::webCustomEntityService.count_entities()) {
|
uint8_t customEntities = EMSESP::webCustomEntityService.count_entities();
|
||||||
|
if (customEntities) {
|
||||||
JsonObject obj = devices.createNestedObject();
|
JsonObject obj = devices.createNestedObject();
|
||||||
obj["id"] = 99; // the last unique id
|
obj["id"] = 99; // the last unique id
|
||||||
obj["tn"] = Helpers::translated_word(FL_(custom_device)); // translated device type name
|
obj["tn"] = Helpers::translated_word(FL_(custom_device)); // translated device type name
|
||||||
@@ -103,7 +104,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
|||||||
obj["d"] = 0; // deviceid
|
obj["d"] = 0; // deviceid
|
||||||
obj["p"] = 0; // productid
|
obj["p"] = 0; // productid
|
||||||
obj["v"] = 0; // version
|
obj["v"] = 0; // version
|
||||||
obj["e"] = EMSESP::webCustomEntityService.count_entities(); // number of custom entities
|
obj["e"] = customEntities; // number of custom entities
|
||||||
}
|
}
|
||||||
|
|
||||||
root["connected"] = EMSESP::bus_status() != 2;
|
root["connected"] = EMSESP::bus_status() != 2;
|
||||||
@@ -163,7 +164,8 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root["analog_enabled"] = EMSESP::analogsensor_.analog_enabled();
|
root["analog_enabled"] = EMSESP::analog_enabled();
|
||||||
|
root["platform"] = EMSESP_PLATFORM;
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
@@ -180,7 +182,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) {
|
|||||||
auto * response = new MsgpackAsyncJsonResponse(false, buffer);
|
auto * response = new MsgpackAsyncJsonResponse(false, buffer);
|
||||||
|
|
||||||
// check size
|
// check size
|
||||||
while (!response->getSize()) {
|
while (!response) {
|
||||||
delete response;
|
delete response;
|
||||||
buffer -= 1024;
|
buffer -= 1024;
|
||||||
response = new MsgpackAsyncJsonResponse(false, buffer);
|
response = new MsgpackAsyncJsonResponse(false, buffer);
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
|||||||
|
|
||||||
// load default GPIO configuration based on board profile
|
// load default GPIO configuration based on board profile
|
||||||
std::vector<int8_t> data; // // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
|
std::vector<int8_t> data; // // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
|
||||||
|
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
|
||||||
|
if ((String)EMSESP_DEFAULT_BOARD_PROFILE != "default" && EMSESP::nvs_.getString("boot") == "") {
|
||||||
|
EMSESP::nvs_.putString("boot", (const char *)EMSESP_DEFAULT_BOARD_PROFILE);
|
||||||
|
}
|
||||||
|
/*
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
settings.board_profile = root["board_profile"] | "C3MINI";
|
settings.board_profile = root["board_profile"] | "C3MINI";
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
@@ -97,12 +102,12 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
|||||||
#elif CONFIG_IDF_TARGET_ESP32
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
|
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
if (!System::load_board_profile(data, settings.board_profile.c_str())) {
|
if (!System::load_board_profile(data, settings.board_profile.c_str())) {
|
||||||
// unknown, check for NVS or scan for ethernet, use default E32/E32V2/S32
|
// unknown, check for NVS or scan for ethernet, use default E32/E32V2/S32
|
||||||
#if CONFIG_IDF_TARGET_ESP32 && !defined(EMSESP_STANDALONE)
|
|
||||||
settings.board_profile = EMSESP::nvs_.getString("boot");
|
settings.board_profile = EMSESP::nvs_.getString("boot");
|
||||||
if (!System::load_board_profile(data, settings.board_profile.c_str())) {
|
if (!System::load_board_profile(data, settings.board_profile.c_str())) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32 && !defined(EMSESP_STANDALONE)
|
||||||
if (settings.board_profile == "") { // empty: new test
|
if (settings.board_profile == "") { // empty: new test
|
||||||
if (ETH.begin((eth_phy_type_t)1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
|
if (ETH.begin((eth_phy_type_t)1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
|
||||||
EMSESP::nvs_.putString("boot", "E32");
|
EMSESP::nvs_.putString("boot", "E32");
|
||||||
@@ -119,11 +124,11 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
|||||||
EMSESP::nvs_.putString("boot", "S32");
|
EMSESP::nvs_.putString("boot", "S32");
|
||||||
}
|
}
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
settings.board_profile = "S32";
|
settings.board_profile = "S32";
|
||||||
System::load_board_profile(data, settings.board_profile.c_str());
|
System::load_board_profile(data, settings.board_profile.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
EMSESP::logger().info("No board profile found. Re-setting to %s", settings.board_profile.c_str());
|
EMSESP::logger().info("No board profile found. Re-setting to %s", settings.board_profile.c_str());
|
||||||
} else {
|
} else {
|
||||||
EMSESP::logger().info("Loading board profile %s", settings.board_profile.c_str());
|
EMSESP::logger().info("Loading board profile %s", settings.board_profile.c_str());
|
||||||
|
|||||||
Reference in New Issue
Block a user