mirror of
https://github.com/tbnobody/OpenDTU.git
synced 2025-12-11 17:30:37 +01:00
BREAKING CHANGE: WebAPI endpoint /api/limit/config requires different parameters
Due to the fact that different inverters require different type identifiers in the backend the `limit_type` parameter was changed to numbers from 0 to 3. * AbsolutNonPersistent = 0 * RelativNonPersistent = 1 * AbsolutPersistent = 2 * RelativPersistent = 3
This commit is contained in:
@@ -25,6 +25,13 @@ ID Target Addr Source Addr Cmd SCmd ? Limit Type CRC16 CRC8
|
|||||||
|
|
||||||
#define CRC_SIZE 6
|
#define CRC_SIZE 6
|
||||||
|
|
||||||
|
const uint32_t _powerLimitControlTypeValue[] = {
|
||||||
|
0x0000,
|
||||||
|
0x0001,
|
||||||
|
0x0100,
|
||||||
|
0x0101,
|
||||||
|
};
|
||||||
|
|
||||||
ActivePowerControlCommand::ActivePowerControlCommand(InverterAbstract* inv, const uint64_t router_address)
|
ActivePowerControlCommand::ActivePowerControlCommand(InverterAbstract* inv, const uint64_t router_address)
|
||||||
: DevControlCommand(inv, router_address)
|
: DevControlCommand(inv, router_address)
|
||||||
{
|
{
|
||||||
@@ -64,8 +71,9 @@ void ActivePowerControlCommand::setActivePowerLimit(const float limit, const Pow
|
|||||||
_payload[13] = (l) & 0xff;
|
_payload[13] = (l) & 0xff;
|
||||||
|
|
||||||
// type
|
// type
|
||||||
_payload[14] = (type >> 8) & 0xff;
|
uint32_t type_value = _powerLimitControlTypeValue[type];
|
||||||
_payload[15] = (type) & 0xff;
|
_payload[14] = (type_value >> 8) & 0xff;
|
||||||
|
_payload[15] = (type_value) & 0xff;
|
||||||
|
|
||||||
udpateCRC(CRC_SIZE);
|
udpateCRC(CRC_SIZE);
|
||||||
}
|
}
|
||||||
@@ -102,7 +110,13 @@ float ActivePowerControlCommand::getLimit() const
|
|||||||
|
|
||||||
PowerLimitControlType ActivePowerControlCommand::getType() const
|
PowerLimitControlType ActivePowerControlCommand::getType() const
|
||||||
{
|
{
|
||||||
return (PowerLimitControlType)((static_cast<uint16_t>(_payload[14]) << 8) | _payload[15]);
|
uint32_t type_val = ((static_cast<uint16_t>(_payload[14]) << 8) | _payload[15]);
|
||||||
|
for (uint8_t i = 0; i < PowerLimitControl_Max; i++) {
|
||||||
|
if (type_val == _powerLimitControlTypeValue[i]) {
|
||||||
|
return static_cast<PowerLimitControlType>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PowerLimitControlType::RelativNonPersistent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivePowerControlCommand::gotTimeout()
|
void ActivePowerControlCommand::gotTimeout()
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
#include "DevControlCommand.h"
|
#include "DevControlCommand.h"
|
||||||
|
|
||||||
typedef enum { // ToDo: to be verified by field tests
|
typedef enum { // ToDo: to be verified by field tests
|
||||||
AbsolutNonPersistent = 0x0000, // 0
|
AbsolutNonPersistent,
|
||||||
RelativNonPersistent = 0x0001, // 1
|
RelativNonPersistent,
|
||||||
AbsolutPersistent = 0x0100, // 256
|
AbsolutPersistent,
|
||||||
RelativPersistent = 0x0101 // 257
|
RelativPersistent,
|
||||||
|
PowerLimitControl_Max
|
||||||
} PowerLimitControlType;
|
} PowerLimitControlType;
|
||||||
|
|
||||||
class ActivePowerControlCommand : public DevControlCommand {
|
class ActivePowerControlCommand : public DevControlCommand {
|
||||||
|
|||||||
@@ -91,11 +91,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((root["limit_type"].as<uint16_t>() == PowerLimitControlType::AbsolutNonPersistent)
|
if (!(root["limit_type"].as<uint16_t>() < PowerLimitControlType::PowerLimitControl_Max)) {
|
||||||
|| (root["limit_type"].as<uint16_t>() == PowerLimitControlType::AbsolutPersistent)
|
|
||||||
|| (root["limit_type"].as<uint16_t>() == PowerLimitControlType::RelativNonPersistent)
|
|
||||||
|| (root["limit_type"].as<uint16_t>() == PowerLimitControlType::RelativPersistent))) {
|
|
||||||
|
|
||||||
retMsg["message"] = "Invalid type specified!";
|
retMsg["message"] = "Invalid type specified!";
|
||||||
retMsg["code"] = WebApiError::LimitInvalidType;
|
retMsg["code"] = WebApiError::LimitInvalidType;
|
||||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
|
export enum LimitType {
|
||||||
|
AbsolutNonPersistent,
|
||||||
|
RelativNonPersistent,
|
||||||
|
AbsolutPersistent,
|
||||||
|
RelativPersistent,
|
||||||
|
PowerLimitControl_Max,
|
||||||
|
}
|
||||||
|
|
||||||
export interface LimitConfig {
|
export interface LimitConfig {
|
||||||
serial: string;
|
serial: string;
|
||||||
limit_value: number;
|
limit_value: number;
|
||||||
limit_type: number;
|
limit_type: LimitType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -434,15 +434,15 @@
|
|||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
<ul class="dropdown-menu dropdown-menu-end">
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" @click="onSelectType(1)" href="#">{{ $t('home.Relative') }}</a>
|
<a class="dropdown-item" @click="onSelectType(true)" href="#">{{ $t('home.Relative') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" @click="onSelectType(0)" href="#">{{ $t('home.Absolute') }}</a>
|
<a class="dropdown-item" @click="onSelectType(false)" href="#">{{ $t('home.Absolute') }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="targetLimitType == 0"
|
v-if="!targetLimitRelative"
|
||||||
class="alert alert-secondary mt-3"
|
class="alert alert-secondary mt-3"
|
||||||
role="alert"
|
role="alert"
|
||||||
v-html="$t('home.LimitHint')"
|
v-html="$t('home.LimitHint')"
|
||||||
@@ -507,6 +507,7 @@ import GridProfile from '@/components/GridProfile.vue';
|
|||||||
import HintView from '@/components/HintView.vue';
|
import HintView from '@/components/HintView.vue';
|
||||||
import InverterChannelInfo from '@/components/InverterChannelInfo.vue';
|
import InverterChannelInfo from '@/components/InverterChannelInfo.vue';
|
||||||
import InverterTotalInfo from '@/components/InverterTotalInfo.vue';
|
import InverterTotalInfo from '@/components/InverterTotalInfo.vue';
|
||||||
|
import { LimitType } from '@/types/LimitConfig';
|
||||||
import ModalDialog from '@/components/ModalDialog.vue';
|
import ModalDialog from '@/components/ModalDialog.vue';
|
||||||
import type { DevInfoStatus } from '@/types/DevInfoStatus';
|
import type { DevInfoStatus } from '@/types/DevInfoStatus';
|
||||||
import type { EventlogItems } from '@/types/EventlogStatus';
|
import type { EventlogItems } from '@/types/EventlogStatus';
|
||||||
@@ -584,7 +585,7 @@ export default defineComponent({
|
|||||||
targetLimitMin: 0,
|
targetLimitMin: 0,
|
||||||
targetLimitMax: 100,
|
targetLimitMax: 100,
|
||||||
targetLimitTypeText: this.$t('home.Relative'),
|
targetLimitTypeText: this.$t('home.Relative'),
|
||||||
targetLimitType: 1,
|
targetLimitRelative: true,
|
||||||
|
|
||||||
alertMessageLimit: '',
|
alertMessageLimit: '',
|
||||||
alertTypeLimit: 'info',
|
alertTypeLimit: 'info',
|
||||||
@@ -823,8 +824,7 @@ export default defineComponent({
|
|||||||
this.showAlertLimit = false;
|
this.showAlertLimit = false;
|
||||||
this.targetLimitList.serial = '';
|
this.targetLimitList.serial = '';
|
||||||
this.targetLimitList.limit_value = 0;
|
this.targetLimitList.limit_value = 0;
|
||||||
this.targetLimitType = 1;
|
this.onSelectType(true);
|
||||||
this.targetLimitTypeText = this.$t('home.Relative');
|
|
||||||
|
|
||||||
this.limitSettingLoading = true;
|
this.limitSettingLoading = true;
|
||||||
fetch('/api/limit/status', { headers: authHeader() })
|
fetch('/api/limit/status', { headers: authHeader() })
|
||||||
@@ -846,7 +846,19 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSetLimitSettings(setPersistent: boolean) {
|
onSetLimitSettings(setPersistent: boolean) {
|
||||||
this.targetLimitList.limit_type = (setPersistent ? 256 : 0) + this.targetLimitType;
|
if (setPersistent) {
|
||||||
|
if (this.targetLimitRelative) {
|
||||||
|
this.targetLimitList.limit_type = LimitType.RelativPersistent;
|
||||||
|
} else {
|
||||||
|
this.targetLimitList.limit_type = LimitType.AbsolutPersistent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.targetLimitRelative) {
|
||||||
|
this.targetLimitList.limit_type = LimitType.RelativNonPersistent;
|
||||||
|
} else {
|
||||||
|
this.targetLimitList.limit_type = LimitType.AbsolutNonPersistent;
|
||||||
|
}
|
||||||
|
}
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('data', JSON.stringify(this.targetLimitList));
|
formData.append('data', JSON.stringify(this.targetLimitList));
|
||||||
|
|
||||||
@@ -868,8 +880,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSelectType(type: number) {
|
onSelectType(isRelative: boolean) {
|
||||||
if (type == 1) {
|
if (isRelative) {
|
||||||
this.targetLimitTypeText = this.$t('home.Relative');
|
this.targetLimitTypeText = this.$t('home.Relative');
|
||||||
this.targetLimitMin = 0;
|
this.targetLimitMin = 0;
|
||||||
this.targetLimitMax = 100;
|
this.targetLimitMax = 100;
|
||||||
@@ -878,7 +890,7 @@ export default defineComponent({
|
|||||||
this.targetLimitMin = 0;
|
this.targetLimitMin = 0;
|
||||||
this.targetLimitMax = this.currentLimitList.max_power > 0 ? this.currentLimitList.max_power : 2250;
|
this.targetLimitMax = this.currentLimitList.max_power > 0 ? this.currentLimitList.max_power : 2250;
|
||||||
}
|
}
|
||||||
this.targetLimitType = type;
|
this.targetLimitRelative = isRelative;
|
||||||
},
|
},
|
||||||
|
|
||||||
onShowPowerSettings(serial: string) {
|
onShowPowerSettings(serial: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user