Skip to content

Updated Phoenix Contact modbus driver for newer models - #2689

Merged
jimklimov merged 17 commits into
networkupstools:masterfrom
RikyPlaza:phoenixcontact_modbus_drv
Dec 1, 2024
Merged

jimklimov merged 17 commits into
networkupstools:masterfrom
RikyPlaza:phoenixcontact_modbus_drv

Conversation

@RikyPlaza

Copy link
Copy Markdown
Contributor

Updated Phoenix Contact modbus driver for newer models which are using different modbus addresses. Choice is made basing on the UPS firmware version and the model information have been changed in order to have a quick feedback over the new/old model detection.

…es. Choice is made basing on firmware version.

Signed-off-by: RikyPlaza <rikyrod2001@gmail.com>

@jimklimov jimklimov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for a solid-looking enhancement. A NEWS.adoc entry would be good, beside addressing the specific comments I mentioned during a look at code.

Comment thread drivers/phoenixcontact_modbus.c Outdated
fatalx(EXIT_FAILURE, "Invalid modbus slave ID %d",MODBUS_SLAVE_ID);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and several times above - needless added whitespace

Comment thread drivers/phoenixcontact_modbus.c Outdated
if (CHECK_BIT(tab_reg[0], 16))
alarm_set("Low Battery (Service)");

uint32_t alarms_word;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and above, variable definitions are added in the middle of scope. NUT coding style requires all definitions to be before code, so older systems can build current NUT too. Probably that is what CI failed about all over the place.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undersoot!

Comment thread drivers/phoenixcontact_modbus.c Outdated

mrir(modbus_ctx, 0x2000, 1, &actual_code_functions);

tab_reg[0] = CHECK_BIT(actual_code_functions, 2); //battery mode is the 2nd bit of the register 0x2000

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use block comment style /* ... */

break;
case OLD_UPS:

mrir(modbus_ctx, 29697, 3, tab_reg); /* LB is actually called "shutdown event" on this ups */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea if these numbers make more sense in hex? Are they perhaps bit-masks of some command combos?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason why i kept the old addresses in dec and put the new ones in hex is the way they are reported in the UPSes datasheet. If you want to use a standard for coding i can change all addresses in the same way, but for maintenence in the furure it will be necessary to convery all numbers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, got no particular preference here. If maintenance would be easier with decimal numbers - so be it. Maybe worth a short comment at start of the file though.

Comment thread drivers/phoenixcontact_modbus.c Outdated
#define MODBUS_SLAVE_ID 192

#define OLD_UPS 0
#define NEW_UPS 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how soon "old" vs. "new" would become obsolete? Maybe more symbolic names would be better (just a thought)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, i've put the models. To be honest there would be another model (TRIO) but i don't have the hardware to test the communication. As soon as it will arrive i can test the driver and see if changes are needed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another options can be an enum to also constrain the values accepted at compile-time (and get warnings like that a switch does not look at all newly defined options).


uint16_t FWVersion;

mrir(modbus_ctx, 0x0004, 1, &FWVersion);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to also populate ups.firmware

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, not sure if the variable should be defined somewhere else or i can just call the dstate_setinfo function.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the global variable makes sense if this info would be used elsewhere (e.g. instead of those OLD_UPS/NEW_UPS defines?)

Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
@RikyPlaza

Copy link
Copy Markdown
Contributor Author

@jimklimov Hello, regarding the NEWS.adoc, could you give me some references please? I've looked in other pull requests but i can't find any example. Thank you!

@AppVeyorBot

Copy link
Copy Markdown

…cted alarm trigger (wrong bit used)

Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
@jimklimov

Copy link
Copy Markdown
Member

@jimklimov Hello, regarding the NEWS.adoc, could you give me some references please? I've looked in other pull requests but i can't find any example. Thank you!

Probably just add a paragraph (bullet point) similar to ones that are already there.

Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
@AppVeyorBot

Copy link
Copy Markdown

Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>

@RikyPlaza RikyPlaza left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files reviewed.

@AppVeyorBot

Copy link
Copy Markdown

@RikyPlaza
RikyPlaza requested a review from jimklimov November 26, 2024 05:36
Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
@jimklimov

Copy link
Copy Markdown
Member

FYI: If the lack of default label would also prove a problem with some other compilers, check other drivers for use of pragmas around that. Typically we end up with a monster like:

#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_COVERED_SWITCH_DEFAULT) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) )
# pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_COVERED_SWITCH_DEFAULT
# pragma GCC diagnostic ignored "-Wcovered-switch-default"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
# pragma GCC diagnostic ignored "-Wunreachable-code"
#endif
/* Older CLANG (e.g. clang-3.4) seems to not support the GCC pragmas above */
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunreachable-code"
# pragma clang diagnostic ignored "-Wcovered-switch-default"
#endif
                /* All enum cases defined as of the time of coding
                 * have been covered above. Handle later definitions,
                 * memory corruptions and buggy inputs below...
                 */
                default:
                        fatalx(EXIT_FAILURE, "no suitable definition found!");
#ifdef __clang__
# pragma clang diagnostic pop
#endif
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_COVERED_SWITCH_DEFAULT) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) )
# pragma GCC diagnostic pop
#endif

@jimklimov

Copy link
Copy Markdown
Member

Also remembered: a man page would be needed to describe the supported devices and the driver options (per addvar() in code) and maybe other nuances - known caveats, etc. Ideally this comes from a driver author, as they best know if there is anything special to know about the devices.

@RikyPlaza

RikyPlaza commented Nov 26, 2024 •

Copy link
Copy Markdown
Contributor Author

the lack of default label would also prove a problem with some other compilers, check other drivers for use of pragmas around that. Typically we end up with a monster like:

@jimklimov I'm not sure if the checks are running, for now i don't see any error so i would let the check finish. Do you know how much time do they ususally take?

@RikyPlaza

Copy link
Copy Markdown
Contributor Author

embered: a man page would be needed to describe the supported devices and the driver options (per addvar() in code) and maybe other nuances - known caveats, etc. Ideally this comes from a driver author, as they best know if there is anything special to know about the devices.

@jimklimov Ok, as soon as the checks are ok i'll take a look to the man page. Should i modify something already present or should i make a new man page?

@jimklimov

Copy link
Copy Markdown
Member

New driver - new man page :)

As for checks, it's about 3-5hrs for all scenarios to run; overall time depends on how maby other PR iterations are queued...

@RikyPlaza

Copy link
Copy Markdown
Contributor Author

@jimklimov Hi, now i see that the there are errors regarding the missing default label in switch statements, but i had to remove them in commit f19c8e0 since the checks were also failing. I really don't understand what it the issue...
In other drivers (blazer_usb.c, clone-outlet.c ecc) i see that the default label is preset.

@jimklimov

Copy link
Copy Markdown
Member

@RikyPlaza : did you try the construct with pragmas per #2689 (comment) ?

@RikyPlaza

Copy link
Copy Markdown
Contributor Author

@jimklimov Hello, if i consider the driver blazer_usb.c i don't see any pragma directive. I'm a little bit confused on how those drivers, without any pragma construct, pass the checks related to the default labels in switch statements...

@RikyPlaza

Copy link
Copy Markdown
Contributor Author

@jimklimov In any case now i try to insert that statemets and commit the driver. Let's see :)

…ault" label in switch statements.

Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
@jimklimov

jimklimov commented Nov 28, 2024 •

Copy link
Copy Markdown
Member

Different compilers and their different warning settings require different rules to be satisfied, and are sonetimes at odds:

  • a switch should definitively handle all cases, so must have a default label - works well for general numeric variables;
  • an enum's valid values are known at compile time, and each must be handled explicitly (even if implemented as many case value: labels preceding the same code block), so...
  • ...a default label is redundant (should never be reachable) in a switch that handles all enum values - this notion is head-on crash vs. the first rule above, hence the pragma's against warnings at this spot and the default label handled to be sure, as the least-worst solution.

Also note fall-through cases (lack of break/return/continue/... before next label) - these are considered a likely oversight by a programmer and in fact often are. Explicit goto superfluous_label to the next line defining this label solves the issue portably.

Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
Signed-off-by: RikyPlaza <158032745+RikyPlaza@users.noreply.github.com>
@RikyPlaza

Copy link
Copy Markdown
Contributor Author

@jimklimov no idea why the checks failed :)

@RikyPlaza RikyPlaza left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea on the fails.

…h cases [networkupstools#2689]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…dbus_drv

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
@jimklimov
jimklimov merged commit 3984321 into networkupstools:master Dec 1, 2024
@jimklimov

Copy link
Copy Markdown
Member

CI setup issue, mis-added new workers :\

Challado pushed a commit to Challado/nut that referenced this pull request Oct 14, 2026
…_modbus_drv

Updated Phoenix Contact modbus driver for newer models

SVN-Git-Bridge: nut-3e341d2d9c-3fc79f1e8124 3984321
Bridge-Author: Jim Klimov <jimklimov+nut@gmail.com>
Bridge-Author-Date: 2024-12-01T18:22:00+01:00
Bridge-Committer: GitHub <noreply@github.com>
Bridge-Committer-Date: 2024-12-01T18:22:00+01:00
From: Jim Klimov <jimklimov+nut@gmail.com>

git-svn-id: file:///mnt/export/subversion/nut/trunk@4172 5f2f2009-99cd-4845-9af7-39d0aa6e3748
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants