Repository: electricitymaps/electricitymaps-contrib

Issue:
Add Moldova
Hey guys,

another part of the puzzle: I just found a site with accessible data for generation and cross-border exchanges for **Moldova**.

http://www.moldelectrica.md/ro/activity/system_state

![image](https://user-images.githubusercontent.com/25743609/34084338-8abbd552-e37e-11e7-9fd5-c6a82ad3bd27.png)

The best thing about it: **it refreshes every minute** and provides the latest numbers.

**POWER PLANTS**:
Numbers next to the symbols represent the electricity generation of the following plants:
- The two NHE are hydro power plants,
- the three units displayed as "CET" run on natural gas and are CHPPs, 
- and the "CERS" power plant may run on multiple fuels, such as gas, coal or oil.

**EMISSION FACTORS**:
For the **unknown CERS fuel-mix**, I would suggest using the "other" category with **700 g/kWh**.

For the **CETs**, I found a [document](https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjhvbnshpLYAhWIEVAKHaIIACQQFgguMAA&url=http%3A%2F%2Fget-moldau.de%2Fdownload%2Fpolicypapers%2F2010%2FGET%2520Moldova_PP%252001%25202010_en.pdf&usg=AOvVaw37WEhiS1RHEn9lR52Ono--) saying the CET's efficiency may be as low as 22% or lower:
 
![image](https://user-images.githubusercontent.com/25743609/34084317-3dee7482-e37e-11e7-8deb-6830db71dc9f.png)

The emission factor should be higher than for modern efficient gas power plants. Based on the efficiency of 22% and released emissions of ca.[ 220 g/kWh(gas)](http://www.klimaneutral-handeln.de/php/kompens-berechnen.php#rechner) **a country-specific gas emission factor of 1,000 g/kWh(el)** for generation of the CET-units might be applied. 

Seems like Estonia and Poland get another carbon-intensive companion ;-)

**INSTALLED CAPACITIES** (presentation from December 2016):

- hydro: 64 MW
- natural gas CHPP (CET): 335 MW
- other (CERS-mix): 2,520 MW 

![image](https://user-images.githubusercontent.com/25743609/34084355-fe2c6380-e37e-11e7-81b3-312b05c3b659.png)

There seem to be some industrial power plants with about 100 MW, and some renewables as PV and wind, but they may be neglected for now, as their generation is unknown anyways.

**CROSS-BORDER FLOWS**
Interconnectors to Ukraine and Romania are also part of the scheme ("Fluxurile MD-UA" and "Fluxurile MD-RO"), where positive values are imports and negative values are exports.

**MISC**
Moldova was previously mentioned in #575 in July, where it says, entso-e were working on implementing data from Moldova in near future. So far, there are no data on entso-e yet. 
So this source should work fine as well, as it is provided by the national TSO.

Greetings, Alex


Discussion:
@alixunderplatz Nice find!  Do you fancy having a go at writing a parser?
@systemcatch Thanks! 

I'd really love to! I even think it might be pretty simple in this case. 
**But**, unfortunately, I focused on learning "_R_" (where I know how to webscrape) rather than "_Python_", so I have no idea how I'll get this to work properly.
From time to time, I look at the parsers folder and the code for different countries, but it remains way too cryptic to me. 😄 I am really sorry!!! 😭

Is there anything I can do like write down where exactly to find the relevant data in the website code?
something like 
- "all power plant data have class="tm2" and "tm3" or
- "the id="tmva378" refers to CET-2 Chişinău and therefore generation from natural gas
![image](https://user-images.githubusercontent.com/25743609/34115433-ebe359f8-e415-11e7-8d3e-d8adbe48a745.png)

Will that help another person writing a parser?
@alixunderplatz That's ok knowing where to get the data on the page is useful.  What would be time saving is if you could create a dictionary mapping each power plant to it's generation type like other the parsers have.
@systemcatch allright, I'll give it a try!
@systemcatch 
I hope it's that simple - I assigned the power plant id from the screenshot above to the types. 
I copied the style of the BG parser list.

```
TYPE_MAPPING = {                        # MOLDOVA
    u'tmva476': 'hydro',                # NHE Costeşti (run-of-river)
    u'tmva112': 'hydro',      		# NHE Dubăsari (run-of-river)
    u'tmva367': 'gas',      		# CET Nord (CHPP)
    u'tmva42': 'gas',             	# CET-1 Chişinău (CHPP)
    u'tmva378': 'gas',             	# CET-2 Chişinău (CHPP)
    u'tmva1024': 'other',             	# CERS Moldovenească (fuel mix coal, gas, oil)
    u'tmva1040': 'consumption',         # Consum
}
```

Further useful ids are:
'tmva1030': total generation
'tmva1052': cross-border flows with UA
'tmva1063': cross-border flows with RO
'time'        : time but without a date

@alixunderplatz  That's good but I don't think we will need the id's, just the plant name (e.g. CET Nord) mapped to type will be enough.

Inspecting the html there doesn't appear to be any values present for each plant.  Watching the developer console there's a request to http://www.moldelectrica.md/utils/load4.php every minute which returns a sequence of numbers that is probably inserted into the page by a script.

Luckily the numbers are in a consistent order so we should be in business. 
@alixunderplatz do you have a link to the presentation of installed capacities?

Resolving patch:
diff --git a/parsers/MD.py b/parsers/MD.py
new file mode 100644
--- /dev/null
+++ b/parsers/MD.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""Parser for Moldova."""
+
+import arrow
+from operator import itemgetter
+import requests
+
+TYPE_MAPPING = {
+    u'tmva476': 'hydro',            # NHE Costeşti (run-of-river) #2 index
+    u'tmva112': 'hydro',      		# NHE Dubăsari (run-of-river) #4 index
+    u'tmva367': 'gas',      		# CET Nord (CHPP) #3 index
+    u'tmva42': 'gas',             	# CET-1 Chişinău (CHPP) #6 index
+    u'tmva378': 'gas',             	# CET-2 Chişinău (CHPP) #5 index
+    u'tmva1024': 'unknown',         # CERS Moldovenească (fuel mix coal, gas, oil) #7 index
+}
+
+display_url = 'http://www.moldelectrica.md/ro/activity/system_state'
+data_url = 'http://www.moldelectrica.md/utils/load4'
+
+def get_data(session = None):
+    """ Returns generation data as a list of floats."""
+
+    s = session or requests.Session()
+
+    #In order for the data url to return data, cookies from the display url must be obtained then reused.
+    response = s.get(display_url)
+    data_response = s.get(data_url)
+    raw_data = data_response.text
+
+    data = [float(i) for i in raw_data.split(',')]
+
+    return data
+
+
+def fetch_production(country_code = 'MD', session = None):
+    """Requests the last known production mix (in MW) of a given country
+
+    Arguments:
+    country_code (optional) -- used in case a parser is able to fetch multiple countries
+    session (optional)      -- request session passed in order to re-use an existing session
+
+    Return:
+    A dictionary in the form:
+    {
+      'countryCode': 'FR',
+      'datetime': '2017-01-01T00:00:00Z',
+      'production': {
+          'biomass': 0.0,
+          'coal': 0.0,
+          'gas': 0.0,
+          'hydro': 0.0,
+          'nuclear': null,
+          'oil': 0.0,
+          'solar': 0.0,
+          'wind': 0.0,
+          'geothermal': 0.0,
+          'unknown': 0.0
+      },
+      'storage': {
+          'hydro': -10.0,
+      },
+      'source': 'mysource.com'
+    }
+    """
+
+    grid_status = get_data(session = session)
+    production = {'solar': None, 'wind': None, 'biomass': None, 'nuclear': 0.0}
+
+    production['gas'] = sum(itemgetter(3,5,6)(grid_status))
+    production['hydro'] = sum(itemgetter(2,4)(grid_status))
+    production['unknown'] = grid_status[7]
+
+    consumption = grid_status[-5]
+
+    dt = arrow.now('Europe/Chisinau').datetime
+
+    datapoint = {
+      'countryCode': country_code,
+      'datetime': dt,
+      'consumption': consumption,
+      'production': production,
+      'storage': {},
+      'source': 'moldelectrica.md'
+    }
+
+    return datapoint
+
+
+def fetch_exchange(country_code1, country_code2, session = None):
+    """Requests the last known power exchange (in MW) between two countries
+    Arguments:
+    country_code1           -- the first country code
+    country_code2           -- the second country code; order of the two codes in params doesn't matter
+    session (optional)      -- request session passed in order to re-use an existing session
+    Return:
+    A dictionary in the form:
+    {
+      'sortedCountryCodes': 'DK->NO',
+      'datetime': '2017-01-01T00:00:00Z',
+      'netFlow': 0.0,
+      'source': 'mysource.com'
+    }
+    where net flow is from DK into NO
+    """
+
+    sortedCountryCodes = '->'.join(sorted([country_code1, country_code2]))
+
+    exchange_status = get_data(session = session)
+
+    if sortedCountryCodes == 'MD->UA':
+        netflow = -1*exchange_status[-3]
+    elif sortedCountryCodes == 'MD->RO':
+        netflow = -1*exchange_status[-2]
+    else:
+        raise NotImplementedError('This exchange pair is not implemented')
+
+    dt = arrow.now('Europe/Chisinau').datetime
+
+    exchange = {
+      'sortedCountryCodes': sortedCountryCodes,
+      'datetime': dt,
+      'netFlow': netflow,
+      'source': 'moldelectrica.md'
+    }
+
+    return exchange
+
+
+if __name__ == '__main__':
+    """Main method, never used by the Electricity Map backend, but handy for testing."""
+
+    print('fetch_production() ->')
+    print(fetch_production())
+    print('fetch_exchange(MD, UA) ->')
+    print(fetch_exchange('MD', 'UA'))
+    print('fetch_exchange(MD, RO) ->')
+    print(fetch_exchange('MD', 'RO'))


Test patch: