~ubuntu-branches/ubuntu/raring/hplip/raring

« back to all changes in this revision

Viewing changes to base/status.py

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2009-12-14 20:08:44 UTC
  • mfrom: (2.1.118 lucid)
  • Revision ID: james.westby@ubuntu.com-20091214200844-z8qhqwgppbu3t7ze
Tags: 3.9.10-4
KBSD patch from KiBi (Closes: #560796)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
import cStringIO
27
27
import xml.parsers.expat as expat
28
28
import re
 
29
import urllib
 
30
try:
 
31
    from xml.etree import ElementTree
 
32
    etree_loaded = True
 
33
except ImportError:
 
34
    etree_loaded = False
29
35
 
30
36
# Local
31
37
from g import *
32
38
from codes import *
33
39
import pml, utils
34
 
 
 
40
import hpmudext
35
41
 
36
42
"""
37
43
status dict structure:
127
133
               STATUS_REV_04 : 20}
128
134
 
129
135
def parseSStatus(s, z=''):
 
136
    revision = ''
 
137
    pens = []
 
138
    top_door = TOP_DOOR_NOT_PRESENT
 
139
    stat = STATUS_UNKNOWN
 
140
    supply_door = SUPPLY_DOOR_NOT_PRESENT
 
141
    duplexer = DUPLEXER_NOT_PRESENT
 
142
    photo_tray = PHOTO_TRAY_NOT_PRESENT
 
143
    in_tray1 = IN_TRAY_NOT_PRESENT
 
144
    in_tray2 = IN_TRAY_NOT_PRESENT
 
145
    media_path = MEDIA_PATH_NOT_PRESENT
130
146
    Z_SIZE = 6
131
147
 
132
 
    z1 = []
133
 
    if len(z) > 0:
134
 
        z_fields = z.split(',')
135
 
 
136
 
        for z_field in z_fields:
137
 
 
138
 
            if len(z_field) > 2 and z_field[:2] == '05':
139
 
                z1s = z_field[2:]
140
 
                z1 = [int(x, 16) for x in z1s]
141
 
 
142
 
    s1 = [int(x, 16) for x in s]
143
 
 
144
 
    revision = s1[1]
145
 
 
146
 
    assert STATUS_REV_00 <= revision <= STATUS_REV_04
147
 
 
148
 
    top_door = bool(s1[2] & 0x8L) + s1[2] & 0x1L
149
 
    supply_door = bool(s1[3] & 0x8L) + s1[3] & 0x1L
150
 
    duplexer = bool(s1[4] & 0xcL) +  s1[4] & 0x1L
151
 
    photo_tray = bool(s1[5] & 0x8L) + s1[5] & 0x1L
152
 
 
153
 
    if revision == STATUS_REV_02:
154
 
        in_tray1 = bool(s1[6] & 0x8L) + s1[6] & 0x1L
155
 
        in_tray2 = bool(s1[7] & 0x8L) + s1[7] & 0x1L
156
 
    else:
157
 
        in_tray1 = bool(s1[6] & 0x8L)
158
 
        in_tray2 = bool(s1[7] & 0x8L)
159
 
 
160
 
    media_path = bool(s1[8] & 0x8L) + (s1[8] & 0x1L) + ((bool(s1[18] & 0x2L))<<1)
161
 
    status_pos = STATUS_POS[revision]
162
 
    status_byte = (s1[status_pos]<<4) + s1[status_pos + 1]
163
 
    stat = status_byte + STATUS_PRINTER_BASE
164
 
 
165
 
    pens, pen, c, d = [], {}, NUM_PEN_POS[revision]+1, 0
166
 
    num_pens = s1[NUM_PEN_POS[revision]]
167
 
    log.debug("Num pens=%d" % num_pens)
168
 
    index = 0
169
 
    pen_data_size = PEN_DATA_SIZE[revision]
170
 
 
171
 
    for p in range(num_pens):
172
 
        info = long(s[c : c + pen_data_size], 16)
173
 
 
174
 
        pen['index'] = index
175
 
 
176
 
        if pen_data_size == 4:
177
 
            pen['type'] = REVISION_2_TYPE_MAP.get(int((info & 0xf000L) >> 12L), 0)
178
 
 
179
 
            if index < (num_pens / 2):
180
 
                pen['kind'] = AGENT_KIND_HEAD
 
148
    try:
 
149
        z1 = []
 
150
        if len(z) > 0:
 
151
            z_fields = z.split(',')
 
152
 
 
153
            for z_field in z_fields:
 
154
 
 
155
                if len(z_field) > 2 and z_field[:2] == '05':
 
156
                    z1s = z_field[2:]
 
157
                    z1 = [int(x, 16) for x in z1s]
 
158
 
 
159
        s1 = [int(x, 16) for x in s]
 
160
 
 
161
        revision = s1[1]
 
162
 
 
163
        assert STATUS_REV_00 <= revision <= STATUS_REV_04
 
164
 
 
165
        top_door = bool(s1[2] & 0x8L) + s1[2] & 0x1L
 
166
        supply_door = bool(s1[3] & 0x8L) + s1[3] & 0x1L
 
167
        duplexer = bool(s1[4] & 0xcL) +  s1[4] & 0x1L
 
168
        photo_tray = bool(s1[5] & 0x8L) + s1[5] & 0x1L
 
169
 
 
170
        if revision == STATUS_REV_02:
 
171
            in_tray1 = bool(s1[6] & 0x8L) + s1[6] & 0x1L
 
172
            in_tray2 = bool(s1[7] & 0x8L) + s1[7] & 0x1L
 
173
        else:
 
174
            in_tray1 = bool(s1[6] & 0x8L)
 
175
            in_tray2 = bool(s1[7] & 0x8L)
 
176
 
 
177
        media_path = bool(s1[8] & 0x8L) + (s1[8] & 0x1L) + ((bool(s1[18] & 0x2L))<<1)
 
178
        status_pos = STATUS_POS[revision]
 
179
        status_byte = (s1[status_pos]<<4) + s1[status_pos + 1]
 
180
        stat = status_byte + STATUS_PRINTER_BASE
 
181
 
 
182
        pen, c, d = {}, NUM_PEN_POS[revision]+1, 0
 
183
        num_pens = s1[NUM_PEN_POS[revision]]
 
184
        index = 0
 
185
        pen_data_size = PEN_DATA_SIZE[revision]
 
186
 
 
187
        log.debug("num_pens = %d" % num_pens)
 
188
        for p in range(num_pens):
 
189
            info = long(s[c : c + pen_data_size], 16)
 
190
 
 
191
            pen['index'] = index
 
192
 
 
193
            if pen_data_size == 4:
 
194
                pen['type'] = REVISION_2_TYPE_MAP.get(int((info & 0xf000L) >> 12L), 0)
 
195
 
 
196
                if index < (num_pens / 2):
 
197
                    pen['kind'] = AGENT_KIND_HEAD
 
198
                else:
 
199
                    pen['kind'] = AGENT_KIND_SUPPLY
 
200
 
 
201
                pen['level-trigger'] = int ((info & 0x0e00L) >> 9L)
 
202
                pen['health'] = int((info & 0x0180L) >> 7L)
 
203
                pen['level'] = int(info & 0x007fL)
 
204
                pen['id'] = 0x1f
 
205
 
 
206
            elif pen_data_size == 8:
 
207
                pen['kind'] = bool(info & 0x80000000L) + ((bool(info & 0x40000000L))<<1L)
 
208
                pen['type'] = int((info & 0x3f000000L) >> 24L)
 
209
                pen['id'] = int((info & 0xf80000) >> 19L)
 
210
                pen['level-trigger'] = int((info & 0x70000L) >> 16L)
 
211
                pen['health'] = int((info & 0xc000L) >> 14L)
 
212
                pen['level'] = int(info & 0xffL)
 
213
 
181
214
            else:
182
 
                pen['kind'] = AGENT_KIND_SUPPLY
183
 
 
184
 
            pen['level-trigger'] = int ((info & 0x0e00L) >> 9L)
185
 
            pen['health'] = int((info & 0x0180L) >> 7L)
186
 
            pen['level'] = int(info & 0x007fL)
187
 
            pen['id'] = 0x1f
188
 
 
189
 
        elif pen_data_size == 8:
190
 
            pen['kind'] = bool(info & 0x80000000L) + ((bool(info & 0x40000000L))<<1L)
191
 
            pen['type'] = int((info & 0x3f000000L) >> 24L)
192
 
            pen['id'] = int((info & 0xf80000) >> 19L)
193
 
            pen['level-trigger'] = int((info & 0x70000L) >> 16L)
194
 
            pen['health'] = int((info & 0xc000L) >> 14L)
195
 
            pen['level'] = int(info & 0xffL)
196
 
 
197
 
        else:
198
 
            log.error("Pen data size error")
199
 
 
200
 
        if len(z1) > 0:
201
 
            # TODO: Determine cause of IndexError for C6100 (defect #1111)
202
 
            try:
203
 
                pen['dvc'] = long(z1s[d+1:d+5], 16)
204
 
                pen['virgin'] = bool(z1[d+5] & 0x8L)
205
 
                pen['hp-ink'] = bool(z1[d+5] & 0x4L)
206
 
                pen['known'] = bool(z1[d+5] & 0x2L)
207
 
                pen['ack'] = bool(z1[d+5] & 0x1L)
208
 
            except IndexError:
209
 
                pen['dvc'] = 0
210
 
                pen['virgin'] = 0
211
 
                pen['hp-ink'] = 0
212
 
                pen['known'] = 0
213
 
                pen['ack'] = 0
214
 
 
215
 
        index += 1
216
 
        pens.append(pen)
217
 
        pen = {}
218
 
        c += pen_data_size
219
 
        d += Z_SIZE
 
215
                log.error("Pen data size error")
 
216
 
 
217
            if len(z1) > 0:
 
218
                # TODO: Determine cause of IndexError for C6100 (defect #1111)
 
219
                try:
 
220
                    pen['dvc'] = long(z1s[d+1:d+5], 16)
 
221
                    pen['virgin'] = bool(z1[d+5] & 0x8L)
 
222
                    pen['hp-ink'] = bool(z1[d+5] & 0x4L)
 
223
                    pen['known'] = bool(z1[d+5] & 0x2L)
 
224
                    pen['ack'] = bool(z1[d+5] & 0x1L)
 
225
                except IndexError:
 
226
                    pen['dvc'] = 0
 
227
                    pen['virgin'] = 0
 
228
                    pen['hp-ink'] = 0
 
229
                    pen['known'] = 0
 
230
                    pen['ack'] = 0
 
231
 
 
232
            log.debug("pen %d %s" % (index, pen))
 
233
 
 
234
            index += 1
 
235
            pens.append(pen)
 
236
            pen = {}
 
237
            c += pen_data_size
 
238
            d += Z_SIZE
 
239
 
 
240
    except (IndexError, ValueError, TypeError), e:
 
241
        log.warn("Status parsing error: %s" % str(e))
220
242
 
221
243
    return {'revision' :    revision,
222
244
             'agents' :      pens,
303
325
 
304
326
    return {'revision' :   STATUS_REV_V,
305
327
             'agents' :     pens,
306
 
             'top-lid' :    top_lid,
 
328
             'top-door' :   top_lid,
307
329
             'status-code': stat,
308
 
             'supply-lid' : SUPPLY_DOOR_NOT_PRESENT,
 
330
             'supply-door': SUPPLY_DOOR_NOT_PRESENT,
309
331
             'duplexer' :   DUPLEXER_NOT_PRESENT,
310
332
             'photo-tray' : PHOTO_TRAY_NOT_PRESENT,
311
333
             'in-tray1' :   IN_TRAY_NOT_PRESENT,
1434
1456
           }
1435
1457
 
1436
1458
 
1437
 
 
1438
 
 
 
1459
element_type10_xlate = { 'ink' : AGENT_KIND_SUPPLY,
 
1460
                         'printhead' : AGENT_KIND_HEAD,
 
1461
                       }
 
1462
 
 
1463
pen_type10_xlate = { 'pK' : AGENT_TYPE_PG,
 
1464
                     'M' : AGENT_TYPE_MAGENTA,
 
1465
                     'C' : AGENT_TYPE_CYAN,
 
1466
                     'Y' : AGENT_TYPE_YELLOW,
 
1467
                     'K' : AGENT_TYPE_BLACK,
 
1468
                   }
 
1469
 
 
1470
pen_level10_xlate = { 'ok' : AGENT_LEVEL_TRIGGER_SUFFICIENT_0,
 
1471
                      'low' : AGENT_LEVEL_TRIGGER_MAY_BE_LOW,
 
1472
                      'out' : AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT,
 
1473
                      'empty' : AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT,
 
1474
                      'missing' : AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT,
 
1475
                    }
 
1476
 
 
1477
pen_health10_xlate = { 'ok' : AGENT_HEALTH_OK,
 
1478
                       'misinstalled' : AGENT_HEALTH_MISINSTALLED,
 
1479
                       'missing' : AGENT_HEALTH_MISINSTALLED,
 
1480
                     }
 
1481
 
 
1482
def StatusType10FetchUrl(dev, url):
 
1483
    if dev.is_local:
 
1484
#       data_fp = cStringIO.StringIO()
 
1485
#       dev.getEWSUrl(url, data_fp)
 
1486
#       data = data_fp.getvalue()
 
1487
        data = parseStatus(dev.deviceID)
 
1488
        log.error("status %s" % data)
 
1489
 
 
1490
    else:
 
1491
        if dev.zc:
 
1492
            status, ip = hpmudext.get_zc_ip_address(dev.zc)
 
1493
            if status != hpmudext.HPMUD_R_OK:
 
1494
                log.error("unable to get IP address of mDNS configured device")
 
1495
                return None
 
1496
        else:
 
1497
            ip = dev.host
 
1498
 
 
1499
        # Get the agent status XML
 
1500
        addr = "http://%s:8080%s" % (ip, url)
 
1501
        feed = urllib.urlopen(addr)
 
1502
        data = feed.read()
 
1503
        feed.close()
 
1504
 
 
1505
    return data
 
1506
 
 
1507
 
 
1508
def StatusType10(dev): # Low End Data Model
 
1509
    status_block = { 'revision' :    STATUS_REV_UNKNOWN,
 
1510
                     'agents' :      [],
 
1511
                     'top-door' :    TOP_DOOR_NOT_PRESENT,
 
1512
                     'supply-door' : TOP_DOOR_NOT_PRESENT,
 
1513
                     'duplexer' :    DUPLEXER_NOT_PRESENT,
 
1514
                     'photo-tray' :  PHOTO_TRAY_NOT_PRESENT,
 
1515
                     'in-tray1' :    IN_TRAY_NOT_PRESENT,
 
1516
                     'in-tray2' :    IN_TRAY_NOT_PRESENT,
 
1517
                     'media-path' :  MEDIA_PATH_NOT_PRESENT,
 
1518
                     'status-code' : STATUS_PRINTER_IDLE,
 
1519
                   }
 
1520
 
 
1521
    if not etree_loaded:
 
1522
        log.error("cannot get status for printer...please load ElementTree module")
 
1523
        return status_block
 
1524
 
 
1525
    # Get the dynamic consumables configuration
 
1526
    data = StatusType10FetchUrl(dev, "/DevMgmt/ConsumableConfigDyn.xml")
 
1527
    if not data:
 
1528
        log.error("unable to fetch pen status")
 
1529
        return status_block
 
1530
    data = data.replace("ccdyn:", "").replace("dd:", "")
 
1531
 
 
1532
    # Parse the agent status XML
 
1533
    agents = []
 
1534
    tree = ElementTree.XML(data)
 
1535
    elements = tree.findall("ConsumableInfo")
 
1536
    for e in elements:
 
1537
#       ElementTree.dump(e)
 
1538
        health = AGENT_HEALTH_OK
 
1539
        ink_level = 0
 
1540
        type = e.find("ConsumableTypeEnum").text
 
1541
        state = e.find("ConsumableLifeState/ConsumableState").text
 
1542
 
 
1543
        # level
 
1544
        if type == "ink":
 
1545
            ink_type = e.find("ConsumableLabelCode").text
 
1546
            if state != "missing":
 
1547
                try:
 
1548
                   ink_level = int(e.find("ConsumablePercentageLevelRemaining").text)
 
1549
                except:
 
1550
                   ink_level = 0
 
1551
        else:
 
1552
            ink_type = ''
 
1553
            if state == "ok":
 
1554
                ink_level = 100
 
1555
 
 
1556
        log.debug("type '%s' state '%s' ink_type '%s' ink_level %d" % (type, state, ink_type, ink_level))
 
1557
 
 
1558
        entry = { 'kind' : element_type10_xlate.get(type, AGENT_KIND_NONE),
 
1559
                  'type' : pen_type10_xlate.get(ink_type, AGENT_TYPE_NONE),
 
1560
                  'health' : pen_health10_xlate.get(state, AGENT_HEALTH_OK),
 
1561
                  'level' : int(ink_level),
 
1562
                  'level-trigger' : pen_level10_xlate.get(state, AGENT_LEVEL_TRIGGER_SUFFICIENT_0)
 
1563
                }
 
1564
 
 
1565
        log.debug("%s" % entry)
 
1566
        agents.append(entry)
 
1567
 
 
1568
    status_block['agents'] = agents
 
1569
 
 
1570
    # Get the media handling configuration
 
1571
    data = StatusType10FetchUrl(dev, "/DevMgmt/MediaHandlingDyn.xml")
 
1572
    if not data:
 
1573
        log.error("unable to fetch media handling status")
 
1574
        return status_block
 
1575
    data = data.replace("mhdyn:", "").replace("dd:", "")
 
1576
 
 
1577
    # Parse the media handling XML
 
1578
    tree = ElementTree.XML(data)
 
1579
    elements = tree.findall("InputTray")
 
1580
    for e in elements:
 
1581
#       ElementTree.dump(e)
 
1582
        bin_name = e.find("InputBin").text
 
1583
        if bin_name == "Tray1":
 
1584
            status_block['in-tray1'] = IN_TRAY_PRESENT
 
1585
        elif bin_name == "Tray2":
 
1586
            status_block['in-tray2'] = IN_TRAY_PRESENT
 
1587
        elif bin_name == "PhotoTray":
 
1588
            status_block['photo-tray'] = PHOTO_TRAY_ENGAGED
 
1589
        else:
 
1590
            log.error("found invalid bin name '%s'" % bin_name)
 
1591
 
 
1592
    elements = tree.findall("Accessories/MediaHandlingDeviceFunctionType")
 
1593
    for e in elements:
 
1594
#       ElementTree.dump(e)
 
1595
        if e.text == "autoDuplexor":
 
1596
            status_block['duplexer'] = DUPLEXER_DOOR_CLOSED
 
1597
        else:
 
1598
            log.error("found invalid media accessory '%s'" % e.text)
 
1599
 
 
1600
    # Get the product status
 
1601
    data = StatusType10FetchUrl(dev, "/DevMgmt/ProductStatusDyn.xml")
 
1602
    if not data:
 
1603
        log.error("unable to fetch product status")
 
1604
        return status_block
 
1605
    data = data.replace("psdyn:", "").replace("locid:", "")
 
1606
    data = data.replace("pscat:", "").replace("dd:", "").replace("ad:", "")
 
1607
 
 
1608
    # Parse the product status XML
 
1609
    tree = ElementTree.XML(data)
 
1610
    elements = tree.findall("Status/StatusCategory")
 
1611
    for e in elements:
 
1612
#       ElementTree.dump(e)
 
1613
        if e.text == "closeDoorOrCover":
 
1614
            status_block['top-door'] = TOP_DOOR_OPEN
 
1615
            status_block['supply-door'] = TOP_DOOR_OPEN
 
1616
        elif e.text == "shuttingDown":
 
1617
            status_block['status-code'] = STATUS_PRINTER_TURNING_OFF
 
1618
        elif e.text == "cancelJob":
 
1619
            status_block['status-code'] = STATUS_PRINTER_CANCELING
 
1620
        elif e.text == "trayEmptyOrOpen":
 
1621
            status_block['status-code'] = STATUS_PRINTER_OUT_OF_PAPER
 
1622
        elif e.text == "jamInPrinter":
 
1623
            status_block['status-code'] = STATUS_PRINTER_MEDIA_JAM
 
1624
        elif e.text == "hardError":
 
1625
            status_block['status-code'] = STATUS_PRINTER_HARD_ERROR
 
1626
        elif e.text == "outputBinFull":
 
1627
            status_block['status-code'] = STATUS_PRINTER_OUTPUT_BIN_FULL
 
1628
        elif e.text == "unexpectedSizeInTray":
 
1629
            status_block['status-code'] = STATUS_PRINTER_MEDIA_SIZE_MISMATCH
 
1630
        elif e.text == "insertOrCloseTray2":
 
1631
            status_block['status-code'] = STATUS_PRINTER_TRAY_2_MISSING
 
1632
 
 
1633
    return status_block