>
>
> On Oct 26, 2009, at 9:44 PM, "Gino Putrino"
> <[email protected]
> > wrote:
>
>> Hi,
>> I just acquired a Ritmo AS-800VA.
>> Unfortunately, it doesn't work out of the box with nut - so I had to
>> do a
>> bit of reverse engineering on the protocol to get it working. Am now
>> posting my findings here in the hope it will get this added to the
>> next
>> release.
>>
>> There are also 1000VA and 12000VA versions that this should work with.
>>
>> The protocol is very similar to the megatec protocol - although
>> simpler.
>> Like megatec - it responds to a 'Q1' request.
>> The response is slightly different - instead of the megatec 46
>> character
>> reply string - the ritmo unit replies with a 35 character string of
>> the
>> form:
>>
>> (AAA BBB CCC DD.D EE.E FFF GGGGGGGG
>>
>> Where:
>> AAA is input voltage
>> BBB is output voltage
>> CCC is load - not sure what the range is - when my server plugged
>> in and
>> running - this is 4
>> DD.D is input frequency
>> EE.E is output frequency
>> FFF is battery voltage - seems to be 195 when fully charged -
>> about 160
>> when flat.
>> GGGGGGGG is a bit mask of the form b7b6b5b4b3b2b1b0. So far I've
>> only
>> established b7=1 when on battery power, b6=1 when battery level is
>> critical. Have not seen the remaining bits change from 0.
>>
>> A sample response to the "Q1" request when my server is running
>> normally is:
>> (233 233 004 50.0 50.0 195 00000000
>>
>> The unit does not respond to any of the other megatec queries.
>>
> Including the "I" query? (For identifying the vendor and model)
>
> Also, it is easier for us to analyze proposed code patches if they are
> sent in the form of a unified diff ("diff -u file.old.c file.c"). This
> is especially true if the driver in question has had changes since the
> last release.
>
Hi Charles,
Unfortunately - yes - including the "I" query. The unit just times out
when I send that. Also, the windows software that came with the unit
that I snooped on doesn't send it at all.
Anyway- here is the unified diff.
Regards,
-Gino
--- megatec.original.c 2009-02-17 18:20:48.000000000 +0900
+++ megatec.c 2009-10-18 21:22:26.000000000 +0800
@@ -62,6 +62,7 @@
/* The expected reply lengths */
#define F_CMD_REPLY_LEN 21
#define Q1_CMD_REPLY_LEN 46
+#define Q1_RITMO_CMD_REPLY_LEN 35
#define I_CMD_REPLY_LEN 38
#define IDENT_MAXTRIES 5
@@ -126,6 +127,7 @@
float freq;
float battvolt;
float temp;
+ float outfreq;
char flags[N_FLAGS + 1];
} QueryValues_t;
@@ -436,6 +438,7 @@
char field[FIELD_BUFFER_LEN];
char *anchor;
int ret;
+ int protocolToUse; //0 = megatec, 1 = ritmo
upsdebugx(2, "Asking for UPS status [Q1]...");
ser_flush_io(upsfd);
@@ -443,7 +446,9 @@
usleep(READ_PACE);
/*
- * Expected reply: "(MMM.M NNN.N PPP.P QQQ RR.R S.SS TT.T b7b6b5b4b3b2b1b0<cr>"
+ * Expected reply
+ * (protocol 0 megatec) : "(MMM.M NNN.N PPP.P QQQ RR.R S.SS TT.T b7b6b5b4b3b2b1b0<cr>"
+ * (protocol 1 ritmo) : "(MMM NNN PPP QQ.Q RR.R SS.S TTT b7b6b5b4b3b2b1b0<cr>"
*/
ret = ser_get_line(upsfd, buffer, RECV_BUFFER_LEN, ENDCHAR, IGNCHARS, READ_TIMEOUT, 0);
@@ -459,7 +464,11 @@
return -1;
}
- if (ret < Q1_CMD_REPLY_LEN) {
+ if (ret >= Q1_CMD_REPLY_LEN) {
+ protocolToUse = 0;
+ } else if (ret == Q1_RITMO_CMD_REPLY_LEN) {
+ protocolToUse = 1;
+ } else {
upsdebugx(2, "Q1 => FAILED [short read]");
upsdebug_hex(3, "Q1 detail", (unsigned char *)buffer, ret);
@@ -474,35 +483,67 @@
}
upsdebugx(2, "Q1 => OK [%s]", buffer);
+ if (protocolToUse == 0) {
+ anchor = copy_field(field, &buffer[1], 5);
+ values->ivolt = atof(field);
- anchor = copy_field(field, &buffer[1], 5);
- values->ivolt = atof(field);
+ anchor = copy_field(field, anchor + 1, 5);
+ values->fvolt = atof(field);
- anchor = copy_field(field, anchor + 1, 5);
- values->fvolt = atof(field);
+ anchor = copy_field(field, anchor + 1, 5);
+ values->ovolt = atof(field);
- anchor = copy_field(field, anchor + 1, 5);
- values->ovolt = atof(field);
+ anchor = copy_field(field, anchor + 1, 3);
+ values->load = atof(field);
- anchor = copy_field(field, anchor + 1, 3);
- values->load = atof(field);
+ anchor = copy_field(field, anchor + 1, 4);
+ values->freq = atof(field);
- anchor = copy_field(field, anchor + 1, 4);
- values->freq = atof(field);
+ anchor = copy_field(field, anchor + 1, 4);
+ values->battvolt = atof(field);
- anchor = copy_field(field, anchor + 1, 4);
- values->battvolt = atof(field);
+ anchor = copy_field(field, anchor + 1, 4);
+ values->temp = atof(field);
- anchor = copy_field(field, anchor + 1, 4);
- values->temp = atof(field);
+ values->outfreq = 0.0;
- anchor = copy_field(values->flags, anchor + 1, N_FLAGS);
+ anchor = copy_field(values->flags, anchor + 1, N_FLAGS);
+
+ if (strlen(values->flags) < N_FLAGS) {
+ upsdebugx(2, "Q1 => FAILED [flags error]");
+ return -1;
+ }
+ } else if (protocolToUse == 1) {
+ anchor = copy_field(field, &buffer[1], 3);
+ values->ivolt = atof(field);
+
+ anchor = copy_field(field, anchor + 1, 3);
+ values->ovolt = atof(field);
+
+ anchor = copy_field(field, anchor + 1, 3);
+ values->load = atof(field);
+
+
+ anchor = copy_field(field, anchor + 1, 4);
+ values->outfreq = atof(field);
- if (strlen(values->flags) < N_FLAGS) {
- upsdebugx(2, "Q1 => FAILED [flags error]");
- return -1;
- }
+ anchor = copy_field(field, anchor + 1, 4);
+ values->freq = atof(field);
+
+ anchor = copy_field(field, anchor + 1, 3);
+ values->battvolt = atof(field);
+
+ values->fvolt = 0.0;
+ values->temp = 0.0;
+
+ anchor = copy_field(values->flags, anchor + 1, N_FLAGS);
+
+ if (strlen(values->flags) < N_FLAGS) {
+ upsdebugx(2, "Q1 => FAILED [flags error]");
+ return -1;
+ }
+ }
upsdebugx(2, "Q1 VALUES => [%.1f %.1f %.1f %.1f %.1f %.1f %.1f %s]",
values->ivolt, values->fvolt, values->ovolt, values->load,
values->freq, values->battvolt, values->temp, values->flags);
@@ -711,6 +752,7 @@
dstate_setinfo("output.voltage", "%.1f", query.ovolt);
dstate_setinfo("ups.load", "%.1f", query.load);
dstate_setinfo("input.frequency", "%.1f", query.freq);
+ dstate_setinfo("output.frequency", "%.1f", query.outfreq);
/*
* The battery voltage multiplier should only be applied to battery.voltage_______________________________________________
Nut-upsdev mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/nut-upsdev