The files contained in this repository can be downloaded to your computer using a svn client.
On Linux you simply type the command displayed below.

This URL has Read-Only access.

Statistics
| Revision:

root / trunk / DomotiGa / CUPS.class @ 550

History | View | Annotate | Download (6.2 kB)

1 2 riemers
' Gambas class file
2 2 riemers
3 2 riemers
' Description:
4 2 riemers
' CCUPS.class
5 2 riemers
' Connect to UPS via upsd's tcp socket and monitor status.
6 2 riemers
7 2 riemers
' Development Status:
8 2 riemers
' Working, maybe later add more variables to monitor.
9 2 riemers
' Only tested with my APC SmartUPS 1000, only one UPS at a time supported.
10 2 riemers
11 2 riemers
' DomotiGa - an open source home automation program.
12 526 rdnzl
' Copyright(C) 2008-2011 Ron Klinkien
13 2 riemers
14 25 rdnzl
' Read file called COPYING for license details.
15 2 riemers
16 2 riemers
PROPERTY Host AS String
17 2 riemers
PROPERTY Port AS Integer
18 2 riemers
PROPERTY PollTime AS Integer
19 2 riemers
PROPERTY UPSDebug AS Boolean
20 2 riemers
21 245 rdnzl
PRIVATE sTCPHost AS String
22 245 rdnzl
PRIVATE iTCPPort AS Integer
23 2 riemers
PRIVATE iPollTime AS Integer
24 2 riemers
PRIVATE bUPSDebug AS Boolean
25 2 riemers
26 2 riemers
PUBLIC hUPS AS NEW Socket
27 2 riemers
PUBLIC tUPS AS Timer
28 339 rdnzl
PUBLIC sBuffer AS String
29 2 riemers
30 2 riemers
PUBLIC SUB CheckUPS()
31 2 riemers
32 2 riemers
  DIM rResult AS Result
33 2 riemers
34 339 rdnzl
  TRY rResult = Main.hDB.Exec("SELECT * FROM devices WHERE interface = &1 AND enabled is TRUE", Devices.FindInterface("UPS Socket"))
35 339 rdnzl
  IF NOT ERROR THEN
36 339 rdnzl
    IF rResult.Count THEN
37 339 rdnzl
      FOR EACH rResult
38 339 rdnzl
        IF bUPSDebug THEN Main.WriteDebugLog(("[UPS] checking UPS named '") & rResult!name & ("' with address '") & rResult!address & "'")
39 339 rdnzl
        Check(rResult!address, rResult!module)
40 339 rdnzl
      NEXT
41 339 rdnzl
    ELSE
42 339 rdnzl
      Main.WriteLog(("UPS: no UPS(s) found in device table!"))
43 339 rdnzl
    END IF
44 339 rdnzl
  END IF
45 2 riemers
46 2 riemers
END
47 2 riemers
48 2 riemers
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 2 riemers
' connect to the host:port
50 2 riemers
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
51 2 riemers
PUBLIC FUNCTION Connect() AS Boolean
52 2 riemers
53 2 riemers
  ' try to close the connection
54 2 riemers
  TRY hUPS.Close
55 2 riemers
56 2 riemers
  ' get a new one
57 2 riemers
  hUPS = NEW Socket AS "UPS"
58 245 rdnzl
  hUPS.Connect(sTCPHost, iTCPPort)
59 2 riemers
60 2 riemers
  ' all ok
61 2 riemers
  RETURN TRUE
62 2 riemers
63 2 riemers
CATCH ' some errors
64 245 rdnzl
  Main.WriteLog(("UPS Error: ") & ERROR.Text)
65 2 riemers
  RETURN FALSE
66 2 riemers
67 2 riemers
END
68 2 riemers
69 2 riemers
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70 2 riemers
' disconnect from the host
71 2 riemers
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72 2 riemers
PUBLIC FUNCTION Disconnect() AS Boolean
73 2 riemers
74 2 riemers
  ' try to close the connection
75 2 riemers
  TRY hUPS.Close
76 245 rdnzl
  Main.WriteLog(("UPS socket close."))
77 2 riemers
78 2 riemers
  ' all ok
79 2 riemers
  RETURN TRUE
80 2 riemers
81 2 riemers
CATCH ' some errors
82 245 rdnzl
  Main.WriteLog(("UPS Error: ") & ERROR.Text)
83 2 riemers
  RETURN FALSE
84 2 riemers
85 2 riemers
END
86 2 riemers
87 2 riemers
PUBLIC SUB UPS_Error()
88 2 riemers
89 2 riemers
  ' handle error
90 2 riemers
  SELECT CASE hUPS.Status
91 2 riemers
    CASE Net.CannotCreateSocket
92 454 rdnzl
      Main.WriteLog(("UPS: The system does not allow to create a socket."))
93 2 riemers
    CASE Net.HostNotFound
94 454 rdnzl
      Main.WriteLog(("UPS: Host '") & sTCPHost & ("' not found."))
95 2 riemers
    CASE Net.ConnectionRefused
96 454 rdnzl
      Main.WriteLog(("UPS: Unable to connect. Connection refused."))
97 2 riemers
    CASE Net.CannotRead
98 454 rdnzl
      Main.WriteLog(("UPS: Error reading data."))
99 2 riemers
    CASE Net.CannotWrite
100 454 rdnzl
      Main.WriteLog(("UPS: Error writing data."))
101 2 riemers
  END SELECT
102 2 riemers
103 2 riemers
END
104 2 riemers
105 2 riemers
PUBLIC SUB UPS_Read()
106 2 riemers
107 339 rdnzl
  DIM sData AS String
108 339 rdnzl
109 339 rdnzl
  TRY READ #hUPS, sData, 1
110 453 rdnzl
  IF ERROR THEN Main.WriteDebugLog(("[UPS] Error reading data from network socket! -> ") & Error.Text)
111 339 rdnzl
  IF sData = Chr(10) THEN ' buffer until newline then parse
112 339 rdnzl
    IF Len(sBuffer) > 1 THEN ParseLine(sBuffer)
113 339 rdnzl
    sBuffer = NULL
114 339 rdnzl
  ELSE
115 339 rdnzl
    sBuffer &= sData
116 339 rdnzl
  END IF
117 339 rdnzl
118 339 rdnzl
END
119 339 rdnzl
120 339 rdnzl
PUBLIC SUB ParseLine(sBuf AS String)
121 339 rdnzl
122 339 rdnzl
  DIM sValue, sAddress AS String
123 2 riemers
  DIM iDeviceId AS Integer
124 2 riemers
125 339 rdnzl
  IF bUPSDebug THEN Main.WriteDebugLog(sBuf)
126 339 rdnzl
127 339 rdnzl
  ' try to find address and deviceid
128 339 rdnzl
  IF NOT InStr(sBuf, "ERR") THEN
129 339 rdnzl
    sAddress = Replace(sBuf, "VAR ", "")
130 339 rdnzl
    sAddress = Mid(sAddress, 1, InStr(sAddress, " ", 1) - 1)
131 339 rdnzl
    iDeviceId = Devices.Find(sAddress, Devices.FindInterface("UPS Socket"), "UPS Device")
132 339 rdnzl
  END IF
133 339 rdnzl
134 2 riemers
  ' VAR smartups1000 input.voltage "223.6"
135 2 riemers
  ' VAR smartups1000 ups.status "OL"
136 61 rdnzl
  ' VAR smartups1000 ups.temperature "030.1"
137 339 rdnzl
  ' VAR smartups1000 ups.load "41"
138 339 rdnzl
  IF iDeviceId THEN
139 339 rdnzl
    IF InStr(sBuf, "ups.status") THEN
140 339 rdnzl
      IF InStr(sBuf, "OL") THEN
141 339 rdnzl
        sValue = "Online"
142 339 rdnzl
      ELSE IF InStr(sBuf, "OB") THEN
143 339 rdnzl
        sValue = "On Battery"
144 339 rdnzl
      ELSE IF InStr(sBuf, "LB") THEN
145 339 rdnzl
        sValue = "Low Battery"
146 339 rdnzl
      END IF
147 339 rdnzl
      Devices.ValueUpdate(iDeviceId, sValue, "", "", "")
148 339 rdnzl
    ELSE IF InStr(sBuf, "input.voltage") THEN
149 339 rdnzl
      sValue = Mid$(sBuf, Len(sBuf) - 5, -1)
150 339 rdnzl
      Devices.ValueUpdate(iDeviceId, "", sValue, "", "")
151 526 rdnzl
    ELSE IF InStr(sBuf, "battery.charge") THEN
152 526 rdnzl
      sValue = Mid$(sBuf, Len(sBuf) - 2, -1)
153 526 rdnzl
      Devices.ValueUpdate(iDeviceId, "", sValue, "", "")
154 339 rdnzl
    ELSE IF InStr(sBuf, "ups.temperature") THEN
155 339 rdnzl
      sValue = Mid$(sBuf, Len(sBuf) - 4, -1)
156 339 rdnzl
      Devices.ValueUpdate(iDeviceId, "", "", sValue, "")
157 339 rdnzl
    ELSE IF InStr(sBuf, "ups.load") THEN
158 339 rdnzl
      sValue = Mid$(sBuf, Len(sBuf) - 2, -1)
159 339 rdnzl
      Devices.ValueUpdate(iDeviceId, "", "", sValue, "")
160 2 riemers
    END IF
161 2 riemers
  END IF
162 2 riemers
163 2 riemers
END
164 2 riemers
165 2 riemers
PUBLIC SUB UPS_Ready()
166 2 riemers
167 245 rdnzl
  Main.WriteLog(("UPS socket connected."))
168 2 riemers
169 2 riemers
  ' start poll timer for UPS
170 2 riemers
  tUPS = NEW Timer AS "tUPS"
171 2 riemers
  tUPS.Delay = iPollTime * 1000 ' multiply for seconds
172 2 riemers
  tUPS.Start
173 2 riemers
174 2 riemers
END
175 2 riemers
176 2 riemers
PUBLIC SUB tUPS_Timer()
177 2 riemers
178 2 riemers
  CheckUPS()
179 2 riemers
180 2 riemers
END
181 2 riemers
182 339 rdnzl
PUBLIC SUB Check(sAddress AS String, iModule AS Integer)
183 2 riemers
184 526 rdnzl
  DIM sCmd AS String = "GET VAR " & sAddress & " ups.status"
185 2 riemers
186 2 riemers
  IF bUPSDebug THEN Main.WriteDebugLog("[UPS] " & sCmd)
187 2 riemers
  TRY PRINT #hUPS, sCmd
188 526 rdnzl
  IF ERROR THEN Main.WriteDebugLog(("[UPS] Error writing data to network socket! -> ") & Error.Text)
189 2 riemers
  sCmd = "GET VAR " & sAddress & " input.voltage"
190 2 riemers
  IF bUPSDebug THEN Main.WriteDebugLog("[UPS] " & sCmd)
191 2 riemers
  TRY PRINT #hUPS, sCmd
192 454 rdnzl
  IF ERROR THEN Main.WriteDebugLog(("[UPS] Error writing data to network socket! -> ") & Error.Text)
193 339 rdnzl
194 526 rdnzl
  SELECT CASE Devices.FindDescrForDeviceType(iModule)
195 526 rdnzl
    CASE "BackUPS" ' APC BackUPS
196 339 rdnzl
      sCmd = "GET VAR " & sAddress & " ups.load"
197 526 rdnzl
    CASE "MGE" ' MGE PC 675
198 526 rdnzl
      sCmd = "GET VAR " & sAddress & " battery.charge"
199 526 rdnzl
    CASE ELSE ' APC SmartUPS
200 339 rdnzl
      sCmd = "GET VAR " & sAddress & " ups.temperature"
201 339 rdnzl
  END SELECT
202 61 rdnzl
  IF bUPSDebug THEN Main.WriteDebugLog("[UPS] " & sCmd)
203 61 rdnzl
  TRY PRINT #hUPS, sCmd
204 454 rdnzl
  IF ERROR THEN Main.WriteDebugLog(("[UPS] Error writing data to network socket! -> ") & Error.Text)
205 2 riemers
206 2 riemers
END
207 2 riemers
208 2 riemers
' implement properties
209 2 riemers
PRIVATE FUNCTION Host_Read() AS String
210 2 riemers
211 245 rdnzl
  RETURN sTCPHost
212 2 riemers
213 2 riemers
END
214 2 riemers
215 2 riemers
PRIVATE SUB Host_Write(Value AS String)
216 2 riemers
217 245 rdnzl
  sTCPHost = Value
218 2 riemers
219 2 riemers
END
220 2 riemers
221 2 riemers
PRIVATE FUNCTION Port_Read() AS Integer
222 2 riemers
223 245 rdnzl
  RETURN iTCPPort
224 2 riemers
225 2 riemers
END
226 2 riemers
227 2 riemers
PRIVATE SUB Port_Write(Value AS Integer)
228 2 riemers
229 245 rdnzl
  iTCPPort = Value
230 2 riemers
231 2 riemers
END
232 2 riemers
233 2 riemers
PRIVATE FUNCTION UPSDebug_Read() AS Boolean
234 2 riemers
235 2 riemers
  RETURN bUPSDebug
236 2 riemers
237 2 riemers
END
238 2 riemers
239 2 riemers
PRIVATE SUB UPSDebug_Write(Value AS Boolean)
240 2 riemers
241 2 riemers
  bUPSDebug = Value
242 2 riemers
243 2 riemers
END
244 2 riemers
245 2 riemers
PRIVATE FUNCTION PollTime_Read() AS Integer
246 2 riemers
247 2 riemers
  RETURN iPollTime
248 2 riemers
249 2 riemers
END
250 2 riemers
251 2 riemers
PRIVATE SUB PollTime_Write(Value AS Integer)
252 2 riemers
253 2 riemers
  iPollTime = Value
254 2 riemers
255 2 riemers
END