Skip to content
This repository was archived by the owner on Nov 4, 2025. It is now read-only.

Commit 6dcb062

Browse files
committed
python 3 support
1 parent 6e66f9c commit 6dcb062

5 files changed

Lines changed: 219 additions & 67 deletions

File tree

emp_mos_api/examples/read_profile.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
# -*- coding: utf-8 -*-
2+
from __future__ import print_function
23
import argparse
3-
from emp_mos_api.mos import MosAPI
4+
from emp_mos_api.mos import MosAPI, \
5+
get_flat_name, get_flat_address, get_flat_paycode, get_flat_number, \
6+
get_profile_firstname, get_profile_middlename, get_profile_lastname, \
7+
get_profile_birthdate, get_profile_msisdn, get_profile_email
48

59

10+
# Код написан общим для python2, python3 синтаксисом благодаря
11+
# http://python-future.org/compatible_idioms.html
12+
613
if __name__ == "__main__":
714

815
parser = argparse.ArgumentParser(description='emp.mos.ru API')
@@ -26,24 +33,26 @@
2633

2734
try:
2835
api.login(args.login, args.pwd)
29-
profile = api.get_profile()
36+
p = api.get_profile()
3037

31-
print u'ФИО: {} {} {}'.format(profile['firstname'], profile['middlename'], profile['lastname'])
32-
print u'Дата рождения: {}'.format(profile['birthdate'])
33-
print u'Телефон: {}'.format(profile['msisdn'])
34-
print u'Эл. почта: {}'.format(profile['email'])
38+
print('ФИО: ', get_profile_firstname(p),
39+
' ', get_profile_middlename(p),
40+
' ', get_profile_lastname(p))
41+
print('Дата рождения: ', get_profile_birthdate(p))
42+
print('Телефон: ', get_profile_msisdn(p))
43+
print('Эл. почта: ', get_profile_email(p))
3544

3645
flats = api.get_flats()
3746

38-
print u'Кол-во квартир: {}'.format(len(flats))
39-
assert flats, u'Добавьте квартиру в приложении Госуслуги Москвы'
47+
print('Кол-во квартир: ', len(flats))
48+
assert flats, 'Добавьте квартиру в приложении Госуслуги Москвы'
4049

4150
for f in flats:
42-
print u'Квартира #{}'.format(flats.index(f) + 1)
43-
print u'Название: {}'.format(f['name'])
44-
print u'Адрес: {}'.format(f['address'])
45-
print u'Номер кв: {}'.format(f['flat_number'])
46-
print u'Номер платежки: {}'.format(f['paycode'])
51+
print('Квартира #', flats.index(f) + 1)
52+
print('Название: ', get_flat_name(f))
53+
print('Адрес: ', get_flat_address(f))
54+
print('Номер кв: ', get_flat_number(f))
55+
print('Номер платежки: ', get_flat_paycode(f))
4756

4857
finally:
4958
api.logout()
Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# -*- coding: utf-8 -*-
2+
from __future__ import print_function
23
import argparse
3-
import datetime
4-
from emp_mos_api.mos import MosAPI, get_watercounters_id, get_watercounter_value
4+
from emp_mos_api.mos import MosAPI, \
5+
get_flat_id, get_flat_address, get_flat_paycode, get_flat_number, \
6+
get_watercounters_by_type, get_watermeter_last_value, \
7+
get_watermeter_id, watermeter_new_value_json, get_watercounter_value, \
8+
HOT_WATER, COLD_WATER
59

610

711
if __name__ == "__main__":
@@ -34,52 +38,42 @@
3438
flats = api.get_flats()
3539
assert flats, u'Добавьте квартиру в приложении Госуслуги Москвы'
3640
f = flats[0]
37-
print u'Адрес: {}'.format(f['address'])
38-
print u'Номер кв: {}'.format(f['flat_number'])
39-
print u'Номер платежки: {}'.format(f['paycode'])
41+
print('Адрес: ', get_flat_address(f))
42+
print('Номер кв: ', get_flat_number(f))
43+
print('Номер платежки: ', get_flat_paycode(f))
4044

41-
water = api.get_watercounters(f['flat_id'])
45+
json_data = api.get_watercounters(get_flat_id(f))
4246

4347
new_values = []
4448

45-
hot_ids = get_watercounters_id(u'ГВС', water) # разбираем ответ
49+
#
50+
hots_json = get_watercounters_by_type(HOT_WATER, json_data) # разбираем ответ
4651

47-
if hot_ids:
48-
hot_id = hot_ids[0]
49-
hot_value = get_watercounter_value(hot_id, water) # разбираем ответ
50-
print 'Текущее показание горячей воды: {:.2f} m3'.format(hot_value)
52+
if hots_json:
53+
hot_value = get_watermeter_last_value(hots_json[0])
54+
print('Текущее показание горячей воды: {:.2f} m3'.format(hot_value))
5155

5256
if args.hot:
53-
new_values.append({
54-
'counter_id': hot_id,
55-
'period': datetime.datetime.now().strftime("%Y-%m-%d"),
56-
'indication': '{:.2f}'.format(args.hot).replace('.', ',')
57-
})
58-
print 'Новое показание горячей воды: {:.2f} m3'.format(args.hot)
57+
new_values.append(watermeter_new_value_json(get_watermeter_id(hots_json[0]), args.hot))
58+
print('Новое показание горячей воды: {:.2f} m3'.format(args.hot))
5959
else:
60-
print u'Не найден счетчик горячей воды'
60+
print('Не найден счетчик горячей воды')
6161

6262
#
63-
cold_ids = get_watercounters_id(u'ХВС', water)
64-
65-
if cold_ids:
66-
cold_id = cold_ids[0]
67-
cold_value = get_watercounter_value(cold_id, water)
68-
print 'Текущее показание холодной воды: {:.2f} m3'.format(cold_value)
63+
colds_json = get_watercounters_by_type(COLD_WATER, json_data)
64+
if colds_json:
65+
cold_value = get_watermeter_last_value(colds_json[0])
66+
print('Текущее показание холодной воды: {:.2f} m3'.format(cold_value))
6967

7068
if args.cold:
71-
new_values.append({
72-
'counter_id': cold_id,
73-
'period': datetime.datetime.now().strftime("%Y-%m-%d"),
74-
'indication': '{:.2f}'.format(args.cold).replace('.', ',')
75-
})
76-
print 'Новое показание холодной воды: {:.2f} m3'.format(args.cold)
69+
new_values.append(watermeter_new_value_json(get_watermeter_id(colds_json[0]), args.cold))
70+
print('Новое показание холодной воды: {:.2f} m3'.format(args.cold))
7771
else:
78-
print u'Не найден счетчик холодной воды'
72+
print('Не найден счетчик холодной воды')
7973

8074
if new_values:
81-
api.send_watercounters(f['flat_id'], new_values)
82-
print 'Показания отправлены на сервер'
75+
api.send_watercounters(get_flat_id(f), new_values)
76+
print('Показания отправлены на сервер')
8377

8478
finally:
8579
api.logout()

emp_mos_api/mos.py

Lines changed: 161 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
2+
from __future__ import print_function
23
import requests
3-
import datetime
4-
import argparse
4+
from datetime import datetime, tzinfo
55
from copy import deepcopy
66

77

@@ -18,14 +18,20 @@ def check_error(answer):
1818
:return:
1919
"""
2020
if answer['errorCode'] != 0:
21-
raise Exception(u'Error code: {0}, message: {1}'.format(answer['errorCode'], answer['errorMessage']))
21+
raise Exception('Error code: {0}, message: {1}'.format(answer['errorCode'], answer['errorMessage']))
2222

2323

24+
COLD_WATER = 1
25+
HOT_WATER = 2
26+
2427
counter_types = {
25-
1: u'ХВС',
26-
2: u'ГВС'
28+
COLD_WATER: 'ХВС',
29+
HOT_WATER: 'ГВС'
2730
}
2831

32+
COLD_WATER_TITLE_RUS = counter_types[COLD_WATER]
33+
HOT_WATER_TITLE_RUS = counter_types[HOT_WATER]
34+
2935

3036
class MosAPI(object):
3137

@@ -110,7 +116,7 @@ def get_profile(self):
110116
"""
111117
:return: JSON
112118
{
113-
u'profile': {
119+
u'profile': {
114120
u'drive_license': None,
115121
u'firstname': u'x',
116122
u'middlename': u'x',
@@ -260,7 +266,7 @@ def send_watercounters(self, flat_id, counters_data):
260266
:param counters_data: array of
261267
[{
262268
'counter_id': u'123456', # ['counters'][0]['counterId']
263-
'period': datetime.datetime.now().strftime("%Y-%m-%d"),
269+
'period': datetime.now().strftime("%Y-%m-%d"),
264270
'indication': 'xxx,xx'
265271
}, {
266272
...
@@ -314,28 +320,166 @@ def logout(self):
314320
return response['result']
315321

316322

317-
def get_watercounters_id(water_type, response):
323+
def get_profile_firstname(profile_json):
324+
return profile_json['firstname']
325+
326+
327+
def get_profile_middlename(profile_json):
328+
return profile_json['middlename']
329+
330+
331+
def get_profile_lastname(profile_json):
332+
return profile_json['lastname']
333+
334+
335+
def get_profile_birthdate(profile_json):
336+
return profile_json['birthdate']
337+
338+
339+
def get_profile_msisdn(profile_json):
340+
return profile_json['msisdn']
341+
342+
343+
def get_profile_email(profile_json):
344+
return profile_json['email']
345+
346+
347+
def get_flat_id(flat_json):
348+
"""
349+
:param flat_json answer for api.get_flats()
350+
:return:
351+
"""
352+
return flat_json['flat_id']
353+
354+
355+
def get_flat_name(flat_json):
356+
"""
357+
:param flat_json answer for api.get_flats()
358+
:return:
359+
"""
360+
return flat_json['name']
361+
362+
363+
def get_flat_address(flat_json):
364+
"""
365+
:param flat_json answer for api.get_flats()
366+
:return:
367+
"""
368+
return flat_json['address']
369+
370+
371+
def get_flat_number(flat_json):
372+
"""
373+
:param flat_json answer for api.get_flats()
374+
:return:
375+
"""
376+
return flat_json['flat_number']
377+
378+
379+
def get_flat_paycode(flat_json):
380+
"""
381+
:param flat_json answer for api.get_flats()
382+
:return:
318383
"""
319-
:param water_type: ГВС, ХВС
384+
return flat_json['paycode']
385+
386+
387+
def get_watercounters_id(water_type_id, response):
388+
"""
389+
:param water_type_id: COLD_WATER, HOT_WATER
320390
:param response: get_watercounters() response
321391
:return: array of int or NULL
322392
"""
323-
counters = filter(lambda x: counter_types[x['type']] == water_type, response['counters'])
393+
counters = filter(lambda x: x['type'] == water_type_id, response['counters'])
324394
if counters:
325395
return list(c['counterId'] for c in counters)
326396

327397

398+
def get_watercounters_by_type(water_type_id, response):
399+
"""
400+
:param water_type_id: COLD_WATER, HOT_WATER
401+
:param response: get_watercounters() response
402+
:return: response JSON array:
403+
[{'counterId': 1437373,
404+
'type': 1,
405+
'num': '417944',
406+
'checkup': '2023-09-25+03:00',
407+
'indications':
408+
[{'period': '2018-08-31+03:00', 'indication': '21.38'},
409+
{'period': '2018-07-31+03:00', 'indication': '20.7'},
410+
{'period': '2018-06-30+03:00', 'indication': '19'}]
411+
},
412+
{...}]
413+
"""
414+
return list(filter(lambda x: x['type'] == water_type_id, response['counters']))
415+
416+
417+
def get_watercounter_by_id(id, response):
418+
return list(filter(lambda x: x['counterId'] == id, response['counters']))[0]
419+
420+
421+
def get_counter_by_num(num, response):
422+
"""
423+
:param num: Номер счетчика из приложения
424+
:param response: JSON
425+
{'counterId': 1437373,
426+
'type': 1,
427+
'num': '417944',
428+
'checkup': '2023-09-25+03:00',
429+
'indications':
430+
[{'period': '2018-08-31+03:00', 'indication': '21.38'},
431+
{'period': '2018-07-31+03:00', 'indication': '20.7'},
432+
{'period': '2018-06-30+03:00', 'indication': '19'}]
433+
}
434+
:return:
435+
"""
436+
return list(filter(lambda x: x['num'] == num, response['counters']))[0]
437+
438+
439+
def get_watermeter_last_value(counter):
440+
"""
441+
:param counter: counter JSON from get_counter_by_num
442+
:return: float
443+
"""
444+
indications = counter['indications']
445+
indications.sort(key=lambda x: x['period']) # alphabetical sort data =)
446+
assert indications, 'Нет показаний'
447+
return float(indications[-1]['indication'])
448+
449+
450+
def get_watermeter_id(counter):
451+
return counter['counterId']
452+
453+
454+
def get_watermeter_checkup(counter):
455+
"""
456+
:param counter: counter JSON from get_counter_by_num
457+
'checkup': '2023-09-25+03:00'
458+
:return: datetime с временной зоной
459+
"""
460+
checkup = counter['checkup']
461+
d = datetime.strptime(checkup, '%Y-%m-%d%z') #https://docs.python.org/3/library/datetime.html#datetime.timezone
462+
return d # Не будем приводить к UTC d.replace(tzinfo=None)
463+
464+
328465
def get_watercounter_value(counterId, response):
329466
"""
330467
:param counterId: ['counters'][x]['counterId']
331468
:param response: get_watercounters() response
332469
:return: float
333470
"""
334-
for c in response['counters']:
335-
if c['counterId'] == counterId:
336-
if 'indications' in c:
337-
indications = c['indications']
338-
indications.sort(key=lambda x: x['period']) # alphabetical sort data =)
339-
assert indications
340-
return float(indications[-1]['indication'])
471+
c = get_watercounter_by_id(counterId, response)
472+
return get_watermeter_last_value(c)
473+
341474

475+
def watermeter_new_value_json(counterId, value):
476+
"""
477+
:param counterId: id счетчика. не номер из приложения!
478+
:param value: значение float
479+
:return: dict
480+
"""
481+
return {
482+
'counter_id': int(counterId),
483+
'period': datetime.now().strftime("%Y-%m-%d"),
484+
'indication': '{:.2f}'.format(value).replace('.', ',')
485+
}

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
requests
1+
requests==2.19.1
2+
distro==1.3.0

0 commit comments

Comments
 (0)