3
* newvictron.c - Model specific routines for IMV/Victron units
4
* Match, Match Lite, NetUps
7
* Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
8
* Copyright (C) 2000 Radek Benedikt <benedikt@lphard.cz>
9
* old style "victronups"
10
* Copyright (C) 2001 Daniel.Prynych <Daniel.Prynych@hornet.cz>
11
* porting to now style "newvictron"
12
* Copyright (C) 2003 Gert Lynge <gert@lynge.org>
13
* Removes \n from data (was causing periodic misreadings of temperature
15
* This program is free software; you can redistribute it and/or modify
16
* it under the terms of the GNU General Public License as published by
17
* the Free Software Foundation; either version 2 of the License, or
18
* (at your option) any later version.
20
* This program is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU General Public License for more details.
25
* You should have received a copy of the GNU General Public License
26
* along with this program; if not, write to the Free Software
27
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
#define DRV_VERSION "0.1.3.2"
39
#define UPS_DELAY 150000
40
#define UPS_LONG_DELAY 450000
42
#define VICTRON_OVER 128
47
#define LENGTH_TEMP 256
49
int sdwdelay = 0; /* shutdown after 0 second */
51
extern int sddelay; /* doba po kterou ceka driver po vypnuti ups */
52
extern char upssend_endchar;
53
extern int upsc_debug;
57
void upsdrv_initinfo(void)
59
dstate_setinfo("driver.version.internal", "%s", DRV_VERSION);
61
dstate_setinfo("ups.model", "%s", model_name);
65
int get_data (const char *out_string, char *in_string)
70
ret_code = upsrecv (in_string, LENGTH_TEMP, ENDCHAR, IGNCHARS);
79
void upsdrv_updateinfo(void)
82
char temp[ LENGTH_TEMP ];
85
if (get_data("vAa?",temp)) return;
86
flags = atoi (temp+3);
90
if (flags & VICTRON_OVER)
93
if (flags & VICTRON_RB)
96
if (flags & VICTRON_LB)
99
if (flags & VICTRON_OB)
105
/* dstate_dataok(); */
107
upsdebugx(1, "ups.status = %s\n", dstate_getinfo("ups.status"));
110
/************** ups.x ***************************/
115
if (get_data("vDM?",temp)) return;
116
dstate_setinfo("ups.model", "%s", temp+3);
117
upsdebugx(1, "ups.model >%s<>%s<\n",temp,temp+3);
123
if (get_data("vDm?",temp)) return;
124
dstate_setinfo("ups.mfr", "%s", temp+3);
125
upsdebugx(1, "ups.mfr >%s<>%s<\n",temp,temp+3);
129
if (get_data("vDS?",temp)) return;
130
if (strcmp(temp+3,"NA"))
131
dstate_setinfo("ups.serial", "%s", temp+3);
132
upsdebugx(1, "ups.serial >%s<>%s<\n",temp,temp+3);
135
if (get_data("vDV?",temp)) return;
136
dstate_setinfo("ups.firmware", "%s", temp+3);
137
upsdebugx(1, "ups.firmware >%s<>%s<\n",temp,temp+3);
139
/* ups.temperature */
140
if (get_data("vBT?",temp)) return;
141
if (strcmp(temp+3,"NA"))
142
dstate_setinfo("ups.temperature", "%s", temp+3);
143
upsdebugx(1, "ups.temperature >%s<>%s<\n",temp,temp+3);
146
if (get_data("vO0L?",temp)) return;
147
dstate_setinfo("ups.load", "%s", temp+4);
148
upsdebugx(1, "ups.load >%s<>%s<\n",temp,temp+4);
153
/*if (get_data("vDC?",temp)) return;
154
dstate_setinfo("ups.protocol", "%s", temp+3;
155
upsdebugx(1, "ups.protocol >%s<>%s<\n",temp,temp+3;
159
/************** input.x *****************/
162
if (get_data("vI0U?",temp)) return;
163
dstate_setinfo("input.voltage", "%s", temp+4);
164
upsdebugx(1, "input.voltage >%s<>%s<\n",temp,temp+4);
167
/* input.transfer.low */
168
if (get_data("vFi?",temp)) return;
169
dstate_setinfo("input.transfer.low", "%s", temp+3);
170
upsdebugx(1, "input.transfer.low >%s<>%s<\n",temp,temp+3);
173
/* input.transfer.high */
174
if (get_data("vFj?",temp)) return;
175
dstate_setinfo("input.transfer.high", "%s", temp+3);
176
upsdebugx(1, "input.transfer.high >%s<>%s<\n",temp,temp+3);
179
/* input.frequency */
180
if (get_data("vI0f?",temp)) return;
181
dstate_setinfo("input.frequency", "%2.1f", atof(temp+4) / 10.0);
182
upsdebugx(1, "input.frequency >%s<>%s<\n",temp,temp+4);
185
/*************** output.x ********************************/
189
if (get_data("vO0U?",temp)) return;
190
dstate_setinfo("output.voltage", "%s", temp+4);
191
upsdebugx(1, "output.voltage >%s<>%s<\n",temp,temp+4);
194
/* output.frequency */
195
if (get_data("vOf?",temp)) return;
196
dstate_setinfo("output.frequency", "%2.1f", atof(temp+3) / 10.0);
197
upsdebugx(1, "output.frequency >%s<>%s<\n",temp,temp+3);
201
if (get_data("vO0I?",temp)) return;
202
if (strcmp(temp+4,"NA"))
203
dstate_setinfo("output.current", "%2.1f", atof(temp+4) / 10.0);
204
upsdebugx(1, "output.current >%s<>%s<\n",temp,temp+4);
207
/*************** battery.x *******************************/
210
if (get_data("vBC?",temp)) return;
211
if (strcmp(temp+3,"NA"))
212
dstate_setinfo("battery.charge", "%s", temp+3);
213
upsdebugx(1, "battery.charge >%s<>%s<\n",temp,temp+3);
215
/* battery.voltage */
216
if (get_data("vBU?",temp)) return;
217
dstate_setinfo("battery.voltage", "%2.1f", atof(temp+3) / 10.0);
218
upsdebugx(1, "battery.voltage >%s<>%s<\n",temp,temp+3);
221
/* battery.current */
222
if (get_data("vBI?",temp)) return;
223
if (strcmp(temp+3,"NA"))
224
dstate_setinfo("battery.current", "%2.1f", atof(temp+3) / 10.0);
225
upsdebugx(1, "battery.current >%s<>%s<\n",temp,temp+3);
227
/* battery.temperature */
228
if (get_data("vBT?",temp)) return;
229
if (strcmp(temp+3,"NA"))
230
dstate_setinfo("battery.temperature", "%s", temp+3);
231
upsdebugx(1, "battery.temperature >%s<>%s<\n",temp,temp+3);
233
/* battery.runtime */
234
if (get_data("vBt?",temp)) return;
235
if (strcmp(temp+3,"NA"))
236
dstate_setinfo("battery.runtime", "%s", temp+3);
237
upsdebugx(1, "battery.runtime >%s<>%s<\n",temp,temp+3);
242
void upsdrv_shutdown(void)
247
upssend ("vCb%i!",sdwdelay);
251
void instcmd (int auxcmd, int dlen, char *data)
253
/* TODO: reply to upsd? */
256
/* case test.battery.stop: * stop battery test *
259
* case test.battery.start: * start battery test *
262
* case calibrate.stop: * stop calibration *
265
* case calibrate.start: * start calibration *
270
upslogx(LOG_INFO, "instcmd: unknown type 0x%04x", auxcmd);
275
void upsdrv_help(void)
279
/* list flags and values that you want to receive via -x */
280
void upsdrv_makevartable(void)
282
addvar(VAR_VALUE, "usd", "Seting delay before shutdown");
283
addvar(VAR_VALUE, "modelname", "Seting model name");
286
void upsdrv_banner(void)
288
printf("Network UPS Tools - New Victron UPS driver %s (%s)\n\n",
289
DRV_VERSION, UPS_VERSION);
292
void upsdrv_initups(void)
294
char temp[ LENGTH_TEMP ], *usd = NULL; /* = NULL je dulezite jen pro prekladac */
296
upssend_endchar=ENDCHAR;
297
if (nut_debug_level > 1) upsc_debug = nut_debug_level - 1; /* docasne reseni */
299
upssend_delay = 0; /* zpozdeni mezi odeslanim jednotlivych znaku bude 0 sec */
300
open_serial(device_path, B1200);
303
if ((usd = getval("usd"))) sdwdelay=atoi(usd);
305
model_name = getval("modelname"); /* kdyz modelname nebylo zadano je vraceno NULL*/
307
upsdebugx(1, "(-x) Delay before shutdown %i",sdwdelay);
308
upsdebugx(1, "(-x) UPS Name %s",model_name);
310
/* inicializace a synchronizace UPS */
312
upssendchar (ENDCHAR);
313
usleep (UPS_LONG_DELAY);
315
usleep (UPS_LONG_DELAY);
316
upsrecv (temp, sizeof(temp), ENDCHAR, IGNCHARS);
318
usleep (UPS_LONG_DELAY);
319
upsrecv (temp, sizeof(temp), ENDCHAR, IGNCHARS);
322
upsrecv (temp, sizeof(temp), ENDCHAR, IGNCHARS);
325
/* the upsh handlers can't be done here, as they get initialized
326
* shortly after upsdrv_initups returns to main.
330
void upsdrv_cleanup(void)